From 9552ba393e12bdf37947f7b757e354712d24b110 Mon Sep 17 00:00:00 2001 From: toir-bot Date: Sat, 25 Apr 2026 14:45:02 +0000 Subject: [PATCH] chore: initial project scaffold: backend/src/auth/jwt.strategy.ts --- backend/src/auth/jwt.strategy.ts | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 backend/src/auth/jwt.strategy.ts diff --git a/backend/src/auth/jwt.strategy.ts b/backend/src/auth/jwt.strategy.ts new file mode 100644 index 0000000..f2b7e98 --- /dev/null +++ b/backend/src/auth/jwt.strategy.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@nestjs/common'; +import { PassportStrategy } from '@nestjs/passport'; +import { ExtractJwt, Strategy } from 'passport-jwt'; +import { passportJwtSecret } from 'jwks-rsa'; + +@Injectable() +export class JwtStrategy extends PassportStrategy(Strategy) { + constructor() { + super({ + jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), + ignoreExpiration: false, + secretOrKeyProvider: passportJwtSecret({ + cache: true, + rateLimit: true, + jwksRequestsPerMinute: 5, + jwksUri: `${process.env.KEYCLOAK_ISSUER_URL}/protocol/openid-connect/certs`, + }), + algorithms: ['RS256'], + issuer: process.env.KEYCLOAK_ISSUER_URL, + ...(process.env.KEYCLOAK_AUDIENCE + ? { audience: process.env.KEYCLOAK_AUDIENCE } + : {}), + }); + } + + validate(payload: any) { + return { + userId: payload.sub, + username: payload.preferred_username, + roles: payload.realm_access?.roles ?? [], + }; + } +}