import { CanActivate, ExecutionContext, Injectable, UnauthorizedException, } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { Reflector } from '@nestjs/core'; import { JwtService } from '@nestjs/jwt'; import { Request } from 'express'; import { RedisService } from 'src/common/helpers/redis.service'; import { EncryptionHelper } from 'src/common/tools/encryption-helper'; import { IS_PUBLIC_KEY } from './auth.decorator'; @Injectable() export class AppGuard implements CanActivate { constructor( private readonly jwtService: JwtService, private readonly reflector: Reflector, private readonly redisService: RedisService, ) {} async canActivate(context: ExecutionContext): Promise { const isPublic = this.reflector.getAllAndOverride(IS_PUBLIC_KEY, [ context.getHandler(), context.getClass(), ]); if (isPublic) { return true; } const request = context.switchToHttp().getRequest(); const token = this.extractTokenFromHeader(request); if (!token) { throw new UnauthorizedException('توکن الزامی است'); } try { const isBlacklisted = await this.redisService.isTokenBlacklisted(token); // ✅ Using service method if (isBlacklisted) { throw new UnauthorizedException('توکن در لیست سیاه قرار دارد'); } const decryptedToken = EncryptionHelper.decrypt(token); const payload = await this.jwtService.verifyAsync(decryptedToken, { secret: process.env.auth_jwt_secret, // issuer: process.env.auth_jwt_issuer, }); // await bcrypt. JSON.parse(payload) request['user'] = payload; } catch { throw new UnauthorizedException('عدم احراز هویت'); } return true; } private extractTokenFromHeader(request: Request): string | undefined { const [type, token] = request.headers.authorization?.split(' ') ?? []; return type === 'Bearer' ? token : undefined; } }