Started working on the admin panel

This commit is contained in:
2021-01-31 12:07:03 +11:00
parent 71f3f8e370
commit be89c2d8d9
14 changed files with 202 additions and 6 deletions
+2 -1
View File
@@ -12,4 +12,5 @@ DB_USERNAME=template
DB_PASSWORD=pikachu
DB_TIMEZONE=Australia/Sydney
SESSION_SECRET=secret
SESSION_SECRET=secret
SESSION_ADMIN=adminsecret
+4 -2
View File
@@ -38,11 +38,13 @@ const App = props => {
<Header />
<Switch>
<LazyRoute exact path='/' component={() => import('./pages/homepage')} />
<LazyRoute path='/signup' component={() => import('./pages/signup')} />
<LazyRoute path='/login' component={() => import('./pages/login')} />
<LazyRoute path='/account' component={() => import('./pages/account')} />
<LazyRoute path='/admin' component={() => import('./pages/admin')} />
<LazyRoute path='*' component={() => import('./pages/not-found')} />
</Switch>
<Footer />
+1 -1
View File
@@ -5,7 +5,7 @@ import { useCookies } from 'react-cookie';
import DeleteAccount from '../panels/delete-account';
const Account = props => {
const [cookies, setCookie] = useCookies(['loggedin']);
const [cookies, setCookie] = useCookies();
//check for logged in redirect
if (!cookies['loggedin']) {
+25
View File
@@ -0,0 +1,25 @@
import React from 'react';
import { Redirect } from 'react-router-dom';
import { useCookies } from 'react-cookie';
import BannedEmails from '../panels/banned-emails';
import NewsPublisher from '../panels/news-publisher';
const Admin = props => {
const [cookies, setCookie] = useCookies();
//check for logged in redirect
if (!cookies['admin']) {
return <Redirect to='/' />;
}
return (
<div className='page'>
<h1 className='centered'>Administration</h1>
<BannedEmails />
<NewsPublisher />
</div>
);
};
export default Admin;
+1 -1
View File
@@ -6,7 +6,7 @@ import { useCookies } from 'react-cookie';
const validateEmail = require('../../../common/utilities/validate-email.js');
const LogIn = props => {
const [cookies, setCookie] = useCookies(['loggedin']);
const [cookies, setCookie] = useCookies();
//check for logged in redirect
if (cookies['loggedin']) {
+1 -1
View File
@@ -7,7 +7,7 @@ const validateEmail = require('../../../common/utilities/validate-email.js');
const validateUsername = require('../../../common/utilities/validate-username.js');
const SignUp = props => {
const [cookies, setCookie] = useCookies(['loggedin']);
const [cookies, setCookie] = useCookies();
//check for logged in redirect
if (cookies['loggedin']) {
+108
View File
@@ -0,0 +1,108 @@
import React, { useState, useEffect } from 'react';
const BannedEmails = props => {
const [data, setData] = useState(null);
let usernameElement, emailElement, dateElement, reasonElement;
let unbanElement;
fetch('/api/admin/banned', { method: 'POST' })
.then(banned => banned.json())
.then(banned => !data ? setData(banned) : null)
.catch(e => console.error(e))
;
return (
<div>
<h2>Banned Accounts</h2>
<table>
<thead>
<tr>
<th>Username</th>
<th>Email</th>
<th>Privilege</th>
<th>Expiry</th>
<th>Reason</th>
</tr>
</thead>
<tbody>
{(data || []).map((entry, index) =>
<tr key={index}>
<td>{entry.username}</td>
<td>{entry.email}</td>
<td>{entry.privilege}</td>
<td>{entry.expiry}</td>
<td>{entry.reason}</td>
</tr>
)}
</tbody>
</table>
<h2>Ban</h2>
<form onSubmit={async e => { e.preventDefault(); await handleBan(usernameElement.value, emailElement.value, dateElement.value, reasonElement.value); }}>
<div>
<label htmlFor='username'>Username:</label>
<input type='text' name='username' ref={e => usernameElement = e} />
</div>
<div>
<label htmlFor='email'>Email:</label>
<input type='email' name='email' ref={e => emailElement = e} />
</div>
<div>
<label htmlFor='expiry'>Expiry:</label>
<input type='date' name='expiry' ref={e => dateElement = e} />
</div>
<div>
<label htmlFor='reason'>Reason:</label>
<textarea rows='4' cols='50' name='reason' ref={e => reasonElement = e} />
</div>
<button type='submit'>Drop The Banhammer</button>
</form>
<h2>Unban</h2>
<form onSubmit={async e => { e.preventDefault(); await handleUnban(unbanElement.value); }}>
<div>
<label htmlFor='username'>Unban User</label>
<input type='text' name='username' ref={e => unbanElement = e} />
</div>
<button type='submit'>Release From Horny Jail</button>
</form>
</div>
);
};
const handleBan = async (username, email, date, reason) => {
username = username.trim();
email = email.trim();
reason = reason.trim();
//generate a new formdata payload
let formData = new FormData();
formData.append('username', username);
formData.append('email', email);
formData.append('date', date);
formData.append('reason', reason);
const result = await fetch('/api/admin/ban', { method: 'POST', body: formData });
alert(await result.text());
};
const handleUnban = async (username) => {
username = username.trim();
let formData = new FormData();
formData.append('username', username);
const result = await fetch('/api/admin/unban', { method: 'POST', body: formData });
alert(await result.text());
};
export default BannedEmails;
@@ -0,0 +1,5 @@
const NewsPublisher = props => {
return null;
};
export default NewsPublisher;
+4
View File
@@ -40,6 +40,10 @@ const route = async (req, res) => {
req.session.account = account;
res.cookie('loggedin', process.env.WEB_ADDRESS);
if (account.privilege == 'administrator') {
res.cookie('admin', process.env.SESSION_ADMIN);
}
//cancel deletion if any
await accounts.update({ deletion: null }, {
where: {
View File
+39
View File
@@ -0,0 +1,39 @@
const { Op } = require('sequelize');
const { bannedEmails, accounts } = require('../database/models');
const route = async (req, res) => {
//make sure the account is an admin
if (req.cookies['admin'] !== process.env.SESSION_ADMIN) {
return res.status(401).send('invalid admin status');
}
//merge the banned accounts with the account data, if any
const data = await bannedEmails.findAll()
.then(bans => bans.map(async ban => {
//find a matching account
const account = await accounts.findOne({
attrubutes: ['username', 'privilege'],
where: {
email: {
[Op.eq]: ban.email
}
}
}) || {};
//merge the data and return (becomes a promise)
return {
username: account.username,
email: ban.email,
privilege: account.privilege,
expiry: ban.expiry,
reason: ban.reason
};
}))
.then(promises => Promise.all(promises)) //resolve promises
.catch(e => console.error(e))
;
res.status(200).json(data);
};
module.exports = route;
+9
View File
@@ -0,0 +1,9 @@
const express = require('express');
const router = express.Router();
//basic account management
router.post('/banned', require('./banned'));
//router.post('/ban', require('./ban'));
//router.post('/unban', require('./unban'));
module.exports = router;
View File
+3
View File
@@ -22,6 +22,9 @@ const database = require('./database');
//account management
app.use('/api/accounts', require('./accounts'));
//administration
app.use('/api/admin', require('./admin'));
//send static files
app.use('/', express.static(path.resolve(__dirname, 'public')));