@parlor/auth 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +13 -2
- package/dist/client/index.js.map +1 -1
- package/dist/hosts.d.ts +6 -1
- package/dist/hosts.d.ts.map +1 -1
- package/dist/hosts.js +44 -4
- package/dist/hosts.js.map +1 -1
- package/dist/pages.d.ts +1 -1
- package/dist/pages.d.ts.map +1 -1
- package/dist/pages.js +8 -4
- package/dist/pages.js.map +1 -1
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +20 -1
- package/dist/provider.js.map +1 -1
- package/dist/statements.d.ts +2 -0
- package/dist/statements.d.ts.map +1 -1
- package/dist/statements.js +2 -0
- package/dist/statements.js.map +1 -1
- package/dist/tokens.d.ts +27 -1
- package/dist/tokens.d.ts.map +1 -1
- package/dist/tokens.js +82 -3
- package/dist/tokens.js.map +1 -1
- package/package.json +7 -7
package/dist/client/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type AuthBrowser, type DeviceKey, type SessionStore } from "@parlor/capabilities";
|
|
2
|
-
import { type ActionClient, type DeviceLinker, type DeviceSource, type HostAuthorizer, type SessionDevice, type SessionSource } from "@parlor/client";
|
|
2
|
+
import { type ActionClient, type ComputerDisconnector, type DeviceLinker, type DeviceSource, type HostAuthorizer, type SessionDevice, type SessionSource } from "@parlor/client";
|
|
3
3
|
import type { AccountActions } from "../account.js";
|
|
4
4
|
export interface AuthClientOptions {
|
|
5
5
|
/** The backend origin; defaults to the shell's `server.url`, or this page's origin. */
|
|
@@ -33,7 +33,7 @@ export interface SocialSignInInput {
|
|
|
33
33
|
/** On the web, the page a failed sign-in returns to with `?error=`. Defaults to this page. */
|
|
34
34
|
readonly errorCallbackURL?: string | undefined;
|
|
35
35
|
}
|
|
36
|
-
export interface AuthClient extends SessionSource, DeviceSource, HostAuthorizer, DeviceLinker {
|
|
36
|
+
export interface AuthClient extends SessionSource, DeviceSource, HostAuthorizer, DeviceLinker, ComputerDisconnector {
|
|
37
37
|
deviceSetup(): Promise<"needed" | "ready">;
|
|
38
38
|
/** Plug into `createActionClient({ headers })` so every surface carries the session. */
|
|
39
39
|
readonly headers: () => Promise<HeadersInit>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,WAAW,EAGhB,KAAK,SAAS,EAKd,KAAK,YAAY,EAElB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,KAAK,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
|
package/dist/client/index.js
CHANGED
|
@@ -5,14 +5,13 @@ import { appOrigin, createActionClient, LinkOnComputer, } from "@parlor/client";
|
|
|
5
5
|
import { ActionError } from "@parlor/core";
|
|
6
6
|
import { createAuthClient as createBetterAuthClient } from "better-auth/client";
|
|
7
7
|
import { emailOTPClient } from "better-auth/client/plugins";
|
|
8
|
-
import { answerStatement, deviceCommitment, HOST_PAIRING_FRAGMENT, linkCode, normalizeLinkCode, pairingProof, promptStatement, removeStatement, statementBytes, vouchStatement, } from "../statements.js";
|
|
8
|
+
import { answerStatement, deviceCommitment, HOST_PAIRING_FRAGMENT, HOST_PAIRING_KEY, linkCode, normalizeLinkCode, pairingProof, promptStatement, removeStatement, statementBytes, vouchStatement, } from "../statements.js";
|
|
9
9
|
const DEFAULT_BASE_PATH = "/_parlor";
|
|
10
10
|
const RETRY_BASE_MS = 1000;
|
|
11
11
|
const RETRY_MAX_MS = 30_000;
|
|
12
12
|
const TOKEN_HEADER = "set-auth-token";
|
|
13
13
|
const HOST_IPC_REDIRECT = "urn:parlor:ipc";
|
|
14
14
|
const DEBUG_KEY = "parlor:debug";
|
|
15
|
-
const HOST_PAIRING_KEY = "parlor:host-pairing";
|
|
16
15
|
const NATIVE_CALLBACK = "//_parlor/auth/callback";
|
|
17
16
|
function injectedServerUrl() {
|
|
18
17
|
const env = import.meta.env;
|
|
@@ -108,6 +107,14 @@ function keepHostPairing() {
|
|
|
108
107
|
}
|
|
109
108
|
catch { }
|
|
110
109
|
}
|
|
110
|
+
function watchHostPairing(listener) {
|
|
111
|
+
const changed = (event) => {
|
|
112
|
+
if (event.key === HOST_PAIRING_KEY || event.key === null)
|
|
113
|
+
listener();
|
|
114
|
+
};
|
|
115
|
+
globalThis.addEventListener?.("storage", changed);
|
|
116
|
+
return () => globalThis.removeEventListener?.("storage", changed);
|
|
117
|
+
}
|
|
111
118
|
function hostPairing() {
|
|
112
119
|
try {
|
|
113
120
|
return globalThis.localStorage?.getItem(HOST_PAIRING_KEY) ?? undefined;
|
|
@@ -412,6 +419,7 @@ export function createAuthClient(options = {}) {
|
|
|
412
419
|
await (await store)?.set(undefined);
|
|
413
420
|
}
|
|
414
421
|
},
|
|
422
|
+
subscribeLink: watchHostPairing,
|
|
415
423
|
linkState: async () => {
|
|
416
424
|
const pairing = hostPairing() !== undefined;
|
|
417
425
|
const session = current();
|
|
@@ -463,6 +471,9 @@ export function createAuthClient(options = {}) {
|
|
|
463
471
|
code: linkCode(commitment),
|
|
464
472
|
};
|
|
465
473
|
},
|
|
474
|
+
disconnectComputer: async (hostId) => {
|
|
475
|
+
await account.call("revokeHost", { hostId });
|
|
476
|
+
},
|
|
466
477
|
listDevices: async () => {
|
|
467
478
|
const session = current();
|
|
468
479
|
if (session.status !== "signed-in")
|
package/dist/client/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { oauthProviderClient } from \"@better-auth/oauth-provider/client\";\nimport {\n type AuthBrowser,\n authBrowser,\n detectPlatform,\n type DeviceKey,\n deviceKey,\n type PairingPresenceKey,\n type PresencePublicKey,\n resolveCapability,\n type SessionStore,\n sessionStore,\n} from \"@parlor/capabilities\";\nimport { decodeBase64url, encodeBase64url } from \"@parlor/capabilities/encoding\";\nimport {\n type ActionClient,\n appOrigin,\n createActionClient,\n type DeviceLinker,\n type DeviceSource,\n type HostAuthorizer,\n LinkOnComputer,\n type PendingLink,\n type SessionDevice,\n type SessionSnapshot,\n type SessionSource,\n type SessionUser,\n} from \"@parlor/client\";\nimport { ActionError } from \"@parlor/core\";\nimport type { BetterAuthClientPlugin } from \"better-auth/client\";\nimport { createAuthClient as createBetterAuthClient } from \"better-auth/client\";\nimport { emailOTPClient } from \"better-auth/client/plugins\";\n\nimport type { AccountActions } from \"../account.js\";\nimport type { nativeSignIn } from \"../native-sign-in.js\";\nimport {\n answerStatement,\n deviceCommitment,\n HOST_PAIRING_FRAGMENT,\n linkCode,\n normalizeLinkCode,\n pairingProof,\n promptStatement,\n removeStatement,\n type Statement,\n statementBytes,\n vouchStatement,\n} from \"../statements.js\";\n\nconst DEFAULT_BASE_PATH = \"/_parlor\";\nconst RETRY_BASE_MS = 1000;\nconst RETRY_MAX_MS = 30_000;\nconst TOKEN_HEADER = \"set-auth-token\";\nconst HOST_IPC_REDIRECT = \"urn:parlor:ipc\";\nconst DEBUG_KEY = \"parlor:debug\";\nconst HOST_PAIRING_KEY = \"parlor:host-pairing\";\n\nconst NATIVE_CALLBACK = \"//_parlor/auth/callback\";\n\nfunction injectedServerUrl(): string {\n const env = (import.meta as { env?: { PARLOR_SERVER_URL?: string } }).env;\n return env?.PARLOR_SERVER_URL ?? \"\";\n}\n\nfunction injectedScheme(): string {\n const env = (import.meta as { env?: { PARLOR_APP_SCHEME?: string } }).env;\n return env?.PARLOR_APP_SCHEME ?? \"\";\n}\n\nconst nativeSignInClient = {\n id: \"parlor-native-sign-in\",\n $InferServerPlugin: {} as ReturnType<typeof nativeSignIn>,\n atomListeners: [\n { matcher: (path: string) => path === \"/native/token\", signal: \"$sessionSignal\" },\n ],\n} satisfies BetterAuthClientPlugin;\n\nconst randomText = (bytes: number) =>\n encodeBase64url(crypto.getRandomValues(new Uint8Array(bytes)));\n\nasync function pkceChallenge(verifier: string): Promise<string> {\n const digest = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(verifier),\n );\n return encodeBase64url(new Uint8Array(digest));\n}\n\nexport interface AuthClientOptions {\n /** The backend origin; defaults to the shell's `server.url`, or this page's origin. */\n readonly baseUrl?: string | undefined;\n readonly basePath?: string | undefined;\n /**\n * Where a bearer session is kept. Defaults to the `sessionStore` capability: native\n * shells keep a bearer token, the web keeps a cookie.\n */\n readonly session?: SessionStore | undefined;\n /** Where this device's signing keys live. Defaults to the `deviceKey` capability. */\n readonly deviceKey?: DeviceKey | undefined;\n /** Where social sign-in runs. Defaults to the `authBrowser` capability. */\n readonly browser?: AuthBrowser | undefined;\n /** The app's URL scheme, where social sign-in returns in a native shell. Defaults to `app.scheme`. */\n readonly scheme?: string | undefined;\n readonly fetch?: typeof fetch | undefined;\n}\n\nexport class AuthClientError extends Error {\n override readonly name = \"AuthClientError\";\n constructor(\n message: string,\n readonly status: number,\n readonly code: string | undefined,\n ) {\n super(message);\n }\n}\n\nexport type DeviceHandle = SessionDevice;\n\nexport interface SocialSignInInput {\n /** A provider in Better Auth's `socialProviders`, or a `genericOAuth` provider id. */\n readonly provider: string;\n /** On the web, the page the provider returns to once signed in. Defaults to `/`. */\n readonly callbackURL?: string | undefined;\n /** On the web, the page a failed sign-in returns to with `?error=`. Defaults to this page. */\n readonly errorCallbackURL?: string | undefined;\n}\n\nexport interface AuthClient\n extends SessionSource, DeviceSource, HostAuthorizer, DeviceLinker {\n deviceSetup(): Promise<\"needed\" | \"ready\">;\n /** Plug into `createActionClient({ headers })` so every surface carries the session. */\n readonly headers: () => Promise<HeadersInit>;\n signIn(input: { readonly email: string; readonly password: string }): Promise<void>;\n signUp(input: {\n readonly name: string;\n readonly email: string;\n readonly password: string;\n }): Promise<void>;\n signOut(): Promise<void>;\n /** Sign-in with a one-time code sent by email, through Better Auth's `emailOTP` plugin. */\n readonly emailOtp: {\n send(input: { readonly email: string }): Promise<void>;\n /** Signs in, creating the account on first use unless the plugin disables sign-up. */\n signIn(input: {\n readonly email: string;\n readonly otp: string;\n readonly name?: string | undefined;\n }): Promise<void>;\n };\n /** Sign-in with a provider such as Google, through Better Auth's `socialProviders`. */\n readonly social: {\n /** Whether this platform can run it: false in a native shell without the `authBrowser` capability. */\n available(): Promise<boolean>;\n /**\n * On the web the page leaves for the provider and comes back to `callbackURL`, so this\n * never resolves. In a native shell the provider opens in the system's sign-in browser\n * and this resolves once the app is signed in; it throws `AuthClientError` with code\n * `CANCELLED` when the user closes it.\n */\n signIn(input: SocialSignInInput): Promise<void>;\n };\n /** The account actions: `sessions`, `revokeSession`, `agents`, `revokeAgent`. */\n readonly account: ActionClient<AccountActions>;\n}\n\ninterface BetterAuthResult {\n readonly error?: {\n readonly message?: string | undefined;\n readonly status: number;\n readonly code?: string | undefined;\n } | null;\n}\n\nfunction settle(result: BetterAuthResult): void {\n if (!result.error) return;\n const { message, status, code } = result.error;\n throw new AuthClientError(message || \"Authentication failed.\", status, code);\n}\n\nconst ANONYMOUS_SESSION: SessionSnapshot = { status: \"anonymous\" };\n\nconst BROWSERS = [\n [/Edg\\//, \"Edge\"],\n [/OPR\\//, \"Opera\"],\n [/Firefox\\//, \"Firefox\"],\n [/Chrome\\//, \"Chrome\"],\n [/Safari\\//, \"Safari\"],\n] as const;\n\nconst SYSTEMS = [\n [/iPhone|iPad/, \"iOS\"],\n [/Android/, \"Android\"],\n [/Mac OS X/, \"macOS\"],\n [/Windows/, \"Windows\"],\n [/Linux/, \"Linux\"],\n] as const;\n\nfunction deviceName(): string {\n const agent = globalThis.navigator?.userAgent ?? \"\";\n const browser = BROWSERS.find(([pattern]) => pattern.test(agent))?.[1];\n const system = SYSTEMS.find(([pattern]) => pattern.test(agent))?.[1];\n if (browser && system) return `${browser} on ${system}`;\n return browser ?? system ?? \"This device\";\n}\n\nfunction debugStatements(): boolean {\n try {\n return (\n globalThis.localStorage?.getItem(DEBUG_KEY)?.split(\",\").includes(\"statements\") ??\n false\n );\n } catch {\n return false;\n }\n}\n\nasync function logSigned(statement: Statement): Promise<void> {\n if (!debugStatements()) return;\n const digest = await crypto.subtle.digest(\n \"SHA-256\",\n new Uint8Array(statementBytes(statement)),\n );\n const hex = [...new Uint8Array(digest)]\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n console.info(`[parlor] signed ${statement.kind} sha256=${hex}`);\n}\n\n/** Takes the host's pairing secret off this page's URL, where only that redirect puts it. */\nfunction keepHostPairing(): void {\n try {\n const location = globalThis.location;\n if (!location?.hash) return;\n const fragment = new URLSearchParams(location.hash.slice(1));\n const secret = fragment.get(HOST_PAIRING_FRAGMENT);\n if (!secret) return;\n globalThis.localStorage?.setItem(HOST_PAIRING_KEY, secret);\n fragment.delete(HOST_PAIRING_FRAGMENT);\n const rest = fragment.toString();\n globalThis.history?.replaceState(\n globalThis.history.state,\n \"\",\n `${location.pathname}${location.search}${rest ? `#${rest}` : \"\"}`,\n );\n } catch {}\n}\n\nfunction hostPairing(): string | undefined {\n try {\n return globalThis.localStorage?.getItem(HOST_PAIRING_KEY) ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nconst serverHasNoAuth = (error: { readonly status?: unknown }) => error.status === 404;\n\nfunction enrollmentPresence(presence: PresencePublicKey | undefined, rpId: string) {\n if (!presence) return undefined;\n return presence.format === \"webauthn\"\n ? {\n format: \"webauthn\" as const,\n credentialId: presence.credentialId,\n rpId,\n publicKey: { ...presence.publicKey },\n attestation: presence.attestation,\n }\n : {\n format: \"es256-raw\" as const,\n keyId: presence.keyId,\n publicKey: { ...presence.publicKey },\n };\n}\n\nfunction registered(\n presence: ReturnType<typeof enrollmentPresence>,\n): PairingPresenceKey | undefined {\n if (presence?.format !== \"webauthn\") return presence;\n const { attestation: _attestation, ...key } = presence;\n return key;\n}\n\nfunction hostnameOf(origin: string): string {\n try {\n return new URL(origin).hostname;\n } catch {\n return globalThis.location.hostname;\n }\n}\n\nexport function createAuthClient(options: AuthClientOptions = {}): AuthClient {\n keepHostPairing();\n const baseUrl = options.baseUrl ?? injectedServerUrl();\n const basePath = options.basePath ?? DEFAULT_BASE_PATH;\n const store: Promise<SessionStore | undefined> = options.session\n ? Promise.resolve(options.session)\n : resolveCapability(sessionStore).then((handle) =>\n handle.available ? handle.api : undefined,\n );\n\n const headers = async (): Promise<HeadersInit> => {\n const token = await (await store)?.get();\n return token ? { authorization: `Bearer ${token}` } : {};\n };\n\n // Built on first use: importing a module that creates the client must work outside a page.\n let client: ReturnType<typeof connect> | undefined;\n const connect = () =>\n createBetterAuthClient({\n baseURL: `${baseUrl || globalThis.location.origin}${basePath}/auth`,\n plugins: [oauthProviderClient(), emailOTPClient(), nativeSignInClient],\n fetchOptions: {\n ...(options.fetch ? { customFetchImpl: options.fetch } : {}),\n onRequest: async (context) => {\n for (const [name, value] of new Headers(await headers())) {\n context.headers.set(name, value);\n }\n return context;\n },\n onSuccess: async (context) => {\n const token = context.response.headers.get(TOKEN_HEADER);\n if (token) await (await store)?.set(token);\n else if (\n context.request.url.toString().endsWith(\"/get-session\") &&\n !context.data\n ) {\n // A bearer token the server no longer knows would fail every later request.\n await (await store)?.set(undefined);\n }\n },\n },\n });\n const betterAuth = () => (client ??= connect());\n\n let watchers = 0;\n let retry: ReturnType<typeof setTimeout> | undefined;\n let retryDelay = RETRY_BASE_MS;\n const retryAfterError = () => {\n const state = betterAuth().useSession.get();\n if (!state.error || serverHasNoAuth(state.error)) {\n retryDelay = RETRY_BASE_MS;\n return;\n }\n if (retry !== undefined || state.isRefetching) return;\n retry = setTimeout(() => {\n retry = undefined;\n void state.refetch();\n }, retryDelay);\n retryDelay = Math.min(retryDelay * 2, RETRY_MAX_MS);\n };\n\n let last: unknown;\n let snapshot: SessionSnapshot = { status: \"loading\" };\n const current = (): SessionSnapshot => {\n const state = betterAuth().useSession.get();\n if (state === last) return snapshot;\n last = state;\n if (state.error) {\n if (serverHasNoAuth(state.error)) snapshot = ANONYMOUS_SESSION;\n // Only the server saying there is no session signs the user out, never an unreachable one.\n return snapshot;\n }\n const user = state.data?.user;\n snapshot = user\n ? { status: \"signed-in\", user: { id: user.id, name: user.name, email: user.email } }\n : state.isPending\n ? { status: \"loading\" }\n : { status: \"signed-out\" };\n return snapshot;\n };\n\n const account = createActionClient<AccountActions>({\n baseUrl,\n fetch: options.fetch,\n basePath: `${basePath}/auth`,\n headers,\n });\n\n const signInBrowser = async (): Promise<AuthBrowser | undefined> => {\n if (options.browser) return options.browser;\n const handle = await resolveCapability(authBrowser);\n return handle.available ? handle.api : undefined;\n };\n\n const signInOnThePage = async (browser: AuthBrowser, input: SocialSignInInput) => {\n const page = new URL(globalThis.location.href);\n const callbackURL = new URL(input.callbackURL ?? \"/\", page).href;\n const errorPage = new URL(input.errorCallbackURL ?? page, page);\n errorPage.searchParams.delete(\"error\");\n errorPage.searchParams.delete(\"error_description\");\n const result = await betterAuth().signIn.social({\n provider: input.provider,\n callbackURL,\n errorCallbackURL: errorPage.href,\n disableRedirect: true,\n });\n settle(result);\n const url = result.data?.url;\n if (!url)\n throw new AuthClientError(\"The provider gave no sign-in page.\", 500, undefined);\n await browser.open(url, callbackURL);\n };\n\n const signInInTheApp = async (browser: AuthBrowser, provider: string) => {\n const scheme = options.scheme ?? injectedScheme();\n if (!scheme) {\n throw new AuthClientError(\n \"Set app.scheme in parlor.config.ts to sign in with a provider in the app.\",\n 0,\n \"NO_SCHEME\",\n );\n }\n const callback = `${scheme}:${NATIVE_CALLBACK}`;\n const verifier = randomText(32);\n const state = randomText(16);\n const start = new URL(\n `${baseUrl || globalThis.location.origin}${basePath}/auth/native/sign-in/social`,\n );\n start.search = new URLSearchParams({\n provider,\n redirect_uri: callback,\n code_challenge: await pkceChallenge(verifier),\n code_challenge_method: \"S256\",\n state,\n }).toString();\n const returned = await browser.open(start.href, callback);\n if (!returned) throw new AuthClientError(\"Sign-in was cancelled.\", 0, \"CANCELLED\");\n const answer = new URL(returned).searchParams;\n if (answer.get(\"state\") !== state) {\n throw new AuthClientError(\n \"This sign-in was not started here.\",\n 0,\n \"STATE_MISMATCH\",\n );\n }\n const failed = answer.get(\"error\");\n const code = answer.get(\"code\");\n if (failed || !code) {\n throw new AuthClientError(\n answer.get(\"error_description\") || `Sign-in failed (${failed ?? \"no code\"}).`,\n 400,\n failed ?? undefined,\n );\n }\n settle(await betterAuth().native.token({ code, code_verifier: verifier }));\n };\n\n const keysOfThisPlatform = async (): Promise<DeviceKey | undefined> => {\n const handle = await resolveCapability(deviceKey);\n return handle.available ? handle.api : undefined;\n };\n\n const devices = new Map<string, Promise<DeviceHandle | undefined>>();\n const enroll = async (\n user: SessionUser,\n wantsPresence: boolean,\n ): Promise<DeviceHandle | undefined> => {\n const key = options.deviceKey ?? (await keysOfThisPlatform());\n if (!key) return undefined;\n const app = appOrigin(baseUrl || undefined);\n const rpId = hostnameOf(app);\n const { challenge } = await account.call(\"deviceChallenge\", {});\n const keys = await key.publicKeys(\n {\n rpId,\n userId: user.id,\n userName: user.email,\n challenge: decodeBase64url(challenge),\n },\n { presence: wantsPresence },\n );\n const presence = enrollmentPresence(keys.presence, rpId);\n const name = deviceName();\n const platform = detectPlatform();\n const signingKey = { ...keys.signing.publicKey };\n const { id } = await account.call(\"enrollDevice\", {\n name,\n platform,\n challenge,\n signing: { keyId: keys.signing.keyId, publicKey: signingKey },\n ...(presence ? { presence } : {}),\n proof: keys.proof,\n });\n return {\n id,\n keys: {\n deviceId: id,\n name,\n platform,\n signingKey,\n presenceKey: registered(presence),\n },\n signPrompt: async (prompt, wanted) => {\n const at = Date.now();\n const statement = await promptStatement(app, prompt, at);\n const bytes = statementBytes(statement);\n const signature = wanted?.presence\n ? await key.sign(bytes, { presence: true })\n : await key.sign(bytes, { presence: false });\n await logSigned(statement);\n const secret = hostPairing();\n const pairing = secret && (await pairingProof(secret, id, signingKey));\n return { deviceId: id, at, signature, ...(pairing ? { pairing } : {}) };\n },\n signAnswer: async (answer, { presence: wanted }) => {\n const at = Date.now();\n const statement = await answerStatement(app, answer, at);\n const bytes = statementBytes(statement);\n const signature = wanted\n ? await key.sign(bytes, { presence: true })\n : await key.sign(bytes, { presence: false });\n await logSigned(statement);\n return { deviceId: id, at, signature };\n },\n };\n };\n\n const device = async (wanted?: {\n readonly presence?: boolean;\n }): Promise<DeviceHandle | undefined> => {\n const session = current();\n if (session.status !== \"signed-in\") return undefined;\n const known = devices.get(session.user.id);\n if (known) return known;\n // The browser that approved `connect` is on the computer, which answers its permission questions.\n const presence = wanted?.presence ?? hostPairing() === undefined;\n const enrolling = enroll(session.user, presence).catch((error: unknown) => {\n if (error instanceof ActionError && error.code === \"not_found\") return undefined;\n throw error;\n });\n devices.set(session.user.id, enrolling);\n enrolling.then(\n (enrolled) => {\n if (!enrolled) devices.delete(session.user.id);\n },\n () => devices.delete(session.user.id),\n );\n return enrolling;\n };\n\n return {\n headers,\n current,\n subscribe: (listener) => {\n watchers += 1;\n const stop = betterAuth().useSession.listen(() => {\n retryAfterError();\n listener();\n });\n return () => {\n stop();\n watchers -= 1;\n if (watchers === 0 && retry !== undefined) {\n clearTimeout(retry);\n retry = undefined;\n }\n };\n },\n signIn: async (input) => settle(await betterAuth().signIn.email(input)),\n signUp: async (input) => settle(await betterAuth().signUp.email(input)),\n emailOtp: {\n send: async ({ email }) =>\n settle(\n await betterAuth().emailOtp.sendVerificationOtp({ email, type: \"sign-in\" }),\n ),\n signIn: async ({ email, otp, name }) =>\n settle(\n await betterAuth().signIn.emailOtp({ email, otp, ...(name ? { name } : {}) }),\n ),\n },\n social: {\n available: async () => (await signInBrowser()) !== undefined,\n signIn: async (input) => {\n const browser = await signInBrowser();\n if (!browser) {\n throw new AuthClientError(\n `Signing in with ${input.provider} is not available here.`,\n 0,\n \"UNSUPPORTED\",\n );\n }\n if (await store) await signInInTheApp(browser, input.provider);\n else await signInOnThePage(browser, input);\n },\n },\n signOut: async () => {\n try {\n settle(await betterAuth().signOut());\n } finally {\n await (await store)?.set(undefined);\n }\n },\n linkState: async () => {\n const pairing = hostPairing() !== undefined;\n const session = current();\n if (session.status !== \"signed-in\") return { vouched: false, pairing };\n const known = devices.get(session.user.id);\n const key = options.deviceKey ?? (await keysOfThisPlatform());\n const silent =\n known !== undefined ||\n (key !== undefined && (await key.presenceSetup?.()) !== \"needed\");\n const own = silent ? await device() : undefined;\n if (!own) return { vouched: false, pairing };\n const listed = await account.call(\"devices\", {});\n const listing = listed.find((entry) => entry.id === own.id);\n if (!listing) {\n devices.delete(session.user.id);\n return { vouched: false, pairing };\n }\n return { deviceId: own.id, vouched: listing.vouched, pairing };\n },\n startLink: async (wanted) => {\n const own = await device(wanted);\n if (!own) throw new Error(\"Sign in on this device first.\");\n const app = appOrigin(baseUrl || undefined);\n const commitment = await deviceCommitment(\n app,\n own.id,\n own.keys.signingKey,\n own.keys.presenceKey?.publicKey,\n );\n const code = linkCode(commitment);\n const { expiresAt } = await account.call(\"startDeviceLink\", {\n device: own.id,\n code,\n });\n return { deviceId: own.id, code, commitment, expiresAt };\n },\n resolveLink: async (from): Promise<PendingLink> => {\n const code = typeof from === \"string\" ? normalizeLinkCode(from) : undefined;\n const found = await account.call(\n \"resolveDeviceLink\",\n code ? { code } : { device: (from as { deviceId: string }).deviceId },\n );\n const commitment = await deviceCommitment(\n appOrigin(baseUrl || undefined),\n found.id,\n found.signingKey,\n found.presenceKey?.publicKey,\n );\n const matches =\n typeof from === \"string\"\n ? linkCode(commitment) === code\n : found.id === from.deviceId && commitment === from.commitment;\n if (!matches) {\n throw new Error(\n \"The app returned a device whose keys do not match this code, so it was not linked.\",\n );\n }\n return {\n id: found.id,\n name: found.name,\n platform: found.platform,\n commitment,\n code: linkCode(commitment),\n };\n },\n listDevices: async () => {\n const session = current();\n if (session.status !== \"signed-in\") return [];\n const own = devices.has(session.user.id) ? await device() : undefined;\n const listed = await account.call(\"devices\", {});\n return listed.map((entry) => ({ ...entry, current: entry.id === own?.id }));\n },\n removeDevice: async (id) => {\n const own = await device();\n const key = options.deviceKey ?? (await keysOfThisPlatform());\n if (!own?.keys.presenceKey || !key) {\n throw new LinkOnComputer(\"This device cannot confirm it is you.\");\n }\n const app = appOrigin(baseUrl || undefined);\n const at = Date.now();\n const signature = await key.sign(\n statementBytes(removeStatement(app, own.id, id, at)),\n {\n presence: true,\n },\n );\n await account.call(\"removeDevice\", {\n device: id,\n actor: own.id,\n app,\n at,\n signature,\n });\n const session = current();\n if (id === own.id && session.status === \"signed-in\")\n devices.delete(session.user.id);\n },\n canVouch: async () => {\n const session = current();\n if (session.status !== \"signed-in\") return false;\n const known = devices.get(session.user.id);\n const key = options.deviceKey ?? (await keysOfThisPlatform());\n if (!known && (await key?.presenceSetup?.()) === \"needed\") return false;\n return (await device())?.keys.presenceKey !== undefined;\n },\n vouch: async (link) => {\n const own = await device();\n const key = options.deviceKey ?? (await keysOfThisPlatform());\n if (!own?.keys.presenceKey || !key) {\n throw new LinkOnComputer(\"This device cannot confirm it is you.\");\n }\n const app = appOrigin(baseUrl || undefined);\n const at = Date.now();\n const statement = vouchStatement(app, own.id, link.id, link.commitment, at);\n const signature = await key.sign(statementBytes(statement), { presence: true });\n await account.call(\"vouchDevice\", {\n device: link.id,\n voucher: own.id,\n app,\n commitment: link.commitment,\n at,\n signature,\n });\n },\n deviceSetup: async () => {\n const session = current();\n if (session.status !== \"signed-in\" || devices.has(session.user.id)) return \"ready\";\n const key = options.deviceKey ?? (await keysOfThisPlatform());\n return (await key?.presenceSetup?.()) === \"needed\" ? \"needed\" : \"ready\";\n },\n device,\n authorizeHost: async (pairing) => {\n const response = await (options.fetch ?? fetch)(\n `${baseUrl}${basePath}/auth/hosts/authorize`,\n {\n method: \"POST\",\n headers: { ...(await headers()), \"content-type\": \"application/json\" },\n body: JSON.stringify({\n ...pairing,\n redirectUri: HOST_IPC_REDIRECT,\n decision: \"connect\",\n }),\n },\n );\n const body = (await response.json().catch(() => undefined)) as\n | { code?: unknown; state?: unknown; error?: { message?: string; code?: string } }\n | undefined;\n if (\n !response.ok ||\n typeof body?.code !== \"string\" ||\n body.state !== pairing.state\n ) {\n throw new AuthClientError(\n body?.error?.message ?? \"The computer could not be connected.\",\n response.status,\n body?.error?.code,\n );\n }\n return body.code;\n },\n account,\n };\n}\n\nexport type { AuthBrowser, HostPairing, SessionStore } from \"@parlor/capabilities\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { oauthProviderClient } from \"@better-auth/oauth-provider/client\";\nimport {\n type AuthBrowser,\n authBrowser,\n detectPlatform,\n type DeviceKey,\n deviceKey,\n type PairingPresenceKey,\n type PresencePublicKey,\n resolveCapability,\n type SessionStore,\n sessionStore,\n} from \"@parlor/capabilities\";\nimport { decodeBase64url, encodeBase64url } from \"@parlor/capabilities/encoding\";\nimport {\n type ActionClient,\n appOrigin,\n type ComputerDisconnector,\n createActionClient,\n type DeviceLinker,\n type DeviceSource,\n type HostAuthorizer,\n LinkOnComputer,\n type PendingLink,\n type SessionDevice,\n type SessionSnapshot,\n type SessionSource,\n type SessionUser,\n} from \"@parlor/client\";\nimport { ActionError } from \"@parlor/core\";\nimport type { BetterAuthClientPlugin } from \"better-auth/client\";\nimport { createAuthClient as createBetterAuthClient } from \"better-auth/client\";\nimport { emailOTPClient } from \"better-auth/client/plugins\";\n\nimport type { AccountActions } from \"../account.js\";\nimport type { nativeSignIn } from \"../native-sign-in.js\";\nimport {\n answerStatement,\n deviceCommitment,\n HOST_PAIRING_FRAGMENT,\n HOST_PAIRING_KEY,\n linkCode,\n normalizeLinkCode,\n pairingProof,\n promptStatement,\n removeStatement,\n type Statement,\n statementBytes,\n vouchStatement,\n} from \"../statements.js\";\n\nconst DEFAULT_BASE_PATH = \"/_parlor\";\nconst RETRY_BASE_MS = 1000;\nconst RETRY_MAX_MS = 30_000;\nconst TOKEN_HEADER = \"set-auth-token\";\nconst HOST_IPC_REDIRECT = \"urn:parlor:ipc\";\nconst DEBUG_KEY = \"parlor:debug\";\n\nconst NATIVE_CALLBACK = \"//_parlor/auth/callback\";\n\nfunction injectedServerUrl(): string {\n const env = (import.meta as { env?: { PARLOR_SERVER_URL?: string } }).env;\n return env?.PARLOR_SERVER_URL ?? \"\";\n}\n\nfunction injectedScheme(): string {\n const env = (import.meta as { env?: { PARLOR_APP_SCHEME?: string } }).env;\n return env?.PARLOR_APP_SCHEME ?? \"\";\n}\n\nconst nativeSignInClient = {\n id: \"parlor-native-sign-in\",\n $InferServerPlugin: {} as ReturnType<typeof nativeSignIn>,\n atomListeners: [\n { matcher: (path: string) => path === \"/native/token\", signal: \"$sessionSignal\" },\n ],\n} satisfies BetterAuthClientPlugin;\n\nconst randomText = (bytes: number) =>\n encodeBase64url(crypto.getRandomValues(new Uint8Array(bytes)));\n\nasync function pkceChallenge(verifier: string): Promise<string> {\n const digest = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(verifier),\n );\n return encodeBase64url(new Uint8Array(digest));\n}\n\nexport interface AuthClientOptions {\n /** The backend origin; defaults to the shell's `server.url`, or this page's origin. */\n readonly baseUrl?: string | undefined;\n readonly basePath?: string | undefined;\n /**\n * Where a bearer session is kept. Defaults to the `sessionStore` capability: native\n * shells keep a bearer token, the web keeps a cookie.\n */\n readonly session?: SessionStore | undefined;\n /** Where this device's signing keys live. Defaults to the `deviceKey` capability. */\n readonly deviceKey?: DeviceKey | undefined;\n /** Where social sign-in runs. Defaults to the `authBrowser` capability. */\n readonly browser?: AuthBrowser | undefined;\n /** The app's URL scheme, where social sign-in returns in a native shell. Defaults to `app.scheme`. */\n readonly scheme?: string | undefined;\n readonly fetch?: typeof fetch | undefined;\n}\n\nexport class AuthClientError extends Error {\n override readonly name = \"AuthClientError\";\n constructor(\n message: string,\n readonly status: number,\n readonly code: string | undefined,\n ) {\n super(message);\n }\n}\n\nexport type DeviceHandle = SessionDevice;\n\nexport interface SocialSignInInput {\n /** A provider in Better Auth's `socialProviders`, or a `genericOAuth` provider id. */\n readonly provider: string;\n /** On the web, the page the provider returns to once signed in. Defaults to `/`. */\n readonly callbackURL?: string | undefined;\n /** On the web, the page a failed sign-in returns to with `?error=`. Defaults to this page. */\n readonly errorCallbackURL?: string | undefined;\n}\n\nexport interface AuthClient\n extends\n SessionSource,\n DeviceSource,\n HostAuthorizer,\n DeviceLinker,\n ComputerDisconnector {\n deviceSetup(): Promise<\"needed\" | \"ready\">;\n /** Plug into `createActionClient({ headers })` so every surface carries the session. */\n readonly headers: () => Promise<HeadersInit>;\n signIn(input: { readonly email: string; readonly password: string }): Promise<void>;\n signUp(input: {\n readonly name: string;\n readonly email: string;\n readonly password: string;\n }): Promise<void>;\n signOut(): Promise<void>;\n /** Sign-in with a one-time code sent by email, through Better Auth's `emailOTP` plugin. */\n readonly emailOtp: {\n send(input: { readonly email: string }): Promise<void>;\n /** Signs in, creating the account on first use unless the plugin disables sign-up. */\n signIn(input: {\n readonly email: string;\n readonly otp: string;\n readonly name?: string | undefined;\n }): Promise<void>;\n };\n /** Sign-in with a provider such as Google, through Better Auth's `socialProviders`. */\n readonly social: {\n /** Whether this platform can run it: false in a native shell without the `authBrowser` capability. */\n available(): Promise<boolean>;\n /**\n * On the web the page leaves for the provider and comes back to `callbackURL`, so this\n * never resolves. In a native shell the provider opens in the system's sign-in browser\n * and this resolves once the app is signed in; it throws `AuthClientError` with code\n * `CANCELLED` when the user closes it.\n */\n signIn(input: SocialSignInInput): Promise<void>;\n };\n /** The account actions: `sessions`, `revokeSession`, `agents`, `revokeAgent`. */\n readonly account: ActionClient<AccountActions>;\n}\n\ninterface BetterAuthResult {\n readonly error?: {\n readonly message?: string | undefined;\n readonly status: number;\n readonly code?: string | undefined;\n } | null;\n}\n\nfunction settle(result: BetterAuthResult): void {\n if (!result.error) return;\n const { message, status, code } = result.error;\n throw new AuthClientError(message || \"Authentication failed.\", status, code);\n}\n\nconst ANONYMOUS_SESSION: SessionSnapshot = { status: \"anonymous\" };\n\nconst BROWSERS = [\n [/Edg\\//, \"Edge\"],\n [/OPR\\//, \"Opera\"],\n [/Firefox\\//, \"Firefox\"],\n [/Chrome\\//, \"Chrome\"],\n [/Safari\\//, \"Safari\"],\n] as const;\n\nconst SYSTEMS = [\n [/iPhone|iPad/, \"iOS\"],\n [/Android/, \"Android\"],\n [/Mac OS X/, \"macOS\"],\n [/Windows/, \"Windows\"],\n [/Linux/, \"Linux\"],\n] as const;\n\nfunction deviceName(): string {\n const agent = globalThis.navigator?.userAgent ?? \"\";\n const browser = BROWSERS.find(([pattern]) => pattern.test(agent))?.[1];\n const system = SYSTEMS.find(([pattern]) => pattern.test(agent))?.[1];\n if (browser && system) return `${browser} on ${system}`;\n return browser ?? system ?? \"This device\";\n}\n\nfunction debugStatements(): boolean {\n try {\n return (\n globalThis.localStorage?.getItem(DEBUG_KEY)?.split(\",\").includes(\"statements\") ??\n false\n );\n } catch {\n return false;\n }\n}\n\nasync function logSigned(statement: Statement): Promise<void> {\n if (!debugStatements()) return;\n const digest = await crypto.subtle.digest(\n \"SHA-256\",\n new Uint8Array(statementBytes(statement)),\n );\n const hex = [...new Uint8Array(digest)]\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n console.info(`[parlor] signed ${statement.kind} sha256=${hex}`);\n}\n\n/** Takes the host's pairing secret off this page's URL, where only that redirect puts it. */\nfunction keepHostPairing(): void {\n try {\n const location = globalThis.location;\n if (!location?.hash) return;\n const fragment = new URLSearchParams(location.hash.slice(1));\n const secret = fragment.get(HOST_PAIRING_FRAGMENT);\n if (!secret) return;\n globalThis.localStorage?.setItem(HOST_PAIRING_KEY, secret);\n fragment.delete(HOST_PAIRING_FRAGMENT);\n const rest = fragment.toString();\n globalThis.history?.replaceState(\n globalThis.history.state,\n \"\",\n `${location.pathname}${location.search}${rest ? `#${rest}` : \"\"}`,\n );\n } catch {}\n}\n\nfunction watchHostPairing(listener: () => void): () => void {\n const changed = (event: StorageEvent) => {\n if (event.key === HOST_PAIRING_KEY || event.key === null) listener();\n };\n globalThis.addEventListener?.(\"storage\", changed);\n return () => globalThis.removeEventListener?.(\"storage\", changed);\n}\n\nfunction hostPairing(): string | undefined {\n try {\n return globalThis.localStorage?.getItem(HOST_PAIRING_KEY) ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nconst serverHasNoAuth = (error: { readonly status?: unknown }) => error.status === 404;\n\nfunction enrollmentPresence(presence: PresencePublicKey | undefined, rpId: string) {\n if (!presence) return undefined;\n return presence.format === \"webauthn\"\n ? {\n format: \"webauthn\" as const,\n credentialId: presence.credentialId,\n rpId,\n publicKey: { ...presence.publicKey },\n attestation: presence.attestation,\n }\n : {\n format: \"es256-raw\" as const,\n keyId: presence.keyId,\n publicKey: { ...presence.publicKey },\n };\n}\n\nfunction registered(\n presence: ReturnType<typeof enrollmentPresence>,\n): PairingPresenceKey | undefined {\n if (presence?.format !== \"webauthn\") return presence;\n const { attestation: _attestation, ...key } = presence;\n return key;\n}\n\nfunction hostnameOf(origin: string): string {\n try {\n return new URL(origin).hostname;\n } catch {\n return globalThis.location.hostname;\n }\n}\n\nexport function createAuthClient(options: AuthClientOptions = {}): AuthClient {\n keepHostPairing();\n const baseUrl = options.baseUrl ?? injectedServerUrl();\n const basePath = options.basePath ?? DEFAULT_BASE_PATH;\n const store: Promise<SessionStore | undefined> = options.session\n ? Promise.resolve(options.session)\n : resolveCapability(sessionStore).then((handle) =>\n handle.available ? handle.api : undefined,\n );\n\n const headers = async (): Promise<HeadersInit> => {\n const token = await (await store)?.get();\n return token ? { authorization: `Bearer ${token}` } : {};\n };\n\n // Built on first use: importing a module that creates the client must work outside a page.\n let client: ReturnType<typeof connect> | undefined;\n const connect = () =>\n createBetterAuthClient({\n baseURL: `${baseUrl || globalThis.location.origin}${basePath}/auth`,\n plugins: [oauthProviderClient(), emailOTPClient(), nativeSignInClient],\n fetchOptions: {\n ...(options.fetch ? { customFetchImpl: options.fetch } : {}),\n onRequest: async (context) => {\n for (const [name, value] of new Headers(await headers())) {\n context.headers.set(name, value);\n }\n return context;\n },\n onSuccess: async (context) => {\n const token = context.response.headers.get(TOKEN_HEADER);\n if (token) await (await store)?.set(token);\n else if (\n context.request.url.toString().endsWith(\"/get-session\") &&\n !context.data\n ) {\n // A bearer token the server no longer knows would fail every later request.\n await (await store)?.set(undefined);\n }\n },\n },\n });\n const betterAuth = () => (client ??= connect());\n\n let watchers = 0;\n let retry: ReturnType<typeof setTimeout> | undefined;\n let retryDelay = RETRY_BASE_MS;\n const retryAfterError = () => {\n const state = betterAuth().useSession.get();\n if (!state.error || serverHasNoAuth(state.error)) {\n retryDelay = RETRY_BASE_MS;\n return;\n }\n if (retry !== undefined || state.isRefetching) return;\n retry = setTimeout(() => {\n retry = undefined;\n void state.refetch();\n }, retryDelay);\n retryDelay = Math.min(retryDelay * 2, RETRY_MAX_MS);\n };\n\n let last: unknown;\n let snapshot: SessionSnapshot = { status: \"loading\" };\n const current = (): SessionSnapshot => {\n const state = betterAuth().useSession.get();\n if (state === last) return snapshot;\n last = state;\n if (state.error) {\n if (serverHasNoAuth(state.error)) snapshot = ANONYMOUS_SESSION;\n // Only the server saying there is no session signs the user out, never an unreachable one.\n return snapshot;\n }\n const user = state.data?.user;\n snapshot = user\n ? { status: \"signed-in\", user: { id: user.id, name: user.name, email: user.email } }\n : state.isPending\n ? { status: \"loading\" }\n : { status: \"signed-out\" };\n return snapshot;\n };\n\n const account = createActionClient<AccountActions>({\n baseUrl,\n fetch: options.fetch,\n basePath: `${basePath}/auth`,\n headers,\n });\n\n const signInBrowser = async (): Promise<AuthBrowser | undefined> => {\n if (options.browser) return options.browser;\n const handle = await resolveCapability(authBrowser);\n return handle.available ? handle.api : undefined;\n };\n\n const signInOnThePage = async (browser: AuthBrowser, input: SocialSignInInput) => {\n const page = new URL(globalThis.location.href);\n const callbackURL = new URL(input.callbackURL ?? \"/\", page).href;\n const errorPage = new URL(input.errorCallbackURL ?? page, page);\n errorPage.searchParams.delete(\"error\");\n errorPage.searchParams.delete(\"error_description\");\n const result = await betterAuth().signIn.social({\n provider: input.provider,\n callbackURL,\n errorCallbackURL: errorPage.href,\n disableRedirect: true,\n });\n settle(result);\n const url = result.data?.url;\n if (!url)\n throw new AuthClientError(\"The provider gave no sign-in page.\", 500, undefined);\n await browser.open(url, callbackURL);\n };\n\n const signInInTheApp = async (browser: AuthBrowser, provider: string) => {\n const scheme = options.scheme ?? injectedScheme();\n if (!scheme) {\n throw new AuthClientError(\n \"Set app.scheme in parlor.config.ts to sign in with a provider in the app.\",\n 0,\n \"NO_SCHEME\",\n );\n }\n const callback = `${scheme}:${NATIVE_CALLBACK}`;\n const verifier = randomText(32);\n const state = randomText(16);\n const start = new URL(\n `${baseUrl || globalThis.location.origin}${basePath}/auth/native/sign-in/social`,\n );\n start.search = new URLSearchParams({\n provider,\n redirect_uri: callback,\n code_challenge: await pkceChallenge(verifier),\n code_challenge_method: \"S256\",\n state,\n }).toString();\n const returned = await browser.open(start.href, callback);\n if (!returned) throw new AuthClientError(\"Sign-in was cancelled.\", 0, \"CANCELLED\");\n const answer = new URL(returned).searchParams;\n if (answer.get(\"state\") !== state) {\n throw new AuthClientError(\n \"This sign-in was not started here.\",\n 0,\n \"STATE_MISMATCH\",\n );\n }\n const failed = answer.get(\"error\");\n const code = answer.get(\"code\");\n if (failed || !code) {\n throw new AuthClientError(\n answer.get(\"error_description\") || `Sign-in failed (${failed ?? \"no code\"}).`,\n 400,\n failed ?? undefined,\n );\n }\n settle(await betterAuth().native.token({ code, code_verifier: verifier }));\n };\n\n const keysOfThisPlatform = async (): Promise<DeviceKey | undefined> => {\n const handle = await resolveCapability(deviceKey);\n return handle.available ? handle.api : undefined;\n };\n\n const devices = new Map<string, Promise<DeviceHandle | undefined>>();\n const enroll = async (\n user: SessionUser,\n wantsPresence: boolean,\n ): Promise<DeviceHandle | undefined> => {\n const key = options.deviceKey ?? (await keysOfThisPlatform());\n if (!key) return undefined;\n const app = appOrigin(baseUrl || undefined);\n const rpId = hostnameOf(app);\n const { challenge } = await account.call(\"deviceChallenge\", {});\n const keys = await key.publicKeys(\n {\n rpId,\n userId: user.id,\n userName: user.email,\n challenge: decodeBase64url(challenge),\n },\n { presence: wantsPresence },\n );\n const presence = enrollmentPresence(keys.presence, rpId);\n const name = deviceName();\n const platform = detectPlatform();\n const signingKey = { ...keys.signing.publicKey };\n const { id } = await account.call(\"enrollDevice\", {\n name,\n platform,\n challenge,\n signing: { keyId: keys.signing.keyId, publicKey: signingKey },\n ...(presence ? { presence } : {}),\n proof: keys.proof,\n });\n return {\n id,\n keys: {\n deviceId: id,\n name,\n platform,\n signingKey,\n presenceKey: registered(presence),\n },\n signPrompt: async (prompt, wanted) => {\n const at = Date.now();\n const statement = await promptStatement(app, prompt, at);\n const bytes = statementBytes(statement);\n const signature = wanted?.presence\n ? await key.sign(bytes, { presence: true })\n : await key.sign(bytes, { presence: false });\n await logSigned(statement);\n const secret = hostPairing();\n const pairing = secret && (await pairingProof(secret, id, signingKey));\n return { deviceId: id, at, signature, ...(pairing ? { pairing } : {}) };\n },\n signAnswer: async (answer, { presence: wanted }) => {\n const at = Date.now();\n const statement = await answerStatement(app, answer, at);\n const bytes = statementBytes(statement);\n const signature = wanted\n ? await key.sign(bytes, { presence: true })\n : await key.sign(bytes, { presence: false });\n await logSigned(statement);\n return { deviceId: id, at, signature };\n },\n };\n };\n\n const device = async (wanted?: {\n readonly presence?: boolean;\n }): Promise<DeviceHandle | undefined> => {\n const session = current();\n if (session.status !== \"signed-in\") return undefined;\n const known = devices.get(session.user.id);\n if (known) return known;\n // The browser that approved `connect` is on the computer, which answers its permission questions.\n const presence = wanted?.presence ?? hostPairing() === undefined;\n const enrolling = enroll(session.user, presence).catch((error: unknown) => {\n if (error instanceof ActionError && error.code === \"not_found\") return undefined;\n throw error;\n });\n devices.set(session.user.id, enrolling);\n enrolling.then(\n (enrolled) => {\n if (!enrolled) devices.delete(session.user.id);\n },\n () => devices.delete(session.user.id),\n );\n return enrolling;\n };\n\n return {\n headers,\n current,\n subscribe: (listener) => {\n watchers += 1;\n const stop = betterAuth().useSession.listen(() => {\n retryAfterError();\n listener();\n });\n return () => {\n stop();\n watchers -= 1;\n if (watchers === 0 && retry !== undefined) {\n clearTimeout(retry);\n retry = undefined;\n }\n };\n },\n signIn: async (input) => settle(await betterAuth().signIn.email(input)),\n signUp: async (input) => settle(await betterAuth().signUp.email(input)),\n emailOtp: {\n send: async ({ email }) =>\n settle(\n await betterAuth().emailOtp.sendVerificationOtp({ email, type: \"sign-in\" }),\n ),\n signIn: async ({ email, otp, name }) =>\n settle(\n await betterAuth().signIn.emailOtp({ email, otp, ...(name ? { name } : {}) }),\n ),\n },\n social: {\n available: async () => (await signInBrowser()) !== undefined,\n signIn: async (input) => {\n const browser = await signInBrowser();\n if (!browser) {\n throw new AuthClientError(\n `Signing in with ${input.provider} is not available here.`,\n 0,\n \"UNSUPPORTED\",\n );\n }\n if (await store) await signInInTheApp(browser, input.provider);\n else await signInOnThePage(browser, input);\n },\n },\n signOut: async () => {\n try {\n settle(await betterAuth().signOut());\n } finally {\n await (await store)?.set(undefined);\n }\n },\n subscribeLink: watchHostPairing,\n linkState: async () => {\n const pairing = hostPairing() !== undefined;\n const session = current();\n if (session.status !== \"signed-in\") return { vouched: false, pairing };\n const known = devices.get(session.user.id);\n const key = options.deviceKey ?? (await keysOfThisPlatform());\n const silent =\n known !== undefined ||\n (key !== undefined && (await key.presenceSetup?.()) !== \"needed\");\n const own = silent ? await device() : undefined;\n if (!own) return { vouched: false, pairing };\n const listed = await account.call(\"devices\", {});\n const listing = listed.find((entry) => entry.id === own.id);\n if (!listing) {\n devices.delete(session.user.id);\n return { vouched: false, pairing };\n }\n return { deviceId: own.id, vouched: listing.vouched, pairing };\n },\n startLink: async (wanted) => {\n const own = await device(wanted);\n if (!own) throw new Error(\"Sign in on this device first.\");\n const app = appOrigin(baseUrl || undefined);\n const commitment = await deviceCommitment(\n app,\n own.id,\n own.keys.signingKey,\n own.keys.presenceKey?.publicKey,\n );\n const code = linkCode(commitment);\n const { expiresAt } = await account.call(\"startDeviceLink\", {\n device: own.id,\n code,\n });\n return { deviceId: own.id, code, commitment, expiresAt };\n },\n resolveLink: async (from): Promise<PendingLink> => {\n const code = typeof from === \"string\" ? normalizeLinkCode(from) : undefined;\n const found = await account.call(\n \"resolveDeviceLink\",\n code ? { code } : { device: (from as { deviceId: string }).deviceId },\n );\n const commitment = await deviceCommitment(\n appOrigin(baseUrl || undefined),\n found.id,\n found.signingKey,\n found.presenceKey?.publicKey,\n );\n const matches =\n typeof from === \"string\"\n ? linkCode(commitment) === code\n : found.id === from.deviceId && commitment === from.commitment;\n if (!matches) {\n throw new Error(\n \"The app returned a device whose keys do not match this code, so it was not linked.\",\n );\n }\n return {\n id: found.id,\n name: found.name,\n platform: found.platform,\n commitment,\n code: linkCode(commitment),\n };\n },\n disconnectComputer: async (hostId) => {\n await account.call(\"revokeHost\", { hostId });\n },\n listDevices: async () => {\n const session = current();\n if (session.status !== \"signed-in\") return [];\n const own = devices.has(session.user.id) ? await device() : undefined;\n const listed = await account.call(\"devices\", {});\n return listed.map((entry) => ({ ...entry, current: entry.id === own?.id }));\n },\n removeDevice: async (id) => {\n const own = await device();\n const key = options.deviceKey ?? (await keysOfThisPlatform());\n if (!own?.keys.presenceKey || !key) {\n throw new LinkOnComputer(\"This device cannot confirm it is you.\");\n }\n const app = appOrigin(baseUrl || undefined);\n const at = Date.now();\n const signature = await key.sign(\n statementBytes(removeStatement(app, own.id, id, at)),\n {\n presence: true,\n },\n );\n await account.call(\"removeDevice\", {\n device: id,\n actor: own.id,\n app,\n at,\n signature,\n });\n const session = current();\n if (id === own.id && session.status === \"signed-in\")\n devices.delete(session.user.id);\n },\n canVouch: async () => {\n const session = current();\n if (session.status !== \"signed-in\") return false;\n const known = devices.get(session.user.id);\n const key = options.deviceKey ?? (await keysOfThisPlatform());\n if (!known && (await key?.presenceSetup?.()) === \"needed\") return false;\n return (await device())?.keys.presenceKey !== undefined;\n },\n vouch: async (link) => {\n const own = await device();\n const key = options.deviceKey ?? (await keysOfThisPlatform());\n if (!own?.keys.presenceKey || !key) {\n throw new LinkOnComputer(\"This device cannot confirm it is you.\");\n }\n const app = appOrigin(baseUrl || undefined);\n const at = Date.now();\n const statement = vouchStatement(app, own.id, link.id, link.commitment, at);\n const signature = await key.sign(statementBytes(statement), { presence: true });\n await account.call(\"vouchDevice\", {\n device: link.id,\n voucher: own.id,\n app,\n commitment: link.commitment,\n at,\n signature,\n });\n },\n deviceSetup: async () => {\n const session = current();\n if (session.status !== \"signed-in\" || devices.has(session.user.id)) return \"ready\";\n const key = options.deviceKey ?? (await keysOfThisPlatform());\n return (await key?.presenceSetup?.()) === \"needed\" ? \"needed\" : \"ready\";\n },\n device,\n authorizeHost: async (pairing) => {\n const response = await (options.fetch ?? fetch)(\n `${baseUrl}${basePath}/auth/hosts/authorize`,\n {\n method: \"POST\",\n headers: { ...(await headers()), \"content-type\": \"application/json\" },\n body: JSON.stringify({\n ...pairing,\n redirectUri: HOST_IPC_REDIRECT,\n decision: \"connect\",\n }),\n },\n );\n const body = (await response.json().catch(() => undefined)) as\n | { code?: unknown; state?: unknown; error?: { message?: string; code?: string } }\n | undefined;\n if (\n !response.ok ||\n typeof body?.code !== \"string\" ||\n body.state !== pairing.state\n ) {\n throw new AuthClientError(\n body?.error?.message ?? \"The computer could not be connected.\",\n response.status,\n body?.error?.code,\n );\n }\n return body.code;\n },\n account,\n };\n}\n\nexport type { AuthBrowser, HostPairing, SessionStore } from \"@parlor/capabilities\";\n"]}
|
package/dist/hosts.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ export interface HostAuthorizeRequest {
|
|
|
16
16
|
readonly matchingCode: string;
|
|
17
17
|
/** RFC 7638 thumbprint of the key the code exchange must be signed with. */
|
|
18
18
|
readonly keyThumbprint: string;
|
|
19
|
+
/** The host can also hand the app to the coding agents on the computer, outside the sidebar. */
|
|
20
|
+
readonly agentTools?: "offered" | undefined;
|
|
19
21
|
}
|
|
20
22
|
/** `POST /hosts/token` */
|
|
21
23
|
export interface HostKeyExchange {
|
|
@@ -40,6 +42,8 @@ export interface HostGrantResponse {
|
|
|
40
42
|
/** The host shows it locally before it keeps the grant. */
|
|
41
43
|
readonly account: AccountSummary;
|
|
42
44
|
readonly approvedBy?: ApprovingDevice | undefined;
|
|
45
|
+
/** The app's page, on its origin, that the host sends the approving browser to with the pairing secret. */
|
|
46
|
+
readonly landing?: string | undefined;
|
|
43
47
|
}
|
|
44
48
|
export declare const HOST_ASSERTION_TTL_MS = 60000;
|
|
45
49
|
/** `authorization: ParlorHost <jws>`, DPoP style: bound to one method and URL, dead in a minute. */
|
|
@@ -109,7 +113,8 @@ export declare function hostAccountActions(deps: HostGrantDeps): import("@parlor
|
|
|
109
113
|
export type HostAccountActions = ActionsOf<ReturnType<typeof hostAccountActions>>;
|
|
110
114
|
/**
|
|
111
115
|
* `GET|POST /hosts/authorize` is the framework-owned consent page and its answer, `POST
|
|
112
|
-
* /hosts/token` the PKCE exchange binding the host's key, `
|
|
116
|
+
* /hosts/token` the PKCE exchange binding the host's key, `GET /hosts/connected` where the
|
|
117
|
+
* approving browser lands and keeps the pairing secret, `POST /hosts/revoke` the host
|
|
113
118
|
* disconnecting itself.
|
|
114
119
|
*/
|
|
115
120
|
export declare function hostRoutes(deps: HostGrantDeps): readonly AnyPluginRoute[];
|
package/dist/hosts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hosts.d.ts","sourceRoot":"","sources":["../src/hosts.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,YAAY,EAEjB,KAAK,OAAO,EACZ,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,MAAM,EACZ,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,SAAS,EAAkB,MAAM,uBAAuB,CAAC;AACvE,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,UAAU,EAEf,KAAK,SAAS,EACd,KAAK,UAAU,EAKhB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAA2B,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"hosts.d.ts","sourceRoot":"","sources":["../src/hosts.ts"],"names":[],"mappings":"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"}
|
package/dist/hosts.js
CHANGED
|
@@ -11,6 +11,7 @@ import { jwkOf, rowsOf } from "./database.js";
|
|
|
11
11
|
import { findPendingDevice } from "./devices.js";
|
|
12
12
|
import { escape, failure, page } from "./pages.js";
|
|
13
13
|
import { RevocationSet } from "./revocation.js";
|
|
14
|
+
import { HOST_PAIRING_FRAGMENT, HOST_PAIRING_KEY } from "./statements.js";
|
|
14
15
|
import { HOST_ASSERTION_TYP, HOST_AUDIENCE } from "./tokens.js";
|
|
15
16
|
export const HOST_CLIENT_ID = "parlor-host";
|
|
16
17
|
export const MATCHING_CODE = /^[A-Z2-9]{3}-[A-Z2-9]{3}$/;
|
|
@@ -309,9 +310,11 @@ const authorizeRequest = z.object({
|
|
|
309
310
|
.refine(isPrintable, "Use printable characters."),
|
|
310
311
|
matchingCode: z.string().regex(MATCHING_CODE),
|
|
311
312
|
keyThumbprint: z.string().regex(THUMBPRINT),
|
|
313
|
+
agentTools: z.literal("offered").optional(),
|
|
312
314
|
});
|
|
313
315
|
const authorizeAnswer = authorizeRequest.extend({
|
|
314
316
|
decision: z.enum(["connect", "cancel"]),
|
|
317
|
+
useAgentTools: z.literal("on").optional(),
|
|
315
318
|
});
|
|
316
319
|
const publicKeySchema = z.looseObject({
|
|
317
320
|
kty: z.literal("EC"),
|
|
@@ -365,15 +368,20 @@ async function verifyProof(publicKey, code, proof) {
|
|
|
365
368
|
return false;
|
|
366
369
|
}
|
|
367
370
|
}
|
|
371
|
+
/** The MCP server name the host registered the app under, as the connected page shows it. */
|
|
372
|
+
const AGENT_TOOLS_NAME = /^[a-z0-9][a-z0-9_-]{0,79}$/;
|
|
373
|
+
const KEEP_PAIRING = `try{const s=new URLSearchParams(location.hash.slice(1)).get(${JSON.stringify(HOST_PAIRING_FRAGMENT)});if(s)localStorage.setItem(${JSON.stringify(HOST_PAIRING_KEY)},s)}catch{}history.replaceState(null,"",location.pathname)`;
|
|
368
374
|
/**
|
|
369
375
|
* `GET|POST /hosts/authorize` is the framework-owned consent page and its answer, `POST
|
|
370
|
-
* /hosts/token` the PKCE exchange binding the host's key, `
|
|
376
|
+
* /hosts/token` the PKCE exchange binding the host's key, `GET /hosts/connected` where the
|
|
377
|
+
* approving browser lands and keeps the pairing secret, `POST /hosts/revoke` the host
|
|
371
378
|
* disconnecting itself.
|
|
372
379
|
*/
|
|
373
380
|
export function hostRoutes(deps) {
|
|
374
381
|
const { host, settings } = deps;
|
|
375
382
|
const appName = () => process.env.PARLOR_APP_NAME ?? settings.appName ?? new URL(settings.origin).host;
|
|
376
383
|
const authorizeUrl = `${host.basePath}/${AUTH_PLUGIN}/hosts/authorize`;
|
|
384
|
+
const connectedUrl = `${host.basePath}/${AUTH_PLUGIN}/hosts/connected`;
|
|
377
385
|
const accountOf = async (userId) => host.auth?.account?.(userId);
|
|
378
386
|
return [
|
|
379
387
|
pluginRoute({
|
|
@@ -399,6 +407,9 @@ export function hostRoutes(deps) {
|
|
|
399
407
|
<p>The coding agents on <strong>${escape(pairing.hostName)}</strong> (${escape(pairing.platform)}) will take your prompts from ${escape(app)} and run on that computer. Continue only if you just ran <code>connect</code> there.</p>
|
|
400
408
|
<form method="post" action="${escape(authorizeUrl)}">
|
|
401
409
|
${hidden}
|
|
410
|
+
${pairing.agentTools === "offered"
|
|
411
|
+
? `<label class="choice"><input type="checkbox" name="useAgentTools" value="on" checked><span>Also let Claude Code and Codex on this computer use ${escape(app)} when you name it. They ask before their first change in each conversation.</span></label>`
|
|
412
|
+
: ""}
|
|
402
413
|
<button type="submit" name="decision" value="cancel">Cancel</button>
|
|
403
414
|
<button type="submit" name="decision" value="connect">Connect</button>
|
|
404
415
|
</form>`;
|
|
@@ -429,7 +440,7 @@ ${hidden}
|
|
|
429
440
|
if (!parsed.success) {
|
|
430
441
|
return refuse(400, "invalid_input", "This connection request is incomplete.");
|
|
431
442
|
}
|
|
432
|
-
const { decision, ...pairing } = parsed.data;
|
|
443
|
+
const { decision, useAgentTools, ...pairing } = parsed.data;
|
|
433
444
|
const target = pairing.redirectUri === IPC_REDIRECT ? undefined : new URL(pairing.redirectUri);
|
|
434
445
|
if (decision === "cancel") {
|
|
435
446
|
if (!target)
|
|
@@ -449,10 +460,18 @@ ${hidden}
|
|
|
449
460
|
${pairing.keyThumbprint}, ${pairing.redirectUri}, ${pairing.hostName}, ${pairing.platform},
|
|
450
461
|
${new Date(Date.now() + CODE_TTL_MS).toISOString()})`);
|
|
451
462
|
});
|
|
452
|
-
|
|
453
|
-
|
|
463
|
+
const agentTools = pairing.agentTools === "offered" ? useAgentTools === "on" : undefined;
|
|
464
|
+
if (!target) {
|
|
465
|
+
return Response.json({
|
|
466
|
+
code,
|
|
467
|
+
state: pairing.state,
|
|
468
|
+
...(agentTools === undefined ? {} : { agentTools }),
|
|
469
|
+
});
|
|
470
|
+
}
|
|
454
471
|
target.searchParams.set("code", code);
|
|
455
472
|
target.searchParams.set("state", pairing.state);
|
|
473
|
+
if (agentTools !== undefined)
|
|
474
|
+
target.searchParams.set("agentTools", agentTools ? "on" : "off");
|
|
456
475
|
return new Response(null, { status: 303, headers: { location: target.href } });
|
|
457
476
|
},
|
|
458
477
|
}),
|
|
@@ -493,10 +512,31 @@ ${hidden}
|
|
|
493
512
|
const response = {
|
|
494
513
|
grant: { id: grantId, hostId },
|
|
495
514
|
account: { userId, name: profile?.name ?? "", email: profile?.email },
|
|
515
|
+
landing: connectedUrl,
|
|
496
516
|
};
|
|
497
517
|
return Response.json(response);
|
|
498
518
|
},
|
|
499
519
|
},
|
|
520
|
+
{
|
|
521
|
+
method: "GET",
|
|
522
|
+
path: "/hosts/connected",
|
|
523
|
+
access: "public",
|
|
524
|
+
handle: async (request) => {
|
|
525
|
+
const app = escape(appName());
|
|
526
|
+
const tools = new URL(request.url).searchParams.get("agentTools");
|
|
527
|
+
const body = tools && AGENT_TOOLS_NAME.test(tools)
|
|
528
|
+
? `<h1>Connected to ${app}</h1>
|
|
529
|
+
<p>Use it two ways:</p>
|
|
530
|
+
<ul>
|
|
531
|
+
<li>In the agent sidebar of ${app}.</li>
|
|
532
|
+
<li>In Claude Code or Codex on this computer: ask them to “use <code>${escape(tools)}</code> to …”. They ask you before their first change in each conversation.</li>
|
|
533
|
+
</ul>
|
|
534
|
+
<p>You can close this tab.</p>`
|
|
535
|
+
: `<h1>Connected to ${app}</h1>
|
|
536
|
+
<p>The coding agents on your computer are ready in the agent sidebar of ${app}. You can close this tab.</p>`;
|
|
537
|
+
return page("Computer connected", body, ["'none'"], KEEP_PAIRING);
|
|
538
|
+
},
|
|
539
|
+
},
|
|
500
540
|
pluginRoute({
|
|
501
541
|
method: "POST",
|
|
502
542
|
path: "/hosts/devices/link",
|