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
```
This commit is contained in:
Fabio Manganiello 2025-03-23 23:44:20 +01:00
parent 595d9528d5
commit d49f8ec013
Signed by: blacklight
GPG key ID: D90FBA7F76362774
2 changed files with 9 additions and 4 deletions

View file

@ -18,7 +18,11 @@ class AuthInfo {
function authenticate(roles: RoleName[] = []) { function authenticate(roles: RoleName[] = []) {
return function (route: any, method: string) { return function (route: any, method: string) {
const routeClass = (<typeof Route> route.constructor); 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 user: Optional<User>;
let session: Optional<UserSession>; let session: Optional<UserSession>;

View file

@ -14,8 +14,8 @@ import { logRequest } from '../helpers/logging';
abstract class Route { abstract class Route {
protected readonly path: string; protected readonly path: string;
// Method -> Handler mapping // Route -> Method -> Handler mapping
public static preRequestHandlers: Record<string, RequestHandler> = {}; public static preRequestHandlers: Record<string, Record<string, RequestHandler>> = {};
constructor(path: string) { constructor(path: string) {
this.path = path; this.path = path;
@ -76,9 +76,10 @@ abstract class Route {
logRequest(req); logRequest(req);
try { try {
const routeClass = <typeof Route> this.constructor;
// @ts-expect-error // @ts-expect-error
const handler = (this[handlerName]) as ((req: Request, res: Response, auth: AuthInfo) => Promise<void>); 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> let authInfo: Optional<AuthInfo>
if (preRequestHandler) { if (preRequestHandler) {