diff --git a/src/auth/jwt.strategy.ts b/src/auth/jwt.strategy.ts index c56ee46..536d6a5 100644 --- a/src/auth/jwt.strategy.ts +++ b/src/auth/jwt.strategy.ts @@ -17,10 +17,14 @@ export class JwtStrategy extends PassportStrategy(Strategy) { }); } - validate(payload: { sub: string; walletAddress: string }) { + validate(payload: { sub: string; walletAddress: string; role?: string }) { if (!payload?.sub) { throw new UnauthorizedException('Invalid token'); } - return { userId: payload.sub, walletAddress: payload.walletAddress }; + return { + userId: payload.sub, + walletAddress: payload.walletAddress, + role: payload.role, + }; } } diff --git a/src/users/guards/admin.guard.spec.ts b/src/users/guards/admin.guard.spec.ts new file mode 100644 index 0000000..9024e96 --- /dev/null +++ b/src/users/guards/admin.guard.spec.ts @@ -0,0 +1,34 @@ +import { ExecutionContext, ForbiddenException } from '@nestjs/common'; +import { AdminGuard } from './admin.guard'; + +const createExecutionContext = (user: unknown): ExecutionContext => + ({ + switchToHttp: () => ({ + getRequest: () => ({ user }), + }), + }) as ExecutionContext; + +describe('AdminGuard', () => { + let guard: AdminGuard; + + beforeEach(() => { + guard = new AdminGuard(); + }); + + it('allows request when user role is ADMIN', () => { + const context = createExecutionContext({ role: 'ADMIN' }); + expect(guard.canActivate(context)).toBe(true); + }); + + it('rejects request when user is missing', () => { + const context = createExecutionContext(undefined); + expect(() => guard.canActivate(context)).toThrow(ForbiddenException); + expect(() => guard.canActivate(context)).toThrow('User not authenticated'); + }); + + it('rejects request when user role is not ADMIN', () => { + const context = createExecutionContext({ role: 'USER' }); + expect(() => guard.canActivate(context)).toThrow(ForbiddenException); + expect(() => guard.canActivate(context)).toThrow('Admin access required'); + }); +}); diff --git a/src/users/guards/admin.guard.ts b/src/users/guards/admin.guard.ts index fa0f3ec..484c0da 100644 --- a/src/users/guards/admin.guard.ts +++ b/src/users/guards/admin.guard.ts @@ -4,26 +4,19 @@ import { ExecutionContext, ForbiddenException, } from '@nestjs/common'; -import { PrismaService } from '../../prisma/prisma.service'; /** Route guard that restricts access to users with ADMIN role */ @Injectable() export class AdminGuard implements CanActivate { - constructor(private readonly prisma: PrismaService) {} - - async canActivate(context: ExecutionContext): Promise { + canActivate(context: ExecutionContext): boolean { const request = context.switchToHttp().getRequest(); const user = request.user; - if (!user || !user.walletAddress) { + if (!user) { throw new ForbiddenException('User not authenticated'); } - const dbUser = await this.prisma.user.findUnique({ - where: { walletAddress: user.walletAddress }, - }); - - if (!dbUser || dbUser.role !== 'ADMIN') { + if (user.role !== 'ADMIN') { throw new ForbiddenException('Admin access required'); }