mirror of
https://github.com/PeterMaquiran/tvone-api.git
synced 2026-04-22 20:15:50 +00:00
44 lines
1.3 KiB
TypeScript
44 lines
1.3 KiB
TypeScript
import { Injectable } from "@nestjs/common";
|
|
import { PassportStrategy } from "@nestjs/passport";
|
|
import { ExtractJwt, Strategy } from "passport-jwt";
|
|
import * as jwksRsa from "jwks-rsa";
|
|
import { Request } from "express";
|
|
|
|
@Injectable()
|
|
export class KeycloakStrategy extends PassportStrategy(Strategy, "keycloak") {
|
|
constructor() {
|
|
super({
|
|
jwtFromRequest: ExtractJwt.fromExtractors([
|
|
(req: Request) => req?.cookies?.access_token || null,
|
|
ExtractJwt.fromAuthHeaderAsBearerToken(),
|
|
]),
|
|
|
|
// 🔑 Get signing key from Keycloak
|
|
secretOrKeyProvider: jwksRsa.passportJwtSecret({
|
|
cache: true,
|
|
rateLimit: true,
|
|
jwksRequestsPerMinute: 5,
|
|
jwksUri:
|
|
"https://keycloak.petermaquiran.xyz/realms/tvone/protocol/openid-connect/certs",
|
|
}),
|
|
|
|
//audience: "tvone-web", // your Keycloak clientId
|
|
issuer: "https://keycloak.petermaquiran.xyz/realms/tvone",
|
|
algorithms: ["RS256"],
|
|
});
|
|
}
|
|
|
|
async validate(payload: any) {
|
|
return {
|
|
userId: payload.sub,
|
|
email: payload.email,
|
|
name: payload.name,
|
|
// Google profile image is usually in 'picture'
|
|
email_verified: payload.email_verified,
|
|
picture: payload.picture,
|
|
roles: payload.realm_access?.roles || [],
|
|
// Keep raw for debugging other custom claims
|
|
raw: payload,
|
|
};
|
|
}
|
|
} |