import * as Hoek from "@hapi/hoek"; import * as Hapi from "@hapi/hapi"; import type { IAppConfig } from "../../config"; // hapi-auth-jwt2 expects the key to be a raw key const jwkToHapiAuthJwt2 = (jwkString) => { try { const jwk = JSON.parse(jwkString); return Buffer.from(jwk.k, "base64"); } catch { throw new Error( "Failed to parse key for JWT verification. This is probably an application configuration error." ); } }; const jwtDefaults = { jwkeysB64: undefined, validate: undefined, strategyName: "nextauth-jwt", }; const jwtRegister = async (server: Hapi.Server, options): Promise => { server.dependency(["hapi-auth-jwt2"]); const settings: any = Hoek.applyToDefaults(jwtDefaults, options); const key = settings.jwkeysB64.map((k) => jwkToHapiAuthJwt2(k)); server.auth.strategy(settings.strategyName!, "jwt", { key, cookieKey: false, urlKey: false, validate: settings.validate, }); }; export const registerNextAuthJwt = async ( server: Hapi.Server, config: IAppConfig ): Promise => { if (config.nextAuth.signingKey) { await server.register({ plugin: { name: "nextauth-jwt", version: "0.0.2", register: jwtRegister, }, options: { jwkeysB64: [config.nextAuth.signingKey], validate: async (decoded, request: Hapi.Request) => { const { email, name, role } = decoded; const user = await request.db().users.findBy({ email }); if (!config.isProd) { server.logger.info( { email, name, role, }, "nextauth-jwt authorizing request" ); // server.logger.info({ user }, "nextauth-jwt user result"); } return { isValid: Boolean(user && user.isActive), // this credentials object is made available in every request // at `request.auth.credentials` credentials: { email, name, role }, }; }, }, }); } else if (config.isProd) { throw new Error("Missing nextauth.signingKey configuration value."); } else { server.log( ["warn"], "Missing nextauth.signingKey configuration value. Authentication of nextauth endpoints disabled!" ); } }; // @hapi/jwt expects the key in its own format /* UNUSED const _jwkToHapiJwt = (jwkString) => { try { const jwk = JSON.parse(jwkString); const rawKey = Buffer.from(jwk.k, "base64"); return { key: rawKey, algorithms: [jwk.alg], kid: jwk.kid, }; } catch { throw new Error( "Failed to parse key for JWT verification. This is probably an application configuration error." ); } }; */