193 lines · 7.1 KB · TypeScript
RawDownload
import { Effect, Layer, Option } from "effect";import { HttpRouter, HttpServerRequest, HttpServerResponse } from "effect/unstable/http"; export const OAUTH_CLIENT_ID_METADATA_DOCUMENT_BASE_PATH = "/oauth/client-id-metadata" as const;export const OAUTH_CLIENT_ID_METADATA_DOCUMENT_PATH =  `${OAUTH_CLIENT_ID_METADATA_DOCUMENT_BASE_PATH}.json` as const;export const OAUTH_CLIENT_ID_METADATA_DOCUMENT_TARGET_PATH_PREFIX =  `${OAUTH_CLIENT_ID_METADATA_DOCUMENT_BASE_PATH}/` as const;export const OAUTH_CLIENT_ID_METADATA_DOCUMENT_DEFAULT_TARGET = "default" as const;export const OAUTH_CLIENT_ID_METADATA_DOCUMENT_LOCAL_TARGET = "local" as const;const OAUTH_CALLBACK_ORG_QUERY_PARAM = "executor_org" as const; type MetadataTarget =  | typeof OAUTH_CLIENT_ID_METADATA_DOCUMENT_DEFAULT_TARGET  | typeof OAUTH_CLIENT_ID_METADATA_DOCUMENT_LOCAL_TARGET  | string; interface OAuthClientIdMetadataDocument {  readonly client_id: string;  readonly client_name: string;  readonly client_uri: string;  readonly redirect_uris: readonly string[];  readonly grant_types: readonly ["authorization_code"];  readonly response_types: readonly ["code"];  readonly token_endpoint_auth_method: "none";  readonly application_type: "web" | "native";} const pathWithMountPrefix = (mountPrefix?: string): `/${string}` =>  `${mountPrefix ?? ""}${OAUTH_CLIENT_ID_METADATA_DOCUMENT_PATH}` as `/${string}`; const targetPathWithMountPrefix = (mountPrefix?: string): `/${string}` =>  `${mountPrefix ?? ""}${OAUTH_CLIENT_ID_METADATA_DOCUMENT_TARGET_PATH_PREFIX}*` as `/${string}`; const callbackPathWithMountPrefix = (mountPrefix?: string): `/${string}` =>  `${mountPrefix ?? ""}/oauth/callback` as `/${string}`; export const oauthClientIdMetadataDocumentPath = (mountPrefix?: string): `/${string}` =>  pathWithMountPrefix(mountPrefix); export const oauthClientIdMetadataDocumentTargetPath = (  target: MetadataTarget,  mountPrefix?: string,): `/${string}` =>  `${mountPrefix ?? ""}${OAUTH_CLIENT_ID_METADATA_DOCUMENT_TARGET_PATH_PREFIX}${encodeURIComponent(    target,  )}.json` as `/${string}`; const firstForwardedHeaderValue = (headers: Headers, name: string): string | undefined => {  const value = headers.get(name)?.split(",")[0]?.trim();  return value ? value : undefined;}; const parseAbsoluteUrl = (value: string): URL | undefined => {  if (!/^[a-z][a-z\d+.-]*:\/\//i.test(value)) return undefined;  return new URL(value);};const decodeUriComponentOption = Option.liftThrowable(decodeURIComponent); const pathSearchAndHash = (value: string, fallbackPath: `/${string}`): string => {  const parsed = parseAbsoluteUrl(value);  if (parsed) return `${parsed.pathname}${parsed.search}${parsed.hash}`;  return value.startsWith("/") ? value : fallbackPath;}; const metadataTargetFromPath = ({  pathname,  mountPrefix,}: {  readonly pathname: string;  readonly mountPrefix?: string;}): MetadataTarget | undefined => {  const prefix = `${mountPrefix ?? ""}${OAUTH_CLIENT_ID_METADATA_DOCUMENT_TARGET_PATH_PREFIX}`;  if (!pathname.startsWith(prefix) || !pathname.endsWith(".json")) return undefined;  const encoded = pathname.slice(prefix.length, -".json".length);  if (!encoded || encoded.includes("/")) return undefined;  const target = Option.getOrUndefined(    Option.map(decodeUriComponentOption(encoded), (value) => value.trim()),  );  return target ? target : undefined;}; const orgSlugFromMetadataTarget = (target: MetadataTarget | undefined): string | undefined => {  if (!target) return undefined;  if (    target === OAUTH_CLIENT_ID_METADATA_DOCUMENT_DEFAULT_TARGET ||    target === OAUTH_CLIENT_ID_METADATA_DOCUMENT_LOCAL_TARGET  ) {    return undefined;  }  return target;}; export const oauthClientIdMetadataDocumentUrlFromRequest = ({  requestUrl,  webRequest,  mountPrefix,}: {  readonly requestUrl: string;  readonly webRequest: Request;  readonly mountPrefix?: string;}): URL => {  const requestAbsoluteUrl = parseAbsoluteUrl(requestUrl) ?? parseAbsoluteUrl(webRequest.url);  const proto =    firstForwardedHeaderValue(webRequest.headers, "x-forwarded-proto") ??    requestAbsoluteUrl?.protocol.replace(/:$/, "") ??    "http";  const host =    firstForwardedHeaderValue(webRequest.headers, "x-forwarded-host") ??    firstForwardedHeaderValue(webRequest.headers, "host") ??    requestAbsoluteUrl?.host ??    "localhost";  const origin = `${proto}://${host}`;  return new URL(pathSearchAndHash(requestUrl, pathWithMountPrefix(mountPrefix)), origin);}; const localLoopbackRedirectUris = (mountPrefix?: string): readonly string[] => {  const callbackPath = callbackPathWithMountPrefix(mountPrefix);  return [    new URL(callbackPath, "http://127.0.0.1").toString(),    new URL(callbackPath, "http://localhost").toString(),    new URL(callbackPath, "http://[::1]").toString(),  ];}; export const oauthClientIdMetadataDocumentFromRequest = ({  requestUrl,  webRequest,  mountPrefix,}: {  readonly requestUrl: string;  readonly webRequest: Request;  readonly mountPrefix?: string;}): OAuthClientIdMetadataDocument => {  const url = oauthClientIdMetadataDocumentUrlFromRequest({ requestUrl, webRequest, mountPrefix });  const target = metadataTargetFromPath({ pathname: url.pathname, mountPrefix });   if (target === OAUTH_CLIENT_ID_METADATA_DOCUMENT_LOCAL_TARGET) {    return {      client_id: url.toString(),      client_name: "Executor Local",      client_uri: url.origin,      redirect_uris: localLoopbackRedirectUris(mountPrefix),      grant_types: ["authorization_code"],      response_types: ["code"],      token_endpoint_auth_method: "none",      application_type: "native",    };  }   const redirectUri = new URL(callbackPathWithMountPrefix(mountPrefix), url.origin);  const orgSlug =    orgSlugFromMetadataTarget(target) ??    url.searchParams.get(OAUTH_CALLBACK_ORG_QUERY_PARAM)?.trim();  if (orgSlug) redirectUri.searchParams.set(OAUTH_CALLBACK_ORG_QUERY_PARAM, orgSlug);   return {    client_id: url.toString(),    client_name: "Executor",    client_uri: url.origin,    redirect_uris: [redirectUri.toString()],    grant_types: ["authorization_code"],    response_types: ["code"],    token_endpoint_auth_method: "none",    application_type: "web",  };}; export const makeOAuthClientIdMetadataRoute = (  mountPrefix?: string,): Layer.Layer<never, never, HttpRouter.HttpRouter> => {  const handler = Effect.gen(function* () {    const request = yield* HttpServerRequest.HttpServerRequest;    // oxlint-disable-next-line executor/no-effect-escape-hatch -- boundary: HTTP router request conversion failure is an edge defect, not recoverable route input    const webRequest = yield* HttpServerRequest.toWeb(request).pipe(Effect.orDie);    const metadata = oauthClientIdMetadataDocumentFromRequest({      requestUrl: request.url,      webRequest,      mountPrefix,    });     return HttpServerResponse.jsonUnsafe(metadata, {      headers: {        "cache-control": "public, max-age=300",      },    });  });   return Layer.mergeAll(    HttpRouter.add("GET", pathWithMountPrefix(mountPrefix), handler),    HttpRouter.add("GET", targetPathWithMountPrefix(mountPrefix), handler),  );};