|
|
|
@ -1,59 +1,79 @@
|
|
|
|
import { Router } from 'express'
|
|
|
|
import { Router } from "express";
|
|
|
|
import { genSalt, hash, compare } from "bcrypt"
|
|
|
|
import { genSalt, hash, compare } from "bcrypt";
|
|
|
|
import { User } from '../../lib/models/User'
|
|
|
|
import { User } from "../../lib/models/User";
|
|
|
|
import { sign } from 'jsonwebtoken'
|
|
|
|
import { sign } from "jsonwebtoken";
|
|
|
|
import config from '../../lib/config'
|
|
|
|
import config from "../../lib/config";
|
|
|
|
import jwt from '../../lib/middleware/jwt'
|
|
|
|
import jwt from "../../lib/middleware/jwt";
|
|
|
|
|
|
|
|
import { celebrate, Joi } from "celebrate";
|
|
|
|
|
|
|
|
|
|
|
|
const NO_EMPTY_SPACE_REGEX = /^\S*$/
|
|
|
|
const NO_EMPTY_SPACE_REGEX = /^\S*$/;
|
|
|
|
|
|
|
|
|
|
|
|
export const auth = Router()
|
|
|
|
export const auth = Router();
|
|
|
|
|
|
|
|
|
|
|
|
const validateAuthPayload = (username: string, password: string): void => {
|
|
|
|
const validateAuthPayload = (username: string, password: string): void => {
|
|
|
|
if (!NO_EMPTY_SPACE_REGEX.test(username) || password.length < 6) {
|
|
|
|
if (!NO_EMPTY_SPACE_REGEX.test(username) || password.length < 6) {
|
|
|
|
throw new Error("Authentication data does not fulfill requirements")
|
|
|
|
throw new Error("Authentication data does not fulfill requirements");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
auth.post('/signup', async (req, res, next) => {
|
|
|
|
auth.post(
|
|
|
|
|
|
|
|
"/signup",
|
|
|
|
|
|
|
|
celebrate({
|
|
|
|
|
|
|
|
params: {
|
|
|
|
|
|
|
|
username: Joi.string().required(),
|
|
|
|
|
|
|
|
password: Joi.string().required(),
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
}),
|
|
|
|
|
|
|
|
async (req, res, next) => {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
validateAuthPayload(req.body.username, req.body.password)
|
|
|
|
validateAuthPayload(req.body.username, req.body.password);
|
|
|
|
|
|
|
|
|
|
|
|
const username = req.body.username.toLowerCase();
|
|
|
|
const username = req.body.username.toLowerCase();
|
|
|
|
|
|
|
|
|
|
|
|
const existingUser = await User.findOne({ where: { username: username } })
|
|
|
|
const existingUser = await User.findOne({
|
|
|
|
|
|
|
|
where: { username: username },
|
|
|
|
|
|
|
|
});
|
|
|
|
if (existingUser) {
|
|
|
|
if (existingUser) {
|
|
|
|
throw new Error("Username already exists")
|
|
|
|
throw new Error("Username already exists");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const salt = await genSalt(10)
|
|
|
|
const salt = await genSalt(10);
|
|
|
|
const user = {
|
|
|
|
const user = {
|
|
|
|
username: username as string,
|
|
|
|
username: username as string,
|
|
|
|
password: await hash(req.body.password, salt)
|
|
|
|
password: await hash(req.body.password, salt),
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const created_user = await User.create(user);
|
|
|
|
const created_user = await User.create(user);
|
|
|
|
|
|
|
|
|
|
|
|
const token = generateAccessToken(created_user.id);
|
|
|
|
const token = generateAccessToken(created_user.id);
|
|
|
|
|
|
|
|
|
|
|
|
res.status(201).json({ token: token, userId: created_user.id })
|
|
|
|
res.status(201).json({ token: token, userId: created_user.id });
|
|
|
|
} catch (e) {
|
|
|
|
} catch (e) {
|
|
|
|
next(e);
|
|
|
|
next(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
);
|
|
|
|
auth.post('/signin', async (req, res, next) => {
|
|
|
|
|
|
|
|
const error = "User does not exist or password is incorrect"
|
|
|
|
auth.post(
|
|
|
|
|
|
|
|
"/signin",
|
|
|
|
|
|
|
|
celebrate({
|
|
|
|
|
|
|
|
params: {
|
|
|
|
|
|
|
|
username: Joi.string().required(),
|
|
|
|
|
|
|
|
password: Joi.string().required(),
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
}),
|
|
|
|
|
|
|
|
async (req, res, next) => {
|
|
|
|
|
|
|
|
const error = "User does not exist or password is incorrect";
|
|
|
|
const errorToThrow = new Error(error);
|
|
|
|
const errorToThrow = new Error(error);
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
if (!req.body.username || !req.body.password) {
|
|
|
|
if (!req.body.username || !req.body.password) {
|
|
|
|
throw errorToThrow
|
|
|
|
throw errorToThrow;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const username = req.body.username.toLowerCase();
|
|
|
|
const username = req.body.username.toLowerCase();
|
|
|
|
const user = await User.findOne({ where: { username: username } });
|
|
|
|
const user = await User.findOne({ where: { username: username } });
|
|
|
|
if (!user) {
|
|
|
|
if (!user) {
|
|
|
|
throw errorToThrow
|
|
|
|
throw errorToThrow;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const password_valid = await compare(req.body.password, user.password);
|
|
|
|
const password_valid = await compare(req.body.password, user.password);
|
|
|
|
@ -61,25 +81,24 @@ auth.post('/signin', async (req, res, next) => {
|
|
|
|
const token = generateAccessToken(user.id);
|
|
|
|
const token = generateAccessToken(user.id);
|
|
|
|
res.status(200).json({ token: token, userId: user.id });
|
|
|
|
res.status(200).json({ token: token, userId: user.id });
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
throw errorToThrow
|
|
|
|
throw errorToThrow;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
} catch (e) {
|
|
|
|
next(e);
|
|
|
|
next(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
function generateAccessToken(id: string) {
|
|
|
|
function generateAccessToken(id: string) {
|
|
|
|
return sign({ id: id }, config.jwt_secret, { expiresIn: '2d' });
|
|
|
|
return sign({ id: id }, config.jwt_secret, { expiresIn: "2d" });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
auth.get("/verify-token", jwt, async (req, res, next) => {
|
|
|
|
auth.get("/verify-token", jwt, async (req, res, next) => {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
res.status(200).json({
|
|
|
|
res.status(200).json({
|
|
|
|
message: "You are authenticated"
|
|
|
|
message: "You are authenticated",
|
|
|
|
})
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
catch (e) {
|
|
|
|
|
|
|
|
next(e);
|
|
|
|
next(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
});
|
|
|
|
|