Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
5.7 kB · 196 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197import { parseBridgeKey } from "./bridge.ts";// Server-only contract for the separate control-plane entry. Never import// this module into worker/ or src/: customer artifacts do not need OAuth secrets.import { requiredSecret } from "./secrets.ts";import { parseCapabilities } from "./oauth-capabilities.ts";import { ConfigurationError, json, origin, record, serverSettings, text, type Bindings, type Environment,} from "./validation.ts";
const keys = [ "schemaVersion", "publicOrigin", "oauthClientId", "oauthRedirectUri", "oauthScopes", "oauthTokenAuthMethod", "oauthCapabilities", "bridge",] as const;const bindingKeys = [ "FLAREBOT_MODE", "FLAREBOT_ENV", "FLAREBOT_CONTROL_PLANE", "FLAREBOT_SESSION_SECRET", "FLAREBOT_OAUTH_CLIENT_SECRET", "FLAREBOT_CREDENTIAL_ENCRYPTION_KEY", "FLAREBOT_BRIDGE_SIGNING_KEY",] as const;
export interface ControlPlaneConfigBindings { FLAREBOT_MODE?: unknown; FLAREBOT_ENV?: unknown; FLAREBOT_CONTROL_PLANE?: unknown; FLAREBOT_SESSION_SECRET?: unknown; FLAREBOT_OAUTH_CLIENT_SECRET?: unknown; FLAREBOT_CREDENTIAL_ENCRYPTION_KEY?: unknown; FLAREBOT_BRIDGE_SIGNING_KEY?: unknown;}
export function parseControlPlaneConfig( value: unknown, environment: Environment = "production",) { const config = record(value, keys, "FLAREBOT_CONTROL_PLANE"); if (config.schemaVersion !== 1) throw new ConfigurationError( "FLAREBOT_CONTROL_PLANE.schemaVersion", "expected version 1", ); const publicOrigin = origin( config.publicOrigin, "FLAREBOT_CONTROL_PLANE.publicOrigin", environment, ); const oauthRedirectUri = text( config.oauthRedirectUri, "FLAREBOT_CONTROL_PLANE.oauthRedirectUri", ); let redirect: URL; try { redirect = new URL(oauthRedirectUri); } catch { throw new ConfigurationError( "FLAREBOT_CONTROL_PLANE.oauthRedirectUri", "set an absolute callback URL registered with Cloudflare", ); } if ( redirect.origin !== publicOrigin || redirect.username || redirect.password || redirect.search || redirect.hash ) throw new ConfigurationError( "FLAREBOT_CONTROL_PLANE.oauthRedirectUri", "set a callback URL on publicOrigin without credentials, query or fragment", ); if ( !Array.isArray(config.oauthScopes) || config.oauthScopes.length === 0 || config.oauthScopes.some( (scope) => typeof scope !== "string" || !/^[a-z][a-z0-9_-]*(\.[a-z][a-z0-9_-]*)*$/.test(scope), ) ) throw new ConfigurationError( "FLAREBOT_CONTROL_PLANE.oauthScopes", "set a nonempty list of reviewed Cloudflare scope IDs", ); return Object.freeze({ schemaVersion: 1 as const, ...(config.bridge === undefined ? {} : { bridge: parseBridgeKey(config.bridge) }), publicOrigin, oauthClientId: text( config.oauthClientId, "FLAREBOT_CONTROL_PLANE.oauthClientId", ), oauthRedirectUri, oauthScopes: Object.freeze([...new Set(config.oauthScopes as string[])]), oauthTokenAuthMethod: parseTokenAuthMethod(config.oauthTokenAuthMethod), oauthCapabilities: config.oauthCapabilities === undefined ? undefined : parseCapabilities(config.oauthCapabilities), });}
function parseTokenAuthMethod(value: unknown) { if (value === undefined) return undefined; if ( value !== "none" && value !== "client_secret_basic" && value !== "client_secret_post" ) throw new ConfigurationError( "FLAREBOT_CONTROL_PLANE.oauthTokenAuthMethod", "set the registered client authentication method", ); return value;}
export function serializeControlPlaneConfig( value: unknown, environment: Environment = "production",): string { return JSON.stringify(parseControlPlaneConfig(value, environment));}
export function loadControlPlaneConfig(env: ControlPlaneConfigBindings) { const settings = serverSettings( env as Bindings, "control-plane", bindingKeys, ); return Object.freeze({ ...settings, mode: "control-plane" as const, config: parseControlPlaneConfig( json(env.FLAREBOT_CONTROL_PLANE, "FLAREBOT_CONTROL_PLANE"), settings.environment, ), });}
export function loadControlPlaneSecrets(env: ControlPlaneConfigBindings) { const bindings = env as Bindings; serverSettings(bindings, "control-plane", bindingKeys); const encryptionKey = requiredSecret( bindings, "FLAREBOT_CREDENTIAL_ENCRYPTION_KEY", ); // A canonical base64url-encoded 256-bit key for the protected credential vault. if (!/^[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$/.test(encryptionKey.reveal())) throw new ConfigurationError( "FLAREBOT_CREDENTIAL_ENCRYPTION_KEY", "set a base64url-encoded 32-byte random key without padding", ); return Object.freeze({ sessionSecret: requiredSecret(bindings, "FLAREBOT_SESSION_SECRET"), credentialEncryptionKey: encryptionKey, oauthClientSecret: env.FLAREBOT_OAUTH_CLIENT_SECRET === undefined ? undefined : requiredSecret(bindings, "FLAREBOT_OAUTH_CLIENT_SECRET", 1), });}
// Local logout requires only a valid authoritative origin, not deployment scope setup.export function loadControlPlaneOrigin(env: ControlPlaneConfigBindings) { const settings = serverSettings( env as Bindings, "control-plane", bindingKeys, ); const config = record( json(env.FLAREBOT_CONTROL_PLANE, "FLAREBOT_CONTROL_PLANE"), keys, "FLAREBOT_CONTROL_PLANE", ); return origin( config.publicOrigin, "FLAREBOT_CONTROL_PLANE.publicOrigin", settings.environment, );}