From e597974581caa4eb9a1b8152396907638cedaf53 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Wed, 24 Mar 2021 08:22:47 +1100 Subject: [PATCH] Updated admin and mod flag system --- README.md | 10 ---------- server/admin/account-privilege.js | 20 -------------------- server/admin/default-account.js | 8 +++++--- server/admin/grant-admin.js | 25 +++++++++++++++++++++++++ server/admin/grant-mod.js | 24 ++++++++++++++++++++++++ server/admin/index.js | 11 +++++++---- server/admin/remove-admin.js | 24 ++++++++++++++++++++++++ server/admin/remove-mod.js | 25 +++++++++++++++++++++++++ server/auth/login.js | 2 +- server/database/models/accounts.js | 24 ++++++++++++++++++------ server/utilities/token-generate.js | 6 ++++-- server/utilities/token-refresh.js | 2 +- 12 files changed, 134 insertions(+), 47 deletions(-) delete mode 100644 server/admin/account-privilege.js create mode 100644 server/admin/grant-admin.js create mode 100644 server/admin/grant-mod.js create mode 100644 server/admin/remove-admin.js create mode 100644 server/admin/remove-mod.js diff --git a/README.md b/README.md index ca2f1be..5c0619d 100644 --- a/README.md +++ b/README.md @@ -76,14 +76,4 @@ Content-Type: application/json { "password": "helloworld" } - -//DOCS: Sets the privilege of the specified user; usable only by admins -PATCH /auth/admin/privilege -Authorization: Bearer accessToken -Content-Type: application/json - -{ - "username": "example", - "privilege: "administrator" -} ``` diff --git a/server/admin/account-privilege.js b/server/admin/account-privilege.js deleted file mode 100644 index 43373ac..0000000 --- a/server/admin/account-privilege.js +++ /dev/null @@ -1,20 +0,0 @@ -const { accounts } = require('../database/models'); - -//auth/account/privilege -const route = async (req, res) => { - const updated = await accounts.update({ - privilege: req.body.privilege - }, { - where: { - username: req.body.username - } - }); - - if (updated < 1) { - return res.status(403).send(`Unknown account`); - } - - return res.status(200).end(); -}; - -module.exports = route; \ No newline at end of file diff --git a/server/admin/default-account.js b/server/admin/default-account.js index ffef6d4..47ad0ee 100644 --- a/server/admin/default-account.js +++ b/server/admin/default-account.js @@ -20,16 +20,18 @@ module.exports = async () => { //check for an existing admin account const adminRecord = await accounts.findOne({ where: { - privilege: 'administrator' + admin: true } }); if (adminRecord == null) { await accounts.create({ - privilege: 'administrator', email: `${process.env.ADMIN_DEFAULT_USERNAME}@${process.env.WEB_ADDRESS}`, username: `${process.env.ADMIN_DEFAULT_USERNAME}`, - hash: await bcrypt.hash(`${process.env.ADMIN_DEFAULT_PASSWORD}`, await bcrypt.genSalt(11)) + hash: await bcrypt.hash(`${process.env.ADMIN_DEFAULT_PASSWORD}`, await bcrypt.genSalt(11)), + type: 'normal', + admin: true, + mod: true }); console.warn(`Created default admin account (email: ${process.env.ADMIN_DEFAULT_USERNAME}@${process.env.WEB_ADDRESS}; password: ${process.env.ADMIN_DEFAULT_PASSWORD})`); diff --git a/server/admin/grant-admin.js b/server/admin/grant-admin.js new file mode 100644 index 0000000..a67dc39 --- /dev/null +++ b/server/admin/grant-admin.js @@ -0,0 +1,25 @@ +const { accounts } = require('../database/models'); +const Sequelize = require('sequelize'); +const Op = Sequelize.Op; + +//admin/admin +const route = async (req, res) => { + const updated = await accounts.update({ + admin: true, + mod: true + }, { + where: { + username: { + [Op.eq]: req.body.username + } + } + }); + + if (!updated[0]) { + return res.status(500).send('Failed to set admin status'); + } + + res.status(200).end(); +}; + +module.exports = route; \ No newline at end of file diff --git a/server/admin/grant-mod.js b/server/admin/grant-mod.js new file mode 100644 index 0000000..85c08ef --- /dev/null +++ b/server/admin/grant-mod.js @@ -0,0 +1,24 @@ +const { accounts } = require('../database/models'); +const Sequelize = require('sequelize'); +const Op = Sequelize.Op; + +//admin/mod +const route = async (req, res) => { + const updated = await accounts.update({ + mod: true + }, { + where: { + username: { + [Op.eq]: req.body.username + } + } + }); + + if (!updated[0]) { + return res.status(500).send('Failed to set mod status'); + } + + res.status(200).end(); +}; + +module.exports = route; \ No newline at end of file diff --git a/server/admin/index.js b/server/admin/index.js index 0ca7a28..6cdd939 100644 --- a/server/admin/index.js +++ b/server/admin/index.js @@ -6,9 +6,9 @@ const tokenAuth = require('../utilities/token-auth'); router.use(tokenAuth); router.use((req, res, next) => { - //check the user's privilege - if (req.user.privilege != 'administrator') { - return res.status(401).send('Admins only'); + //check the user's admin status + if (!req.user.admin) { + return res.status(401).send('Admin only'); } next(); @@ -17,6 +17,9 @@ router.use((req, res, next) => { require('./default-account')(); //generate the default accouunt //basic route management -router.patch('/privilege', require('./account-privilege')); +router.post('/admin', require('./grant-admin')); +router.delete('/admin', require('./remove-admin')); +router.post('/mod', require('./grant-mod')); +router.delete('/mod', require('./remove-mod')); module.exports = router; \ No newline at end of file diff --git a/server/admin/remove-admin.js b/server/admin/remove-admin.js new file mode 100644 index 0000000..8e4c53d --- /dev/null +++ b/server/admin/remove-admin.js @@ -0,0 +1,24 @@ +const { accounts } = require('../database/models'); +const Sequelize = require('sequelize'); +const Op = Sequelize.Op; + +//admin/admin +const route = async (req, res) => { + const updated = await accounts.update({ + admin: false + }, { + where: { + username: { + [Op.eq]: req.body.username + } + } + }); + + if (!updated[0]) { + return res.status(500).send('Failed to set admin status'); + } + + res.status(200).end(); +}; + +module.exports = route; \ No newline at end of file diff --git a/server/admin/remove-mod.js b/server/admin/remove-mod.js new file mode 100644 index 0000000..bebd220 --- /dev/null +++ b/server/admin/remove-mod.js @@ -0,0 +1,25 @@ +const { accounts } = require('../database/models'); +const Sequelize = require('sequelize'); +const Op = Sequelize.Op; + +//admin/admin +const route = async (req, res) => { + const updated = await accounts.update({ + admin: false, + mod: false + }, { + where: { + username: { + [Op.eq]: req.body.username + } + } + }); + + if (!updated[0]) { + return res.status(500).send('Failed to set mod status'); + } + + res.status(200).end(); +}; + +module.exports = route; \ No newline at end of file diff --git a/server/auth/login.js b/server/auth/login.js index 46f7b8f..c2db5c9 100644 --- a/server/auth/login.js +++ b/server/auth/login.js @@ -43,7 +43,7 @@ const route = async (req, res) => { }); //generate the JWT - const tokens = generate(account.id, account.username, account.privilege); + const tokens = generate(account.id, account.username, account.type, account.admin, account.mod); //finally res.status(200).json(tokens); diff --git a/server/database/models/accounts.js b/server/database/models/accounts.js index f20eed6..1f31a42 100644 --- a/server/database/models/accounts.js +++ b/server/database/models/accounts.js @@ -10,12 +10,6 @@ module.exports = sequelize.define('accounts', { unique: true }, - privilege: { - type: Sequelize.ENUM, - values: ['administrator', 'moderator', 'alpha', 'beta', 'gamma', 'normal'], - defaultValue: 'normal' - }, - email: { type: 'varchar(320)', unique: true @@ -28,6 +22,24 @@ module.exports = sequelize.define('accounts', { hash: 'varchar(100)', //for passwords + type: { + type: Sequelize.ENUM, + values: ['normal', 'alpha', 'beta', 'gamma'], + defaultValue: 'normal' + }, + + admin: { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: false + }, + + mod: { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: false + }, + contact: { type: Sequelize.BOOLEAN, allowNull: false, diff --git a/server/utilities/token-generate.js b/server/utilities/token-generate.js index e47cfbc..8f83884 100644 --- a/server/utilities/token-generate.js +++ b/server/utilities/token-generate.js @@ -2,11 +2,13 @@ const jwt = require('jsonwebtoken'); const { tokens } = require('../database/models'); //generates a JWT token based on the given arguments -module.exports = (id, username, privilege) => { +module.exports = (id, username, type, admin, mod) => { const content = { id, username, - privilege + type, + admin, + mod, }; const accessToken = jwt.sign(content, process.env.SECRET_ACCESS, { expiresIn: '10m' }); diff --git a/server/utilities/token-refresh.js b/server/utilities/token-refresh.js index 7231d53..f8d7b15 100644 --- a/server/utilities/token-refresh.js +++ b/server/utilities/token-refresh.js @@ -24,7 +24,7 @@ module.exports = (token, callback) => { return callback(403); } - const result = generate(user.id, user.username, user.privilege); + const result = generate(user.id, user.username, user.type, user.admin, user.mod); destroy(token);