@@ -18,16 +18,17 @@ import {
1818 UserPermissionsModule ,
1919} from "@comet/cms-api" ;
2020import { ApolloDriver , ApolloDriverConfig , ValidationError } from "@nestjs/apollo" ;
21- import { DynamicModule , Module } from "@nestjs/common" ;
22- import { ModuleRef } from "@nestjs/core" ;
21+ import { DynamicModule , MiddlewareConsumer , Module } from "@nestjs/common" ;
22+ import { APP_INTERCEPTOR , ModuleRef } from "@nestjs/core" ;
2323import { Enhancer , GraphQLModule } from "@nestjs/graphql" ;
2424import { AppPermission } from "@src/auth/app-permission.enum" ;
2525import { Config } from "@src/config/config" ;
2626import { ConfigModule } from "@src/config/config.module" ;
2727import { ContentGenerationService } from "@src/content-generation/content-generation.service" ;
2828import { DbModule } from "@src/db/db.module" ;
2929import { TranslationModule } from "@src/translation/translation.module" ;
30- import { Request } from "express" ;
30+ import { AsyncLocalStorage } from "async_hooks" ;
31+ import { NextFunction , Request } from "express" ;
3132
3233import { AccessControlService } from "./auth/access-control.service" ;
3334import { AuthModule , SYSTEM_USER_NAME } from "./auth/auth.module" ;
@@ -36,14 +37,23 @@ import { DepartmentsModule } from "./department/departments.module";
3637import { OpenTelemetryModule } from "./open-telemetry/open-telemetry.module" ;
3738import { ProductsModule } from "./products/products.module" ;
3839import { StatusModule } from "./status/status.module" ;
40+ import { TenantInterceptor } from "./tenant/tenant.interceptor" ;
3941import { TenantsModule } from "./tenant/tenants.module" ;
4042
4143@Module ( { } )
4244export class AppModule {
45+ constructor ( private readonly asyncLocalStorage : AsyncLocalStorage < { tenantId ?: string } > ) { }
46+
4347 static forRoot ( config : Config ) : DynamicModule {
4448 const authModule = AuthModule . forRoot ( config ) ;
4549
4650 return {
51+ providers : [
52+ {
53+ provide : APP_INTERCEPTOR ,
54+ useClass : TenantInterceptor ,
55+ } ,
56+ ] ,
4757 module : AppModule ,
4858 imports : [
4959 ConfigModule . forRoot ( config ) ,
@@ -83,13 +93,18 @@ export class AppModule {
8393 } ) ,
8494 authModule ,
8595 UserPermissionsModule . forRootAsync ( {
86- useFactory : ( userService : UserService , accessControlService : AccessControlService ) => ( {
96+ useFactory : (
97+ userService : UserService ,
98+ accessControlService : AccessControlService ,
99+ asyncLocalStorage : AsyncLocalStorage < { tenantId ?: string } > ,
100+ ) => ( {
87101 availableContentScopes : ( ) => accessControlService . getAvailableContentScopes ( ) ,
88102 userService,
89103 accessControlService,
90104 systemUsers : [ SYSTEM_USER_NAME ] ,
105+ asyncLocalStorage,
91106 } ) ,
92- inject : [ UserService , AccessControlService ] ,
107+ inject : [ UserService , AccessControlService , AsyncLocalStorage < { tenantId ?: string } > ] ,
93108 imports : [ authModule ] ,
94109 AppPermission,
95110 } ) ,
@@ -151,4 +166,15 @@ export class AppModule {
151166 ] ,
152167 } ;
153168 }
169+
170+ configure ( consumer : MiddlewareConsumer ) {
171+ consumer
172+ . apply ( ( req : Request , res : Response , next : NextFunction ) => {
173+ const tenantIdHeader = req . headers [ "x-tenant-id" ] ;
174+ const tenantId = typeof tenantIdHeader === "string" ? tenantIdHeader : undefined ;
175+ const store : { tenantId ?: string } = tenantId ? { tenantId } : { } ;
176+ this . asyncLocalStorage . run ( store , ( ) => next ( ) ) ;
177+ } )
178+ . forRoutes ( "*path" ) ;
179+ }
154180}
0 commit comments