From d49f8ec01369a39ebf643bee1ed841dcfedbdeb0 Mon Sep 17 00:00:00 2001 From: Fabio Manganiello <fabio@manganiello.tech> Date: Sun, 23 Mar 2025 23:44:20 +0100 Subject: [PATCH] Fixed `preRequestHandler` route setup. The map is a static object defined on the root `Route` class. This means that any changes made by its derived classes (e.g. by specifying the `@authenticate` annotation on some methods) will impact the object for all the other derived classes too. To prevent clashes, the structure of the map has been changed from: ``` method -> preRequestHandler ``` to: ``` RouteClass.name -> method -> preRequestHandler ``` --- src/auth.ts | 6 +++++- src/routes/Route.ts | 7 ++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/auth.ts b/src/auth.ts index 307f279..f5b45d8 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -18,7 +18,11 @@ class AuthInfo { function authenticate(roles: RoleName[] = []) { return function (route: any, method: string) { const routeClass = (<typeof Route> route.constructor); - routeClass.preRequestHandlers[method] = async (req: Request): Promise<AuthInfo> => { + if (!routeClass.preRequestHandlers[routeClass.name]) { + routeClass.preRequestHandlers[routeClass.name] = {} + } + + routeClass.preRequestHandlers[routeClass.name][method] = async (req: Request): Promise<AuthInfo> => { let user: Optional<User>; let session: Optional<UserSession>; diff --git a/src/routes/Route.ts b/src/routes/Route.ts index 81da82d..d109fb7 100644 --- a/src/routes/Route.ts +++ b/src/routes/Route.ts @@ -14,8 +14,8 @@ import { logRequest } from '../helpers/logging'; abstract class Route { protected readonly path: string; - // Method -> Handler mapping - public static preRequestHandlers: Record<string, RequestHandler> = {}; + // Route -> Method -> Handler mapping + public static preRequestHandlers: Record<string, Record<string, RequestHandler>> = {}; constructor(path: string) { this.path = path; @@ -76,9 +76,10 @@ abstract class Route { logRequest(req); try { + const routeClass = <typeof Route> this.constructor; // @ts-expect-error const handler = (this[handlerName]) as ((req: Request, res: Response, auth: AuthInfo) => Promise<void>); - const preRequestHandler = (<typeof Route> this.constructor).preRequestHandlers[handlerName]; + const preRequestHandler = routeClass.preRequestHandlers[routeClass.name]?.[handlerName]; let authInfo: Optional<AuthInfo> if (preRequestHandler) {