Files
Sakuin/backend/src/auth/auth.guard.ts
Tetardtek 108f021bd8
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 31s
feat: Sprint 1 core tracker + SuperOAuth PKCE E2E
Backend: cookie-parser, auth guard token introspection (SuperOAuth profile API),
fix réponse wrappée { success, data: { user, linkedProviders } }.
Frontend: page login 4 providers PKCE, callback SSR-safe (browser guard),
search améliorée (debounce, pagination, toast, feedback visuel ajout),
list complète (7 tabs, progression inline, score, vue grille/liste, cards goldées),
profil (XP bar, grades, 8 stats), user store partagé, toast system.
2026-03-25 02:43:36 +01:00

61 lines
1.6 KiB
TypeScript

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<boolean> {
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<any> {
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;
}
}
}