fix(07): replace TenantMiddleware with TenantGuard to fix tenant context
Middleware runs before guards in NestJS — req.user was always undefined when TenantMiddleware executed, so req.tenantId was never set. Convert to TenantGuard (APP_GUARD, registered after JwtAuthGuard) so it runs after JWT validation and can read req.user.tenantId correctly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import {
|
||||
CanActivate,
|
||||
ExecutionContext,
|
||||
ForbiddenException,
|
||||
Injectable,
|
||||
} from '@nestjs/common';
|
||||
import { forTenant } from '../prisma/prisma-tenant.extension';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
|
||||
/**
|
||||
* Runs AFTER JwtAuthGuard (guard execution order follows APP_GUARD registration order).
|
||||
* At this point req.user is populated — middleware ran too early to access it.
|
||||
*
|
||||
* Sets req.tenantId and req.tenantPrisma for downstream controllers.
|
||||
* Super-Admin can override tenant via x-tenant-id header (D-10).
|
||||
*/
|
||||
@Injectable()
|
||||
export class TenantGuard implements CanActivate {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
canActivate(context: ExecutionContext): boolean {
|
||||
const req = context.switchToHttp().getRequest();
|
||||
const user = req.user;
|
||||
|
||||
if (!user) {
|
||||
// Public route (login, health) — skip tenant context
|
||||
return true;
|
||||
}
|
||||
|
||||
let tenantId: string | undefined = user.tenantId;
|
||||
|
||||
if (user.role === 'SUPER_ADMIN' && req.headers['x-tenant-id']) {
|
||||
tenantId = req.headers['x-tenant-id'] as string;
|
||||
}
|
||||
|
||||
if (!tenantId && user.role !== 'SUPER_ADMIN') {
|
||||
throw new ForbiddenException('No tenant context');
|
||||
}
|
||||
|
||||
if (tenantId) {
|
||||
req.tenantPrisma = forTenant(this.prisma, tenantId);
|
||||
req.tenantId = tenantId;
|
||||
} else {
|
||||
req.tenantPrisma = this.prisma;
|
||||
req.tenantId = null;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user