import { createMiddleware } from "hono/factory"; import type { CustomJwtPayload } from "../../../types/jwtToken.js"; import { verify } from "hono/jwt"; import { db } from "../../../../database/dbclient.js"; import { modules } from "../../../../database/schema/modules.js"; import { and, eq } from "drizzle-orm"; import { userRoles } from "../../../../database/schema/userRoles.js"; import { tryCatch } from "../../../globalUtils/tryCatch.js"; const hasCorrectRole = (requiredRole: string[], module: string) => createMiddleware(async (c, next) => { /** * We want to check to make sure you have the correct role to be here */ const authHeader = c.req.header("Authorization"); if (!authHeader || !authHeader.startsWith("Bearer ")) { return c.json({ error: "Unauthorized" }, 401); } const token = authHeader.split(" ")[1]; // deal with token data const { data: tokenData, error: tokenError } = await tryCatch( verify(token, process.env.JWT_SECRET!) ); if (tokenError) { return c.json({ error: "Invalid token" }, 401); } const customToken = tokenData as CustomJwtPayload; // Get the module const { data: mod, error: modError } = await tryCatch( db.select().from(modules).where(eq(modules.name, module)) ); if (modError) { console.log(modError); return; } if (mod.length === 0) { return c.json({ error: "You have entered an invalid module name" }, 403); } // check if the user has the role needed to get into this module const { data: userRole, error: userRoleError } = await tryCatch( db .select() .from(userRoles) .where( and( eq(userRoles.module_id, mod[0].module_id), eq(userRoles.user_id, customToken.user?.user_id!) ) ) ); if (userRoleError) { return; } if (!userRole) { return c.json( { error: "The module you are trying to access is not active or is invalid.", }, 403 ); } if (!requiredRole.includes(userRole[0]?.role)) { return c.json( { error: "You do not have access to this part of the app." }, 403 ); } await next(); }); export default hasCorrectRole;