import { injectable, Injector } from '#di'; import { SystemLogMediator } from '#logger/system-log-mediator.js'; import { HttpInterceptor, HttpHandler, RequestContext } from '#types/http-interceptor.js'; import { CanActivate } from '#types/mix.js'; import { RouteMeta } from '#types/route-data.js'; import { Status } from '#utils/http-status-codes.js'; @injectable() export class SingletonInterceptorWithGuards implements ISingletonInterceptorWithGuards { instantiatedGuards: InstantiatedGuard[] = []; constructor( protected injector: Injector, protected routeMeta: RouteMeta, ) { this.initGuards(); } async intercept(next: HttpHandler, ctx: RequestContext) { for (const item of this.instantiatedGuards) { const canActivate = await item.guard.canActivate(ctx, item.params); if (canActivate !== true) { const status = typeof canActivate == 'number' ? canActivate : undefined; this.prohibitActivation(ctx, status); return; } } return next.handle(); } protected initGuards() { this.routeMeta.resolvedGuards!.forEach((item) => { const guard = this.injector.instantiateResolved(item.guard) as CanActivate; this.instantiatedGuards.push({ guard, params: item.params }); }); } protected prohibitActivation(ctx: RequestContext, status?: Status) { const systemLogMediator = this.injector.get(SystemLogMediator) as SystemLogMediator; systemLogMediator.youCannotActivateRoute(this, ctx.nodeReq.method!, ctx.nodeReq.url!); ctx.send(undefined, status || Status.UNAUTHORIZED); } } export interface ISingletonInterceptorWithGuards extends HttpInterceptor { instantiatedGuards: InstantiatedGuard[]; } export interface InstantiatedGuard { guard: CanActivate; params?: any[]; }