const User = require("../../models/User"); const secret = require("../../secret"); const config = require("../../config"); const jwt = require("jsonwebtoken"); const redirect = (res, status=401, url=undefined) => { if (!url) { res.status(status).json({ error: true, message: "ERROR_ACCESS_DENIED" }); return; } res.redirect(url); }; const checkToken = (token, minPermissionLevel=config.roleMap.RESTRICTED) => { return new Promise((resolve, reject) => { if (!token) reject("no token provided"); jwt.verify(token, secret.jwtPrivateKey, {}, async (err, data) => { if (err) return reject(err); if (!data || !data.username) return reject("invalid token"); const user = await User.findByUsername(data.username); if (!user) return reject("user does not exist"); let permissionLevel = config.roleMap[user.role]; if (!permissionLevel) permissionLevel = 0; if (permissionLevel < minPermissionLevel) reject("user does not have the required permission level"); resolve(user); }); }); }; function authenticateEndpoint(callback, url=undefined, minPermissionLevel=config.roleMap.RESTRICTED) { return (req, res) => { const token = req.headers.authorization || req.cookies.token; if (!token) return redirect(res, 403, url); checkToken(token, minPermissionLevel).then((user) => { if (!user) return redirect(res, 403, url); callback(req, res, user); }).catch(() => { return redirect(res, 403, url); }); }; } module.exports = { authenticateEndpoint, checkToken };