@icp-sdk/auth 7.1.0 → 8.0.1

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.
@@ -53,6 +53,29 @@ export interface AuthClientCreateOptions {
53
53
  * @example "toolbar=0,location=0,menubar=0,width=500,height=500,left=100,top=100"
54
54
  */
55
55
  windowOpenerFeatures?: string;
56
+ /**
57
+ * How the client communicates with the identity provider.
58
+ *
59
+ * - `'window'` (default) — the identity provider opens in a separate browser
60
+ * tab or window (a popup when {@link windowOpenerFeatures} is set) and
61
+ * communicates over the ICRC-29 `postMessage` transport.
62
+ * - `'redirect'` — the current page navigates to the identity provider over
63
+ * the ICRC-167 URL transport, which returns to this same page. The callback
64
+ * URL is the current page's URL (`location.origin + location.pathname`), so
65
+ * that page must be on an origin you control and declared in that origin's
66
+ * `/.well-known/ii-auth-callbacks` allow-list. Use it for full-page sign-in
67
+ * that shouldn't need a user gesture to open a window (e.g. redirecting on a
68
+ * restricted route), or native apps handing off via universal links.
69
+ *
70
+ * With `'redirect'` the page unloads on each step and the flow re-runs on the
71
+ * return load, so call `signIn` / `requestAttributes` directly on the page's
72
+ * load (not deferred behind, say, a click handler): a fresh visit starts the
73
+ * flow and the identity provider's return replays it to completion. Give each
74
+ * flow its own route so its persisted state stays isolated.
75
+ * @default 'window'
76
+ * @see https://github.com/dfinity/wg-identity-authentication/blob/main/topics/icrc_167_browser_url_transport.md
77
+ */
78
+ transport?: 'window' | 'redirect';
56
79
  /**
57
80
  * OpenID provider for one-click sign-in. When set, the identity provider
58
81
  * URL includes an `openid` search param so the user authenticates via
@@ -132,24 +155,69 @@ export declare class AuthClient {
132
155
  /**
133
156
  * Requests signed identity attributes from the identity provider.
134
157
  *
135
- * The `nonce` may be a `Uint8Array` or a `Promise<Uint8Array>`. Passing a
136
- * promise lets the identity provider window open while the nonce (typically
137
- * fetched from the RP canister) is still being resolved, avoiding a perceived
138
- * delay before the user sees the prompt. Auto-close of the signer transport
139
- * channel is temporarily disabled while awaiting the promise so the window
140
- * cannot be closed out from under the pending flow.
158
+ * The `nonce` is a callback that produces the 32-byte nonce (typically
159
+ * fetched from the RP canister), returning a promise resolving to it. It is a
160
+ * callback rather than a value so the redirect flow can journal the nonce and
161
+ * reuse the exact same bytes when the flow replays on the return load,
162
+ * instead of fetching a fresh single-use nonce that the signer never signed
163
+ * against.
164
+ *
165
+ * In 'window' mode the callback lets the identity provider window open while the
166
+ * nonce is still resolving, avoiding a perceived delay before the user sees
167
+ * the prompt; auto-close of the signer transport channel is temporarily
168
+ * disabled while awaiting so the window cannot be closed out from under the
169
+ * pending flow.
141
170
  *
142
171
  * @param params - Request parameters.
143
172
  * @param params.keys - Attribute keys to request (e.g. `['email', 'name']`).
144
- * @param params.nonce - 32-byte nonce issued by the RP canister, or a promise
145
- * resolving to one.
173
+ * @param params.nonce - Produces the 32-byte nonce issued by the RP canister,
174
+ * as a promise resolving to it.
146
175
  * @returns Signed attribute data and signature.
147
176
  * @throws When the identity provider returns an error or an invalid response.
148
177
  */
149
178
  requestAttributes(params: {
150
179
  keys: string[];
151
- nonce: Uint8Array | Promise<Uint8Array>;
180
+ nonce: () => Promise<Uint8Array>;
152
181
  }): Promise<SignedAttributes>;
182
+ /**
183
+ * Runs and journals a piece of your own async work so its result stays stable
184
+ * across the `'redirect'` flow.
185
+ *
186
+ * In `'redirect'` mode the page unloads on each step and `signIn` /
187
+ * `requestAttributes` re-run on the return load, so a value you compute on the
188
+ * first visit (from `location`, a fetch, `crypto`, …) would otherwise be
189
+ * recomputed — and may differ — on the return. Wrap it in `memoize`: it runs
190
+ * `produce` once on the first visit, journals the result, and replays that
191
+ * result on the return load instead of re-running. Use it for a value the
192
+ * post-flow code depends on, e.g. the URL to navigate to once sign-in
193
+ * completes:
194
+ *
195
+ * ```ts
196
+ * const next = await authClient.memoize(
197
+ * () => new URLSearchParams(location.search).get('next') ?? '/',
198
+ * );
199
+ * await authClient.signIn();
200
+ * location.assign(next); // the value captured before the redirect
201
+ * ```
202
+ *
203
+ * Call `memoize` in a stable order relative to `signIn` / `requestAttributes`
204
+ * across loads (same order every load — branch only on values recovered from
205
+ * earlier results), and keep the result JSON-serializable, since the journal
206
+ * is JSON.
207
+ *
208
+ * In `'window'` mode there is no redirect, so this simply runs `produce` and
209
+ * returns its result without persisting anything.
210
+ *
211
+ * Mirrors the producer's shape: a synchronous `produce` returns its value
212
+ * directly, an asynchronous one returns a promise. Awaiting the result is
213
+ * always safe (`await` on a non-promise is a no-op); the synchronous form lets
214
+ * a value be memoized where an `await` is not possible, such as in a
215
+ * constructor.
216
+ * @param produce - Produces the value to journal on the first load.
217
+ * @returns The produced value, or the journaled value on a replay load.
218
+ */
219
+ memoize<T>(produce: () => Promise<T>): Promise<T>;
220
+ memoize<T>(produce: () => T): T;
153
221
  /**
154
222
  * Clears the stored session and resets the client to an anonymous state.
155
223
  *
@@ -1,7 +1,7 @@
1
1
  import { AnonymousIdentity } from '@icp-sdk/core/agent';
2
2
  import { DelegationChain, DelegationIdentity, ECDSAKeyIdentity, Ed25519KeyIdentity, isDelegationValid, PartialDelegationIdentity, } from '@icp-sdk/core/identity';
3
3
  import { Signer } from '@icp-sdk/signer';
4
- import { PostMessageTransport } from '@icp-sdk/signer/web';
4
+ import { PostMessageTransport, UrlTransport } from '@icp-sdk/signer/web';
5
5
  import { IdleManager } from './idle-manager.js';
6
6
  import { IdbStorage, KEY_STORAGE_DELEGATION, KEY_STORAGE_KEY, KEY_VECTOR, LocalStorage, } from './storage.js';
7
7
  const NANOSECONDS_PER_SECOND = BigInt(1_000_000_000);
@@ -14,6 +14,10 @@ const ED25519_KEY_LABEL = 'Ed25519';
14
14
  // localStorage key used to cache the delegation expiration so that
15
15
  // isAuthenticated() can answer synchronously without hitting IndexedDB.
16
16
  const KEY_STORAGE_EXPIRATION = 'ic-delegation_expiration';
17
+ // Storage key prefix for a redirect flow's session key, held only while the
18
+ // flow is in progress (keyed by a per-flow id) and removed once the delegation
19
+ // is persisted. See AuthClient.#acquireSessionKey.
20
+ const PENDING_KEY_PREFIX = 'ic-auth-pending-key:';
17
21
  export const OPENID_PROVIDER_URLS = {
18
22
  google: 'https://accounts.google.com',
19
23
  apple: 'https://appleid.apple.com',
@@ -35,6 +39,9 @@ export class AuthClient {
35
39
  #chain = null;
36
40
  #storage;
37
41
  #signer;
42
+ // Set only in redirect mode, so the redirect-specific paths (nonce/key
43
+ // journaling) can reach `memoize`. Undefined in the default 'window' mode.
44
+ #urlTransport;
38
45
  #options;
39
46
  #initPromise = null;
40
47
  idleManager;
@@ -45,13 +52,29 @@ export class AuthClient {
45
52
  if (options.openIdProvider) {
46
53
  identityProviderUrl.searchParams.set('openid', OPENID_PROVIDER_URLS[options.openIdProvider]);
47
54
  }
48
- const transport = new PostMessageTransport({
49
- url: identityProviderUrl.toString(),
50
- windowOpenerFeatures: options.windowOpenerFeatures,
51
- });
55
+ const transport = options.transport === 'redirect'
56
+ ? new UrlTransport({
57
+ url: identityProviderUrl.toString(),
58
+ // The callback is this page: a fresh visit starts the flow and the
59
+ // provider's return lands back here to replay it. Drop any query
60
+ // and fragment so it stays stable across the redirect.
61
+ callbackUrl: `${globalThis.location.origin}${globalThis.location.pathname}`,
62
+ })
63
+ : new PostMessageTransport({
64
+ url: identityProviderUrl.toString(),
65
+ windowOpenerFeatures: options.windowOpenerFeatures,
66
+ });
67
+ this.#urlTransport = transport instanceof UrlTransport ? transport : undefined;
52
68
  this.#signer = new Signer({
53
69
  transport,
54
- derivationOrigin: options.derivationOrigin?.toString(),
70
+ // Journal the derivation origin so it survives the top-level redirect: the
71
+ // return load reconstructs this client from a query-less callback URL, so
72
+ // `options.derivationOrigin` (like the identity provider) is no longer
73
+ // available — the memoized value replays from the journal instead.
74
+ // `memoize` returns synchronously for a synchronous producer, so the value
75
+ // is usable directly here; in the window flow it is a passthrough that runs
76
+ // the producer without persisting anything.
77
+ derivationOrigin: this.memoize(() => options.derivationOrigin?.toString()),
55
78
  });
56
79
  this.#registerDefaultIdleCallback();
57
80
  // Eagerly start restoring a previous session from storage.
@@ -93,10 +116,27 @@ export class AuthClient {
93
116
  * }
94
117
  */
95
118
  async signIn(options) {
96
- await this.#signer.openChannel();
97
119
  const maxTimeToLive = options?.maxTimeToLive ?? DEFAULT_MAX_TIME_TO_LIVE;
98
- // Fresh key per sign-in so each session has its own cryptographic identity.
99
- const key = this.#options.identity ?? (await generateKey(this.#options.keyType ?? ECDSA_KEY_LABEL));
120
+ const keyType = this.#options.keyType ?? ECDSA_KEY_LABEL;
121
+ // Start session-key acquisition BEFORE opening the channel, awaiting it only
122
+ // after. In the redirect flow the acquisition's first `transport.memoize`
123
+ // runs synchronously when invoked, so its in-flight bump lands in the same
124
+ // tick `signIn` is called — holding the transport's batch flush from the
125
+ // very start of the flow rather than only after the `openChannel` await.
126
+ // Under `Promise.all([signIn, requestAttributes])` this is what keeps a
127
+ // faster concurrent request from flushing before this flow's delegation
128
+ // request is buffered.
129
+ const sessionKeyPromise = this.#urlTransport
130
+ ? this.#ensureSessionKeyForRedirectFlow(this.#urlTransport, keyType)
131
+ : this.#ensureSessionKeyForWindowFlow(keyType).then((key) => ({ key }));
132
+ // The acquisition is started eagerly, before the awaits below. If one of
133
+ // those throws first, `sessionKeyPromise` is never awaited, so attach a
134
+ // no-op rejection handler now to keep a later acquisition failure from
135
+ // surfacing as an unhandled rejection. The `await` below still observes a
136
+ // rejection and propagates it when reached.
137
+ void sessionKeyPromise.catch(() => undefined);
138
+ await this.#signer.openChannel();
139
+ const { key, pendingKeySlot } = await sessionKeyPromise;
100
140
  const delegationChain = await this.#signer.requestDelegation({
101
141
  publicKey: key.getPublicKey(),
102
142
  targets: options?.targets,
@@ -118,27 +158,92 @@ export class AuthClient {
118
158
  // Persist so the session survives page reloads.
119
159
  await persistChain(this.#storage, this.#chain);
120
160
  await persistKey(this.#storage, key);
161
+ // The flow is complete: the delegation is bound to this key and stored, so
162
+ // the per-flow pending copy is no longer needed.
163
+ if (pendingKeySlot !== undefined) {
164
+ await this.#storage.remove(pendingKeySlot);
165
+ }
121
166
  return this.#identity;
122
167
  }
168
+ // Window flow: sign-in completes in a single load, so a fresh session key per
169
+ // sign-in is enough (or the caller-provided identity), with nothing to
170
+ // persist for a later load.
171
+ async #ensureSessionKeyForWindowFlow(keyType) {
172
+ return this.#options.identity ?? (await generateKey(keyType));
173
+ }
174
+ // Redirect flow: `signIn` runs twice — once on the load that navigates to the
175
+ // identity provider, and again on the return load that replays the delegation
176
+ // minted for the FIRST load's key. Both runs must therefore use the same key.
177
+ // A per-flow key id is journaled via the transport (stable across the
178
+ // redirect) and the key is kept in storage under that id, so the return load
179
+ // restores the same key rather than generating a fresh one that would not
180
+ // match the replayed delegation. A caller-provided identity is already stable
181
+ // across the redirect, so it is used as-is with nothing persisted.
182
+ async #ensureSessionKeyForRedirectFlow(transport, keyType) {
183
+ if (this.#options.identity !== undefined) {
184
+ return { key: this.#options.identity };
185
+ }
186
+ const keyId = await transport.memoize(() => globalThis.crypto.randomUUID());
187
+ const pendingKeySlot = `${PENDING_KEY_PREFIX}${keyId}`;
188
+ // Acquire the per-flow key inside a `memoize` producer so the transport
189
+ // holds its batch flush across the (async) key restore/generate + storage
190
+ // write. The transport coalesces concurrently issued requests into one
191
+ // redirect by flushing on a macrotask once no memoize producer is in
192
+ // flight; without this hold, a faster concurrent request (e.g. the nonce
193
+ // path of `requestAttributes`) buffers first and trips that flush before
194
+ // this flow's delegation request — issued only once the key is ready — is
195
+ // buffered, splitting what should be one redirect into two.
196
+ //
197
+ // The key is captured in a closure, not read back after the producer: on
198
+ // the FIRST load the producer sets `acquired`, so the delegation request
199
+ // that follows is issued with no intervening storage read — a read there
200
+ // would re-open the very flush gap this closes. The producer is skipped on
201
+ // the replay load (its result is journaled), where the key is instead
202
+ // restored from storage. Only the id is journaled; the key lives in storage.
203
+ let acquired = null;
204
+ await transport.memoize(async () => {
205
+ acquired = await restoreKeyAt(this.#storage, pendingKeySlot);
206
+ if (acquired === null) {
207
+ acquired = await generateKey(keyType);
208
+ await this.#storage.set(pendingKeySlot, serializeKey(acquired));
209
+ }
210
+ return keyId;
211
+ });
212
+ const key = acquired ?? (await restoreKeyAt(this.#storage, pendingKeySlot));
213
+ if (key === null) {
214
+ throw new Error('Session key missing after acquisition');
215
+ }
216
+ return { key, pendingKeySlot };
217
+ }
123
218
  /**
124
219
  * Requests signed identity attributes from the identity provider.
125
220
  *
126
- * The `nonce` may be a `Uint8Array` or a `Promise<Uint8Array>`. Passing a
127
- * promise lets the identity provider window open while the nonce (typically
128
- * fetched from the RP canister) is still being resolved, avoiding a perceived
129
- * delay before the user sees the prompt. Auto-close of the signer transport
130
- * channel is temporarily disabled while awaiting the promise so the window
131
- * cannot be closed out from under the pending flow.
221
+ * The `nonce` is a callback that produces the 32-byte nonce (typically
222
+ * fetched from the RP canister), returning a promise resolving to it. It is a
223
+ * callback rather than a value so the redirect flow can journal the nonce and
224
+ * reuse the exact same bytes when the flow replays on the return load,
225
+ * instead of fetching a fresh single-use nonce that the signer never signed
226
+ * against.
227
+ *
228
+ * In 'window' mode the callback lets the identity provider window open while the
229
+ * nonce is still resolving, avoiding a perceived delay before the user sees
230
+ * the prompt; auto-close of the signer transport channel is temporarily
231
+ * disabled while awaiting so the window cannot be closed out from under the
232
+ * pending flow.
132
233
  *
133
234
  * @param params - Request parameters.
134
235
  * @param params.keys - Attribute keys to request (e.g. `['email', 'name']`).
135
- * @param params.nonce - 32-byte nonce issued by the RP canister, or a promise
136
- * resolving to one.
236
+ * @param params.nonce - Produces the 32-byte nonce issued by the RP canister,
237
+ * as a promise resolving to it.
137
238
  * @returns Signed attribute data and signature.
138
239
  * @throws When the identity provider returns an error or an invalid response.
139
240
  */
140
241
  async requestAttributes(params) {
141
- const nonceBytes = await this.#resolveNonce(params.nonce);
242
+ // In redirect mode the nonce is journaled (base64, since the journal is
243
+ // JSON) so the replay on the return load signs against the same bytes.
244
+ const nonceBytes = this.#urlTransport
245
+ ? fromBase64(await this.#urlTransport.memoize(async () => toBase64(await params.nonce())))
246
+ : await this.#resolveNonce(params.nonce);
142
247
  const response = await this.#signer.sendRequest({
143
248
  jsonrpc: '2.0',
144
249
  id: globalThis.crypto.randomUUID(),
@@ -162,6 +267,12 @@ export class AuthClient {
162
267
  throw new Error('Invalid response: data or signature is not valid base64', { cause });
163
268
  }
164
269
  }
270
+ memoize(produce) {
271
+ if (this.#urlTransport) {
272
+ return this.#urlTransport.memoize(produce);
273
+ }
274
+ return produce();
275
+ }
165
276
  /**
166
277
  * Clears the stored session and resets the client to an anonymous state.
167
278
  *
@@ -181,21 +292,19 @@ export class AuthClient {
181
292
  }
182
293
  }
183
294
  }
184
- // When the caller passes a Promise<Uint8Array>, open the transport channel
185
- // first so the identity provider window is visible while we wait, and
295
+ // Popup-mode nonce resolution. Start the fetch, then open the transport
296
+ // channel so the identity provider window is visible while we wait, and
186
297
  // suspend auto-close so it can't fire mid-await (e.g. due to a close
187
298
  // scheduled by a prior request on the same signer). The original auto-close
188
299
  // setting is restored before sendRequest, so the next response resumes
189
300
  // normal close behaviour.
190
301
  async #resolveNonce(nonce) {
191
- if (!(nonce instanceof Promise)) {
192
- return nonce;
193
- }
302
+ const value = nonce();
194
303
  await this.#signer.openChannel();
195
304
  const previousAutoClose = this.#signer.autoCloseTransportChannel;
196
305
  this.#signer.autoCloseTransportChannel = false;
197
306
  try {
198
- return await nonce;
307
+ return await value;
199
308
  }
200
309
  finally {
201
310
  this.#signer.autoCloseTransportChannel = previousAutoClose;
@@ -315,6 +424,28 @@ async function restoreKey(storage, keyType) {
315
424
  return null;
316
425
  }
317
426
  }
427
+ /**
428
+ * Loads a session key from a specific storage slot, deserializing by stored
429
+ * shape (`CryptoKeyPair` → ECDSA, JSON string → Ed25519). Unlike
430
+ * {@link restoreKey} it does not migrate from localStorage — it reads only the
431
+ * given slot, as used for a redirect flow's per-flow pending key.
432
+ * @param storage - The storage backend.
433
+ * @param storageKey - The slot to read.
434
+ */
435
+ async function restoreKeyAt(storage, storageKey) {
436
+ const stored = await storage.get(storageKey);
437
+ if (!stored)
438
+ return null;
439
+ try {
440
+ if (typeof stored === 'object') {
441
+ return await ECDSAKeyIdentity.fromKeyPair(stored);
442
+ }
443
+ return Ed25519KeyIdentity.fromJSON(stored);
444
+ }
445
+ catch {
446
+ return null;
447
+ }
448
+ }
318
449
  /**
319
450
  * Converts a key into a format suitable for storage.
320
451
  * @param key - The key to serialize.
@@ -1 +1 @@
1
- {"version":3,"file":"auth-client.js","sourceRoot":"","sources":["../../../src/client/auth-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth-client.js","sourceRoot":"","sources":["../../../src/client/auth-client.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@icp-sdk/auth",
3
- "version": "7.1.0",
3
+ "version": "8.0.1",
4
4
  "author": "DFINITY Stiftung <sdk@dfinity.org>",
5
5
  "license": "Apache-2.0",
6
6
  "description": "Authentication library for Internet Computer web apps",
@@ -54,7 +54,7 @@
54
54
  "@icp-sdk/core": "^5"
55
55
  },
56
56
  "dependencies": {
57
- "@icp-sdk/signer": "^5.4.0",
57
+ "@icp-sdk/signer": "^5.6.0",
58
58
  "idb": "^7.1.1"
59
59
  },
60
60
  "scripts": {
@@ -10,7 +10,7 @@ import {
10
10
  } from '@icp-sdk/core/identity';
11
11
  import type { Principal } from '@icp-sdk/core/principal';
12
12
  import { Signer } from '@icp-sdk/signer';
13
- import { PostMessageTransport } from '@icp-sdk/signer/web';
13
+ import { PostMessageTransport, UrlTransport } from '@icp-sdk/signer/web';
14
14
  import { IdleManager, type IdleManagerOptions } from './idle-manager.js';
15
15
  import {
16
16
  type AuthClientStorage,
@@ -37,6 +37,11 @@ type BaseKeyType = typeof ECDSA_KEY_LABEL | typeof ED25519_KEY_LABEL;
37
37
  // isAuthenticated() can answer synchronously without hitting IndexedDB.
38
38
  const KEY_STORAGE_EXPIRATION = 'ic-delegation_expiration';
39
39
 
40
+ // Storage key prefix for a redirect flow's session key, held only while the
41
+ // flow is in progress (keyed by a per-flow id) and removed once the delegation
42
+ // is persisted. See AuthClient.#acquireSessionKey.
43
+ const PENDING_KEY_PREFIX = 'ic-auth-pending-key:';
44
+
40
45
  export type OpenIdProvider = 'google' | 'apple' | 'microsoft';
41
46
 
42
47
  export const OPENID_PROVIDER_URLS = {
@@ -94,6 +99,30 @@ export interface AuthClientCreateOptions {
94
99
  */
95
100
  windowOpenerFeatures?: string;
96
101
 
102
+ /**
103
+ * How the client communicates with the identity provider.
104
+ *
105
+ * - `'window'` (default) — the identity provider opens in a separate browser
106
+ * tab or window (a popup when {@link windowOpenerFeatures} is set) and
107
+ * communicates over the ICRC-29 `postMessage` transport.
108
+ * - `'redirect'` — the current page navigates to the identity provider over
109
+ * the ICRC-167 URL transport, which returns to this same page. The callback
110
+ * URL is the current page's URL (`location.origin + location.pathname`), so
111
+ * that page must be on an origin you control and declared in that origin's
112
+ * `/.well-known/ii-auth-callbacks` allow-list. Use it for full-page sign-in
113
+ * that shouldn't need a user gesture to open a window (e.g. redirecting on a
114
+ * restricted route), or native apps handing off via universal links.
115
+ *
116
+ * With `'redirect'` the page unloads on each step and the flow re-runs on the
117
+ * return load, so call `signIn` / `requestAttributes` directly on the page's
118
+ * load (not deferred behind, say, a click handler): a fresh visit starts the
119
+ * flow and the identity provider's return replays it to completion. Give each
120
+ * flow its own route so its persisted state stays isolated.
121
+ * @default 'window'
122
+ * @see https://github.com/dfinity/wg-identity-authentication/blob/main/topics/icrc_167_browser_url_transport.md
123
+ */
124
+ transport?: 'window' | 'redirect';
125
+
97
126
  /**
98
127
  * OpenID provider for one-click sign-in. When set, the identity provider
99
128
  * URL includes an `openid` search param so the user authenticates via
@@ -152,6 +181,9 @@ export class AuthClient {
152
181
  #chain: DelegationChain | null = null;
153
182
  #storage: AuthClientStorage;
154
183
  #signer: Signer;
184
+ // Set only in redirect mode, so the redirect-specific paths (nonce/key
185
+ // journaling) can reach `memoize`. Undefined in the default 'window' mode.
186
+ #urlTransport: UrlTransport | undefined;
155
187
  #options: AuthClientCreateOptions;
156
188
  #initPromise: Promise<void> | null = null;
157
189
  idleManager: IdleManager | undefined;
@@ -167,14 +199,31 @@ export class AuthClient {
167
199
  identityProviderUrl.searchParams.set('openid', OPENID_PROVIDER_URLS[options.openIdProvider]);
168
200
  }
169
201
 
170
- const transport = new PostMessageTransport({
171
- url: identityProviderUrl.toString(),
172
- windowOpenerFeatures: options.windowOpenerFeatures,
173
- });
202
+ const transport =
203
+ options.transport === 'redirect'
204
+ ? new UrlTransport({
205
+ url: identityProviderUrl.toString(),
206
+ // The callback is this page: a fresh visit starts the flow and the
207
+ // provider's return lands back here to replay it. Drop any query
208
+ // and fragment so it stays stable across the redirect.
209
+ callbackUrl: `${globalThis.location.origin}${globalThis.location.pathname}`,
210
+ })
211
+ : new PostMessageTransport({
212
+ url: identityProviderUrl.toString(),
213
+ windowOpenerFeatures: options.windowOpenerFeatures,
214
+ });
215
+ this.#urlTransport = transport instanceof UrlTransport ? transport : undefined;
174
216
 
175
217
  this.#signer = new Signer({
176
218
  transport,
177
- derivationOrigin: options.derivationOrigin?.toString(),
219
+ // Journal the derivation origin so it survives the top-level redirect: the
220
+ // return load reconstructs this client from a query-less callback URL, so
221
+ // `options.derivationOrigin` (like the identity provider) is no longer
222
+ // available — the memoized value replays from the journal instead.
223
+ // `memoize` returns synchronously for a synchronous producer, so the value
224
+ // is usable directly here; in the window flow it is a passthrough that runs
225
+ // the producer without persisting anything.
226
+ derivationOrigin: this.memoize(() => options.derivationOrigin?.toString()),
178
227
  });
179
228
 
180
229
  this.#registerDefaultIdleCallback();
@@ -220,13 +269,33 @@ export class AuthClient {
220
269
  * }
221
270
  */
222
271
  async signIn(options?: AuthClientSignInOptions): Promise<Identity> {
223
- await this.#signer.openChannel();
224
-
225
272
  const maxTimeToLive = options?.maxTimeToLive ?? DEFAULT_MAX_TIME_TO_LIVE;
273
+ const keyType = this.#options.keyType ?? ECDSA_KEY_LABEL;
274
+
275
+ // Start session-key acquisition BEFORE opening the channel, awaiting it only
276
+ // after. In the redirect flow the acquisition's first `transport.memoize`
277
+ // runs synchronously when invoked, so its in-flight bump lands in the same
278
+ // tick `signIn` is called — holding the transport's batch flush from the
279
+ // very start of the flow rather than only after the `openChannel` await.
280
+ // Under `Promise.all([signIn, requestAttributes])` this is what keeps a
281
+ // faster concurrent request from flushing before this flow's delegation
282
+ // request is buffered.
283
+ const sessionKeyPromise: Promise<{
284
+ key: SignIdentity | PartialIdentity;
285
+ pendingKeySlot?: string;
286
+ }> = this.#urlTransport
287
+ ? this.#ensureSessionKeyForRedirectFlow(this.#urlTransport, keyType)
288
+ : this.#ensureSessionKeyForWindowFlow(keyType).then((key) => ({ key }));
289
+ // The acquisition is started eagerly, before the awaits below. If one of
290
+ // those throws first, `sessionKeyPromise` is never awaited, so attach a
291
+ // no-op rejection handler now to keep a later acquisition failure from
292
+ // surfacing as an unhandled rejection. The `await` below still observes a
293
+ // rejection and propagates it when reached.
294
+ void sessionKeyPromise.catch(() => undefined);
226
295
 
227
- // Fresh key per sign-in so each session has its own cryptographic identity.
228
- const key =
229
- this.#options.identity ?? (await generateKey(this.#options.keyType ?? ECDSA_KEY_LABEL));
296
+ await this.#signer.openChannel();
297
+
298
+ const { key, pendingKeySlot } = await sessionKeyPromise;
230
299
 
231
300
  const delegationChain = await this.#signer.requestDelegation({
232
301
  publicKey: key.getPublicKey(),
@@ -253,31 +322,107 @@ export class AuthClient {
253
322
  await persistChain(this.#storage, this.#chain);
254
323
  await persistKey(this.#storage, key);
255
324
 
325
+ // The flow is complete: the delegation is bound to this key and stored, so
326
+ // the per-flow pending copy is no longer needed.
327
+ if (pendingKeySlot !== undefined) {
328
+ await this.#storage.remove(pendingKeySlot);
329
+ }
330
+
256
331
  return this.#identity;
257
332
  }
258
333
 
334
+ // Window flow: sign-in completes in a single load, so a fresh session key per
335
+ // sign-in is enough (or the caller-provided identity), with nothing to
336
+ // persist for a later load.
337
+ async #ensureSessionKeyForWindowFlow(
338
+ keyType: BaseKeyType,
339
+ ): Promise<SignIdentity | PartialIdentity> {
340
+ return this.#options.identity ?? (await generateKey(keyType));
341
+ }
342
+
343
+ // Redirect flow: `signIn` runs twice — once on the load that navigates to the
344
+ // identity provider, and again on the return load that replays the delegation
345
+ // minted for the FIRST load's key. Both runs must therefore use the same key.
346
+ // A per-flow key id is journaled via the transport (stable across the
347
+ // redirect) and the key is kept in storage under that id, so the return load
348
+ // restores the same key rather than generating a fresh one that would not
349
+ // match the replayed delegation. A caller-provided identity is already stable
350
+ // across the redirect, so it is used as-is with nothing persisted.
351
+ async #ensureSessionKeyForRedirectFlow(
352
+ transport: UrlTransport,
353
+ keyType: BaseKeyType,
354
+ ): Promise<{ key: SignIdentity | PartialIdentity; pendingKeySlot?: string }> {
355
+ if (this.#options.identity !== undefined) {
356
+ return { key: this.#options.identity };
357
+ }
358
+
359
+ const keyId = await transport.memoize(() => globalThis.crypto.randomUUID());
360
+ const pendingKeySlot = `${PENDING_KEY_PREFIX}${keyId}`;
361
+
362
+ // Acquire the per-flow key inside a `memoize` producer so the transport
363
+ // holds its batch flush across the (async) key restore/generate + storage
364
+ // write. The transport coalesces concurrently issued requests into one
365
+ // redirect by flushing on a macrotask once no memoize producer is in
366
+ // flight; without this hold, a faster concurrent request (e.g. the nonce
367
+ // path of `requestAttributes`) buffers first and trips that flush before
368
+ // this flow's delegation request — issued only once the key is ready — is
369
+ // buffered, splitting what should be one redirect into two.
370
+ //
371
+ // The key is captured in a closure, not read back after the producer: on
372
+ // the FIRST load the producer sets `acquired`, so the delegation request
373
+ // that follows is issued with no intervening storage read — a read there
374
+ // would re-open the very flush gap this closes. The producer is skipped on
375
+ // the replay load (its result is journaled), where the key is instead
376
+ // restored from storage. Only the id is journaled; the key lives in storage.
377
+ let acquired: SignIdentity | PartialIdentity | null = null;
378
+ await transport.memoize(async () => {
379
+ acquired = await restoreKeyAt(this.#storage, pendingKeySlot);
380
+ if (acquired === null) {
381
+ acquired = await generateKey(keyType);
382
+ await this.#storage.set(pendingKeySlot, serializeKey(acquired));
383
+ }
384
+ return keyId;
385
+ });
386
+
387
+ const key = acquired ?? (await restoreKeyAt(this.#storage, pendingKeySlot));
388
+ if (key === null) {
389
+ throw new Error('Session key missing after acquisition');
390
+ }
391
+ return { key, pendingKeySlot };
392
+ }
393
+
259
394
  /**
260
395
  * Requests signed identity attributes from the identity provider.
261
396
  *
262
- * The `nonce` may be a `Uint8Array` or a `Promise<Uint8Array>`. Passing a
263
- * promise lets the identity provider window open while the nonce (typically
264
- * fetched from the RP canister) is still being resolved, avoiding a perceived
265
- * delay before the user sees the prompt. Auto-close of the signer transport
266
- * channel is temporarily disabled while awaiting the promise so the window
267
- * cannot be closed out from under the pending flow.
397
+ * The `nonce` is a callback that produces the 32-byte nonce (typically
398
+ * fetched from the RP canister), returning a promise resolving to it. It is a
399
+ * callback rather than a value so the redirect flow can journal the nonce and
400
+ * reuse the exact same bytes when the flow replays on the return load,
401
+ * instead of fetching a fresh single-use nonce that the signer never signed
402
+ * against.
403
+ *
404
+ * In 'window' mode the callback lets the identity provider window open while the
405
+ * nonce is still resolving, avoiding a perceived delay before the user sees
406
+ * the prompt; auto-close of the signer transport channel is temporarily
407
+ * disabled while awaiting so the window cannot be closed out from under the
408
+ * pending flow.
268
409
  *
269
410
  * @param params - Request parameters.
270
411
  * @param params.keys - Attribute keys to request (e.g. `['email', 'name']`).
271
- * @param params.nonce - 32-byte nonce issued by the RP canister, or a promise
272
- * resolving to one.
412
+ * @param params.nonce - Produces the 32-byte nonce issued by the RP canister,
413
+ * as a promise resolving to it.
273
414
  * @returns Signed attribute data and signature.
274
415
  * @throws When the identity provider returns an error or an invalid response.
275
416
  */
276
417
  async requestAttributes(params: {
277
418
  keys: string[];
278
- nonce: Uint8Array | Promise<Uint8Array>;
419
+ nonce: () => Promise<Uint8Array>;
279
420
  }): Promise<SignedAttributes> {
280
- const nonceBytes = await this.#resolveNonce(params.nonce);
421
+ // In redirect mode the nonce is journaled (base64, since the journal is
422
+ // JSON) so the replay on the return load signs against the same bytes.
423
+ const nonceBytes = this.#urlTransport
424
+ ? fromBase64(await this.#urlTransport.memoize(async () => toBase64(await params.nonce())))
425
+ : await this.#resolveNonce(params.nonce);
281
426
 
282
427
  const response = await this.#signer.sendRequest({
283
428
  jsonrpc: '2.0',
@@ -305,6 +450,52 @@ export class AuthClient {
305
450
  }
306
451
  }
307
452
 
453
+ /**
454
+ * Runs and journals a piece of your own async work so its result stays stable
455
+ * across the `'redirect'` flow.
456
+ *
457
+ * In `'redirect'` mode the page unloads on each step and `signIn` /
458
+ * `requestAttributes` re-run on the return load, so a value you compute on the
459
+ * first visit (from `location`, a fetch, `crypto`, …) would otherwise be
460
+ * recomputed — and may differ — on the return. Wrap it in `memoize`: it runs
461
+ * `produce` once on the first visit, journals the result, and replays that
462
+ * result on the return load instead of re-running. Use it for a value the
463
+ * post-flow code depends on, e.g. the URL to navigate to once sign-in
464
+ * completes:
465
+ *
466
+ * ```ts
467
+ * const next = await authClient.memoize(
468
+ * () => new URLSearchParams(location.search).get('next') ?? '/',
469
+ * );
470
+ * await authClient.signIn();
471
+ * location.assign(next); // the value captured before the redirect
472
+ * ```
473
+ *
474
+ * Call `memoize` in a stable order relative to `signIn` / `requestAttributes`
475
+ * across loads (same order every load — branch only on values recovered from
476
+ * earlier results), and keep the result JSON-serializable, since the journal
477
+ * is JSON.
478
+ *
479
+ * In `'window'` mode there is no redirect, so this simply runs `produce` and
480
+ * returns its result without persisting anything.
481
+ *
482
+ * Mirrors the producer's shape: a synchronous `produce` returns its value
483
+ * directly, an asynchronous one returns a promise. Awaiting the result is
484
+ * always safe (`await` on a non-promise is a no-op); the synchronous form lets
485
+ * a value be memoized where an `await` is not possible, such as in a
486
+ * constructor.
487
+ * @param produce - Produces the value to journal on the first load.
488
+ * @returns The produced value, or the journaled value on a replay load.
489
+ */
490
+ memoize<T>(produce: () => Promise<T>): Promise<T>;
491
+ memoize<T>(produce: () => T): T;
492
+ memoize<T>(produce: () => T | Promise<T>): T | Promise<T> {
493
+ if (this.#urlTransport) {
494
+ return this.#urlTransport.memoize(produce);
495
+ }
496
+ return produce();
497
+ }
498
+
308
499
  /**
309
500
  * Clears the stored session and resets the client to an anonymous state.
310
501
  *
@@ -326,22 +517,19 @@ export class AuthClient {
326
517
  }
327
518
  }
328
519
 
329
- // When the caller passes a Promise<Uint8Array>, open the transport channel
330
- // first so the identity provider window is visible while we wait, and
520
+ // Popup-mode nonce resolution. Start the fetch, then open the transport
521
+ // channel so the identity provider window is visible while we wait, and
331
522
  // suspend auto-close so it can't fire mid-await (e.g. due to a close
332
523
  // scheduled by a prior request on the same signer). The original auto-close
333
524
  // setting is restored before sendRequest, so the next response resumes
334
525
  // normal close behaviour.
335
- async #resolveNonce(nonce: Uint8Array | Promise<Uint8Array>): Promise<Uint8Array> {
336
- if (!(nonce instanceof Promise)) {
337
- return nonce;
338
- }
339
-
526
+ async #resolveNonce(nonce: () => Promise<Uint8Array>): Promise<Uint8Array> {
527
+ const value = nonce();
340
528
  await this.#signer.openChannel();
341
529
  const previousAutoClose = this.#signer.autoCloseTransportChannel;
342
530
  this.#signer.autoCloseTransportChannel = false;
343
531
  try {
344
- return await nonce;
532
+ return await value;
345
533
  } finally {
346
534
  this.#signer.autoCloseTransportChannel = previousAutoClose;
347
535
  }
@@ -475,6 +663,31 @@ async function restoreKey(
475
663
  }
476
664
  }
477
665
 
666
+ /**
667
+ * Loads a session key from a specific storage slot, deserializing by stored
668
+ * shape (`CryptoKeyPair` → ECDSA, JSON string → Ed25519). Unlike
669
+ * {@link restoreKey} it does not migrate from localStorage — it reads only the
670
+ * given slot, as used for a redirect flow's per-flow pending key.
671
+ * @param storage - The storage backend.
672
+ * @param storageKey - The slot to read.
673
+ */
674
+ async function restoreKeyAt(
675
+ storage: AuthClientStorage,
676
+ storageKey: string,
677
+ ): Promise<SignIdentity | PartialIdentity | null> {
678
+ const stored = await storage.get(storageKey);
679
+ if (!stored) return null;
680
+
681
+ try {
682
+ if (typeof stored === 'object') {
683
+ return await ECDSAKeyIdentity.fromKeyPair(stored);
684
+ }
685
+ return Ed25519KeyIdentity.fromJSON(stored);
686
+ } catch {
687
+ return null;
688
+ }
689
+ }
690
+
478
691
  /**
479
692
  * Converts a key into a format suitable for storage.
480
693
  * @param key - The key to serialize.