import jwt from "jsonwebtoken"; import BaseService from "@Services/BaseService"; import { Service } from "typedi"; export type Tokens = { access_token: string; expires_in: number; id_token: string; token_type: string; }; export type OpenIdConfig = { authorization_endpoint: string; token_endpoint: string; userinfo_endpoint: string; claims_supported: string[]; end_session_endpoint: string; grant_types_supported: string[]; response_types_supported: string[]; scopes_supported: string[]; issuer: string; jwks_uri: string; }; @Service() export default class OpenIdService extends BaseService { protected authorizationServerUrl: string; constructor(authorizationServerUrl: string) { super(); this.authorizationServerUrl = authorizationServerUrl; } public async getOpenIdConfig(): Promise { const response = await fetch(this.authorizationServerUrl + "/.well-known/openid-configuration"); return await response.json(); } public async getSigningKey(kid: string): Promise { const jwksUri = (await this.getOpenIdConfig()).jwks_uri; const response = await fetch(jwksUri); const jwks = await response.json(); const signingKey = jwks.keys.find((key: any) => key.kid === kid); if (!signingKey) return null; return signingKey; } /** * @throws Error */ public async verifyIdToken(idToken: string, kid: string) { const signingKey = await this.getSigningKey(kid); if (!signingKey) throw new Error("Signing key not found"); return jwt.verify(idToken, signingKey); } }