diff --git a/packages/server/src/modules/App/App.module.ts b/packages/server/src/modules/App/App.module.ts index 8ae530926..ff4604180 100644 --- a/packages/server/src/modules/App/App.module.ts +++ b/packages/server/src/modules/App/App.module.ts @@ -18,7 +18,7 @@ import { createBullBoardAuthMiddleware } from '@/middleware/bull-board-auth.midd import { BullModule } from '@nestjs/bullmq'; import { ScheduleModule } from '@nestjs/schedule'; import { PassportModule } from '@nestjs/passport'; -import { ClsModule, ClsService } from 'nestjs-cls'; +import { ClsModule } from 'nestjs-cls'; import { AppController } from './App.controller'; import { AppService } from './App.service'; import { ItemsModule } from '../Items/Items.module'; @@ -169,9 +169,6 @@ import { AppThrottleModule } from './AppThrottle.module'; global: true, middleware: { mount: true, - setup: (cls: ClsService, req: Request, res: Response) => { - cls.set('organizationId', req.headers['organization-id']); - }, generateId: true, saveReq: true, }, diff --git a/packages/server/src/modules/Auth/commands/AuthSignin.service.ts b/packages/server/src/modules/Auth/commands/AuthSignin.service.ts index 48694d3ea..73439c79a 100644 --- a/packages/server/src/modules/Auth/commands/AuthSignin.service.ts +++ b/packages/server/src/modules/Auth/commands/AuthSignin.service.ts @@ -2,6 +2,7 @@ import { ClsService } from 'nestjs-cls'; import { Inject, Injectable } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { SystemUser } from '@/modules/System/models/SystemUser'; +import { TenantModel } from '@/modules/System/models/TenantModel'; import { ModelObject } from 'objection'; import { JwtPayload } from '../Auth.interfaces'; import { InvalidEmailPasswordException } from '../exceptions/InvalidEmailPassword.exception'; @@ -12,6 +13,10 @@ export class AuthSigninService { constructor( @Inject(SystemUser.name) private readonly systemUserModel: typeof SystemUser, + + @Inject(TenantModel.name) + private readonly tenantModel: typeof TenantModel, + private readonly jwtService: JwtService, private readonly clsService: ClsService, ) { } @@ -49,6 +54,7 @@ export class AuthSigninService { */ async verifyPayload(payload: JwtPayload): Promise { let user: SystemUser; + let tenant: TenantModel | undefined; try { user = await this.systemUserModel @@ -56,8 +62,14 @@ export class AuthSigninService { .findOne({ email: payload.sub }) .throwIfNotFound(); + tenant = await this.tenantModel + .query() + .findById(user.tenantId) + .throwIfNotFound(); + this.clsService.set('tenantId', user.tenantId); this.clsService.set('userId', user.id); + this.clsService.set('organizationId', tenant.organizationId); } catch (error) { throw new UserNotFoundException(String(payload.sub)); } diff --git a/packages/server/src/modules/Tenancy/TenancyGlobal.guard.ts b/packages/server/src/modules/Tenancy/TenancyGlobal.guard.ts index 04310a100..edb146410 100644 --- a/packages/server/src/modules/Tenancy/TenancyGlobal.guard.ts +++ b/packages/server/src/modules/Tenancy/TenancyGlobal.guard.ts @@ -7,6 +7,7 @@ import { SetMetadata, } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; +import { ClsService } from 'nestjs-cls'; import { IS_PUBLIC_ROUTE } from '../Auth/Auth.constants'; import { getAuthApiKey } from '../Auth/Auth.utils'; @@ -16,7 +17,10 @@ export const TenantAgnosticRoute = () => SetMetadata(IS_TENANT_AGNOSTIC, true); @Injectable() export class TenancyGlobalGuard implements CanActivate { - constructor(private reflector: Reflector) {} + constructor( + private readonly reflector: Reflector, + private readonly clsService: ClsService, + ) {} /** * Validates the organization ID in the request headers. @@ -43,6 +47,14 @@ export class TenancyGlobalGuard implements CanActivate { if (!organizationId) { throw new UnauthorizedException('Organization ID is required.'); } + const authenticatedOrganizationId = + this.clsService.get('organizationId'); + if ( + authenticatedOrganizationId && + authenticatedOrganizationId !== organizationId + ) { + throw new UnauthorizedException('Organization mismatch.'); + } return true; } }