Updated admin and mod flag system
This commit is contained in:
@@ -30,6 +30,7 @@ const App = props => {
|
|||||||
<LazyRoute path='/account' component={() => import('./pages/account')} />
|
<LazyRoute path='/account' component={() => import('./pages/account')} />
|
||||||
|
|
||||||
<LazyRoute path='/admin' component={() => import('./pages/admin')} />
|
<LazyRoute path='/admin' component={() => import('./pages/admin')} />
|
||||||
|
<LazyRoute path='/mod' component={() => import('./pages/mod')} />
|
||||||
|
|
||||||
<LazyRoute path='/privacypolicy' component={async () => () => <Markdown content={require('../markdown/privacy-policy.md').default} />} />
|
<LazyRoute path='/privacypolicy' component={async () => () => <Markdown content={require('../markdown/privacy-policy.md').default} />} />
|
||||||
<LazyRoute path='/credits' component={async () => () => <Markdown content={require('../markdown/credits.md').default} />} />
|
<LazyRoute path='/credits' component={async () => () => <Markdown content={require('../markdown/credits.md').default} />} />
|
||||||
|
|||||||
@@ -5,23 +5,26 @@ import { TokenContext } from '../utilities/token-provider';
|
|||||||
|
|
||||||
import NewsPublisher from '../panels/news-publisher';
|
import NewsPublisher from '../panels/news-publisher';
|
||||||
import NewsEditor from '../panels/news-editor';
|
import NewsEditor from '../panels/news-editor';
|
||||||
import PrivilegeEditor from '../panels/privilege-editor';
|
|
||||||
|
import GrantAdmin from '../panels/grant-admin';
|
||||||
|
import GrantMod from '../panels/grant-mod';
|
||||||
|
|
||||||
const Admin = props => {
|
const Admin = props => {
|
||||||
//context
|
//context
|
||||||
const authTokens = useContext(TokenContext);
|
const authTokens = useContext(TokenContext);
|
||||||
|
|
||||||
//misplaced? (admin only)
|
//misplaced? (admin only)
|
||||||
if (!authTokens.accessToken || authTokens.getPayload().privilege != 'administrator') {
|
if (!authTokens.accessToken || !authTokens.getPayload().admin) {
|
||||||
return <Redirect to='/' />;
|
return <Redirect to='/' />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='page'>
|
<div className='page'>
|
||||||
<h1 className='centered'>Administration</h1>
|
<h1 className='centered'>Administration Tools</h1>
|
||||||
<NewsPublisher />
|
<NewsPublisher />
|
||||||
<NewsEditor />
|
<NewsEditor />
|
||||||
<PrivilegeEditor />
|
<GrantAdmin />
|
||||||
|
<GrantMod />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import React, { useContext } from 'react';
|
||||||
|
import { Redirect } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { TokenContext } from '../utilities/token-provider';
|
||||||
|
|
||||||
|
const Mod = props => {
|
||||||
|
//context
|
||||||
|
const authTokens = useContext(TokenContext);
|
||||||
|
|
||||||
|
//misplaced? (admin only)
|
||||||
|
if (!authTokens.accessToken || !(authTokens.getPayload().admin || authTokens.getPayload().mod)) {
|
||||||
|
return <Redirect to='/' />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='page'>
|
||||||
|
<h1 className='centered'>Moderation Tools</h1>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Mod;
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import React, { useRef, useContext } from 'react';
|
||||||
|
|
||||||
|
import { TokenContext } from '../utilities/token-provider';
|
||||||
|
|
||||||
|
const GrantAdmin = props => {
|
||||||
|
//context
|
||||||
|
const authTokens = useContext(TokenContext);
|
||||||
|
|
||||||
|
//ref
|
||||||
|
const usernameRef = useRef();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2 className='centered'>Grant Admin Privileges</h2>
|
||||||
|
<form>
|
||||||
|
<div>
|
||||||
|
<label htmlFor='username'>Username:</label>
|
||||||
|
<input type='text' name='username' ref={usernameRef} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type='button' onClick={async evt => {
|
||||||
|
evt.preventDefault();
|
||||||
|
const [err, result] = await handleButtonPress(usernameRef.current.value, authTokens.tokenFetch, 'POST');
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
alert(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
alert('admin set');
|
||||||
|
usernameRef.current.value = '';
|
||||||
|
}
|
||||||
|
}}>Submit</button>
|
||||||
|
|
||||||
|
<button type='button' onClick={async evt => {
|
||||||
|
evt.preventDefault();
|
||||||
|
const [err, result] = await handleButtonPress(usernameRef.current.value, authTokens.tokenFetch, 'DELETE');
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
alert(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
alert('admin removed');
|
||||||
|
usernameRef.current.value = '';
|
||||||
|
}
|
||||||
|
}}>Remove</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleButtonPress = async (username, tokenFetch, method) => {
|
||||||
|
const result = await tokenFetch(`${process.env.AUTH_URI}/admin/admin`, {
|
||||||
|
method: method,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Access-Control-Allow-Origin': '*'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
username
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result.ok) {
|
||||||
|
const err = `${result.status}: ${await result.text()}`;
|
||||||
|
console.log(err);
|
||||||
|
return [err, false];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [null, true];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GrantAdmin;
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import React, { useRef, useContext } from 'react';
|
||||||
|
|
||||||
|
import { TokenContext } from '../utilities/token-provider';
|
||||||
|
|
||||||
|
const GrantMod = props => {
|
||||||
|
//context
|
||||||
|
const authTokens = useContext(TokenContext);
|
||||||
|
|
||||||
|
//ref
|
||||||
|
const usernameRef = useRef();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2 className='centered'>Grant Moderation Privileges</h2>
|
||||||
|
<form>
|
||||||
|
<div>
|
||||||
|
<label htmlFor='username'>Username:</label>
|
||||||
|
<input type='text' name='username' ref={usernameRef} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type='button' onClick={async evt => {
|
||||||
|
evt.preventDefault();
|
||||||
|
const [err, result] = await handleButtonPress(usernameRef.current.value, authTokens.tokenFetch, 'POST');
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
alert(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
alert('mod set');
|
||||||
|
usernameRef.current.value = '';
|
||||||
|
}
|
||||||
|
}}>Submit</button>
|
||||||
|
|
||||||
|
<button type='button' onClick={async evt => {
|
||||||
|
evt.preventDefault();
|
||||||
|
const [err, result] = await handleButtonPress(usernameRef.current.value, authTokens.tokenFetch, 'DELETE');
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
alert(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
alert('mod removed');
|
||||||
|
usernameRef.current.value = '';
|
||||||
|
}
|
||||||
|
}}>Remove</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleButtonPress = async (username, tokenFetch, method) => {
|
||||||
|
const result = await tokenFetch(`${process.env.AUTH_URI}/admin/mod`, {
|
||||||
|
method: method,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Access-Control-Allow-Origin': '*'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
username
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result.ok) {
|
||||||
|
const err = `${result.status}: ${await result.text()}`;
|
||||||
|
console.log(err);
|
||||||
|
return [err, false];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [null, true];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GrantMod;
|
||||||
@@ -21,7 +21,7 @@ const Member = () => {
|
|||||||
<Link to='/account'>Account</Link>
|
<Link to='/account'>Account</Link>
|
||||||
<span> - </span>
|
<span> - </span>
|
||||||
|
|
||||||
{ authTokens.getPayload().privilege == 'administrator' ?
|
{ authTokens.getPayload().admin ?
|
||||||
<span>
|
<span>
|
||||||
<Link to='/admin'>Admin</Link>
|
<Link to='/admin'>Admin</Link>
|
||||||
<span> - </span>
|
<span> - </span>
|
||||||
@@ -29,6 +29,14 @@ const Member = () => {
|
|||||||
<span />
|
<span />
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ authTokens.getPayload().mod ?
|
||||||
|
<span>
|
||||||
|
<Link to='/mod'>Moderation</Link>
|
||||||
|
<span> - </span>
|
||||||
|
</span>:
|
||||||
|
<span />
|
||||||
|
}
|
||||||
|
|
||||||
{ /* Logout button logs you out of the server too */ }
|
{ /* Logout button logs you out of the server too */ }
|
||||||
<Link to='/' onClick={async () => {
|
<Link to='/' onClick={async () => {
|
||||||
const result = await authTokens.tokenFetch(`${process.env.AUTH_URI}/auth/logout`, { //NOTE: this gets overwritten as a bugfix
|
const result = await authTokens.tokenFetch(`${process.env.AUTH_URI}/auth/logout`, { //NOTE: this gets overwritten as a bugfix
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
import React, { useState, useRef, useContext } from 'react';
|
|
||||||
import Select from 'react-dropdown-select';
|
|
||||||
|
|
||||||
import { TokenContext } from '../utilities/token-provider';
|
|
||||||
|
|
||||||
const PrivilegeEditor = props => {
|
|
||||||
//context
|
|
||||||
const authTokens = useContext(TokenContext);
|
|
||||||
|
|
||||||
//state
|
|
||||||
const [privilege, setPrivilege] = useState('normal');
|
|
||||||
|
|
||||||
//ref
|
|
||||||
const usernameRef = useRef();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h2 className='centered'>Privilege Editor</h2>
|
|
||||||
<form onSubmit={async evt => {
|
|
||||||
evt.preventDefault();
|
|
||||||
const [err, result] = await handleSubmit(usernameRef.current.value, privilege, authTokens.tokenFetch);
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
alert(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
alert('Privilege set');
|
|
||||||
usernameRef.current.value = '';
|
|
||||||
}
|
|
||||||
}}>
|
|
||||||
<div>
|
|
||||||
<label htmlFor='username'>Username:</label>
|
|
||||||
<input type='text' name='username' ref={usernameRef} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Select
|
|
||||||
options={[{ label: 'administrator', value: 1 }, { label: 'moderator', value: 2 }, { label: 'alpha', value: 3 }, { label: 'beta', value: 4 }, { label: 'gamma', value: 5 }, { label: 'normal', value: 6 }]}
|
|
||||||
onChange={values => setPrivilege(values[0].label)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<button type='submit'>Change</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSubmit = async (username, privilege, tokenFetch) => {
|
|
||||||
const result = await tokenFetch(`${process.env.AUTH_URI}/admin/privilege`, {
|
|
||||||
method: 'PATCH',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Access-Control-Allow-Origin': '*'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
username,
|
|
||||||
privilege
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!result.ok) {
|
|
||||||
const err = `${result.status}: ${await result.text()}`;
|
|
||||||
console.log(err);
|
|
||||||
return [err, false];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [null, true];
|
|
||||||
};
|
|
||||||
|
|
||||||
export default PrivilegeEditor;
|
|
||||||
Reference in New Issue
Block a user