import { AuthorizedTokenRequest, MetadataRouter, tokenAuthMiddleware } from "@dunemask/vix/express"; import Cairo from "@lib/Cairo"; import { getUserTokenId } from "@lib/modules/auth/auth.service"; import { Policy, PolicyComputeType } from "@lib/Policies"; import { UserRequest } from "@lib/types/ApiRequests"; import { Resource } from "@lib/vix/AppResources"; import { AuthErrors, ProjectErrors } from "@lib/vix/ClientErrors"; import { Request, Response, NextFunction, Router, Express } from "express"; import expressBearerToken from "express-bearer-token"; import type PostgresService from "@lib/database/PostgresService.js"; import { KeyPairType, User } from "@prisma/client"; export default function userGuard() { const middlewares: MetadataRouter = Router({ mergeParams: true }); async function userGuardMiddleware(req: Request, _res: Response, next: NextFunction) { const { token } = req as AuthorizedTokenRequest; if (!token) throw AuthErrors.UnauthorizedRequiredToken; const PostgresService = req.app.get(Cairo.PostgresService) as PostgresService; const { project } = req.params; if (!project) throw AuthErrors.UnauthorizedRequiredProject; const userKeypair = await PostgresService.keypair.byUsage(project, KeyPairType.UserToken); if (!userKeypair) throw ProjectErrors.BadRequestProjectIncomplete; const id = await getUserTokenId(token, userKeypair.encryptedPublicKey); if (!id) throw AuthErrors.UnauthorizedRequest; const user = await PostgresService.users.byId(id); if (!user) throw AuthErrors.UnauthorizedRequiredUser; const policies = Policy.parseResourcePolicies(user.rolePolicy.policies as PolicyComputeType); const projectData = { ...user.project }; delete (user as Partial).project; (req as UserRequest).user = user; (req as UserRequest).policies = policies; (req as UserRequest).project = projectData; next(); } middlewares.routeMetadata = { authType: "user" }; middlewares.use([expressBearerToken(), userGuardMiddleware]); return middlewares; }