mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-24 00:11:31 +00:00
49 lines
1.4 KiB
TypeScript
49 lines
1.4 KiB
TypeScript
import type { LookupFn, SsrFPolicy } from "../../api.js";
|
|
import { UrbitAuthError } from "./errors.js";
|
|
import { urbitFetch } from "./fetch.js";
|
|
|
|
export type UrbitAuthenticateOptions = {
|
|
ssrfPolicy?: SsrFPolicy;
|
|
lookupFn?: LookupFn;
|
|
fetchImpl?: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
timeoutMs?: number;
|
|
};
|
|
|
|
export async function authenticate(
|
|
url: string,
|
|
code: string,
|
|
options: UrbitAuthenticateOptions = {},
|
|
): Promise<string> {
|
|
const { response, release } = await urbitFetch({
|
|
baseUrl: url,
|
|
path: "/~/login",
|
|
init: {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
body: new URLSearchParams({ password: code }).toString(),
|
|
},
|
|
ssrfPolicy: options.ssrfPolicy,
|
|
lookupFn: options.lookupFn,
|
|
fetchImpl: options.fetchImpl,
|
|
timeoutMs: options.timeoutMs ?? 15_000,
|
|
maxRedirects: 3,
|
|
auditContext: "tlon-urbit-login",
|
|
});
|
|
|
|
try {
|
|
if (!response.ok) {
|
|
throw new UrbitAuthError("auth_failed", `Login failed with status ${response.status}`);
|
|
}
|
|
|
|
// Some Urbit setups require the response body to be read before cookie headers finalize.
|
|
await response.text().catch(() => {});
|
|
const cookie = response.headers.get("set-cookie");
|
|
if (!cookie) {
|
|
throw new UrbitAuthError("missing_cookie", "No authentication cookie received");
|
|
}
|
|
return cookie;
|
|
} finally {
|
|
await release();
|
|
}
|
|
}
|