import { Injectable, CanActivate, ExecutionContext, UnauthorizedException, } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { JwtService } from '@nestjs/jwt'; import { ConfigService } from '@nestjs/config'; import { Request } from 'express'; export const IS_PUBLIC_KEY = 'isPublic'; @Injectable() export class AdminAuthGuard implements CanActivate { private jwtSecret: string; constructor( private reflector: Reflector, private jwtService: JwtService, private config: ConfigService, ) { this.jwtSecret = this.config.get('ADMIN_JWT_SECRET', 'admin-jwt-secret')!; } async canActivate(context: ExecutionContext): Promise { const request = context.switchToHttp().getRequest(); const url = request.url || ''; // Skip auth for public support endpoints if (url.includes('/public/support')) { return true; } const isPublic = this.reflector.getAllAndOverride(IS_PUBLIC_KEY, [ context.getHandler(), context.getClass(), ]); if (isPublic) return true; const token = this.extractToken(request); if (!token) throw new UnauthorizedException(); try { const payload = await this.jwtService.verifyAsync(token, { secret: this.jwtSecret, }); (request as any)['admin'] = payload; } catch { throw new UnauthorizedException(); } return true; } private extractToken(request: Request): string | undefined { const [type, token] = request.headers.authorization?.split(' ') ?? []; return type === 'Bearer' ? token : undefined; } }