import { CanActivate, ExecutionContext, Injectable, ForbiddenException } from '@nestjs/common'; import type { Request } from 'express'; export interface AuthenticatedSession { userId: string; tenantId: string; role: 'owner' | 'admin' | 'member'; } interface RequestWithSession extends Request { session?: AuthenticatedSession; } /** * Blueprint 11.3: tenant_id vine intotdeauna din sesiune, niciodata din * body/query/params. Orice request fara sesiune valida, sau care incearca * sa suprascrie tenant_id din client, este respins (deny-by-default). */ @Injectable() export class TenantGuard implements CanActivate { canActivate(context: ExecutionContext): boolean { const request = context.switchToHttp().getRequest(); const session = request.session; if (!session?.tenantId) { throw new ForbiddenException('No active tenant session'); } const clientSuppliedTenantId = (request.body as Record | undefined)?.tenantId ?? (request.query as Record | undefined)?.tenantId; if (clientSuppliedTenantId && clientSuppliedTenantId !== session.tenantId) { throw new ForbiddenException('tenant_id must not be supplied by the client'); } return true; } }