83 lines
3.0 KiB
TypeScript
83 lines
3.0 KiB
TypeScript
|
import { NextFunction, Request, Response } from "express";
|
||
|
import LoginToken from "../../models/login_token";
|
||
|
import Logging from "@hibas123/nodelogging";
|
||
|
import RequestError, { HttpStatusCode } from "../../helper/request_error";
|
||
|
import User from "../../models/user";
|
||
|
import promiseMiddleware from "../../helper/promiseMiddleware";
|
||
|
|
||
|
class Invalid extends Error { }
|
||
|
|
||
|
/**
|
||
|
* Returns customized Middleware function, that could also be called directly
|
||
|
* by code and will return true or false depending on the token. In the false
|
||
|
* case it will also send error and redirect if json is not set
|
||
|
* @param json Checks if requests wants an json or html for returning errors
|
||
|
* @param redirect_uri Sets the uri to redirect, if json is not set and user not logged in
|
||
|
*/
|
||
|
export function GetUserMiddleware(json = false, special_token: boolean = false, redirect_uri?: string) {
|
||
|
return promiseMiddleware(async function (req: Request, res: Response, next?: NextFunction) {
|
||
|
const invalid = () => {
|
||
|
throw new Invalid();
|
||
|
}
|
||
|
try {
|
||
|
let { login, special } = req.cookies
|
||
|
|
||
|
if (!login) invalid()
|
||
|
|
||
|
let token = await LoginToken.findOne({ token: login, valid: true })
|
||
|
if (!token) invalid()
|
||
|
|
||
|
let user = await User.findById(token.user);
|
||
|
if (!user) {
|
||
|
token.valid = false;
|
||
|
await LoginToken.save(token);
|
||
|
invalid();
|
||
|
}
|
||
|
|
||
|
if (token.validTill.getTime() < new Date().getTime()) { //Token expired
|
||
|
token.valid = false;
|
||
|
await LoginToken.save(token);
|
||
|
invalid()
|
||
|
}
|
||
|
|
||
|
if (special) {
|
||
|
Logging.debug("Special found")
|
||
|
let st = await LoginToken.findOne({ token: special, special: true, valid: true })
|
||
|
if (st && st.valid && st.user.toHexString() === token.user.toHexString()) {
|
||
|
if (st.validTill.getTime() < new Date().getTime()) { //Token expired
|
||
|
Logging.debug("Special expired")
|
||
|
st.valid = false;
|
||
|
await LoginToken.save(st);
|
||
|
} else {
|
||
|
Logging.debug("Special valid")
|
||
|
req.special = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (special_token && !req.special) invalid();
|
||
|
|
||
|
req.user = user
|
||
|
req.isAdmin = user.admin;
|
||
|
|
||
|
if (next)
|
||
|
next()
|
||
|
return true;
|
||
|
} catch (e) {
|
||
|
if (e instanceof Invalid) {
|
||
|
if (req.method === "GET" && !json) {
|
||
|
res.status(HttpStatusCode.UNAUTHORIZED)
|
||
|
res.redirect("/login?base64=true&state=" + new Buffer(redirect_uri ? redirect_uri : req.originalUrl).toString("base64"))
|
||
|
} else {
|
||
|
throw new RequestError(req.__("You are not logged in or your login is expired"), HttpStatusCode.UNAUTHORIZED)
|
||
|
}
|
||
|
} else {
|
||
|
if (next) next(e);
|
||
|
else throw e;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
export const UserMiddleware = GetUserMiddleware();
|