Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
7.8 kB · 228 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229import { customDomainOrigin } from "../shared/domain-origin.ts";import { DOMAIN_CONFIGURATION_PURPOSE } from "../shared/bridge.ts";import { configuration, type Env } from "./config.ts";import { DomainAPI, domainJson } from "./domain-api.ts";import { domainFail, type DomainStart, type DomainRecord,} from "./domain-metadata.ts";import { authenticatedPrincipal, authorizedGrant, grantedAccounts, vault,} from "./session.ts";import { ownedInstallation, installationRegistry } from "./installations.ts";import { installationId, parse, unwrap, InstallationError, type Installation,} from "./installation-metadata.ts";import { form, privateResponse } from "./http.ts";import { signBridgeAssertion } from "./bridge.ts";
export function requireDomainCapability(env: Env, scopes: string[]) { const manifest = configuration(env).oauthCapabilities!; for (const capability of ["domain-zones", "domain-routing"] as const) { const required = manifest.scopes.filter((scope) => scope.capabilities.includes(capability), ); if (!required.length) domainFail("setup_required"); if (required.some((scope) => !scopes.includes(scope.id))) domainFail("reauthorization_required"); }}export async function configureRuntimeDomain( env: Env, record: Installation, domain: DomainRecord, network: typeof fetch = fetch,) { const assertion = await signBridgeAssertion(env, { aud: record.resources.runtimeOrigin!, sub: record.ownerSubject, installationId: record.installationId, purpose: DOMAIN_CONFIGURATION_PURPOSE, state: String(domain.revision), challenge: domain.origin ?? "", }); const response = await network( new URL("/auth/domain-configuration", record.resources.runtimeOrigin!), { method: "POST", redirect: "manual", signal: AbortSignal.timeout(15_000), headers: { Authorization: `Bearer ${assertion}` }, }, ); if (!response.ok) domainFail( response.status === 404 ? "setup_required" : "temporarily_unavailable", ); const result = await domainJson(response); if ( result?.revision !== domain.revision || result?.origin !== domain.origin || Object.keys(result).sort().join() !== "origin,revision" ) domainFail("temporarily_unavailable");}
// Called only after the installation router's exact-Origin mutation guard.export async function setupDomain( request: Request, env: Env, id: string, action: string | undefined, network: typeof fetch,) { const record = await ownedInstallation(request, env, id); if (!record.installedRelease || !record.resources.runtimeOrigin) domainFail("setup_required"); const principal = await authenticatedPrincipal(request, env); const registry = installationRegistry(env, principal.subject); const json = (data: unknown, status = 200) => privateResponse(Response.json(data, { status })); if (request.method === "GET" && !action) return json({ installationId: id, accountId: record.accountId, runtimeOrigin: record.resources.runtimeOrigin, domain: unwrap(await registry.getDomain(principal.subject, id)), }); const grant = await authorizedGrant(env, principal); requireDomainCapability(env, grant.scopes); if ( !(await grantedAccounts(env, principal, network)).some( (account) => account.id === record.accountId, ) ) domainFail("account_denied"); const api = new DomainAPI(grant.accessToken, record, network); if (request.method === "GET" && action === "zones") return json({ zones: await api.zones() }); if ( request.method !== "POST" || (action && !["remove", "retry"].includes(action)) ) throw new InstallationError("invalid_metadata"); const input = await form(request); const keys = action ? ["requestId"] : ["requestId", "zoneId", "hostname"]; if ( [...input.keys()].length !== keys.length || keys.some((key) => input.getAll(key).length !== 1) ) throw new InstallationError("invalid_metadata"); const requestId = parse(installationId, input.get("requestId")); let intent: DomainStart; if (action) intent = { action: action as "remove" | "retry" }; else { const hostname = input.get("hostname")!.trim().toLowerCase(); const origin = customDomainOrigin(`https://${hostname}`); if (!origin) domainFail("invalid_hostname"); const zoneId = parse(installationId, input.get("zoneId")); await api.zone(zoneId, hostname); intent = { action: "attach", origin, zoneId }; } if (grant.expiresAt < Date.now() + 120_000) domainFail("reauthorization_required"); if ( action && !unwrap(await registry.domainReplay(principal.subject, id, requestId)) ) { const previous = unwrap(await registry.getDomain(principal.subject, id)); if ( action === "remove" && previous?.action === "attach" && (previous.status === "connecting" || (previous.writeIntent && !previous.domainId)) ) domainFail("attachment_outcome_unknown"); if (previous && ["connecting", "removing"].includes(previous.status)) { // Stop the old execution before a new intent can supersede it. Remote // writes already in flight are reconciled using the preserved write intent. try { const workflow = await env.INSTALLATION_WORKFLOW.get( previous.operationId, ); await workflow.terminate(); if ((await workflow.status()).status !== "terminated") domainFail("temporarily_unavailable"); } catch (error) { if ( ![ "instance.not_found", "Error: instance.not_found", "(instance.not_found) Instance not found", ].includes((error as Error)?.message) ) domainFail("temporarily_unavailable"); } const current = unwrap(await registry.getDomain(principal.subject, id)); if (current?.operationId !== previous.operationId) throw new InstallationError("installation_conflict"); if (["connecting", "removing"].includes(current.status)) unwrap( await registry.updateDomain( principal.subject, id, current.operationId, current.revision, { status: "failed", errorCode: "temporarily_unavailable", domainId: current.domainId, writeIntent: current.writeIntent, }, ), ); else if ( action === "retry" && ["active", "removed"].includes(current.status) ) return json({ domain: current }); } } const domain = unwrap( await registry.startDomain( principal.subject, id, requestId, intent, Math.min(Date.now() + 20 * 60_000, grant.expiresAt - 30_000), ), ); if (!["connecting", "removing"].includes(domain.status)) return json({ domain }); // The same reservation repairs ambiguous vault or Workflow creation replies. await vault(env, "operation", domain.operationId).createOperation({ subject: principal.subject, accountId: record.accountId, installationId: id, operationId: domain.operationId, grantRef: principal.grantRef, expiresAt: domain.deadline, bootstrapSecret: null, }); try { await env.INSTALLATION_WORKFLOW.create({ id: domain.operationId, params: { ownerSubject: principal.subject, installationId: id, operationId: domain.operationId, kind: "domain", }, }); } catch { try { await (await env.INSTALLATION_WORKFLOW.get(domain.operationId)).status(); } catch { domainFail("temporarily_unavailable"); } } return json({ domain }, 202);}