Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 547d5dba1c | |||
| e597974581 | |||
| f60833ec17 | |||
| 9ffa45f09d | |||
| b2bf1aaf92 | |||
| 61ddd5b38f | |||
| cbd3ed9d3e | |||
| 7bbd6bbcf1 |
@@ -6,15 +6,26 @@ DB_HOSTNAME=database
|
|||||||
DB_DATABASE=auth
|
DB_DATABASE=auth
|
||||||
DB_USERNAME=auth
|
DB_USERNAME=auth
|
||||||
DB_PASSWORD=venusaur
|
DB_PASSWORD=venusaur
|
||||||
DB_TIMEZONE=Australia/Sydney
|
|
||||||
|
|
||||||
MAIL_SMTP=smtp.example.com
|
MAIL_SMTP=smtp.example.com
|
||||||
MAIL_USERNAME=foobar@example.com
|
MAIL_USERNAME=foobar@example.com
|
||||||
MAIL_PASSWORD=examplepassword
|
MAIL_PASSWORD=examplepassword
|
||||||
MAIL_PHYSICAL=42 Placeholder Ave, Placeholder, 0000, USA
|
MAIL_PHYSICAL=42 Placeholder Ave, Placeholder, 0000, USA
|
||||||
|
|
||||||
|
# Give this a value to generate the default admin account
|
||||||
ADMIN_DEFAULT_USERNAME=admin
|
ADMIN_DEFAULT_USERNAME=admin
|
||||||
|
|
||||||
|
# Give this a value to generate the default admin account (must be at least 8 characters)
|
||||||
ADMIN_DEFAULT_PASSWORD=password
|
ADMIN_DEFAULT_PASSWORD=password
|
||||||
|
|
||||||
|
# Select a "TZ database name" that suits your needs: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||||
|
DB_TIMEZONE=Australia/Sydney
|
||||||
|
|
||||||
|
# Give this any value to enable database logging (such as "true")
|
||||||
|
DB_LOGGING=
|
||||||
|
|
||||||
|
# Make sure this value matches the system that you connect to
|
||||||
SECRET_ACCESS=access
|
SECRET_ACCESS=access
|
||||||
|
|
||||||
|
# Make sure this value is kept secret
|
||||||
SECRET_REFRESH=refresh
|
SECRET_REFRESH=refresh
|
||||||
@@ -37,9 +37,13 @@ Content-Type: application/json
|
|||||||
"refreshToken": "fghij"
|
"refreshToken": "fghij"
|
||||||
}
|
}
|
||||||
|
|
||||||
//DOCS: Retreives the private account data, results vary
|
//Replace an expired authToken pair with these values
|
||||||
GET /auth/account
|
POST /auth/token
|
||||||
Authorization: Bearer accessToken
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"token": "refreshToken"
|
||||||
|
}
|
||||||
|
|
||||||
//DOCS: After this is called, the refresh route will no longer work
|
//DOCS: After this is called, the refresh route will no longer work
|
||||||
DELETE /auth/logout
|
DELETE /auth/logout
|
||||||
@@ -49,13 +53,9 @@ Authorization: Bearer accessToken
|
|||||||
"token": "refreshToken"
|
"token": "refreshToken"
|
||||||
}
|
}
|
||||||
|
|
||||||
//Replace an expired authToken pair with these values
|
//DOCS: Retreives the private account data, results vary
|
||||||
POST /auth/token
|
GET /auth/account
|
||||||
Content-Type: application/json
|
Authorization: Bearer accessToken
|
||||||
|
|
||||||
{
|
|
||||||
"token": "refreshToken"
|
|
||||||
}
|
|
||||||
|
|
||||||
//Result
|
//Result
|
||||||
{
|
{
|
||||||
@@ -64,17 +64,16 @@ Content-Type: application/json
|
|||||||
}
|
}
|
||||||
|
|
||||||
//DOCS: Update account data, input varies, but is always JSON
|
//DOCS: Update account data, input varies, but is always JSON
|
||||||
PATCH /auth/update
|
PATCH /auth/account
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
Authorization: Bearer accessToken
|
Authorization: Bearer accessToken
|
||||||
|
|
||||||
//DOCS: Sets the timer, account will be deleted after 2 days
|
//DOCS: Sets the timer, account will be deleted after 2 days
|
||||||
DELETE /auth/deletion
|
DELETE /auth/account
|
||||||
Authorization: Bearer accessToken
|
Authorization: Bearer accessToken
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"password": "helloworld"
|
"password": "helloworld"
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
Generated
+30
-33
@@ -50,9 +50,9 @@
|
|||||||
"integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ=="
|
"integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "14.14.31",
|
"version": "14.14.35",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.35.tgz",
|
||||||
"integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g=="
|
"integrity": "sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag=="
|
||||||
},
|
},
|
||||||
"node_modules/abbrev": {
|
"node_modules/abbrev": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
@@ -760,9 +760,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/glob-parent": {
|
"node_modules/glob-parent": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||||
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
|
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"is-glob": "^4.0.1"
|
"is-glob": "^4.0.1"
|
||||||
@@ -1013,9 +1013,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-path-inside": {
|
"node_modules/is-path-inside": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
|
||||||
"integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
|
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
@@ -1407,9 +1407,6 @@
|
|||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"nopt": "bin/nopt.js"
|
"nopt": "bin/nopt.js"
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "*"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/normalize-path": {
|
"node_modules/normalize-path": {
|
||||||
@@ -1752,9 +1749,9 @@
|
|||||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||||
},
|
},
|
||||||
"node_modules/sequelize": {
|
"node_modules/sequelize": {
|
||||||
"version": "6.5.0",
|
"version": "6.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.6.2.tgz",
|
||||||
"integrity": "sha512-owBt8fnzVy8E1OvyCyfCdVk7OOLyPVrBCMEf+CvRReC5oCyo+UqeXCtwaex9L6LM9ifZ1i3TG3sFeM5MgLK0CQ==",
|
"integrity": "sha512-H/zrzmTK+tis9PJaSigkuXI57nKBvNCtPQol0yxCvau1iWLzSOuq8t3tMOVeQ+Ep8QH2HoD9/+FCCIAqzUr/BQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "^4.1.1",
|
"debug": "^4.1.1",
|
||||||
"dottie": "^2.0.0",
|
"dottie": "^2.0.0",
|
||||||
@@ -1824,9 +1821,9 @@
|
|||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
},
|
},
|
||||||
"node_modules/sequelize/node_modules/semver": {
|
"node_modules/sequelize/node_modules/semver": {
|
||||||
"version": "7.3.4",
|
"version": "7.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||||
"integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
|
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lru-cache": "^6.0.0"
|
"lru-cache": "^6.0.0"
|
||||||
},
|
},
|
||||||
@@ -2185,9 +2182,9 @@
|
|||||||
"integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ=="
|
"integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ=="
|
||||||
},
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "14.14.31",
|
"version": "14.14.35",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.35.tgz",
|
||||||
"integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g=="
|
"integrity": "sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag=="
|
||||||
},
|
},
|
||||||
"abbrev": {
|
"abbrev": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
@@ -2747,9 +2744,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"glob-parent": {
|
"glob-parent": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||||
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
|
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"is-glob": "^4.0.1"
|
"is-glob": "^4.0.1"
|
||||||
@@ -2934,9 +2931,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"is-path-inside": {
|
"is-path-inside": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
|
||||||
"integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
|
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"is-typedarray": {
|
"is-typedarray": {
|
||||||
@@ -3524,9 +3521,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sequelize": {
|
"sequelize": {
|
||||||
"version": "6.5.0",
|
"version": "6.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.6.2.tgz",
|
||||||
"integrity": "sha512-owBt8fnzVy8E1OvyCyfCdVk7OOLyPVrBCMEf+CvRReC5oCyo+UqeXCtwaex9L6LM9ifZ1i3TG3sFeM5MgLK0CQ==",
|
"integrity": "sha512-H/zrzmTK+tis9PJaSigkuXI57nKBvNCtPQol0yxCvau1iWLzSOuq8t3tMOVeQ+Ep8QH2HoD9/+FCCIAqzUr/BQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"debug": "^4.1.1",
|
"debug": "^4.1.1",
|
||||||
"dottie": "^2.0.0",
|
"dottie": "^2.0.0",
|
||||||
@@ -3557,9 +3554,9 @@
|
|||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
},
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "7.3.4",
|
"version": "7.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
|
||||||
"integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
|
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"lru-cache": "^6.0.0"
|
"lru-cache": "^6.0.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
const { accounts, tokens } = require('../database/models');
|
||||||
|
const Sequelize = require('sequelize');
|
||||||
|
const Op = Sequelize.Op;
|
||||||
|
|
||||||
|
//admin/banuser
|
||||||
|
const route = async (req, res) => {
|
||||||
|
const updated = await accounts.update({
|
||||||
|
banned: true
|
||||||
|
}, {
|
||||||
|
where: {
|
||||||
|
username: {
|
||||||
|
[Op.eq]: req.body.username
|
||||||
|
},
|
||||||
|
admin: {
|
||||||
|
[Op.not]: true
|
||||||
|
},
|
||||||
|
mod: {
|
||||||
|
[Op.not]: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!updated[0]) {
|
||||||
|
return res.status(500).send('Failed to set banned status');
|
||||||
|
}
|
||||||
|
|
||||||
|
//forcibly logout
|
||||||
|
tokens.destroy({
|
||||||
|
where: {
|
||||||
|
username: req.body.username
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(200).end();
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = route;
|
||||||
@@ -20,16 +20,18 @@ module.exports = async () => {
|
|||||||
//check for an existing admin account
|
//check for an existing admin account
|
||||||
const adminRecord = await accounts.findOne({
|
const adminRecord = await accounts.findOne({
|
||||||
where: {
|
where: {
|
||||||
privilege: 'administrator'
|
admin: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (adminRecord == null) {
|
if (adminRecord == null) {
|
||||||
await accounts.create({
|
await accounts.create({
|
||||||
privilege: 'administrator',
|
|
||||||
email: `${process.env.ADMIN_DEFAULT_USERNAME}@${process.env.WEB_ADDRESS}`,
|
email: `${process.env.ADMIN_DEFAULT_USERNAME}@${process.env.WEB_ADDRESS}`,
|
||||||
username: `${process.env.ADMIN_DEFAULT_USERNAME}`,
|
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})`);
|
console.warn(`Created default admin account (email: ${process.env.ADMIN_DEFAULT_USERNAME}@${process.env.WEB_ADDRESS}; password: ${process.env.ADMIN_DEFAULT_PASSWORD})`);
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -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;
|
||||||
+61
-3
@@ -1,3 +1,61 @@
|
|||||||
module.exports = {
|
const express = require('express');
|
||||||
defaultAccount: require('./default-account')
|
const router = express.Router();
|
||||||
};
|
|
||||||
|
const { accounts } = require('../database/models');
|
||||||
|
|
||||||
|
//middleware
|
||||||
|
const tokenAuth = require('../utilities/token-auth');
|
||||||
|
|
||||||
|
router.use(tokenAuth);
|
||||||
|
|
||||||
|
//handle ban stuff
|
||||||
|
router.use(async (req, res, next) => {
|
||||||
|
const record = await accounts.findOne({
|
||||||
|
where: {
|
||||||
|
username: req.user.username
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!record) {
|
||||||
|
return res.status(500).send('Account not found in banning middleware');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (record.banned) {
|
||||||
|
return res.status(403).send('This account has been banned');
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
//handle mod stuff
|
||||||
|
router.use((req, res, next) => {
|
||||||
|
//check the user's mod status
|
||||||
|
if (!req.user.mod) {
|
||||||
|
return res.status(401).send('Mods only');
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
//routes
|
||||||
|
router.post('/banuser', require('./ban-user'));
|
||||||
|
|
||||||
|
//handle admin stuff
|
||||||
|
router.use((req, res, next) => {
|
||||||
|
//check the user's admin status
|
||||||
|
if (!req.user.admin) {
|
||||||
|
return res.status(401).send('Admin only');
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
require('./default-account')(); //generate the default accouunt
|
||||||
|
|
||||||
|
//basic route management
|
||||||
|
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;
|
||||||
@@ -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;
|
||||||
@@ -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;
|
||||||
@@ -9,12 +9,12 @@ const route = async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!account) {
|
if (!account) {
|
||||||
res.status(401).send('Unknown account');
|
return res.status(401).send('Unknown account');
|
||||||
}
|
}
|
||||||
|
|
||||||
//respond with the private-facing data
|
//respond with the private-facing data
|
||||||
res.status(200).json({
|
return res.status(200).json({
|
||||||
contact: await account.contact
|
contact: account.contact
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
+25
-5
@@ -1,8 +1,10 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
|
const { accounts } = require('../database/models');
|
||||||
|
|
||||||
//middleware
|
//middleware
|
||||||
const authToken = require('../utilities/token-auth');
|
const tokenAuth = require('../utilities/token-auth');
|
||||||
|
|
||||||
//signup -> validate -> login all without a token
|
//signup -> validate -> login all without a token
|
||||||
router.post('/signup', require('./signup'));
|
router.post('/signup', require('./signup'));
|
||||||
@@ -13,12 +15,30 @@ router.post('/login', require('./login'));
|
|||||||
router.post('/token', require('./token'));
|
router.post('/token', require('./token'));
|
||||||
|
|
||||||
//middleware
|
//middleware
|
||||||
router.use(authToken);
|
router.use(tokenAuth);
|
||||||
|
|
||||||
|
router.use(async (req, res, next) => {
|
||||||
|
const record = await accounts.findOne({
|
||||||
|
where: {
|
||||||
|
username: req.user.username
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!record) {
|
||||||
|
return res.status(500).send('Account not found in banning middleware');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (record.banned) {
|
||||||
|
return res.status(403).send('This account has been banned');
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
//basic account management (needs a token)
|
//basic account management (needs a token)
|
||||||
router.delete('/logout', require('./logout'));
|
router.delete('/logout', require('./logout'));
|
||||||
router.get('/account', require('./account'));
|
router.get('/account', require('./account-query'));
|
||||||
router.patch('/update', require('./update'));
|
router.patch('/account', require('./account-update'));
|
||||||
router.delete('/deletion', require('./deletion'));
|
router.delete('/account', require('./account-delete'));
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|||||||
@@ -42,8 +42,13 @@ const route = async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//reject on banned
|
||||||
|
if (account.banned) {
|
||||||
|
return res.status(403).send('this account has been banned');
|
||||||
|
}
|
||||||
|
|
||||||
//generate the JWT
|
//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
|
//finally
|
||||||
res.status(200).json(tokens);
|
res.status(200).json(tokens);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ const sequelize = new Sequelize(process.env.DB_DATABASE, process.env.DB_USERNAME
|
|||||||
host: process.env.DB_HOSTNAME,
|
host: process.env.DB_HOSTNAME,
|
||||||
dialect: 'mariadb',
|
dialect: 'mariadb',
|
||||||
timezone: process.env.DB_TIMEZONE,
|
timezone: process.env.DB_TIMEZONE,
|
||||||
logging: !!process.env.DB_QUIET
|
logging: process.env.DB_LOGGING ? console.log : false
|
||||||
});
|
});
|
||||||
|
|
||||||
sequelize.sync();
|
sequelize.sync();
|
||||||
|
|||||||
@@ -10,12 +10,6 @@ module.exports = sequelize.define('accounts', {
|
|||||||
unique: true
|
unique: true
|
||||||
},
|
},
|
||||||
|
|
||||||
privilege: {
|
|
||||||
type: Sequelize.ENUM,
|
|
||||||
values: ['administrator', 'moderator', 'alpha', 'beta', 'gamma', 'normal'],
|
|
||||||
defaultValue: 'normal'
|
|
||||||
},
|
|
||||||
|
|
||||||
email: {
|
email: {
|
||||||
type: 'varchar(320)',
|
type: 'varchar(320)',
|
||||||
unique: true
|
unique: true
|
||||||
@@ -28,6 +22,30 @@ module.exports = sequelize.define('accounts', {
|
|||||||
|
|
||||||
hash: 'varchar(100)', //for passwords
|
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
|
||||||
|
},
|
||||||
|
|
||||||
|
banned: {
|
||||||
|
type: Sequelize.BOOLEAN,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: false
|
||||||
|
},
|
||||||
|
|
||||||
contact: {
|
contact: {
|
||||||
type: Sequelize.BOOLEAN,
|
type: Sequelize.BOOLEAN,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
|
|||||||
@@ -3,4 +3,5 @@ const sequelize = require('..');
|
|||||||
|
|
||||||
module.exports = sequelize.define('tokens', {
|
module.exports = sequelize.define('tokens', {
|
||||||
token: 'varchar(320)',
|
token: 'varchar(320)',
|
||||||
|
username: 'varchar(320)'
|
||||||
});
|
});
|
||||||
|
|||||||
+2
-2
@@ -15,8 +15,8 @@ app.use(cors());
|
|||||||
//database connection
|
//database connection
|
||||||
const database = require('./database');
|
const database = require('./database');
|
||||||
|
|
||||||
const admin = require('./admin');
|
//access the admin
|
||||||
admin.defaultAccount();
|
app.use('/admin', require('./admin'));
|
||||||
|
|
||||||
//access the auth
|
//access the auth
|
||||||
app.use('/auth', require('./auth'));
|
app.use('/auth', require('./auth'));
|
||||||
|
|||||||
@@ -6,16 +6,16 @@ module.exports = (req, res, next) => {
|
|||||||
const token = authHeader?.split (' ')[1]; //'Bearer token'
|
const token = authHeader?.split (' ')[1]; //'Bearer token'
|
||||||
|
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return res.status(401).end();
|
return res.status(401).send('No token found');
|
||||||
}
|
}
|
||||||
|
|
||||||
jwt.verify(token, process.env.SECRET_ACCESS, (err, user) => {
|
return jwt.verify(token, process.env.SECRET_ACCESS, (err, user) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return res.status(403).end();
|
return res.status(403).send(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
req.user = user;
|
req.user = user;
|
||||||
|
|
||||||
next();
|
return next();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -2,17 +2,19 @@ const jwt = require('jsonwebtoken');
|
|||||||
const { tokens } = require('../database/models');
|
const { tokens } = require('../database/models');
|
||||||
|
|
||||||
//generates a JWT token based on the given arguments
|
//generates a JWT token based on the given arguments
|
||||||
module.exports = (id, username, privilege) => {
|
module.exports = (id, username, type, admin, mod) => {
|
||||||
const content = {
|
const content = {
|
||||||
id,
|
id,
|
||||||
username,
|
username,
|
||||||
privilege
|
type,
|
||||||
|
admin,
|
||||||
|
mod,
|
||||||
};
|
};
|
||||||
|
|
||||||
const accessToken = jwt.sign(content, process.env.SECRET_ACCESS, { expiresIn: '10m' });
|
const accessToken = jwt.sign(content, process.env.SECRET_ACCESS, { expiresIn: '10m' });
|
||||||
const refreshToken = jwt.sign(content, process.env.SECRET_REFRESH, { expiresIn: '30d' });
|
const refreshToken = jwt.sign(content, process.env.SECRET_REFRESH, { expiresIn: '30d' });
|
||||||
|
|
||||||
tokens.create({ token: refreshToken });
|
tokens.create({ token: refreshToken, username: username });
|
||||||
|
|
||||||
return { accessToken, refreshToken };
|
return { accessToken, refreshToken };
|
||||||
};
|
};
|
||||||
@@ -24,7 +24,7 @@ module.exports = (token, callback) => {
|
|||||||
return callback(403);
|
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);
|
destroy(token);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user