import { Request, Response } from "express" import User, { IUser, TokenTypes } from "../../models/user"; import { randomBytes } from "crypto"; import moment = require("moment"); import LoginToken from "../../models/login_token"; import RequestError, { HttpStatusCode } from "../../helper/request_error"; import promiseMiddleware from "../../helper/promiseMiddleware"; const Login = promiseMiddleware(async (req: Request, res: Response) => { let type = req.query.type; if (type === "username") { let { username, uid } = req.query; let user = await User.findOne(username ? { username: username.toLowerCase() } : { uid: uid }); if (!user) { res.json({ error: req.__("User not found") }) } else { res.json({ salt: user.salt, uid: user.uid }); } return; } const sendToken = async (user: IUser, tfa?: TokenTypes[]) => { let token_str = randomBytes(16).toString("hex"); let tfa_exp = moment().add(5, "minutes").toDate() let token_exp = moment().add(6, "months").toDate() let token = LoginToken.new({ token: token_str, valid: true, validTill: tfa ? tfa_exp : token_exp, user: user._id, validated: tfa ? false : true }); await LoginToken.save(token); let special_str = randomBytes(24).toString("hex"); let special_exp = moment().add(30, "minutes").toDate() let special = LoginToken.new({ token: special_str, valid: true, validTill: tfa ? tfa_exp : special_exp, special: true, user: user._id, validated: tfa ? false : true }); await LoginToken.save(special); res.json({ login: { token: token_str, expires: token.validTill.toUTCString() }, special: { token: special_str, expires: special.validTill.toUTCString() }, tfa }); } if (type === "password" || type === "twofactor") { let { username, password, uid } = req.body; let user = await User.findOne(username ? { username: username.toLowerCase() } : { uid: uid }) if (!user) { res.json({ error: req.__("User not found") }) } else { if (user.password !== password) { res.json({ error: req.__("Password or username wrong") }) } else { if (type === "twofactor") { } else { if (user.twofactor && user.twofactor.length > 0) { let types = user.twofactor.filter(f => f.valid).map(f => f.type) await sendToken(user, types); } else { await sendToken(user); } } } } } else { throw new RequestError("Invalid type!", HttpStatusCode.BAD_REQUEST); } }); export default Login;