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() if (!token.validated) 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.validated && 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();