Organize directories

This commit is contained in:
Darren Clarke 2023-02-13 13:10:48 +00:00
parent 8a91c9b89b
commit 4898382f78
433 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,114 @@
import * as Boom from "@hapi/boom";
import * as Hoek from "@hapi/hoek";
import * as Hapi from "@hapi/hapi";
import { promisify } from "util";
import jwt from "jsonwebtoken";
import jwksClient, { hapiJwt2KeyAsync } from "jwks-rsa";
import type { IAppConfig } from "../../config";
const CF_JWT_HEADER_NAME = "cf-access-jwt-assertion";
const CF_JWT_ALGOS = ["RS256"];
const verifyToken = (settings: any) => {
const { audience, issuer } = settings;
const client = jwksClient({
jwksUri: `${issuer}/cdn-cgi/access/certs`,
});
return async (token: any) => {
const getKey = (header: any, callback: any) => {
client.getSigningKey(header.kid, (err, key) => {
if (err)
throw Boom.serverUnavailable(
"failed to fetch cloudflare access jwks"
);
callback(undefined, key?.getPublicKey());
});
};
const opts = {
algorithms: CF_JWT_ALGOS,
audience,
issuer,
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return (promisify(jwt.verify) as any)(token, getKey, opts);
};
};
const handleCfJwt = (verify: any) => async (
request: Hapi.Request,
h: Hapi.ResponseToolkit
) => {
const token = request.headers[CF_JWT_HEADER_NAME];
if (token) {
try {
await verify(token);
} catch (error) {
console.error(error);
return Boom.unauthorized("invalid cloudflare access token");
}
}
return h.continue;
};
const defaultOpts = {
issuer: undefined,
audience: undefined,
strategyName: "clouflareaccess",
validate: undefined,
};
const cfJwtRegister = async (server: Hapi.Server, options: any): Promise<void> => {
server.dependency(["hapi-auth-jwt2"]);
const settings = Hoek.applyToDefaults(defaultOpts, options);
const verify = verifyToken(settings);
const { validate, strategyName, audience, issuer } = settings;
server.ext("onPreAuth", handleCfJwt(verify));
server.auth.strategy(strategyName!, "jwt", {
key: hapiJwt2KeyAsync({
jwksUri: `${issuer}/cdn-cgi/access/certs`,
}),
cookieKey: false,
urlKey: false,
headerKey: CF_JWT_HEADER_NAME,
validate,
verifyOptions: {
audience,
issuer,
algorithms: ["RS256"],
},
});
};
export const registerCloudflareAccessJwt = async (
server: Hapi.Server,
config: IAppConfig
): Promise<void> => {
const { audience, domain } = config.cfaccess;
// only enable this plugin if cloudflare access config is configured
if (audience && domain) {
server.log(["auth"], "cloudflare access authorization enabled");
await server.register({
plugin: {
name: "cloudflare-jwt",
version: "0.0.1",
register: cfJwtRegister,
},
options: {
issuer: `https://${domain}`,
audience,
validate: (decoded: any, _request: any) => {
const { email, name } = decoded;
return {
isValid: true,
credentials: { user: { email, name } },
};
},
},
});
}
};