import type { AuthBearerBootstrapResult, AuthSessionState, AuthWebSocketTokenResult, ExecutionEnvironmentDescriptor, } from "@t3tools/contracts"; class RemoteEnvironmentAuthHttpError extends Error { readonly status: number; constructor(message: string, status: number) { super(message); this.name = "RemoteEnvironmentAuthHttpError"; this.status = status; } } function remoteEndpointUrl(httpBaseUrl: string, pathname: string): string { const url = new URL(httpBaseUrl); url.pathname = pathname; url.search = ""; url.hash = ""; return url.toString(); } async function readRemoteAuthErrorMessage( response: Response, fallbackMessage: string, ): Promise { const text = await response.text(); if (!text) { return fallbackMessage; } try { const parsed = JSON.parse(text) as { readonly error?: string }; if (typeof parsed.error === "string" && parsed.error.length > 0) { return parsed.error; } } catch { // Fall back to raw text below. } return text; } async function fetchRemoteJson(input: { readonly httpBaseUrl: string; readonly pathname: string; readonly method?: "GET" | "POST"; readonly bearerToken?: string; readonly body?: unknown; }): Promise { const requestUrl = remoteEndpointUrl(input.httpBaseUrl, input.pathname); let response: Response; try { response = await fetch(requestUrl, { method: input.method ?? "GET", headers: { ...(input.body !== undefined ? { "content-type": "application/json" } : {}), ...(input.bearerToken ? { authorization: `Bearer ${input.bearerToken}` } : {}), }, ...(input.body !== undefined ? { body: JSON.stringify(input.body) } : {}), }); } catch (error) { throw new Error( `Failed to fetch remote auth endpoint ${requestUrl} (${(error as Error).message}).`, { cause: error }, ); } if (!response.ok) { throw new RemoteEnvironmentAuthHttpError( await readRemoteAuthErrorMessage( response, `Remote auth request failed (${response.status}).`, ), response.status, ); } return (await response.json()) as T; } export async function bootstrapRemoteBearerSession(input: { readonly httpBaseUrl: string; readonly credential: string; }): Promise { return fetchRemoteJson({ httpBaseUrl: input.httpBaseUrl, pathname: "/api/auth/bootstrap/bearer", method: "POST", body: { credential: input.credential, }, }); } export async function fetchRemoteSessionState(input: { readonly httpBaseUrl: string; readonly bearerToken: string; }): Promise { return fetchRemoteJson({ httpBaseUrl: input.httpBaseUrl, pathname: "/api/auth/session", bearerToken: input.bearerToken, }); } export async function fetchRemoteEnvironmentDescriptor(input: { readonly httpBaseUrl: string; }): Promise { return fetchRemoteJson({ httpBaseUrl: input.httpBaseUrl, pathname: "/.well-known/t3/environment", }); } export async function issueRemoteWebSocketToken(input: { readonly httpBaseUrl: string; readonly bearerToken: string; }): Promise { return fetchRemoteJson({ httpBaseUrl: input.httpBaseUrl, pathname: "/api/auth/ws-token", method: "POST", bearerToken: input.bearerToken, }); } export async function resolveRemoteWebSocketConnectionUrl(input: { readonly wsBaseUrl: string; readonly httpBaseUrl: string; readonly bearerToken: string; }): Promise { const issued = await issueRemoteWebSocketToken({ httpBaseUrl: input.httpBaseUrl, bearerToken: input.bearerToken, }); const url = new URL(input.wsBaseUrl, window.location.origin); url.searchParams.set("wsToken", issued.token); return url.toString(); }