Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 72b3babfd8 | |||
| c63e14ddf3 |
@@ -19,9 +19,11 @@ Content-Type: application/json
|
||||
"password": "helloworld"
|
||||
}
|
||||
|
||||
|
||||
//DOCS: Used for validating the email address above
|
||||
GET /auth/validation?username=example&token=12345678
|
||||
|
||||
|
||||
//DOCS: Login after validation
|
||||
POST /auth/login
|
||||
Content-Type: application/json
|
||||
@@ -37,7 +39,8 @@ Content-Type: application/json
|
||||
"refreshToken": "fghij"
|
||||
}
|
||||
|
||||
//Replace an expired authToken pair with these values
|
||||
|
||||
//DOCS: Replace an expired authToken pair with these values
|
||||
POST /auth/token
|
||||
Content-Type: application/json
|
||||
|
||||
@@ -45,6 +48,7 @@ Content-Type: application/json
|
||||
"token": "refreshToken"
|
||||
}
|
||||
|
||||
|
||||
//DOCS: After this is called, the refresh route will no longer work
|
||||
DELETE /auth/logout
|
||||
Authorization: Bearer accessToken
|
||||
@@ -53,6 +57,7 @@ Authorization: Bearer accessToken
|
||||
"token": "refreshToken"
|
||||
}
|
||||
|
||||
|
||||
//DOCS: Retreives the private account data, results vary
|
||||
GET /auth/account
|
||||
Authorization: Bearer accessToken
|
||||
@@ -63,11 +68,13 @@ Authorization: Bearer accessToken
|
||||
"refreshToken": "fghij"
|
||||
}
|
||||
|
||||
|
||||
//DOCS: Update account data, input varies, but is always JSON
|
||||
PATCH /auth/account
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer accessToken
|
||||
|
||||
|
||||
//DOCS: Sets the timer, account will be deleted after 2 days
|
||||
DELETE /auth/account
|
||||
Authorization: Bearer accessToken
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "auth-server",
|
||||
"version": "1.3.1",
|
||||
"version": "1.4.0",
|
||||
"description": "An API centric auth server. Uses Sequelize and mariaDB by default.",
|
||||
"main": "server/server.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -27,7 +27,7 @@ const route = async (req, res) => {
|
||||
//forcibly logout
|
||||
tokens.destroy({
|
||||
where: {
|
||||
username: req.body.username || ''
|
||||
email: req.body.email || ''
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ router.use(tokenAuth);
|
||||
router.use(async (req, res, next) => {
|
||||
const record = await accounts.findOne({
|
||||
where: {
|
||||
username: req.user.username || ''
|
||||
email: req.user.email || ''
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -9,18 +9,26 @@ const { accounts } = require('../database/models');
|
||||
|
||||
//auth/deletion
|
||||
const route = async (req, res) => {
|
||||
if (!req.body.password) {
|
||||
return res.status(401).end('Missing password');
|
||||
}
|
||||
|
||||
const account = await accounts.findOne({
|
||||
where: {
|
||||
index: req.user.index
|
||||
index: req.user.index || ''
|
||||
}
|
||||
});
|
||||
|
||||
if (!account) {
|
||||
return res.status(401).end('Missing account');
|
||||
}
|
||||
|
||||
//compare the user's password
|
||||
const compare = utils.promisify(bcrypt.compare);
|
||||
const match = await compare(req.body.password || '', account.hash);
|
||||
const match = await compare(req.body.password, account.hash);
|
||||
|
||||
if (!match) {
|
||||
return res.status(401).send('incorrect password');
|
||||
return res.status(401).send('Incorrect password');
|
||||
}
|
||||
|
||||
//set the deletion time (2 days from now)
|
||||
|
||||
@@ -4,12 +4,12 @@ const { accounts } = require('../database/models');
|
||||
const route = async (req, res) => {
|
||||
const account = await accounts.findOne({
|
||||
where: {
|
||||
index: req.user.index
|
||||
index: req.user.index || ''
|
||||
}
|
||||
});
|
||||
|
||||
if (!account) {
|
||||
return res.status(401).send('Unknown account');
|
||||
return res.status(401).end('Unknown account');
|
||||
}
|
||||
|
||||
//respond with the private-facing data
|
||||
|
||||
@@ -3,13 +3,13 @@ const { accounts } = require('../database/models');
|
||||
|
||||
//auth/update
|
||||
const route = async (req, res) => {
|
||||
//generate the password hash
|
||||
let hash;
|
||||
|
||||
if (req.body.password) {
|
||||
hash = await bcrypt.hash(req.body.password, await bcrypt.genSalt(11));
|
||||
if (!req.body.password) {
|
||||
return res.status(401).end('Missing password');
|
||||
}
|
||||
|
||||
//generate the password hash
|
||||
let hash = await bcrypt.hash(req.body.password, await bcrypt.genSalt(11));
|
||||
|
||||
//update the account
|
||||
await accounts.update({
|
||||
contact: req.body.contact,
|
||||
|
||||
@@ -17,10 +17,13 @@ router.post('/token', require('./token'));
|
||||
//middleware
|
||||
router.use(tokenAuth);
|
||||
|
||||
//logouts allowed when banned, still needs tokens
|
||||
router.delete('/logout', require('./logout'));
|
||||
|
||||
router.use(async (req, res, next) => {
|
||||
const record = await accounts.findOne({
|
||||
where: {
|
||||
username: req.user.username || ''
|
||||
email: req.user.email || ''
|
||||
}
|
||||
});
|
||||
|
||||
@@ -36,7 +39,6 @@ router.use(async (req, res, next) => {
|
||||
});
|
||||
|
||||
//basic account management (needs a token)
|
||||
router.delete('/logout', require('./logout'));
|
||||
router.get('/account', require('./account-query'));
|
||||
router.patch('/account', require('./account-update'));
|
||||
router.delete('/account', require('./account-delete'));
|
||||
|
||||
+14
-9
@@ -3,7 +3,7 @@ const utils = require('util');
|
||||
const bcrypt = require('bcryptjs');
|
||||
|
||||
const { accounts } = require('../database/models');
|
||||
const generate = require('../utilities/token-generate');
|
||||
const tokenGenerate = require('../utilities/token-generate');
|
||||
|
||||
//utilities
|
||||
const validateEmail = require('../utilities/validate-email');
|
||||
@@ -13,7 +13,7 @@ const route = async (req, res) => {
|
||||
//validate the given details
|
||||
const validateErr = await validateDetails(req.body);
|
||||
if (validateErr) {
|
||||
return res.status(401).send(validateErr);
|
||||
return res.status(401).end(validateErr);
|
||||
}
|
||||
|
||||
//get the existing account
|
||||
@@ -48,20 +48,25 @@ const route = async (req, res) => {
|
||||
}
|
||||
|
||||
//generate the JWT
|
||||
const tokens = generate(account.index, account.username, account.type, account.admin, account.mod);
|
||||
const token = tokenGenerate(account.index, account.email, account.username, account.type, account.admin, account.mod);
|
||||
|
||||
//finally
|
||||
res.status(200).json(tokens);
|
||||
res.status(200).json(token);
|
||||
};
|
||||
|
||||
const validateDetails = async (body) => {
|
||||
//basic formatting (with an exception for the default admin account)
|
||||
if (!validateEmail(body.email) && body.email != `${process.env.ADMIN_DEFAULT_USERNAME}@${process.env.WEB_ADDRESS}`) {
|
||||
return 'invalid email';
|
||||
if (!body.email) {
|
||||
return 'Missing email';
|
||||
}
|
||||
|
||||
//check for existing (banned)
|
||||
//TODO: restore banning
|
||||
if (!body.password) {
|
||||
return 'Missing password';
|
||||
}
|
||||
|
||||
//basic formatting (with an exception for the default admin account)
|
||||
if (!validateEmail(body.email) && body.email != `${process.env.ADMIN_DEFAULT_USERNAME}@${process.env.WEB_ADDRESS}`) {
|
||||
return 'Invalid email';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const destroy = require('../utilities/token-destroy');
|
||||
const tokenDestroy = require('../utilities/token-destroy');
|
||||
|
||||
//auth/logout
|
||||
const route = (req, res) => {
|
||||
destroy(req.body.token);
|
||||
tokenDestroy(req.body.token);
|
||||
|
||||
return res.status(200).end();
|
||||
};
|
||||
|
||||
+14
-7
@@ -6,7 +6,6 @@ const Op = Sequelize.Op;
|
||||
|
||||
const { accounts, pendingSignups } = require('../database/models');
|
||||
|
||||
|
||||
//utilities
|
||||
const uuid = require('../utilities/uuid');
|
||||
const validateEmail = require('../utilities/validate-email');
|
||||
@@ -46,11 +45,11 @@ const route = async (req, res) => {
|
||||
const validateDetails = async (body) => {
|
||||
//basic formatting
|
||||
if (!validateEmail(body.email)) {
|
||||
return 'invalid email';
|
||||
return 'Invalid email';
|
||||
}
|
||||
|
||||
if (!validateUsername(body.username)) {
|
||||
return 'invalid username';
|
||||
return 'Invalid username';
|
||||
}
|
||||
|
||||
//check for existing (banned)
|
||||
@@ -64,23 +63,31 @@ const validateDetails = async (body) => {
|
||||
});
|
||||
|
||||
if (emailRecord) {
|
||||
return 'email already exists';
|
||||
return 'Email already exists';
|
||||
}
|
||||
|
||||
if (!body.username) {
|
||||
return 'Missing username';
|
||||
}
|
||||
|
||||
//check for existing username
|
||||
const usernameRecord = await accounts.findOne({
|
||||
where: {
|
||||
username: body.username || ''
|
||||
username: body.username
|
||||
}
|
||||
});
|
||||
|
||||
if (usernameRecord) {
|
||||
return 'username already exists';
|
||||
return 'Username already exists';
|
||||
}
|
||||
|
||||
//validate password
|
||||
if (!body.password) {
|
||||
return 'Missing password';
|
||||
}
|
||||
|
||||
if (body.password.length < 8) {
|
||||
return 'password too short';
|
||||
return 'Password too short';
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
const jwt = require('jsonwebtoken');
|
||||
|
||||
const refresh = require('../utilities/token-refresh');
|
||||
const tokenRefresh = require('../utilities/token-refresh');
|
||||
|
||||
//auth/token
|
||||
module.exports = async (req, res) => {
|
||||
const refreshToken = req.body.token;
|
||||
|
||||
return refresh(refreshToken, (err, tokens) => {
|
||||
return tokenRefresh(refreshToken, (err, token) => {
|
||||
if (err) {
|
||||
return res.status(err).end();
|
||||
}
|
||||
|
||||
return res.status(200).send(tokens);
|
||||
return res.status(200).send(token);
|
||||
});
|
||||
};
|
||||
@@ -11,11 +11,11 @@ const route = async (req, res) => {
|
||||
|
||||
//check the given info
|
||||
if (!info) {
|
||||
return res.status(401).send('validation failed');
|
||||
return res.status(401).send('Validation failed');
|
||||
}
|
||||
|
||||
if (info.token != req.query.token) {
|
||||
return res.status(401).send('tokens do not match');
|
||||
return res.status(401).send('Tokens do not match');
|
||||
}
|
||||
|
||||
//move data to the accounts table
|
||||
|
||||
@@ -3,5 +3,5 @@ const sequelize = require('..');
|
||||
|
||||
module.exports = sequelize.define('tokens', {
|
||||
token: 'varchar(320)',
|
||||
username: 'varchar(320)' //TODO: why username?
|
||||
email: 'varchar(320)'
|
||||
});
|
||||
|
||||
@@ -2,9 +2,10 @@ const jwt = require('jsonwebtoken');
|
||||
const { tokens } = require('../database/models');
|
||||
|
||||
//generates a JWT token based on the given arguments
|
||||
module.exports = (index, username, type, admin, mod) => {
|
||||
module.exports = (index, email, username, type, admin, mod) => {
|
||||
const content = {
|
||||
index,
|
||||
email,
|
||||
username,
|
||||
type,
|
||||
admin,
|
||||
@@ -14,7 +15,7 @@ module.exports = (index, username, type, admin, mod) => {
|
||||
const accessToken = jwt.sign(content, process.env.SECRET_ACCESS, { expiresIn: '10m' });
|
||||
const refreshToken = jwt.sign(content, process.env.SECRET_REFRESH, { expiresIn: '30d' });
|
||||
|
||||
tokens.create({ token: refreshToken, username: username });
|
||||
tokens.create({ token: refreshToken, email: email });
|
||||
|
||||
return { accessToken, refreshToken };
|
||||
};
|
||||
@@ -24,7 +24,7 @@ module.exports = (token, callback) => {
|
||||
return callback(403);
|
||||
}
|
||||
|
||||
const result = generate(user.index, user.username, user.type, user.admin, user.mod);
|
||||
const result = generate(user.index, user.email, user.username, user.type, user.admin, user.mod);
|
||||
|
||||
destroy(token);
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE `accounts` CHANGE `id` `index` INT( 11 ) NOT NULL AUTO_INCREMENT;
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE tokens;
|
||||
Reference in New Issue
Block a user