initial: standalone repo from monorepo split
This commit is contained in:
53
src/common/guards/access.guard.ts
Normal file
53
src/common/guards/access.guard.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { Injectable, CanActivate, ExecutionContext, ForbiddenException } from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
import { ACCESS_KEY, AccessRequirement } from '../decorators/access.decorator';
|
||||
import { PrismaService } from '../../prisma/prisma.service';
|
||||
|
||||
@Injectable()
|
||||
export class AccessGuard implements CanActivate {
|
||||
constructor(
|
||||
private reflector: Reflector,
|
||||
private prisma: PrismaService,
|
||||
) {}
|
||||
|
||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
const requirement = this.reflector.getAllAndOverride<AccessRequirement>(ACCESS_KEY, [
|
||||
context.getHandler(),
|
||||
context.getClass(),
|
||||
]);
|
||||
|
||||
// No @RequireAccess decorator → allow
|
||||
if (!requirement) return true;
|
||||
|
||||
const request = context.switchToHttp().getRequest();
|
||||
const user = request.user;
|
||||
if (!user) return false;
|
||||
|
||||
// Super admin bypasses all access checks
|
||||
if (user.roles?.includes('super_admin')) return true;
|
||||
|
||||
// Resolve user's tenant role permissions from DB
|
||||
const assignments = await this.prisma.userTenantRole.findMany({
|
||||
where: { userId: user.sub },
|
||||
include: {
|
||||
tenantRole: {
|
||||
include: { permissions: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Check if any assigned role grants the required module+action
|
||||
for (const a of assignments) {
|
||||
if (!a.tenantRole.isActive || a.tenantRole.deletedAt) continue;
|
||||
for (const p of a.tenantRole.permissions) {
|
||||
if (p.module === requirement.module && p[requirement.action]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new ForbiddenException(
|
||||
`Access denied: requires ${requirement.action} on ${requirement.module}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user