import { CanActivate, ExecutionContext, Injectable, UnauthorizedException, } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; @Injectable() export class AuthGuard implements CanActivate { constructor(private readonly configService: ConfigService) {} async canActivate(context: ExecutionContext): Promise { const request = context.switchToHttp().getRequest(); const token = this.extractToken(request); if (!token) { throw new UnauthorizedException('No token provided'); } const userInfo = await this.introspect(token); if (!userInfo) { throw new UnauthorizedException('Invalid token'); } request.user = userInfo; return true; } private extractToken(request: any): string | null { const authHeader = request.headers.authorization; if (authHeader?.startsWith('Bearer ')) { return authHeader.slice(7); } return request.cookies?.access_token || null; } private async introspect(token: string): Promise { const url = this.configService.get('SUPEROAUTH_URL'); try { const res = await fetch(`${url}/api/v1/user/profile`, { headers: { Authorization: `Bearer ${token}` }, }); if (!res.ok) return null; const body = await res.json(); if (!body?.success || !body?.data?.user) return null; const user = body.data.user; const avatar = body.data.linkedProviders?.[0]?.avatar || null; return { id: user.id, nickname: user.nickname || user.email, avatar, }; } catch { return null; } } }