link-stack/apps/metamigo-api/app/plugins/nextauth-jwt.ts
2023-03-10 08:26:51 +00:00

100 lines
2.7 KiB
TypeScript

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<void> => {
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<void> => {
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."
);
}
};
*/