From 7076b51a2536c4aa4334619742c7141100c985c7 Mon Sep 17 00:00:00 2001 From: "D. Berge" Date: Fri, 3 Nov 2023 21:22:02 +0100 Subject: [PATCH] Add auth.access.role(roles) higher order middleware --- lib/www/server/api/middleware/auth/access.js | 48 +++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/lib/www/server/api/middleware/auth/access.js b/lib/www/server/api/middleware/auth/access.js index 57d6df4..82f5e8f 100644 --- a/lib/www/server/api/middleware/auth/access.js +++ b/lib/www/server/api/middleware/auth/access.js @@ -24,8 +24,54 @@ async function admin (req, res, next) { } } +/** Return a middleware to check for arbitrary roles. + * + * Examples: + * + * req1 = {user: {role: "admin"}}; + * + * role("admin")(req1) → true + * role("user")(req1) → false + * role(["user", "admin"])(req1) → true + * role("guest")(req1) → false + * + * req2 = {user: {role: ["admin", "user"]}} + * + * role("admin")(req2) → true + * role("user")(req2) → true + * role(["user", "admin"])(req2) → true + * role("guest")(req2) → false + * + * To check for role1 AND role2, use two middlewares: + * + * [role("role1"), role("role2")] + * + */ +async function role (required_role) { + + const roles = Array.isArray(required_role) + ? required_role + : [ required_role ]; + + function check (user_role) { + if (Array.isArray(user_role)) { + return user_role.some(check); + } else { + return roles.includes(user_role); + } + } + + return (req, res, next) => { + if (req.user && check(req.user?.role) { + next(); + } + next({status: 403, message: "Access denied"}); + }; +} + module.exports = { read, write, - admin + admin, + role };