Added user sign up and login.
This commit is contained in:
80
src/auth.js
Normal file
80
src/auth.js
Normal file
@@ -0,0 +1,80 @@
|
||||
'use strict';
|
||||
|
||||
const util = require('util');
|
||||
const crypto = require('crypto');
|
||||
|
||||
const knex = require('./knex');
|
||||
const { curateUser } = require('./users');
|
||||
const { HttpError } = require('./errors');
|
||||
|
||||
const scrypt = util.promisify(crypto.scrypt);
|
||||
|
||||
async function verifyPassword(password, storedPassword) {
|
||||
const [salt, hash] = storedPassword.split('/');
|
||||
const hashedPassword = (await scrypt(password, salt, 64)).toString('hex');
|
||||
|
||||
if (hashedPassword === hash) {
|
||||
return true;
|
||||
}
|
||||
|
||||
throw new HttpError('Username or password incorrect', 401);
|
||||
}
|
||||
|
||||
async function login(credentials) {
|
||||
const user = await knex('users')
|
||||
.select('users.*', 'users_roles.abilities as role_abilities')
|
||||
.where('username', credentials.username)
|
||||
.orWhere('email', credentials.username)
|
||||
.leftJoin('users_roles', 'users_roles.role', 'users.role')
|
||||
.first();
|
||||
|
||||
if (!user) {
|
||||
throw new HttpError('Username or password incorrect', 401);
|
||||
}
|
||||
|
||||
await verifyPassword(credentials.password, user.password);
|
||||
|
||||
return curateUser(user);
|
||||
}
|
||||
|
||||
async function signup(credentials) {
|
||||
if (!credentials.username) {
|
||||
throw new HttpError('Username required', 400);
|
||||
}
|
||||
|
||||
if (!credentials.email) {
|
||||
throw new HttpError('E-mail required', 400);
|
||||
}
|
||||
|
||||
if (credentials.password?.length < 3) {
|
||||
throw new HttpError('Password must be 3 characters or longer', 400);
|
||||
}
|
||||
|
||||
const existingUser = await knex('users')
|
||||
.where('username', credentials.username)
|
||||
.orWhere('email', credentials.email)
|
||||
.first();
|
||||
|
||||
if (existingUser) {
|
||||
throw new HttpError('Username or e-mail already in use', 409);
|
||||
}
|
||||
|
||||
const salt = crypto.randomBytes(16).toString('hex');
|
||||
const hashedPassword = (await scrypt(credentials.password, salt, 64)).toString('hex');
|
||||
const storedPassword = `${salt}/${hashedPassword}`;
|
||||
|
||||
const [user] = await knex('users')
|
||||
.insert({
|
||||
username: credentials.username,
|
||||
email: credentials.email,
|
||||
password: storedPassword,
|
||||
})
|
||||
.returning('*');
|
||||
|
||||
return curateUser(user);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
login,
|
||||
signup,
|
||||
};
|
||||
Reference in New Issue
Block a user