import { Injectable, ExecutionContext, UnauthorizedException, } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { AuthGuard } from '@nestjs/passport'; import { IS_PUBLIC_KEY } from '../../common/decorators/public.decorator'; import { RedisService } from '../../redis/redis.service'; import { JwtPayload } from '../../common/decorators/current-user.decorator'; @Injectable() export class JwtAuthGuard extends AuthGuard('jwt') { constructor( private readonly reflector: Reflector, private readonly redis: RedisService, ) { super(); } async canActivate(context: ExecutionContext): Promise { const isPublic = this.reflector.getAllAndOverride(IS_PUBLIC_KEY, [ context.getHandler(), context.getClass(), ]); if (isPublic) { return true; } const canActivate = await super.canActivate(context); if (!canActivate) { return false; } // Token-Revocation pruefen (Redis Blocklist) const request = context.switchToHttp().getRequest(); const user = request.user as JwtPayload; if (user?.jti) { const isBlocked = await this.redis.isTokenBlocked(user.jti); if (isBlocked) { throw new UnauthorizedException('Token wurde widerrufen'); } } return true; } handleRequest(err: Error | null, user: T, info: Error | undefined): T { if (err || !user) { throw err || new UnauthorizedException('Zugriff verweigert'); } return user; } }