@absolutejs/auth 0.76.1 → 0.76.3
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.js +30 -14
- package/dist/client/index.js.map +4 -4
- package/dist/client/mobile.d.ts +10 -0
- package/dist/client/mobile.js +30 -14
- package/dist/client/mobile.js.map +4 -4
- package/dist/index.js +4 -3
- package/dist/index.js.map +3 -3
- package/dist/server.js +4 -3
- package/dist/server.js.map +3 -3
- package/dist/syncNamespace.d.ts +2 -1
- package/package.json +1 -1
package/dist/client/mobile.js
CHANGED
|
@@ -57,14 +57,15 @@ var base64Url = (value) => {
|
|
|
57
57
|
};
|
|
58
58
|
var deriveAuthSyncNamespace = async ({
|
|
59
59
|
clientId,
|
|
60
|
+
digestSha256 = async (value) => new Uint8Array(await crypto.subtle.digest("SHA-256", new Uint8Array(value))),
|
|
60
61
|
issuer,
|
|
61
62
|
partition,
|
|
62
63
|
subject
|
|
63
64
|
}) => {
|
|
64
65
|
if (clientId.length === 0 || issuer.length === 0 || subject.length === 0)
|
|
65
66
|
throw new TypeError("Auth Sync namespace requires issuer, clientId, and subject.");
|
|
66
|
-
const digest = await
|
|
67
|
-
return `auth:v1:${base64Url(
|
|
67
|
+
const digest = await digestSha256(new TextEncoder().encode(JSON.stringify([issuer, clientId, subject, partition ?? null])));
|
|
68
|
+
return `auth:v1:${base64Url(digest)}`;
|
|
68
69
|
};
|
|
69
70
|
var readAuthSyncPartition = (user) => {
|
|
70
71
|
if (typeof user !== "object" || user === null)
|
|
@@ -130,12 +131,20 @@ var decodeBase64Url = (value) => {
|
|
|
130
131
|
const binary = atob(padded);
|
|
131
132
|
return Uint8Array.from(binary, (character) => character.charCodeAt(0));
|
|
132
133
|
};
|
|
133
|
-
var
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
134
|
+
var webCrypto = {
|
|
135
|
+
digestSha256: async (value) => new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", new Uint8Array(value))),
|
|
136
|
+
randomBytes: (length) => {
|
|
137
|
+
const value = new Uint8Array(length);
|
|
138
|
+
globalThis.crypto.getRandomValues(value);
|
|
139
|
+
return value;
|
|
140
|
+
},
|
|
141
|
+
verifyEs256: async ({ data, jwk, signature }) => {
|
|
142
|
+
const key = await globalThis.crypto.subtle.importKey("jwk", jwk, { hash: "SHA-256", name: "ECDSA", namedCurve: "P-256" }, false, ["verify"]);
|
|
143
|
+
return globalThis.crypto.subtle.verify({ hash: "SHA-256", name: "ECDSA" }, key, new Uint8Array(signature), new Uint8Array(data));
|
|
144
|
+
}
|
|
137
145
|
};
|
|
138
|
-
var
|
|
146
|
+
var randomValue = (cryptoProvider) => base64Url2(cryptoProvider.randomBytes(RANDOM_BYTES));
|
|
147
|
+
var pkceChallenge = async (verifier, cryptoProvider) => base64Url2(await cryptoProvider.digestSha256(new TextEncoder().encode(verifier)));
|
|
139
148
|
var normalizeIssuer = (value) => {
|
|
140
149
|
const issuer = new URL(value);
|
|
141
150
|
const loopback = issuer.protocol === "http:" && ["127.0.0.1", "[::1]", "localhost"].includes(issuer.hostname);
|
|
@@ -221,6 +230,7 @@ var parseDiscovery = (value, issuer) => {
|
|
|
221
230
|
};
|
|
222
231
|
var verifyIdToken = async ({
|
|
223
232
|
clientId,
|
|
233
|
+
cryptoProvider,
|
|
224
234
|
fetchImpl,
|
|
225
235
|
idToken,
|
|
226
236
|
issuer,
|
|
@@ -251,8 +261,11 @@ var verifyIdToken = async ({
|
|
|
251
261
|
const jwk = keys.find((candidate) => isRecord(candidate) && candidate.kid === header.kid);
|
|
252
262
|
if (!jwk)
|
|
253
263
|
throw new MobileAuthError("id-token", "The ID token signing key is unknown.");
|
|
254
|
-
const
|
|
255
|
-
|
|
264
|
+
const valid = await cryptoProvider.verifyEs256({
|
|
265
|
+
data: new TextEncoder().encode(`${encodedHeader}.${encodedPayload}`),
|
|
266
|
+
jwk,
|
|
267
|
+
signature: decodeBase64Url(encodedSignature)
|
|
268
|
+
});
|
|
256
269
|
const audience = payload.aud;
|
|
257
270
|
if (!valid || payload.iss !== issuer || !(audience === clientId || Array.isArray(audience) && audience.includes(clientId)) || payload.nonce !== nonce || typeof payload.exp !== "number" || payload.exp * 1000 <= now)
|
|
258
271
|
throw new MobileAuthError("id-token", "The ID token signature or claims are invalid.");
|
|
@@ -261,6 +274,7 @@ var createMobileAuthClient = (config) => {
|
|
|
261
274
|
const issuer = normalizeIssuer(config.issuer);
|
|
262
275
|
const redirectUri = new URL(config.redirectUri).href;
|
|
263
276
|
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
277
|
+
const cryptoProvider = config.crypto ?? webCrypto;
|
|
264
278
|
const now = config.now ?? Date.now;
|
|
265
279
|
const clockSkewMs = config.clockSkewMs ?? DEFAULT_CLOCK_SKEW_MS;
|
|
266
280
|
const scopes = [...new Set(config.scopes ?? ["openid", "profile"])];
|
|
@@ -290,6 +304,7 @@ var createMobileAuthClient = (config) => {
|
|
|
290
304
|
issuer,
|
|
291
305
|
namespace: await deriveAuthSyncNamespace({
|
|
292
306
|
clientId: config.clientId,
|
|
307
|
+
digestSha256: cryptoProvider.digestSha256,
|
|
293
308
|
issuer,
|
|
294
309
|
partition,
|
|
295
310
|
subject: user.sub
|
|
@@ -343,6 +358,7 @@ var createMobileAuthClient = (config) => {
|
|
|
343
358
|
if (nonce)
|
|
344
359
|
await verifyIdToken({
|
|
345
360
|
clientId: config.clientId,
|
|
361
|
+
cryptoProvider,
|
|
346
362
|
fetchImpl,
|
|
347
363
|
idToken: tokens.id_token,
|
|
348
364
|
issuer,
|
|
@@ -477,15 +493,15 @@ var createMobileAuthClient = (config) => {
|
|
|
477
493
|
const metadata = await discovery();
|
|
478
494
|
const pending = {
|
|
479
495
|
createdAt: now(),
|
|
480
|
-
nonce: randomValue(),
|
|
481
|
-
state: randomValue(),
|
|
482
|
-
verifier: randomValue()
|
|
496
|
+
nonce: randomValue(cryptoProvider),
|
|
497
|
+
state: randomValue(cryptoProvider),
|
|
498
|
+
verifier: randomValue(cryptoProvider)
|
|
483
499
|
};
|
|
484
500
|
await config.storage.set(PENDING_KEY, JSON.stringify(pending));
|
|
485
501
|
const url = new URL(metadata.authorization_endpoint);
|
|
486
502
|
url.search = new URLSearchParams({
|
|
487
503
|
client_id: config.clientId,
|
|
488
|
-
code_challenge: await pkceChallenge(pending.verifier),
|
|
504
|
+
code_challenge: await pkceChallenge(pending.verifier, cryptoProvider),
|
|
489
505
|
code_challenge_method: "S256",
|
|
490
506
|
nonce: pending.nonce,
|
|
491
507
|
redirect_uri: redirectUri,
|
|
@@ -683,5 +699,5 @@ export {
|
|
|
683
699
|
installAuthClientRuntimeTransport
|
|
684
700
|
};
|
|
685
701
|
|
|
686
|
-
//# debugId=
|
|
702
|
+
//# debugId=133719A26A0DF6AA64756E2164756E21
|
|
687
703
|
//# sourceMappingURL=mobile.js.map
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/syncNamespace.ts", "../src/client/runtimeTransport.ts", "../src/client/mobile.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"const base64Url = (value: Uint8Array) => {\n\tlet binary = '';\n\tfor (const byte of value) binary += String.fromCharCode(byte);\n\n\treturn btoa(binary)\n\t\t.replaceAll('+', '-')\n\t\t.replaceAll('/', '_')\n\t\t.replace(/=+$/u, '');\n};\n\n/** Derive a non-reversible local Sync partition without persisting user PII. */\nexport const deriveAuthSyncNamespace = async ({\n\tclientId,\n\tissuer,\n\tpartition,\n\tsubject\n}: {\n\tclientId: string;\n\tissuer: string;\n\tpartition?: string;\n\tsubject: string;\n}) => {\n\tif (clientId.length === 0 || issuer.length === 0 || subject.length === 0)\n\t\tthrow new TypeError(\n\t\t\t'Auth Sync namespace requires issuer, clientId, and subject.'\n\t\t);\n\tconst digest = await
|
|
5
|
+
"const base64Url = (value: Uint8Array) => {\n\tlet binary = '';\n\tfor (const byte of value) binary += String.fromCharCode(byte);\n\n\treturn btoa(binary)\n\t\t.replaceAll('+', '-')\n\t\t.replaceAll('/', '_')\n\t\t.replace(/=+$/u, '');\n};\n\n/** Derive a non-reversible local Sync partition without persisting user PII. */\nexport const deriveAuthSyncNamespace = async ({\n\tclientId,\n\tdigestSha256 = async (value) =>\n\t\tnew Uint8Array(\n\t\t\tawait crypto.subtle.digest('SHA-256', new Uint8Array(value))\n\t\t),\n\tissuer,\n\tpartition,\n\tsubject\n}: {\n\tclientId: string;\n\tdigestSha256?: (value: Uint8Array) => Promise<Uint8Array>;\n\tissuer: string;\n\tpartition?: string;\n\tsubject: string;\n}) => {\n\tif (clientId.length === 0 || issuer.length === 0 || subject.length === 0)\n\t\tthrow new TypeError(\n\t\t\t'Auth Sync namespace requires issuer, clientId, and subject.'\n\t\t);\n\tconst digest = await digestSha256(\n\t\tnew TextEncoder().encode(\n\t\t\tJSON.stringify([issuer, clientId, subject, partition ?? null])\n\t\t)\n\t);\n\n\treturn `auth:v1:${base64Url(digest)}`;\n};\n\nexport const readAuthSyncPartition = (user: unknown) => {\n\tif (typeof user !== 'object' || user === null) return undefined;\n\tconst value = Reflect.get(user, 'absolutejs_sync_partition');\n\n\treturn typeof value === 'string' && value.length > 0 ? value : undefined;\n};\n",
|
|
6
6
|
"import type { AuthClientTransport } from './createAuthClient';\n\ntype AuthTransportInstallation = { transport: AuthClientTransport };\ntype AuthTransportRegistry = { installations: AuthTransportInstallation[] };\n\nconst AUTH_TRANSPORT_REGISTRY = Symbol.for(\n\t'@absolutejs/auth/client-runtime-transport'\n);\nconst isRegistry = (value: unknown): value is AuthTransportRegistry =>\n\ttypeof value === 'object' &&\n\tvalue !== null &&\n\tArray.isArray(Reflect.get(value, 'installations'));\n\nconst createRegistry = () => {\n\tconst existing = Reflect.get(globalThis, AUTH_TRANSPORT_REGISTRY);\n\tif (isRegistry(existing)) return existing;\n\tconst created: AuthTransportRegistry = { installations: [] };\n\tObject.defineProperty(globalThis, AUTH_TRANSPORT_REGISTRY, {\n\t\tconfigurable: false,\n\t\tenumerable: false,\n\t\tvalue: created,\n\t\twritable: false\n\t});\n\n\treturn created;\n};\n\nconst registry = createRegistry();\n\nexport const getAuthClientRuntimeTransport = () =>\n\tregistry.installations.at(-1)?.transport;\n\nexport const installAuthClientRuntimeTransport = (\n\ttransport: AuthClientTransport\n) => {\n\tconst installation: AuthTransportInstallation = { transport };\n\tregistry.installations.push(installation);\n\n\treturn () => {\n\t\tconst index = registry.installations.indexOf(installation);\n\t\tif (index >= 0) registry.installations.splice(index, 1);\n\t};\n};\n",
|
|
7
|
-
"import {\n\tderiveAuthSyncNamespace,\n\treadAuthSyncPartition\n} from '../syncNamespace';\n\nexport type MobileAuthSecureStorage = {\n\tcapability?: () => Promise<{\n\t\tavailable: boolean;\n\t\tmessage?: string;\n\t}>;\n\tget(key: string): Promise<string | null>;\n\tremove(key: string): Promise<void>;\n\tset(key: string, value: string): Promise<void>;\n\t/** Serialize refresh-token rotation with a native background worker. */\n\twithLock?<T>(key: string, run: () => Promise<T>): Promise<T>;\n};\n\nexport type MobileAuthLinks = {\n\tgetLaunchUrl(): Promise<string | null>;\n\tonOpen(\n\t\tlistener: (url: string) => void\n\t): Promise<() => Promise<void> | void>;\n\topenExternal(url: string): Promise<void>;\n};\n\nexport type MobileAuthLifecycle = {\n\tonResume?(listener: () => void): Promise<() => Promise<void> | void>;\n};\n\nexport type MobileAuthDiscovery = {\n\tauthorization_endpoint: string;\n\tcode_challenge_methods_supported?: string[];\n\tissuer: string;\n\tjwks_uri: string;\n\trevocation_endpoint?: string;\n\tsocket_ticket_endpoint?: string;\n\ttoken_endpoint: string;\n\ttoken_endpoint_auth_methods_supported?: string[];\n\tuserinfo_endpoint: string;\n};\n\nexport type MobileAuthClientConfig = {\n\tallowedOrigins?: readonly string[];\n\t/** Runs while renewable credentials still exist, before native sign-out. */\n\tbeforeSignOut?: () => Promise<void> | void;\n\tclientId: string;\n\tclockSkewMs?: number;\n\tfetch?: typeof globalThis.fetch;\n\tissuer: string;\n\tlifecycle?: MobileAuthLifecycle;\n\tlinks: MobileAuthLinks;\n\tnow?: () => number;\n\tredirectUri: string;\n\tresource?: string;\n\tscopes?: readonly string[];\n\tstorage: MobileAuthSecureStorage;\n};\n\nexport type MobileAuthSignInOptions = {\n\tauthorizationParameters?: Readonly<Record<string, string>>;\n\tsignal?: AbortSignal;\n};\n\nexport type MobileAuthTokens = {\n\taccessToken: string;\n\texpiresAt: number;\n\tidToken: string;\n\trefreshToken: string;\n\tscope: string[];\n\ttokenType: 'Bearer';\n};\n\nexport type MobileAuthUser = Record<string, unknown> & { sub: string };\n\nexport type MobileAuthPrincipal = {\n\tissuer: string;\n\tnamespace: string;\n\t/** Optional server-owned tenant/account partition from userinfo. */\n\tpartition?: string;\n\tsubject: string;\n};\n\nexport type MobileAuthErrorCode =\n\t| 'aborted'\n\t| 'callback'\n\t| 'discovery'\n\t| 'id-token'\n\t| 'network'\n\t| 'oauth'\n\t| 'origin'\n\t| 'secure-storage'\n\t| 'token';\n\nexport class MobileAuthError extends Error {\n\treadonly code: MobileAuthErrorCode;\n\treadonly cause?: unknown;\n\n\tconstructor(\n\t\tcode: MobileAuthErrorCode,\n\t\tmessage: string,\n\t\toptions?: { cause?: unknown }\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'MobileAuthError';\n\t\tthis.code = code;\n\t\tthis.cause = options?.cause;\n\t}\n}\n\ntype PendingAuthorization = {\n\tcreatedAt: number;\n\tnonce: string;\n\tstate: string;\n\tverifier: string;\n};\n\ntype TokenResponse = {\n\taccess_token: string;\n\texpires_in: number;\n\tid_token: string;\n\trefresh_token: string;\n\tscope?: string;\n\ttoken_type: string;\n};\n\ntype DeferredSignIn = {\n\treject: (error: unknown) => void;\n\tresolve: (tokens: MobileAuthTokens) => void;\n};\n\nconst PENDING_KEY = 'oidc.pending';\nconst REFRESH_KEY = 'oidc.refresh';\nconst DEFAULT_CLOCK_SKEW_MS = 30_000;\nconst PENDING_TTL_MS = 10 * 60_000;\nconst RANDOM_BYTES = 32;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n\ttypeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst base64Url = (value: Uint8Array) => {\n\tlet binary = '';\n\tfor (const byte of value) binary += String.fromCharCode(byte);\n\n\treturn btoa(binary)\n\t\t.replaceAll('+', '-')\n\t\t.replaceAll('/', '_')\n\t\t.replace(/=+$/u, '');\n};\n\nconst decodeBase64Url = (value: string) => {\n\tconst normalized = value.replaceAll('-', '+').replaceAll('_', '/');\n\tconst padded = normalized.padEnd(\n\t\tnormalized.length + ((4 - (normalized.length % 4)) % 4),\n\t\t'='\n\t);\n\tconst binary = atob(padded);\n\n\treturn Uint8Array.from(binary, (character) => character.charCodeAt(0));\n};\n\nconst randomValue = () => {\n\tconst value = new Uint8Array(RANDOM_BYTES);\n\tcrypto.getRandomValues(value);\n\n\treturn base64Url(value);\n};\n\nconst pkceChallenge = async (verifier: string) =>\n\tbase64Url(\n\t\tnew Uint8Array(\n\t\t\tawait crypto.subtle.digest(\n\t\t\t\t'SHA-256',\n\t\t\t\tnew TextEncoder().encode(verifier)\n\t\t\t)\n\t\t)\n\t);\n\nconst normalizeIssuer = (value: string) => {\n\tconst issuer = new URL(value);\n\tconst loopback =\n\t\tissuer.protocol === 'http:' &&\n\t\t['127.0.0.1', '[::1]', 'localhost'].includes(issuer.hostname);\n\tif (issuer.protocol !== 'https:' && !loopback)\n\t\tthrow new TypeError('Mobile auth issuer must use HTTPS.');\n\tif (issuer.username || issuer.password || issuer.search || issuer.hash)\n\t\tthrow new TypeError(\n\t\t\t'Mobile auth issuer cannot contain credentials, query, or fragment.'\n\t\t);\n\tissuer.pathname = issuer.pathname.replace(/\\/$/u, '');\n\n\treturn issuer.href.replace(/\\/$/u, '');\n};\n\nconst exactRedirect = (actualValue: string, expectedValue: string) => {\n\tconst actual = new URL(actualValue);\n\tconst expected = new URL(expectedValue);\n\n\treturn (\n\t\tactual.protocol === expected.protocol &&\n\t\tactual.host === expected.host &&\n\t\tactual.pathname === expected.pathname &&\n\t\tactual.username === '' &&\n\t\tactual.password === ''\n\t);\n};\n\nconst parsePending = (value: string | null) => {\n\tif (value === null) return undefined;\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(value);\n\t\tif (\n\t\t\t!isRecord(parsed) ||\n\t\t\ttypeof parsed.createdAt !== 'number' ||\n\t\t\ttypeof parsed.nonce !== 'string' ||\n\t\t\ttypeof parsed.state !== 'string' ||\n\t\t\ttypeof parsed.verifier !== 'string'\n\t\t)\n\t\t\treturn undefined;\n\n\t\treturn {\n\t\t\tcreatedAt: parsed.createdAt,\n\t\t\tnonce: parsed.nonce,\n\t\t\tstate: parsed.state,\n\t\t\tverifier: parsed.verifier\n\t\t} satisfies PendingAuthorization;\n\t} catch {\n\t\treturn undefined;\n\t}\n};\n\nconst parseTokenResponse = (value: unknown) => {\n\tif (\n\t\t!isRecord(value) ||\n\t\ttypeof value.access_token !== 'string' ||\n\t\ttypeof value.expires_in !== 'number' ||\n\t\t!Number.isFinite(value.expires_in) ||\n\t\tvalue.expires_in <= 0 ||\n\t\ttypeof value.id_token !== 'string' ||\n\t\ttypeof value.refresh_token !== 'string' ||\n\t\ttypeof value.token_type !== 'string'\n\t)\n\t\tthrow new MobileAuthError('token', 'The token response is malformed.');\n\tif (value.token_type.toLowerCase() !== 'bearer')\n\t\tthrow new MobileAuthError(\n\t\t\t'token',\n\t\t\t`Unsupported mobile token type ${value.token_type}; DPoP is not enabled for this client.`\n\t\t);\n\n\treturn {\n\t\taccess_token: value.access_token,\n\t\texpires_in: value.expires_in,\n\t\tid_token: value.id_token,\n\t\trefresh_token: value.refresh_token,\n\t\tscope: typeof value.scope === 'string' ? value.scope : undefined,\n\t\ttoken_type: value.token_type\n\t} satisfies TokenResponse;\n};\n\nconst responseBody = async (response: Response) => {\n\tconst text = await response.text();\n\ttry {\n\t\treturn JSON.parse(text);\n\t} catch {\n\t\treturn text;\n\t}\n};\n\nconst requireEndpoint = (value: unknown, name: string, issuer: string) => {\n\tif (typeof value !== 'string')\n\t\tthrow new MobileAuthError(\n\t\t\t'discovery',\n\t\t\t`OIDC discovery is missing ${name}.`\n\t\t);\n\tconst endpoint = new URL(value);\n\tif (endpoint.protocol !== 'https:' && new URL(issuer).protocol === 'https:')\n\t\tthrow new MobileAuthError(\n\t\t\t'discovery',\n\t\t\t`OIDC discovery ${name} must use HTTPS.`\n\t\t);\n\n\treturn endpoint.href;\n};\n\nconst parseDiscovery = (\n\tvalue: unknown,\n\tissuer: string\n): MobileAuthDiscovery => {\n\tif (!isRecord(value) || value.issuer !== issuer)\n\t\tthrow new MobileAuthError(\n\t\t\t'discovery',\n\t\t\t'OIDC discovery issuer does not match the configured issuer.'\n\t\t);\n\tconst methods = Array.isArray(value.code_challenge_methods_supported)\n\t\t? value.code_challenge_methods_supported.filter(\n\t\t\t\t(method): method is string => typeof method === 'string'\n\t\t\t)\n\t\t: undefined;\n\tif (!methods?.includes('S256'))\n\t\tthrow new MobileAuthError(\n\t\t\t'discovery',\n\t\t\t'OIDC provider does not advertise S256 PKCE.'\n\t\t);\n\tconst authMethods = Array.isArray(\n\t\tvalue.token_endpoint_auth_methods_supported\n\t)\n\t\t? value.token_endpoint_auth_methods_supported.filter(\n\t\t\t\t(method): method is string => typeof method === 'string'\n\t\t\t)\n\t\t: undefined;\n\tif (!authMethods?.includes('none'))\n\t\tthrow new MobileAuthError(\n\t\t\t'discovery',\n\t\t\t'OIDC provider does not accept public clients at the token endpoint.'\n\t\t);\n\n\treturn {\n\t\tauthorization_endpoint: requireEndpoint(\n\t\t\tvalue.authorization_endpoint,\n\t\t\t'authorization_endpoint',\n\t\t\tissuer\n\t\t),\n\t\tcode_challenge_methods_supported: methods,\n\t\tissuer,\n\t\tjwks_uri: requireEndpoint(value.jwks_uri, 'jwks_uri', issuer),\n\t\trevocation_endpoint:\n\t\t\ttypeof value.revocation_endpoint === 'string'\n\t\t\t\t? requireEndpoint(\n\t\t\t\t\t\tvalue.revocation_endpoint,\n\t\t\t\t\t\t'revocation_endpoint',\n\t\t\t\t\t\tissuer\n\t\t\t\t\t)\n\t\t\t\t: undefined,\n\t\tsocket_ticket_endpoint:\n\t\t\ttypeof value.socket_ticket_endpoint === 'string'\n\t\t\t\t? requireEndpoint(\n\t\t\t\t\t\tvalue.socket_ticket_endpoint,\n\t\t\t\t\t\t'socket_ticket_endpoint',\n\t\t\t\t\t\tissuer\n\t\t\t\t\t)\n\t\t\t\t: undefined,\n\t\ttoken_endpoint: requireEndpoint(\n\t\t\tvalue.token_endpoint,\n\t\t\t'token_endpoint',\n\t\t\tissuer\n\t\t),\n\t\ttoken_endpoint_auth_methods_supported: authMethods,\n\t\tuserinfo_endpoint: requireEndpoint(\n\t\t\tvalue.userinfo_endpoint,\n\t\t\t'userinfo_endpoint',\n\t\t\tissuer\n\t\t)\n\t};\n};\n\nconst verifyIdToken = async ({\n\tclientId,\n\tfetchImpl,\n\tidToken,\n\tissuer,\n\tjwksUri,\n\tnonce,\n\tnow\n}: {\n\tclientId: string;\n\tfetchImpl: typeof globalThis.fetch;\n\tidToken: string;\n\tissuer: string;\n\tjwksUri: string;\n\tnonce: string;\n\tnow: number;\n}) => {\n\tconst [encodedHeader, encodedPayload, encodedSignature, ...extra] =\n\t\tidToken.split('.');\n\tif (!encodedHeader || !encodedPayload || !encodedSignature || extra.length)\n\t\tthrow new MobileAuthError('id-token', 'The ID token is malformed.');\n\tlet header: unknown;\n\tlet payload: unknown;\n\ttry {\n\t\theader = JSON.parse(\n\t\t\tnew TextDecoder().decode(decodeBase64Url(encodedHeader))\n\t\t);\n\t\tpayload = JSON.parse(\n\t\t\tnew TextDecoder().decode(decodeBase64Url(encodedPayload))\n\t\t);\n\t} catch (cause) {\n\t\tthrow new MobileAuthError('id-token', 'The ID token is malformed.', {\n\t\t\tcause\n\t\t});\n\t}\n\tif (\n\t\t!isRecord(header) ||\n\t\theader.alg !== 'ES256' ||\n\t\ttypeof header.kid !== 'string' ||\n\t\t!isRecord(payload)\n\t)\n\t\tthrow new MobileAuthError(\n\t\t\t'id-token',\n\t\t\t'The ID token header or claims are invalid.'\n\t\t);\n\tconst response = await fetchImpl(jwksUri, { cache: 'no-store' });\n\tif (!response.ok)\n\t\tthrow new MobileAuthError(\n\t\t\t'network',\n\t\t\t'Unable to fetch OIDC signing keys.'\n\t\t);\n\tconst body: unknown = await response.json();\n\tconst keys = isRecord(body) && Array.isArray(body.keys) ? body.keys : [];\n\tconst jwk = keys.find(\n\t\t(candidate): candidate is JsonWebKey & { kid: string } =>\n\t\t\tisRecord(candidate) && candidate.kid === header.kid\n\t);\n\tif (!jwk)\n\t\tthrow new MobileAuthError(\n\t\t\t'id-token',\n\t\t\t'The ID token signing key is unknown.'\n\t\t);\n\tconst key = await crypto.subtle.importKey(\n\t\t'jwk',\n\t\tjwk,\n\t\t{ hash: 'SHA-256', name: 'ECDSA', namedCurve: 'P-256' },\n\t\tfalse,\n\t\t['verify']\n\t);\n\tconst valid = await crypto.subtle.verify(\n\t\t{ hash: 'SHA-256', name: 'ECDSA' },\n\t\tkey,\n\t\tdecodeBase64Url(encodedSignature),\n\t\tnew TextEncoder().encode(`${encodedHeader}.${encodedPayload}`)\n\t);\n\tconst audience = payload.aud;\n\tif (\n\t\t!valid ||\n\t\tpayload.iss !== issuer ||\n\t\t!(\n\t\t\taudience === clientId ||\n\t\t\t(Array.isArray(audience) && audience.includes(clientId))\n\t\t) ||\n\t\tpayload.nonce !== nonce ||\n\t\ttypeof payload.exp !== 'number' ||\n\t\tpayload.exp * 1000 <= now\n\t)\n\t\tthrow new MobileAuthError(\n\t\t\t'id-token',\n\t\t\t'The ID token signature or claims are invalid.'\n\t\t);\n};\n\nexport const createMobileAuthClient = (config: MobileAuthClientConfig) => {\n\tconst issuer = normalizeIssuer(config.issuer);\n\tconst redirectUri = new URL(config.redirectUri).href;\n\tconst fetchImpl = config.fetch ?? globalThis.fetch;\n\tconst now = config.now ?? Date.now;\n\tconst clockSkewMs = config.clockSkewMs ?? DEFAULT_CLOCK_SKEW_MS;\n\tconst scopes = [...new Set(config.scopes ?? ['openid', 'profile'])];\n\tconst resource = config.resource ?? issuer;\n\tif (!scopes.includes('openid')) scopes.unshift('openid');\n\tconst allowedOrigins = new Set(\n\t\t(config.allowedOrigins ?? [new URL(issuer).origin]).map(\n\t\t\t(value) => new URL(value).origin\n\t\t)\n\t);\n\tlet discoveryPromise: Promise<MobileAuthDiscovery> | undefined;\n\tlet access: Omit<MobileAuthTokens, 'refreshToken'> | undefined;\n\tlet refreshPromise: Promise<string> | undefined;\n\tlet stopLinks: (() => Promise<void> | void) | undefined;\n\tlet stopResume: (() => Promise<void> | void) | undefined;\n\tlet startPromise: Promise<void> | undefined;\n\tconst pendingSignIns = new Map<string, DeferredSignIn>();\n\tlet currentPrincipal: MobileAuthPrincipal | null | undefined;\n\tconst principalListeners = new Set<\n\t\t(principal: MobileAuthPrincipal | null) => void\n\t>();\n\tconst publishPrincipal = (principal: MobileAuthPrincipal | null) => {\n\t\tif (\n\t\t\tcurrentPrincipal !== undefined &&\n\t\t\tcurrentPrincipal?.namespace === principal?.namespace\n\t\t)\n\t\t\treturn;\n\t\tcurrentPrincipal = principal;\n\t\tfor (const listener of principalListeners) listener(principal);\n\t};\n\tconst principalFor = async (\n\t\tuser: MobileAuthUser\n\t): Promise<MobileAuthPrincipal> => {\n\t\tconst partition = readAuthSyncPartition(user);\n\n\t\treturn {\n\t\t\tissuer,\n\t\t\tnamespace: await deriveAuthSyncNamespace({\n\t\t\t\tclientId: config.clientId,\n\t\t\t\tissuer,\n\t\t\t\tpartition,\n\t\t\t\tsubject: user.sub\n\t\t\t}),\n\t\t\t...(partition === undefined ? {} : { partition }),\n\t\t\tsubject: user.sub\n\t\t};\n\t};\n\n\tconst fetchDiscovery = async () => {\n\t\tconst url = new URL('/.well-known/openid-configuration', `${issuer}/`);\n\t\tconst response = await fetchImpl(url, {\n\t\t\tcache: 'no-store',\n\t\t\theaders: { accept: 'application/json' }\n\t\t});\n\t\tif (!response.ok)\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'discovery',\n\t\t\t\t`OIDC discovery failed with HTTP ${response.status}.`\n\t\t\t);\n\n\t\treturn parseDiscovery(await response.json(), issuer);\n\t};\n\n\tconst discovery = () => {\n\t\tdiscoveryPromise ??= fetchDiscovery();\n\n\t\treturn discoveryPromise;\n\t};\n\n\tconst assertSecureStorage = async () => {\n\t\tconst capability = await config.storage.capability?.();\n\t\tif (capability && !capability.available)\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'secure-storage',\n\t\t\t\tcapability.message ??\n\t\t\t\t\t'Native secure credential storage is unavailable.'\n\t\t\t);\n\t};\n\n\tconst tokenRequest = async (\n\t\tmetadata: MobileAuthDiscovery,\n\t\tbody: URLSearchParams,\n\t\tnonce?: string\n\t) => {\n\t\tlet response: Response;\n\t\ttry {\n\t\t\tresponse = await fetchImpl(metadata.token_endpoint, {\n\t\t\t\tbody,\n\t\t\t\tcredentials: 'omit',\n\t\t\t\theaders: {\n\t\t\t\t\taccept: 'application/json',\n\t\t\t\t\t'content-type': 'application/x-www-form-urlencoded'\n\t\t\t\t},\n\t\t\t\tmethod: 'POST'\n\t\t\t});\n\t\t} catch (cause) {\n\t\t\tthrow new MobileAuthError('network', 'The token request failed.', {\n\t\t\t\tcause\n\t\t\t});\n\t\t}\n\t\tconst value = await responseBody(response);\n\t\tif (!response.ok) {\n\t\t\tconst oauthCode =\n\t\t\t\tisRecord(value) && typeof value.error === 'string'\n\t\t\t\t\t? value.error\n\t\t\t\t\t: `HTTP ${response.status}`;\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'oauth',\n\t\t\t\t`The authorization server rejected the token request (${oauthCode}).`\n\t\t\t);\n\t\t}\n\t\tconst tokens = parseTokenResponse(value);\n\t\tif (nonce)\n\t\t\tawait verifyIdToken({\n\t\t\t\tclientId: config.clientId,\n\t\t\t\tfetchImpl,\n\t\t\t\tidToken: tokens.id_token,\n\t\t\t\tissuer,\n\t\t\t\tjwksUri: metadata.jwks_uri,\n\t\t\t\tnonce,\n\t\t\t\tnow: now()\n\t\t\t});\n\n\t\treturn tokens;\n\t};\n\n\tconst acceptTokens = async (\n\t\ttokens: TokenResponse\n\t): Promise<MobileAuthTokens> => {\n\t\ttry {\n\t\t\tawait config.storage.set(REFRESH_KEY, tokens.refresh_token);\n\t\t} catch (cause) {\n\t\t\taccess = undefined;\n\t\t\tawait config.storage.remove(REFRESH_KEY).catch(() => undefined);\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'secure-storage',\n\t\t\t\t'The rotated refresh credential could not be saved securely.',\n\t\t\t\t{ cause }\n\t\t\t);\n\t\t}\n\t\taccess = {\n\t\t\taccessToken: tokens.access_token,\n\t\t\texpiresAt: now() + tokens.expires_in * 1000,\n\t\t\tidToken: tokens.id_token,\n\t\t\tscope: tokens.scope?.split(' ').filter(Boolean) ?? scopes,\n\t\t\ttokenType: 'Bearer'\n\t\t};\n\n\t\treturn { ...access, refreshToken: tokens.refresh_token };\n\t};\n\n\tconst rotateAccessToken = async () => {\n\t\tawait assertSecureStorage();\n\t\tconst exchange = async () => {\n\t\t\tconst refreshToken = await config.storage.get(REFRESH_KEY);\n\t\t\tif (!refreshToken)\n\t\t\t\tthrow new MobileAuthError(\n\t\t\t\t\t'token',\n\t\t\t\t\t'This app has no renewable mobile session.'\n\t\t\t\t);\n\t\t\tconst metadata = await discovery();\n\t\t\tconst body = new URLSearchParams({\n\t\t\t\tclient_id: config.clientId,\n\t\t\t\tgrant_type: 'refresh_token',\n\t\t\t\trefresh_token: refreshToken\n\t\t\t});\n\t\t\tbody.set('resource', resource);\n\t\t\tconst tokens = await tokenRequest(metadata, body);\n\n\t\t\treturn (await acceptTokens(tokens)).accessToken;\n\t\t};\n\n\t\treturn config.storage.withLock\n\t\t\t? config.storage.withLock(REFRESH_KEY, exchange)\n\t\t\t: exchange();\n\t};\n\n\tconst refreshAccessToken = async () => {\n\t\tif (access && access.expiresAt - clockSkewMs > now())\n\t\t\treturn access.accessToken;\n\t\tif (refreshPromise) return refreshPromise;\n\t\trefreshPromise = rotateAccessToken().finally(() => {\n\t\t\trefreshPromise = undefined;\n\t\t});\n\n\t\treturn refreshPromise;\n\t};\n\n\tconst handleCallback = async (value: string) => {\n\t\tif (!exactRedirect(value, redirectUri))\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'callback',\n\t\t\t\t'The authorization callback does not match this app registration.'\n\t\t\t);\n\t\tconst url = new URL(value);\n\t\tconst pending = parsePending(await config.storage.get(PENDING_KEY));\n\t\tif (!pending || now() - pending.createdAt > PENDING_TTL_MS) {\n\t\t\tawait config.storage.remove(PENDING_KEY).catch(() => undefined);\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'callback',\n\t\t\t\t'The authorization transaction is missing or expired.'\n\t\t\t);\n\t\t}\n\t\tconst deferred = pendingSignIns.get(pending.state);\n\t\tconst reject = (error: unknown) => {\n\t\t\tpendingSignIns.delete(pending.state);\n\t\t\tvoid config.storage.remove(PENDING_KEY);\n\t\t\tdeferred?.reject(error);\n\t\t\tthrow error;\n\t\t};\n\t\tif (url.searchParams.get('state') !== pending.state)\n\t\t\treturn reject(\n\t\t\t\tnew MobileAuthError(\n\t\t\t\t\t'callback',\n\t\t\t\t\t'The authorization callback state does not match.'\n\t\t\t\t)\n\t\t\t);\n\t\tif (url.searchParams.get('iss') !== issuer)\n\t\t\treturn reject(\n\t\t\t\tnew MobileAuthError(\n\t\t\t\t\t'callback',\n\t\t\t\t\t'The authorization callback issuer does not match.'\n\t\t\t\t)\n\t\t\t);\n\t\tconst oauthError = url.searchParams.get('error');\n\t\tif (oauthError) {\n\t\t\tawait config.storage.remove(PENDING_KEY);\n\n\t\t\treturn reject(\n\t\t\t\tnew MobileAuthError(\n\t\t\t\t\t'oauth',\n\t\t\t\t\t`Authorization failed (${oauthError}).`\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\t\tconst code = url.searchParams.get('code');\n\t\tif (!code)\n\t\t\treturn reject(\n\t\t\t\tnew MobileAuthError(\n\t\t\t\t\t'callback',\n\t\t\t\t\t'The authorization callback contains no code.'\n\t\t\t\t)\n\t\t\t);\n\t\tawait config.storage.remove(PENDING_KEY);\n\t\ttry {\n\t\t\tconst metadata = await discovery();\n\t\t\tconst body = new URLSearchParams({\n\t\t\t\tclient_id: config.clientId,\n\t\t\t\tcode,\n\t\t\t\tcode_verifier: pending.verifier,\n\t\t\t\tgrant_type: 'authorization_code',\n\t\t\t\tredirect_uri: redirectUri\n\t\t\t});\n\t\t\tbody.set('resource', resource);\n\t\t\tconst tokens = await acceptTokens(\n\t\t\t\tawait tokenRequest(metadata, body, pending.nonce)\n\t\t\t);\n\t\t\tpendingSignIns.delete(pending.state);\n\t\t\tdeferred?.resolve(tokens);\n\n\t\t\treturn tokens;\n\t\t} catch (error) {\n\t\t\treturn reject(error);\n\t\t}\n\t};\n\n\tconst initialize = async () => {\n\t\tawait assertSecureStorage();\n\t\tstopLinks = await config.links.onOpen((url) => {\n\t\t\tif (exactRedirect(url, redirectUri))\n\t\t\t\tvoid handleCallback(url).catch(() => undefined);\n\t\t});\n\t\tif (config.lifecycle?.onResume)\n\t\t\tstopResume = await config.lifecycle.onResume(() => {\n\t\t\t\tvoid refreshAccessToken().catch(() => undefined);\n\t\t\t});\n\t\tconst launchUrl = await config.links.getLaunchUrl();\n\t\tif (launchUrl && exactRedirect(launchUrl, redirectUri))\n\t\t\tawait handleCallback(launchUrl);\n\t};\n\n\tconst start = () => {\n\t\tstartPromise ??= initialize();\n\n\t\treturn startPromise;\n\t};\n\n\tconst signIn = async (options: MobileAuthSignInOptions = {}) => {\n\t\tawait start();\n\t\tif (options.signal?.aborted)\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'aborted',\n\t\t\t\t'Authorization was cancelled.'\n\t\t\t);\n\t\tconst metadata = await discovery();\n\t\tconst pending: PendingAuthorization = {\n\t\t\tcreatedAt: now(),\n\t\t\tnonce: randomValue(),\n\t\t\tstate: randomValue(),\n\t\t\tverifier: randomValue()\n\t\t};\n\t\tawait config.storage.set(PENDING_KEY, JSON.stringify(pending));\n\t\tconst url = new URL(metadata.authorization_endpoint);\n\t\turl.search = new URLSearchParams({\n\t\t\tclient_id: config.clientId,\n\t\t\tcode_challenge: await pkceChallenge(pending.verifier),\n\t\t\tcode_challenge_method: 'S256',\n\t\t\tnonce: pending.nonce,\n\t\t\tredirect_uri: redirectUri,\n\t\t\tresponse_type: 'code',\n\t\t\tscope: scopes.join(' '),\n\t\t\tstate: pending.state,\n\t\t\t...options.authorizationParameters\n\t\t}).toString();\n\t\turl.searchParams.set('resource', resource);\n\t\tconst result = new Promise<MobileAuthTokens>((resolve, reject) => {\n\t\t\tpendingSignIns.set(pending.state, { reject, resolve });\n\t\t\toptions.signal?.addEventListener(\n\t\t\t\t'abort',\n\t\t\t\t() => {\n\t\t\t\t\tpendingSignIns.delete(pending.state);\n\t\t\t\t\tvoid config.storage.remove(PENDING_KEY);\n\t\t\t\t\treject(\n\t\t\t\t\t\tnew MobileAuthError(\n\t\t\t\t\t\t\t'aborted',\n\t\t\t\t\t\t\t'Authorization was cancelled.'\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\t{ once: true }\n\t\t\t);\n\t\t});\n\t\ttry {\n\t\t\tawait config.links.openExternal(url.href);\n\t\t} catch (error) {\n\t\t\tpendingSignIns.delete(pending.state);\n\t\t\tawait config.storage.remove(PENDING_KEY);\n\t\t\tthrow error;\n\t\t}\n\n\t\treturn result;\n\t};\n\n\tconst authenticatedFetch = async (\n\t\tinput: RequestInfo | URL,\n\t\tinit?: RequestInit\n\t) => {\n\t\tconst original = new Request(input, init);\n\t\tif (!allowedOrigins.has(new URL(original.url).origin))\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'origin',\n\t\t\t\t'Mobile auth refused to send a credential to an unregistered origin.'\n\t\t\t);\n\t\tconst send = async (forceRefresh: boolean) => {\n\t\t\tif (forceRefresh) access = undefined;\n\t\t\tconst token = await refreshAccessToken();\n\t\t\tconst request = original.clone();\n\t\t\tconst headers = new Headers(request.headers);\n\t\t\theaders.set('authorization', `Bearer ${token}`);\n\n\t\t\treturn fetchImpl(\n\t\t\t\tnew Request(request, { credentials: 'omit', headers })\n\t\t\t);\n\t\t};\n\t\tconst response = await send(false);\n\n\t\treturn response.status === 401 ? send(true) : response;\n\t};\n\n\tconst optionalAuthenticatedFetch = async (\n\t\tinput: RequestInfo | URL,\n\t\tinit?: RequestInit\n\t) => {\n\t\tconst request = new Request(input, init);\n\t\tif (!allowedOrigins.has(new URL(request.url).origin))\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'origin',\n\t\t\t\t'Mobile auth refused to send a request outside an allowed origin.'\n\t\t\t);\n\t\tconst refreshToken = await config.storage.get(REFRESH_KEY);\n\t\tif (access || refreshToken) return authenticatedFetch(request);\n\n\t\treturn fetchImpl(new Request(request, { credentials: 'omit' }));\n\t};\n\tconst signedOut = () => {\n\t\tpublishPrincipal(null);\n\n\t\treturn null;\n\t};\n\n\tconst status = async () => {\n\t\ttry {\n\t\t\tconst metadata = await discovery();\n\t\t\tconst response = await authenticatedFetch(\n\t\t\t\tmetadata.userinfo_endpoint\n\t\t\t);\n\t\t\tif (response.status === 401) return signedOut();\n\t\t\tif (!response.ok)\n\t\t\t\tthrow new MobileAuthError(\n\t\t\t\t\t'network',\n\t\t\t\t\t`User info failed with HTTP ${response.status}.`\n\t\t\t\t);\n\t\t\tconst user: unknown = await response.json();\n\t\t\tif (!isRecord(user) || typeof user.sub !== 'string')\n\t\t\t\tthrow new MobileAuthError(\n\t\t\t\t\t'token',\n\t\t\t\t\t'The user-info response is malformed.'\n\t\t\t\t);\n\n\t\t\tconst normalized = {\n\t\t\t\t...user,\n\t\t\t\tsub: user.sub\n\t\t\t} satisfies MobileAuthUser;\n\t\t\tpublishPrincipal(await principalFor(normalized));\n\n\t\t\treturn normalized;\n\t\t} catch (error) {\n\t\t\tif (\n\t\t\t\t!(\n\t\t\t\t\terror instanceof MobileAuthError &&\n\t\t\t\t\t(error.code === 'oauth' || error.code === 'token')\n\t\t\t\t)\n\t\t\t)\n\t\t\t\tthrow error;\n\n\t\t\treturn signedOut();\n\t\t}\n\t};\n\n\tconst socketTicket = async (audience = resource) => {\n\t\tconst metadata = await discovery();\n\t\tif (!metadata.socket_ticket_endpoint)\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'discovery',\n\t\t\t\t'The authorization server does not advertise WebSocket tickets.'\n\t\t\t);\n\t\tconst response = await authenticatedFetch(\n\t\t\tmetadata.socket_ticket_endpoint,\n\t\t\t{\n\t\t\t\tbody: JSON.stringify({ audience }),\n\t\t\t\theaders: { 'content-type': 'application/json' },\n\t\t\t\tmethod: 'POST'\n\t\t\t}\n\t\t);\n\t\tconst body: unknown = await responseBody(response);\n\t\tif (!response.ok || !isRecord(body) || typeof body.ticket !== 'string')\n\t\t\tthrow new MobileAuthError(\n\t\t\t\tresponse.ok ? 'token' : 'oauth',\n\t\t\t\t`WebSocket ticket request failed with HTTP ${response.status}.`\n\t\t\t);\n\n\t\treturn body.ticket;\n\t};\n\n\tconst revokeRefreshToken = async (refreshToken: string) => {\n\t\tconst metadata = await discovery();\n\t\tif (metadata.revocation_endpoint)\n\t\t\tawait fetchImpl(metadata.revocation_endpoint, {\n\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\tclient_id: config.clientId,\n\t\t\t\t\ttoken: refreshToken,\n\t\t\t\t\ttoken_type_hint: 'refresh_token'\n\t\t\t\t}),\n\t\t\t\tcredentials: 'omit',\n\t\t\t\theaders: {\n\t\t\t\t\t'content-type': 'application/x-www-form-urlencoded'\n\t\t\t\t},\n\t\t\t\tmethod: 'POST'\n\t\t\t});\n\t};\n\tconst runBeforeSignOut = async () => {\n\t\ttry {\n\t\t\tawait config.beforeSignOut?.();\n\t\t} catch {\n\t\t\t// Sign-out must remain available. Native integrations fail closed\n\t\t\t// locally and stale provider registrations retire on send.\n\t\t}\n\t};\n\n\tconst signOut = async () => {\n\t\tconst refreshToken = await config.storage.get(REFRESH_KEY);\n\t\ttry {\n\t\t\tawait runBeforeSignOut();\n\t\t\tif (refreshToken) await revokeRefreshToken(refreshToken);\n\t\t} finally {\n\t\t\taccess = undefined;\n\t\t\tawait Promise.all([\n\t\t\t\tconfig.storage.remove(PENDING_KEY),\n\t\t\t\tconfig.storage.remove(REFRESH_KEY)\n\t\t\t]);\n\t\t\tpublishPrincipal(null);\n\t\t}\n\t};\n\n\tconst principal = async () => {\n\t\tawait status();\n\n\t\treturn currentPrincipal ?? null;\n\t};\n\n\tconst onPrincipalChange = (\n\t\tlistener: (principal: MobileAuthPrincipal | null) => void\n\t) => {\n\t\tprincipalListeners.add(listener);\n\t\tif (currentPrincipal !== undefined) listener(currentPrincipal);\n\n\t\treturn () => {\n\t\t\tprincipalListeners.delete(listener);\n\t\t};\n\t};\n\n\tconst stop = async () => {\n\t\tawait Promise.all([stopLinks?.(), stopResume?.()]);\n\t\tstopLinks = undefined;\n\t\tstopResume = undefined;\n\t\tstartPromise = undefined;\n\t};\n\n\treturn {\n\t\tfetch: authenticatedFetch,\n\t\tfetchOptional: optionalAuthenticatedFetch,\n\t\thandleCallback,\n\t\tonPrincipalChange,\n\t\tprincipal,\n\t\trefresh: refreshAccessToken,\n\t\tsignIn,\n\t\tsignOut,\n\t\tsocketTicket,\n\t\tstart,\n\t\tstatus,\n\t\tstop\n\t};\n};\n\nexport type MobileAuthClient = ReturnType<typeof createMobileAuthClient>;\n\n/** Adapts the native OAuth lifecycle behind the same createAuthClient API used\n * by web applications. Passwords stay out of the WebView request path; the\n * external authorization UI owns credential entry and MFA. */\nexport const createMobileAuthTransport = (\n\tclient: MobileAuthClient,\n\toptions: { baseUrl?: string } = {}\n): import('./createAuthClient').AuthClientTransport => ({\n\tfetch: (input, init) => {\n\t\tconst resolved =\n\t\t\toptions.baseUrl &&\n\t\t\t(typeof input === 'string' || input instanceof URL)\n\t\t\t\t? new URL(String(input), options.baseUrl)\n\t\t\t\t: input;\n\n\t\treturn client.fetchOptional(resolved, init);\n\t},\n\tsignInEmail: async ({ email }) => {\n\t\tawait client.signIn({\n\t\t\tauthorizationParameters: { login_hint: email }\n\t\t});\n\n\t\treturn { status: 'authenticated' };\n\t},\n\tsignOut: async () => {\n\t\tawait client.signOut();\n\n\t\treturn null;\n\t},\n\tsignUpEmail: async ({ email }) => {\n\t\tawait client.signIn({\n\t\t\tauthorizationParameters: {\n\t\t\t\tlogin_hint: email,\n\t\t\t\tscreen_hint: 'signup'\n\t\t\t}\n\t\t});\n\n\t\treturn { status: 'authenticated' };\n\t},\n\tstatus: async () => {\n\t\tconst user = await client.status();\n\n\t\treturn { user };\n\t}\n});\n\nexport { installAuthClientRuntimeTransport } from './runtimeTransport';\n"
|
|
7
|
+
"import {\n\tderiveAuthSyncNamespace,\n\treadAuthSyncPartition\n} from '../syncNamespace';\n\nexport type MobileAuthSecureStorage = {\n\tcapability?: () => Promise<{\n\t\tavailable: boolean;\n\t\tmessage?: string;\n\t}>;\n\tget(key: string): Promise<string | null>;\n\tremove(key: string): Promise<void>;\n\tset(key: string, value: string): Promise<void>;\n\t/** Serialize refresh-token rotation with a native background worker. */\n\twithLock?<T>(key: string, run: () => Promise<T>): Promise<T>;\n};\n\nexport type MobileAuthLinks = {\n\tgetLaunchUrl(): Promise<string | null>;\n\tonOpen(\n\t\tlistener: (url: string) => void\n\t): Promise<() => Promise<void> | void>;\n\topenExternal(url: string): Promise<void>;\n};\n\nexport type MobileAuthLifecycle = {\n\tonResume?(listener: () => void): Promise<() => Promise<void> | void>;\n};\n\nexport type MobileAuthCrypto = {\n\tdigestSha256(value: Uint8Array): Promise<Uint8Array>;\n\trandomBytes(length: number): Uint8Array;\n\tverifyEs256(input: {\n\t\tdata: Uint8Array;\n\t\tjwk: JsonWebKey;\n\t\tsignature: Uint8Array;\n\t}): Promise<boolean>;\n};\n\nexport type MobileAuthDiscovery = {\n\tauthorization_endpoint: string;\n\tcode_challenge_methods_supported?: string[];\n\tissuer: string;\n\tjwks_uri: string;\n\trevocation_endpoint?: string;\n\tsocket_ticket_endpoint?: string;\n\ttoken_endpoint: string;\n\ttoken_endpoint_auth_methods_supported?: string[];\n\tuserinfo_endpoint: string;\n};\n\nexport type MobileAuthClientConfig = {\n\tallowedOrigins?: readonly string[];\n\t/** Runs while renewable credentials still exist, before native sign-out. */\n\tbeforeSignOut?: () => Promise<void> | void;\n\tclientId: string;\n\tclockSkewMs?: number;\n\tcrypto?: MobileAuthCrypto;\n\tfetch?: typeof globalThis.fetch;\n\tissuer: string;\n\tlifecycle?: MobileAuthLifecycle;\n\tlinks: MobileAuthLinks;\n\tnow?: () => number;\n\tredirectUri: string;\n\tresource?: string;\n\tscopes?: readonly string[];\n\tstorage: MobileAuthSecureStorage;\n};\n\nexport type MobileAuthSignInOptions = {\n\tauthorizationParameters?: Readonly<Record<string, string>>;\n\tsignal?: AbortSignal;\n};\n\nexport type MobileAuthTokens = {\n\taccessToken: string;\n\texpiresAt: number;\n\tidToken: string;\n\trefreshToken: string;\n\tscope: string[];\n\ttokenType: 'Bearer';\n};\n\nexport type MobileAuthUser = Record<string, unknown> & { sub: string };\n\nexport type MobileAuthPrincipal = {\n\tissuer: string;\n\tnamespace: string;\n\t/** Optional server-owned tenant/account partition from userinfo. */\n\tpartition?: string;\n\tsubject: string;\n};\n\nexport type MobileAuthErrorCode =\n\t| 'aborted'\n\t| 'callback'\n\t| 'discovery'\n\t| 'id-token'\n\t| 'network'\n\t| 'oauth'\n\t| 'origin'\n\t| 'secure-storage'\n\t| 'token';\n\nexport class MobileAuthError extends Error {\n\treadonly code: MobileAuthErrorCode;\n\treadonly cause?: unknown;\n\n\tconstructor(\n\t\tcode: MobileAuthErrorCode,\n\t\tmessage: string,\n\t\toptions?: { cause?: unknown }\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'MobileAuthError';\n\t\tthis.code = code;\n\t\tthis.cause = options?.cause;\n\t}\n}\n\ntype PendingAuthorization = {\n\tcreatedAt: number;\n\tnonce: string;\n\tstate: string;\n\tverifier: string;\n};\n\ntype TokenResponse = {\n\taccess_token: string;\n\texpires_in: number;\n\tid_token: string;\n\trefresh_token: string;\n\tscope?: string;\n\ttoken_type: string;\n};\n\ntype DeferredSignIn = {\n\treject: (error: unknown) => void;\n\tresolve: (tokens: MobileAuthTokens) => void;\n};\n\nconst PENDING_KEY = 'oidc.pending';\nconst REFRESH_KEY = 'oidc.refresh';\nconst DEFAULT_CLOCK_SKEW_MS = 30_000;\nconst PENDING_TTL_MS = 10 * 60_000;\nconst RANDOM_BYTES = 32;\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n\ttypeof value === 'object' && value !== null && !Array.isArray(value);\n\nconst base64Url = (value: Uint8Array) => {\n\tlet binary = '';\n\tfor (const byte of value) binary += String.fromCharCode(byte);\n\n\treturn btoa(binary)\n\t\t.replaceAll('+', '-')\n\t\t.replaceAll('/', '_')\n\t\t.replace(/=+$/u, '');\n};\n\nconst decodeBase64Url = (value: string) => {\n\tconst normalized = value.replaceAll('-', '+').replaceAll('_', '/');\n\tconst padded = normalized.padEnd(\n\t\tnormalized.length + ((4 - (normalized.length % 4)) % 4),\n\t\t'='\n\t);\n\tconst binary = atob(padded);\n\n\treturn Uint8Array.from(binary, (character) => character.charCodeAt(0));\n};\n\nconst webCrypto: MobileAuthCrypto = {\n\tdigestSha256: async (value) =>\n\t\tnew Uint8Array(\n\t\t\tawait globalThis.crypto.subtle.digest(\n\t\t\t\t'SHA-256',\n\t\t\t\tnew Uint8Array(value)\n\t\t\t)\n\t\t),\n\trandomBytes: (length) => {\n\t\tconst value = new Uint8Array(length);\n\t\tglobalThis.crypto.getRandomValues(value);\n\n\t\treturn value;\n\t},\n\tverifyEs256: async ({ data, jwk, signature }) => {\n\t\tconst key = await globalThis.crypto.subtle.importKey(\n\t\t\t'jwk',\n\t\t\tjwk,\n\t\t\t{ hash: 'SHA-256', name: 'ECDSA', namedCurve: 'P-256' },\n\t\t\tfalse,\n\t\t\t['verify']\n\t\t);\n\n\t\treturn globalThis.crypto.subtle.verify(\n\t\t\t{ hash: 'SHA-256', name: 'ECDSA' },\n\t\t\tkey,\n\t\t\tnew Uint8Array(signature),\n\t\t\tnew Uint8Array(data)\n\t\t);\n\t}\n};\n\nconst randomValue = (cryptoProvider: MobileAuthCrypto) =>\n\tbase64Url(cryptoProvider.randomBytes(RANDOM_BYTES));\n\nconst pkceChallenge = async (\n\tverifier: string,\n\tcryptoProvider: MobileAuthCrypto\n) =>\n\tbase64Url(\n\t\tawait cryptoProvider.digestSha256(new TextEncoder().encode(verifier))\n\t);\n\nconst normalizeIssuer = (value: string) => {\n\tconst issuer = new URL(value);\n\tconst loopback =\n\t\tissuer.protocol === 'http:' &&\n\t\t['127.0.0.1', '[::1]', 'localhost'].includes(issuer.hostname);\n\tif (issuer.protocol !== 'https:' && !loopback)\n\t\tthrow new TypeError('Mobile auth issuer must use HTTPS.');\n\tif (issuer.username || issuer.password || issuer.search || issuer.hash)\n\t\tthrow new TypeError(\n\t\t\t'Mobile auth issuer cannot contain credentials, query, or fragment.'\n\t\t);\n\tissuer.pathname = issuer.pathname.replace(/\\/$/u, '');\n\n\treturn issuer.href.replace(/\\/$/u, '');\n};\n\nconst exactRedirect = (actualValue: string, expectedValue: string) => {\n\tconst actual = new URL(actualValue);\n\tconst expected = new URL(expectedValue);\n\n\treturn (\n\t\tactual.protocol === expected.protocol &&\n\t\tactual.host === expected.host &&\n\t\tactual.pathname === expected.pathname &&\n\t\tactual.username === '' &&\n\t\tactual.password === ''\n\t);\n};\n\nconst parsePending = (value: string | null) => {\n\tif (value === null) return undefined;\n\ttry {\n\t\tconst parsed: unknown = JSON.parse(value);\n\t\tif (\n\t\t\t!isRecord(parsed) ||\n\t\t\ttypeof parsed.createdAt !== 'number' ||\n\t\t\ttypeof parsed.nonce !== 'string' ||\n\t\t\ttypeof parsed.state !== 'string' ||\n\t\t\ttypeof parsed.verifier !== 'string'\n\t\t)\n\t\t\treturn undefined;\n\n\t\treturn {\n\t\t\tcreatedAt: parsed.createdAt,\n\t\t\tnonce: parsed.nonce,\n\t\t\tstate: parsed.state,\n\t\t\tverifier: parsed.verifier\n\t\t} satisfies PendingAuthorization;\n\t} catch {\n\t\treturn undefined;\n\t}\n};\n\nconst parseTokenResponse = (value: unknown) => {\n\tif (\n\t\t!isRecord(value) ||\n\t\ttypeof value.access_token !== 'string' ||\n\t\ttypeof value.expires_in !== 'number' ||\n\t\t!Number.isFinite(value.expires_in) ||\n\t\tvalue.expires_in <= 0 ||\n\t\ttypeof value.id_token !== 'string' ||\n\t\ttypeof value.refresh_token !== 'string' ||\n\t\ttypeof value.token_type !== 'string'\n\t)\n\t\tthrow new MobileAuthError('token', 'The token response is malformed.');\n\tif (value.token_type.toLowerCase() !== 'bearer')\n\t\tthrow new MobileAuthError(\n\t\t\t'token',\n\t\t\t`Unsupported mobile token type ${value.token_type}; DPoP is not enabled for this client.`\n\t\t);\n\n\treturn {\n\t\taccess_token: value.access_token,\n\t\texpires_in: value.expires_in,\n\t\tid_token: value.id_token,\n\t\trefresh_token: value.refresh_token,\n\t\tscope: typeof value.scope === 'string' ? value.scope : undefined,\n\t\ttoken_type: value.token_type\n\t} satisfies TokenResponse;\n};\n\nconst responseBody = async (response: Response) => {\n\tconst text = await response.text();\n\ttry {\n\t\treturn JSON.parse(text);\n\t} catch {\n\t\treturn text;\n\t}\n};\n\nconst requireEndpoint = (value: unknown, name: string, issuer: string) => {\n\tif (typeof value !== 'string')\n\t\tthrow new MobileAuthError(\n\t\t\t'discovery',\n\t\t\t`OIDC discovery is missing ${name}.`\n\t\t);\n\tconst endpoint = new URL(value);\n\tif (endpoint.protocol !== 'https:' && new URL(issuer).protocol === 'https:')\n\t\tthrow new MobileAuthError(\n\t\t\t'discovery',\n\t\t\t`OIDC discovery ${name} must use HTTPS.`\n\t\t);\n\n\treturn endpoint.href;\n};\n\nconst parseDiscovery = (\n\tvalue: unknown,\n\tissuer: string\n): MobileAuthDiscovery => {\n\tif (!isRecord(value) || value.issuer !== issuer)\n\t\tthrow new MobileAuthError(\n\t\t\t'discovery',\n\t\t\t'OIDC discovery issuer does not match the configured issuer.'\n\t\t);\n\tconst methods = Array.isArray(value.code_challenge_methods_supported)\n\t\t? value.code_challenge_methods_supported.filter(\n\t\t\t\t(method): method is string => typeof method === 'string'\n\t\t\t)\n\t\t: undefined;\n\tif (!methods?.includes('S256'))\n\t\tthrow new MobileAuthError(\n\t\t\t'discovery',\n\t\t\t'OIDC provider does not advertise S256 PKCE.'\n\t\t);\n\tconst authMethods = Array.isArray(\n\t\tvalue.token_endpoint_auth_methods_supported\n\t)\n\t\t? value.token_endpoint_auth_methods_supported.filter(\n\t\t\t\t(method): method is string => typeof method === 'string'\n\t\t\t)\n\t\t: undefined;\n\tif (!authMethods?.includes('none'))\n\t\tthrow new MobileAuthError(\n\t\t\t'discovery',\n\t\t\t'OIDC provider does not accept public clients at the token endpoint.'\n\t\t);\n\n\treturn {\n\t\tauthorization_endpoint: requireEndpoint(\n\t\t\tvalue.authorization_endpoint,\n\t\t\t'authorization_endpoint',\n\t\t\tissuer\n\t\t),\n\t\tcode_challenge_methods_supported: methods,\n\t\tissuer,\n\t\tjwks_uri: requireEndpoint(value.jwks_uri, 'jwks_uri', issuer),\n\t\trevocation_endpoint:\n\t\t\ttypeof value.revocation_endpoint === 'string'\n\t\t\t\t? requireEndpoint(\n\t\t\t\t\t\tvalue.revocation_endpoint,\n\t\t\t\t\t\t'revocation_endpoint',\n\t\t\t\t\t\tissuer\n\t\t\t\t\t)\n\t\t\t\t: undefined,\n\t\tsocket_ticket_endpoint:\n\t\t\ttypeof value.socket_ticket_endpoint === 'string'\n\t\t\t\t? requireEndpoint(\n\t\t\t\t\t\tvalue.socket_ticket_endpoint,\n\t\t\t\t\t\t'socket_ticket_endpoint',\n\t\t\t\t\t\tissuer\n\t\t\t\t\t)\n\t\t\t\t: undefined,\n\t\ttoken_endpoint: requireEndpoint(\n\t\t\tvalue.token_endpoint,\n\t\t\t'token_endpoint',\n\t\t\tissuer\n\t\t),\n\t\ttoken_endpoint_auth_methods_supported: authMethods,\n\t\tuserinfo_endpoint: requireEndpoint(\n\t\t\tvalue.userinfo_endpoint,\n\t\t\t'userinfo_endpoint',\n\t\t\tissuer\n\t\t)\n\t};\n};\n\nconst verifyIdToken = async ({\n\tclientId,\n\tcryptoProvider,\n\tfetchImpl,\n\tidToken,\n\tissuer,\n\tjwksUri,\n\tnonce,\n\tnow\n}: {\n\tclientId: string;\n\tcryptoProvider: MobileAuthCrypto;\n\tfetchImpl: typeof globalThis.fetch;\n\tidToken: string;\n\tissuer: string;\n\tjwksUri: string;\n\tnonce: string;\n\tnow: number;\n}) => {\n\tconst [encodedHeader, encodedPayload, encodedSignature, ...extra] =\n\t\tidToken.split('.');\n\tif (!encodedHeader || !encodedPayload || !encodedSignature || extra.length)\n\t\tthrow new MobileAuthError('id-token', 'The ID token is malformed.');\n\tlet header: unknown;\n\tlet payload: unknown;\n\ttry {\n\t\theader = JSON.parse(\n\t\t\tnew TextDecoder().decode(decodeBase64Url(encodedHeader))\n\t\t);\n\t\tpayload = JSON.parse(\n\t\t\tnew TextDecoder().decode(decodeBase64Url(encodedPayload))\n\t\t);\n\t} catch (cause) {\n\t\tthrow new MobileAuthError('id-token', 'The ID token is malformed.', {\n\t\t\tcause\n\t\t});\n\t}\n\tif (\n\t\t!isRecord(header) ||\n\t\theader.alg !== 'ES256' ||\n\t\ttypeof header.kid !== 'string' ||\n\t\t!isRecord(payload)\n\t)\n\t\tthrow new MobileAuthError(\n\t\t\t'id-token',\n\t\t\t'The ID token header or claims are invalid.'\n\t\t);\n\tconst response = await fetchImpl(jwksUri, { cache: 'no-store' });\n\tif (!response.ok)\n\t\tthrow new MobileAuthError(\n\t\t\t'network',\n\t\t\t'Unable to fetch OIDC signing keys.'\n\t\t);\n\tconst body: unknown = await response.json();\n\tconst keys = isRecord(body) && Array.isArray(body.keys) ? body.keys : [];\n\tconst jwk = keys.find(\n\t\t(candidate): candidate is JsonWebKey & { kid: string } =>\n\t\t\tisRecord(candidate) && candidate.kid === header.kid\n\t);\n\tif (!jwk)\n\t\tthrow new MobileAuthError(\n\t\t\t'id-token',\n\t\t\t'The ID token signing key is unknown.'\n\t\t);\n\tconst valid = await cryptoProvider.verifyEs256({\n\t\tdata: new TextEncoder().encode(`${encodedHeader}.${encodedPayload}`),\n\t\tjwk,\n\t\tsignature: decodeBase64Url(encodedSignature)\n\t});\n\tconst audience = payload.aud;\n\tif (\n\t\t!valid ||\n\t\tpayload.iss !== issuer ||\n\t\t!(\n\t\t\taudience === clientId ||\n\t\t\t(Array.isArray(audience) && audience.includes(clientId))\n\t\t) ||\n\t\tpayload.nonce !== nonce ||\n\t\ttypeof payload.exp !== 'number' ||\n\t\tpayload.exp * 1000 <= now\n\t)\n\t\tthrow new MobileAuthError(\n\t\t\t'id-token',\n\t\t\t'The ID token signature or claims are invalid.'\n\t\t);\n};\n\nexport const createMobileAuthClient = (config: MobileAuthClientConfig) => {\n\tconst issuer = normalizeIssuer(config.issuer);\n\tconst redirectUri = new URL(config.redirectUri).href;\n\tconst fetchImpl = config.fetch ?? globalThis.fetch;\n\tconst cryptoProvider = config.crypto ?? webCrypto;\n\tconst now = config.now ?? Date.now;\n\tconst clockSkewMs = config.clockSkewMs ?? DEFAULT_CLOCK_SKEW_MS;\n\tconst scopes = [...new Set(config.scopes ?? ['openid', 'profile'])];\n\tconst resource = config.resource ?? issuer;\n\tif (!scopes.includes('openid')) scopes.unshift('openid');\n\tconst allowedOrigins = new Set(\n\t\t(config.allowedOrigins ?? [new URL(issuer).origin]).map(\n\t\t\t(value) => new URL(value).origin\n\t\t)\n\t);\n\tlet discoveryPromise: Promise<MobileAuthDiscovery> | undefined;\n\tlet access: Omit<MobileAuthTokens, 'refreshToken'> | undefined;\n\tlet refreshPromise: Promise<string> | undefined;\n\tlet stopLinks: (() => Promise<void> | void) | undefined;\n\tlet stopResume: (() => Promise<void> | void) | undefined;\n\tlet startPromise: Promise<void> | undefined;\n\tconst pendingSignIns = new Map<string, DeferredSignIn>();\n\tlet currentPrincipal: MobileAuthPrincipal | null | undefined;\n\tconst principalListeners = new Set<\n\t\t(principal: MobileAuthPrincipal | null) => void\n\t>();\n\tconst publishPrincipal = (principal: MobileAuthPrincipal | null) => {\n\t\tif (\n\t\t\tcurrentPrincipal !== undefined &&\n\t\t\tcurrentPrincipal?.namespace === principal?.namespace\n\t\t)\n\t\t\treturn;\n\t\tcurrentPrincipal = principal;\n\t\tfor (const listener of principalListeners) listener(principal);\n\t};\n\tconst principalFor = async (\n\t\tuser: MobileAuthUser\n\t): Promise<MobileAuthPrincipal> => {\n\t\tconst partition = readAuthSyncPartition(user);\n\n\t\treturn {\n\t\t\tissuer,\n\t\t\tnamespace: await deriveAuthSyncNamespace({\n\t\t\t\tclientId: config.clientId,\n\t\t\t\tdigestSha256: cryptoProvider.digestSha256,\n\t\t\t\tissuer,\n\t\t\t\tpartition,\n\t\t\t\tsubject: user.sub\n\t\t\t}),\n\t\t\t...(partition === undefined ? {} : { partition }),\n\t\t\tsubject: user.sub\n\t\t};\n\t};\n\n\tconst fetchDiscovery = async () => {\n\t\tconst url = new URL('/.well-known/openid-configuration', `${issuer}/`);\n\t\tconst response = await fetchImpl(url, {\n\t\t\tcache: 'no-store',\n\t\t\theaders: { accept: 'application/json' }\n\t\t});\n\t\tif (!response.ok)\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'discovery',\n\t\t\t\t`OIDC discovery failed with HTTP ${response.status}.`\n\t\t\t);\n\n\t\treturn parseDiscovery(await response.json(), issuer);\n\t};\n\n\tconst discovery = () => {\n\t\tdiscoveryPromise ??= fetchDiscovery();\n\n\t\treturn discoveryPromise;\n\t};\n\n\tconst assertSecureStorage = async () => {\n\t\tconst capability = await config.storage.capability?.();\n\t\tif (capability && !capability.available)\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'secure-storage',\n\t\t\t\tcapability.message ??\n\t\t\t\t\t'Native secure credential storage is unavailable.'\n\t\t\t);\n\t};\n\n\tconst tokenRequest = async (\n\t\tmetadata: MobileAuthDiscovery,\n\t\tbody: URLSearchParams,\n\t\tnonce?: string\n\t) => {\n\t\tlet response: Response;\n\t\ttry {\n\t\t\tresponse = await fetchImpl(metadata.token_endpoint, {\n\t\t\t\tbody,\n\t\t\t\tcredentials: 'omit',\n\t\t\t\theaders: {\n\t\t\t\t\taccept: 'application/json',\n\t\t\t\t\t'content-type': 'application/x-www-form-urlencoded'\n\t\t\t\t},\n\t\t\t\tmethod: 'POST'\n\t\t\t});\n\t\t} catch (cause) {\n\t\t\tthrow new MobileAuthError('network', 'The token request failed.', {\n\t\t\t\tcause\n\t\t\t});\n\t\t}\n\t\tconst value = await responseBody(response);\n\t\tif (!response.ok) {\n\t\t\tconst oauthCode =\n\t\t\t\tisRecord(value) && typeof value.error === 'string'\n\t\t\t\t\t? value.error\n\t\t\t\t\t: `HTTP ${response.status}`;\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'oauth',\n\t\t\t\t`The authorization server rejected the token request (${oauthCode}).`\n\t\t\t);\n\t\t}\n\t\tconst tokens = parseTokenResponse(value);\n\t\tif (nonce)\n\t\t\tawait verifyIdToken({\n\t\t\t\tclientId: config.clientId,\n\t\t\t\tcryptoProvider,\n\t\t\t\tfetchImpl,\n\t\t\t\tidToken: tokens.id_token,\n\t\t\t\tissuer,\n\t\t\t\tjwksUri: metadata.jwks_uri,\n\t\t\t\tnonce,\n\t\t\t\tnow: now()\n\t\t\t});\n\n\t\treturn tokens;\n\t};\n\n\tconst acceptTokens = async (\n\t\ttokens: TokenResponse\n\t): Promise<MobileAuthTokens> => {\n\t\ttry {\n\t\t\tawait config.storage.set(REFRESH_KEY, tokens.refresh_token);\n\t\t} catch (cause) {\n\t\t\taccess = undefined;\n\t\t\tawait config.storage.remove(REFRESH_KEY).catch(() => undefined);\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'secure-storage',\n\t\t\t\t'The rotated refresh credential could not be saved securely.',\n\t\t\t\t{ cause }\n\t\t\t);\n\t\t}\n\t\taccess = {\n\t\t\taccessToken: tokens.access_token,\n\t\t\texpiresAt: now() + tokens.expires_in * 1000,\n\t\t\tidToken: tokens.id_token,\n\t\t\tscope: tokens.scope?.split(' ').filter(Boolean) ?? scopes,\n\t\t\ttokenType: 'Bearer'\n\t\t};\n\n\t\treturn { ...access, refreshToken: tokens.refresh_token };\n\t};\n\n\tconst rotateAccessToken = async () => {\n\t\tawait assertSecureStorage();\n\t\tconst exchange = async () => {\n\t\t\tconst refreshToken = await config.storage.get(REFRESH_KEY);\n\t\t\tif (!refreshToken)\n\t\t\t\tthrow new MobileAuthError(\n\t\t\t\t\t'token',\n\t\t\t\t\t'This app has no renewable mobile session.'\n\t\t\t\t);\n\t\t\tconst metadata = await discovery();\n\t\t\tconst body = new URLSearchParams({\n\t\t\t\tclient_id: config.clientId,\n\t\t\t\tgrant_type: 'refresh_token',\n\t\t\t\trefresh_token: refreshToken\n\t\t\t});\n\t\t\tbody.set('resource', resource);\n\t\t\tconst tokens = await tokenRequest(metadata, body);\n\n\t\t\treturn (await acceptTokens(tokens)).accessToken;\n\t\t};\n\n\t\treturn config.storage.withLock\n\t\t\t? config.storage.withLock(REFRESH_KEY, exchange)\n\t\t\t: exchange();\n\t};\n\n\tconst refreshAccessToken = async () => {\n\t\tif (access && access.expiresAt - clockSkewMs > now())\n\t\t\treturn access.accessToken;\n\t\tif (refreshPromise) return refreshPromise;\n\t\trefreshPromise = rotateAccessToken().finally(() => {\n\t\t\trefreshPromise = undefined;\n\t\t});\n\n\t\treturn refreshPromise;\n\t};\n\n\tconst handleCallback = async (value: string) => {\n\t\tif (!exactRedirect(value, redirectUri))\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'callback',\n\t\t\t\t'The authorization callback does not match this app registration.'\n\t\t\t);\n\t\tconst url = new URL(value);\n\t\tconst pending = parsePending(await config.storage.get(PENDING_KEY));\n\t\tif (!pending || now() - pending.createdAt > PENDING_TTL_MS) {\n\t\t\tawait config.storage.remove(PENDING_KEY).catch(() => undefined);\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'callback',\n\t\t\t\t'The authorization transaction is missing or expired.'\n\t\t\t);\n\t\t}\n\t\tconst deferred = pendingSignIns.get(pending.state);\n\t\tconst reject = (error: unknown) => {\n\t\t\tpendingSignIns.delete(pending.state);\n\t\t\tvoid config.storage.remove(PENDING_KEY);\n\t\t\tdeferred?.reject(error);\n\t\t\tthrow error;\n\t\t};\n\t\tif (url.searchParams.get('state') !== pending.state)\n\t\t\treturn reject(\n\t\t\t\tnew MobileAuthError(\n\t\t\t\t\t'callback',\n\t\t\t\t\t'The authorization callback state does not match.'\n\t\t\t\t)\n\t\t\t);\n\t\tif (url.searchParams.get('iss') !== issuer)\n\t\t\treturn reject(\n\t\t\t\tnew MobileAuthError(\n\t\t\t\t\t'callback',\n\t\t\t\t\t'The authorization callback issuer does not match.'\n\t\t\t\t)\n\t\t\t);\n\t\tconst oauthError = url.searchParams.get('error');\n\t\tif (oauthError) {\n\t\t\tawait config.storage.remove(PENDING_KEY);\n\n\t\t\treturn reject(\n\t\t\t\tnew MobileAuthError(\n\t\t\t\t\t'oauth',\n\t\t\t\t\t`Authorization failed (${oauthError}).`\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\t\tconst code = url.searchParams.get('code');\n\t\tif (!code)\n\t\t\treturn reject(\n\t\t\t\tnew MobileAuthError(\n\t\t\t\t\t'callback',\n\t\t\t\t\t'The authorization callback contains no code.'\n\t\t\t\t)\n\t\t\t);\n\t\tawait config.storage.remove(PENDING_KEY);\n\t\ttry {\n\t\t\tconst metadata = await discovery();\n\t\t\tconst body = new URLSearchParams({\n\t\t\t\tclient_id: config.clientId,\n\t\t\t\tcode,\n\t\t\t\tcode_verifier: pending.verifier,\n\t\t\t\tgrant_type: 'authorization_code',\n\t\t\t\tredirect_uri: redirectUri\n\t\t\t});\n\t\t\tbody.set('resource', resource);\n\t\t\tconst tokens = await acceptTokens(\n\t\t\t\tawait tokenRequest(metadata, body, pending.nonce)\n\t\t\t);\n\t\t\tpendingSignIns.delete(pending.state);\n\t\t\tdeferred?.resolve(tokens);\n\n\t\t\treturn tokens;\n\t\t} catch (error) {\n\t\t\treturn reject(error);\n\t\t}\n\t};\n\n\tconst initialize = async () => {\n\t\tawait assertSecureStorage();\n\t\tstopLinks = await config.links.onOpen((url) => {\n\t\t\tif (exactRedirect(url, redirectUri))\n\t\t\t\tvoid handleCallback(url).catch(() => undefined);\n\t\t});\n\t\tif (config.lifecycle?.onResume)\n\t\t\tstopResume = await config.lifecycle.onResume(() => {\n\t\t\t\tvoid refreshAccessToken().catch(() => undefined);\n\t\t\t});\n\t\tconst launchUrl = await config.links.getLaunchUrl();\n\t\tif (launchUrl && exactRedirect(launchUrl, redirectUri))\n\t\t\tawait handleCallback(launchUrl);\n\t};\n\n\tconst start = () => {\n\t\tstartPromise ??= initialize();\n\n\t\treturn startPromise;\n\t};\n\n\tconst signIn = async (options: MobileAuthSignInOptions = {}) => {\n\t\tawait start();\n\t\tif (options.signal?.aborted)\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'aborted',\n\t\t\t\t'Authorization was cancelled.'\n\t\t\t);\n\t\tconst metadata = await discovery();\n\t\tconst pending: PendingAuthorization = {\n\t\t\tcreatedAt: now(),\n\t\t\tnonce: randomValue(cryptoProvider),\n\t\t\tstate: randomValue(cryptoProvider),\n\t\t\tverifier: randomValue(cryptoProvider)\n\t\t};\n\t\tawait config.storage.set(PENDING_KEY, JSON.stringify(pending));\n\t\tconst url = new URL(metadata.authorization_endpoint);\n\t\turl.search = new URLSearchParams({\n\t\t\tclient_id: config.clientId,\n\t\t\tcode_challenge: await pkceChallenge(\n\t\t\t\tpending.verifier,\n\t\t\t\tcryptoProvider\n\t\t\t),\n\t\t\tcode_challenge_method: 'S256',\n\t\t\tnonce: pending.nonce,\n\t\t\tredirect_uri: redirectUri,\n\t\t\tresponse_type: 'code',\n\t\t\tscope: scopes.join(' '),\n\t\t\tstate: pending.state,\n\t\t\t...options.authorizationParameters\n\t\t}).toString();\n\t\turl.searchParams.set('resource', resource);\n\t\tconst result = new Promise<MobileAuthTokens>((resolve, reject) => {\n\t\t\tpendingSignIns.set(pending.state, { reject, resolve });\n\t\t\toptions.signal?.addEventListener(\n\t\t\t\t'abort',\n\t\t\t\t() => {\n\t\t\t\t\tpendingSignIns.delete(pending.state);\n\t\t\t\t\tvoid config.storage.remove(PENDING_KEY);\n\t\t\t\t\treject(\n\t\t\t\t\t\tnew MobileAuthError(\n\t\t\t\t\t\t\t'aborted',\n\t\t\t\t\t\t\t'Authorization was cancelled.'\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\t{ once: true }\n\t\t\t);\n\t\t});\n\t\ttry {\n\t\t\tawait config.links.openExternal(url.href);\n\t\t} catch (error) {\n\t\t\tpendingSignIns.delete(pending.state);\n\t\t\tawait config.storage.remove(PENDING_KEY);\n\t\t\tthrow error;\n\t\t}\n\n\t\treturn result;\n\t};\n\n\tconst authenticatedFetch = async (\n\t\tinput: RequestInfo | URL,\n\t\tinit?: RequestInit\n\t) => {\n\t\tconst original = new Request(input, init);\n\t\tif (!allowedOrigins.has(new URL(original.url).origin))\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'origin',\n\t\t\t\t'Mobile auth refused to send a credential to an unregistered origin.'\n\t\t\t);\n\t\tconst send = async (forceRefresh: boolean) => {\n\t\t\tif (forceRefresh) access = undefined;\n\t\t\tconst token = await refreshAccessToken();\n\t\t\tconst request = original.clone();\n\t\t\tconst headers = new Headers(request.headers);\n\t\t\theaders.set('authorization', `Bearer ${token}`);\n\n\t\t\treturn fetchImpl(\n\t\t\t\tnew Request(request, { credentials: 'omit', headers })\n\t\t\t);\n\t\t};\n\t\tconst response = await send(false);\n\n\t\treturn response.status === 401 ? send(true) : response;\n\t};\n\n\tconst optionalAuthenticatedFetch = async (\n\t\tinput: RequestInfo | URL,\n\t\tinit?: RequestInit\n\t) => {\n\t\tconst request = new Request(input, init);\n\t\tif (!allowedOrigins.has(new URL(request.url).origin))\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'origin',\n\t\t\t\t'Mobile auth refused to send a request outside an allowed origin.'\n\t\t\t);\n\t\tconst refreshToken = await config.storage.get(REFRESH_KEY);\n\t\tif (access || refreshToken) return authenticatedFetch(request);\n\n\t\treturn fetchImpl(new Request(request, { credentials: 'omit' }));\n\t};\n\tconst signedOut = () => {\n\t\tpublishPrincipal(null);\n\n\t\treturn null;\n\t};\n\n\tconst status = async () => {\n\t\ttry {\n\t\t\tconst metadata = await discovery();\n\t\t\tconst response = await authenticatedFetch(\n\t\t\t\tmetadata.userinfo_endpoint\n\t\t\t);\n\t\t\tif (response.status === 401) return signedOut();\n\t\t\tif (!response.ok)\n\t\t\t\tthrow new MobileAuthError(\n\t\t\t\t\t'network',\n\t\t\t\t\t`User info failed with HTTP ${response.status}.`\n\t\t\t\t);\n\t\t\tconst user: unknown = await response.json();\n\t\t\tif (!isRecord(user) || typeof user.sub !== 'string')\n\t\t\t\tthrow new MobileAuthError(\n\t\t\t\t\t'token',\n\t\t\t\t\t'The user-info response is malformed.'\n\t\t\t\t);\n\n\t\t\tconst normalized = {\n\t\t\t\t...user,\n\t\t\t\tsub: user.sub\n\t\t\t} satisfies MobileAuthUser;\n\t\t\tpublishPrincipal(await principalFor(normalized));\n\n\t\t\treturn normalized;\n\t\t} catch (error) {\n\t\t\tif (\n\t\t\t\t!(\n\t\t\t\t\terror instanceof MobileAuthError &&\n\t\t\t\t\t(error.code === 'oauth' || error.code === 'token')\n\t\t\t\t)\n\t\t\t)\n\t\t\t\tthrow error;\n\n\t\t\treturn signedOut();\n\t\t}\n\t};\n\n\tconst socketTicket = async (audience = resource) => {\n\t\tconst metadata = await discovery();\n\t\tif (!metadata.socket_ticket_endpoint)\n\t\t\tthrow new MobileAuthError(\n\t\t\t\t'discovery',\n\t\t\t\t'The authorization server does not advertise WebSocket tickets.'\n\t\t\t);\n\t\tconst response = await authenticatedFetch(\n\t\t\tmetadata.socket_ticket_endpoint,\n\t\t\t{\n\t\t\t\tbody: JSON.stringify({ audience }),\n\t\t\t\theaders: { 'content-type': 'application/json' },\n\t\t\t\tmethod: 'POST'\n\t\t\t}\n\t\t);\n\t\tconst body: unknown = await responseBody(response);\n\t\tif (!response.ok || !isRecord(body) || typeof body.ticket !== 'string')\n\t\t\tthrow new MobileAuthError(\n\t\t\t\tresponse.ok ? 'token' : 'oauth',\n\t\t\t\t`WebSocket ticket request failed with HTTP ${response.status}.`\n\t\t\t);\n\n\t\treturn body.ticket;\n\t};\n\n\tconst revokeRefreshToken = async (refreshToken: string) => {\n\t\tconst metadata = await discovery();\n\t\tif (metadata.revocation_endpoint)\n\t\t\tawait fetchImpl(metadata.revocation_endpoint, {\n\t\t\t\tbody: new URLSearchParams({\n\t\t\t\t\tclient_id: config.clientId,\n\t\t\t\t\ttoken: refreshToken,\n\t\t\t\t\ttoken_type_hint: 'refresh_token'\n\t\t\t\t}),\n\t\t\t\tcredentials: 'omit',\n\t\t\t\theaders: {\n\t\t\t\t\t'content-type': 'application/x-www-form-urlencoded'\n\t\t\t\t},\n\t\t\t\tmethod: 'POST'\n\t\t\t});\n\t};\n\tconst runBeforeSignOut = async () => {\n\t\ttry {\n\t\t\tawait config.beforeSignOut?.();\n\t\t} catch {\n\t\t\t// Sign-out must remain available. Native integrations fail closed\n\t\t\t// locally and stale provider registrations retire on send.\n\t\t}\n\t};\n\n\tconst signOut = async () => {\n\t\tconst refreshToken = await config.storage.get(REFRESH_KEY);\n\t\ttry {\n\t\t\tawait runBeforeSignOut();\n\t\t\tif (refreshToken) await revokeRefreshToken(refreshToken);\n\t\t} finally {\n\t\t\taccess = undefined;\n\t\t\tawait Promise.all([\n\t\t\t\tconfig.storage.remove(PENDING_KEY),\n\t\t\t\tconfig.storage.remove(REFRESH_KEY)\n\t\t\t]);\n\t\t\tpublishPrincipal(null);\n\t\t}\n\t};\n\n\tconst principal = async () => {\n\t\tawait status();\n\n\t\treturn currentPrincipal ?? null;\n\t};\n\n\tconst onPrincipalChange = (\n\t\tlistener: (principal: MobileAuthPrincipal | null) => void\n\t) => {\n\t\tprincipalListeners.add(listener);\n\t\tif (currentPrincipal !== undefined) listener(currentPrincipal);\n\n\t\treturn () => {\n\t\t\tprincipalListeners.delete(listener);\n\t\t};\n\t};\n\n\tconst stop = async () => {\n\t\tawait Promise.all([stopLinks?.(), stopResume?.()]);\n\t\tstopLinks = undefined;\n\t\tstopResume = undefined;\n\t\tstartPromise = undefined;\n\t};\n\n\treturn {\n\t\tfetch: authenticatedFetch,\n\t\tfetchOptional: optionalAuthenticatedFetch,\n\t\thandleCallback,\n\t\tonPrincipalChange,\n\t\tprincipal,\n\t\trefresh: refreshAccessToken,\n\t\tsignIn,\n\t\tsignOut,\n\t\tsocketTicket,\n\t\tstart,\n\t\tstatus,\n\t\tstop\n\t};\n};\n\nexport type MobileAuthClient = ReturnType<typeof createMobileAuthClient>;\n\n/** Adapts the native OAuth lifecycle behind the same createAuthClient API used\n * by web applications. Passwords stay out of the WebView request path; the\n * external authorization UI owns credential entry and MFA. */\nexport const createMobileAuthTransport = (\n\tclient: MobileAuthClient,\n\toptions: { baseUrl?: string } = {}\n): import('./createAuthClient').AuthClientTransport => ({\n\tfetch: (input, init) => {\n\t\tconst resolved =\n\t\t\toptions.baseUrl &&\n\t\t\t(typeof input === 'string' || input instanceof URL)\n\t\t\t\t? new URL(String(input), options.baseUrl)\n\t\t\t\t: input;\n\n\t\treturn client.fetchOptional(resolved, init);\n\t},\n\tsignInEmail: async ({ email }) => {\n\t\tawait client.signIn({\n\t\t\tauthorizationParameters: { login_hint: email }\n\t\t});\n\n\t\treturn { status: 'authenticated' };\n\t},\n\tsignOut: async () => {\n\t\tawait client.signOut();\n\n\t\treturn null;\n\t},\n\tsignUpEmail: async ({ email }) => {\n\t\tawait client.signIn({\n\t\t\tauthorizationParameters: {\n\t\t\t\tlogin_hint: email,\n\t\t\t\tscreen_hint: 'signup'\n\t\t\t}\n\t\t});\n\n\t\treturn { status: 'authenticated' };\n\t},\n\tstatus: async () => {\n\t\tconst user = await client.status();\n\n\t\treturn { user };\n\t}\n});\n\nexport { installAuthClientRuntimeTransport } from './runtimeTransport';\n"
|
|
8
8
|
],
|
|
9
|
-
"mappings": "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",
|
|
10
|
-
"debugId": "
|
|
9
|
+
"mappings": "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",
|
|
10
|
+
"debugId": "133719A26A0DF6AA64756E2164756E21",
|
|
11
11
|
"names": []
|
|
12
12
|
}
|
package/dist/index.js
CHANGED
|
@@ -4836,14 +4836,15 @@ var base64Url2 = (value) => {
|
|
|
4836
4836
|
};
|
|
4837
4837
|
var deriveAuthSyncNamespace = async ({
|
|
4838
4838
|
clientId,
|
|
4839
|
+
digestSha256 = async (value) => new Uint8Array(await crypto.subtle.digest("SHA-256", new Uint8Array(value))),
|
|
4839
4840
|
issuer,
|
|
4840
4841
|
partition,
|
|
4841
4842
|
subject
|
|
4842
4843
|
}) => {
|
|
4843
4844
|
if (clientId.length === 0 || issuer.length === 0 || subject.length === 0)
|
|
4844
4845
|
throw new TypeError("Auth Sync namespace requires issuer, clientId, and subject.");
|
|
4845
|
-
const digest = await
|
|
4846
|
-
return `auth:v1:${base64Url2(
|
|
4846
|
+
const digest = await digestSha256(new TextEncoder().encode(JSON.stringify([issuer, clientId, subject, partition ?? null])));
|
|
4847
|
+
return `auth:v1:${base64Url2(digest)}`;
|
|
4847
4848
|
};
|
|
4848
4849
|
var readAuthSyncPartition = (user) => {
|
|
4849
4850
|
if (typeof user !== "object" || user === null)
|
|
@@ -41422,5 +41423,5 @@ export {
|
|
|
41422
41423
|
writeWarrant
|
|
41423
41424
|
};
|
|
41424
41425
|
|
|
41425
|
-
//# debugId=
|
|
41426
|
+
//# debugId=B86263B79140DD5464756E2164756E21
|
|
41426
41427
|
//# sourceMappingURL=index.js.map
|