OpenAuth_server/src/api/user/login.ts

107 lines
4.0 KiB
TypeScript

import { Request, Response } from "express"
import User, { IUser } from "../../models/user";
import { randomBytes } from "crypto";
import moment = require("moment");
import LoginToken from "../../models/login_token";
import promiseMiddleware from "../../helper/promiseMiddleware";
import TwoFactor, { TFATypes, TFANames } from "../../models/twofactor";
import * as crypto from "crypto";
import Logging from "@hibas123/nodelogging";
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;
} else if (type === "password") {
const sendToken = async (user: IUser, tfa?: any[]) => {
let ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress
let client = {
ip: Array.isArray(ip) ? ip[0] : ip,
browser: req.headers["user-agent"]
}
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,
...client
});
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,
...client
});
await LoginToken.save(special);
res.json({
login: { token: token_str, expires: token.validTill.toUTCString() },
special: { token: special_str, expires: special.validTill.toUTCString() },
tfa
});
}
let { username, password, uid, date } = req.body;
let user = await User.findOne(username ? { username: username.toLowerCase() } : { uid: uid })
if (!user) {
res.json({ error: req.__("User not found") })
} else {
let upw = user.password;
if (date) {
if (!moment(date).isBetween(moment().subtract(1, "minute"), moment().add(1, "minute"))) {
res.json({ error: req.__("Invalid timestamp. Please check your devices time!") });
return;
} else {
upw = crypto.createHash("sha512").update(upw + date.toString()).digest("hex");
}
}
if (upw !== password) {
res.json({ error: req.__("Password or username wrong") })
} else {
let twofactor = await TwoFactor.find({ user: user._id, valid: true })
let expired = twofactor.filter(e => e.expires ? moment().isAfter(moment(e.expires)) : false)
await Promise.all(expired.map(e => {
e.valid = false;
return TwoFactor.save(e);
}));
twofactor = twofactor.filter(e => e.valid);
if (twofactor && twofactor.length > 0) {
let tfa = twofactor.map(e => {
return {
id: e._id,
name: e.name || TFANames.get(e.type),
type: e.type
}
})
await sendToken(user, tfa);
} else {
await sendToken(user);
}
}
}
} else {
res.json({ error: req.__("Invalid type!") });
}
});
export default Login;