@icp-sdk/auth 7.0.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -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,16 +155,62 @@ export declare class AuthClient {
|
|
|
132
155
|
/**
|
|
133
156
|
* Requests signed identity attributes from the identity provider.
|
|
134
157
|
*
|
|
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.
|
|
170
|
+
*
|
|
135
171
|
* @param params - Request parameters.
|
|
136
172
|
* @param params.keys - Attribute keys to request (e.g. `['email', 'name']`).
|
|
137
|
-
* @param params.nonce - 32-byte nonce issued by the RP canister
|
|
173
|
+
* @param params.nonce - Produces the 32-byte nonce issued by the RP canister,
|
|
174
|
+
* as a promise resolving to it.
|
|
138
175
|
* @returns Signed attribute data and signature.
|
|
139
176
|
* @throws When the identity provider returns an error or an invalid response.
|
|
140
177
|
*/
|
|
141
178
|
requestAttributes(params: {
|
|
142
179
|
keys: string[];
|
|
143
|
-
nonce: Uint8Array
|
|
180
|
+
nonce: () => Promise<Uint8Array>;
|
|
144
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
|
+
* @param produce - Produces the value to journal on the first load.
|
|
211
|
+
* @returns The produced value, or the journaled value on a replay load.
|
|
212
|
+
*/
|
|
213
|
+
memoize<T>(produce: () => T | Promise<T>): Promise<T>;
|
|
145
214
|
/**
|
|
146
215
|
* Clears the stored session and resets the client to an anonymous state.
|
|
147
216
|
*
|
|
@@ -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,10 +52,19 @@ export class AuthClient {
|
|
|
45
52
|
if (options.openIdProvider) {
|
|
46
53
|
identityProviderUrl.searchParams.set('openid', OPENID_PROVIDER_URLS[options.openIdProvider]);
|
|
47
54
|
}
|
|
48
|
-
const transport =
|
|
49
|
-
|
|
50
|
-
|
|
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
70
|
derivationOrigin: options.derivationOrigin?.toString(),
|
|
@@ -95,8 +111,10 @@ export class AuthClient {
|
|
|
95
111
|
async signIn(options) {
|
|
96
112
|
await this.#signer.openChannel();
|
|
97
113
|
const maxTimeToLive = options?.maxTimeToLive ?? DEFAULT_MAX_TIME_TO_LIVE;
|
|
98
|
-
|
|
99
|
-
const key
|
|
114
|
+
const keyType = this.#options.keyType ?? ECDSA_KEY_LABEL;
|
|
115
|
+
const { key, pendingKeySlot } = this.#urlTransport
|
|
116
|
+
? await this.#ensureSessionKeyForRedirectFlow(this.#urlTransport, keyType)
|
|
117
|
+
: { key: await this.#ensureSessionKeyForWindowFlow(keyType) };
|
|
100
118
|
const delegationChain = await this.#signer.requestDelegation({
|
|
101
119
|
publicKey: key.getPublicKey(),
|
|
102
120
|
targets: options?.targets,
|
|
@@ -118,19 +136,70 @@ export class AuthClient {
|
|
|
118
136
|
// Persist so the session survives page reloads.
|
|
119
137
|
await persistChain(this.#storage, this.#chain);
|
|
120
138
|
await persistKey(this.#storage, key);
|
|
139
|
+
// The flow is complete: the delegation is bound to this key and stored, so
|
|
140
|
+
// the per-flow pending copy is no longer needed.
|
|
141
|
+
if (pendingKeySlot !== undefined) {
|
|
142
|
+
await this.#storage.remove(pendingKeySlot);
|
|
143
|
+
}
|
|
121
144
|
return this.#identity;
|
|
122
145
|
}
|
|
146
|
+
// Window flow: sign-in completes in a single load, so a fresh session key per
|
|
147
|
+
// sign-in is enough (or the caller-provided identity), with nothing to
|
|
148
|
+
// persist for a later load.
|
|
149
|
+
async #ensureSessionKeyForWindowFlow(keyType) {
|
|
150
|
+
return this.#options.identity ?? (await generateKey(keyType));
|
|
151
|
+
}
|
|
152
|
+
// Redirect flow: `signIn` runs twice — once on the load that navigates to the
|
|
153
|
+
// identity provider, and again on the return load that replays the delegation
|
|
154
|
+
// minted for the FIRST load's key. Both runs must therefore use the same key.
|
|
155
|
+
// A per-flow key id is journaled via the transport (stable across the
|
|
156
|
+
// redirect) and the key is kept in storage under that id, so the return load
|
|
157
|
+
// restores the same key rather than generating a fresh one that would not
|
|
158
|
+
// match the replayed delegation. A caller-provided identity is already stable
|
|
159
|
+
// across the redirect, so it is used as-is with nothing persisted.
|
|
160
|
+
async #ensureSessionKeyForRedirectFlow(transport, keyType) {
|
|
161
|
+
if (this.#options.identity !== undefined) {
|
|
162
|
+
return { key: this.#options.identity };
|
|
163
|
+
}
|
|
164
|
+
const keyId = await transport.memoize(() => globalThis.crypto.randomUUID());
|
|
165
|
+
const pendingKeySlot = `${PENDING_KEY_PREFIX}${keyId}`;
|
|
166
|
+
const restored = await restoreKeyAt(this.#storage, pendingKeySlot);
|
|
167
|
+
if (restored) {
|
|
168
|
+
return { key: restored, pendingKeySlot };
|
|
169
|
+
}
|
|
170
|
+
const key = await generateKey(keyType);
|
|
171
|
+
await this.#storage.set(pendingKeySlot, serializeKey(key));
|
|
172
|
+
return { key, pendingKeySlot };
|
|
173
|
+
}
|
|
123
174
|
/**
|
|
124
175
|
* Requests signed identity attributes from the identity provider.
|
|
125
176
|
*
|
|
177
|
+
* The `nonce` is a callback that produces the 32-byte nonce (typically
|
|
178
|
+
* fetched from the RP canister), returning a promise resolving to it. It is a
|
|
179
|
+
* callback rather than a value so the redirect flow can journal the nonce and
|
|
180
|
+
* reuse the exact same bytes when the flow replays on the return load,
|
|
181
|
+
* instead of fetching a fresh single-use nonce that the signer never signed
|
|
182
|
+
* against.
|
|
183
|
+
*
|
|
184
|
+
* In 'window' mode the callback lets the identity provider window open while the
|
|
185
|
+
* nonce is still resolving, avoiding a perceived delay before the user sees
|
|
186
|
+
* the prompt; auto-close of the signer transport channel is temporarily
|
|
187
|
+
* disabled while awaiting so the window cannot be closed out from under the
|
|
188
|
+
* pending flow.
|
|
189
|
+
*
|
|
126
190
|
* @param params - Request parameters.
|
|
127
191
|
* @param params.keys - Attribute keys to request (e.g. `['email', 'name']`).
|
|
128
|
-
* @param params.nonce - 32-byte nonce issued by the RP canister
|
|
192
|
+
* @param params.nonce - Produces the 32-byte nonce issued by the RP canister,
|
|
193
|
+
* as a promise resolving to it.
|
|
129
194
|
* @returns Signed attribute data and signature.
|
|
130
195
|
* @throws When the identity provider returns an error or an invalid response.
|
|
131
196
|
*/
|
|
132
197
|
async requestAttributes(params) {
|
|
133
|
-
|
|
198
|
+
// In redirect mode the nonce is journaled (base64, since the journal is
|
|
199
|
+
// JSON) so the replay on the return load signs against the same bytes.
|
|
200
|
+
const nonceBytes = this.#urlTransport
|
|
201
|
+
? fromBase64(await this.#urlTransport.memoize(async () => toBase64(await params.nonce())))
|
|
202
|
+
: await this.#resolveNonce(params.nonce);
|
|
134
203
|
const response = await this.#signer.sendRequest({
|
|
135
204
|
jsonrpc: '2.0',
|
|
136
205
|
id: globalThis.crypto.randomUUID(),
|
|
@@ -154,6 +223,43 @@ export class AuthClient {
|
|
|
154
223
|
throw new Error('Invalid response: data or signature is not valid base64', { cause });
|
|
155
224
|
}
|
|
156
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Runs and journals a piece of your own async work so its result stays stable
|
|
228
|
+
* across the `'redirect'` flow.
|
|
229
|
+
*
|
|
230
|
+
* In `'redirect'` mode the page unloads on each step and `signIn` /
|
|
231
|
+
* `requestAttributes` re-run on the return load, so a value you compute on the
|
|
232
|
+
* first visit (from `location`, a fetch, `crypto`, …) would otherwise be
|
|
233
|
+
* recomputed — and may differ — on the return. Wrap it in `memoize`: it runs
|
|
234
|
+
* `produce` once on the first visit, journals the result, and replays that
|
|
235
|
+
* result on the return load instead of re-running. Use it for a value the
|
|
236
|
+
* post-flow code depends on, e.g. the URL to navigate to once sign-in
|
|
237
|
+
* completes:
|
|
238
|
+
*
|
|
239
|
+
* ```ts
|
|
240
|
+
* const next = await authClient.memoize(
|
|
241
|
+
* () => new URLSearchParams(location.search).get('next') ?? '/',
|
|
242
|
+
* );
|
|
243
|
+
* await authClient.signIn();
|
|
244
|
+
* location.assign(next); // the value captured before the redirect
|
|
245
|
+
* ```
|
|
246
|
+
*
|
|
247
|
+
* Call `memoize` in a stable order relative to `signIn` / `requestAttributes`
|
|
248
|
+
* across loads (same order every load — branch only on values recovered from
|
|
249
|
+
* earlier results), and keep the result JSON-serializable, since the journal
|
|
250
|
+
* is JSON.
|
|
251
|
+
*
|
|
252
|
+
* In `'window'` mode there is no redirect, so this simply runs `produce` and
|
|
253
|
+
* returns its result without persisting anything.
|
|
254
|
+
* @param produce - Produces the value to journal on the first load.
|
|
255
|
+
* @returns The produced value, or the journaled value on a replay load.
|
|
256
|
+
*/
|
|
257
|
+
async memoize(produce) {
|
|
258
|
+
if (this.#urlTransport) {
|
|
259
|
+
return this.#urlTransport.memoize(produce);
|
|
260
|
+
}
|
|
261
|
+
return produce();
|
|
262
|
+
}
|
|
157
263
|
/**
|
|
158
264
|
* Clears the stored session and resets the client to an anonymous state.
|
|
159
265
|
*
|
|
@@ -173,6 +279,24 @@ export class AuthClient {
|
|
|
173
279
|
}
|
|
174
280
|
}
|
|
175
281
|
}
|
|
282
|
+
// Popup-mode nonce resolution. Start the fetch, then open the transport
|
|
283
|
+
// channel so the identity provider window is visible while we wait, and
|
|
284
|
+
// suspend auto-close so it can't fire mid-await (e.g. due to a close
|
|
285
|
+
// scheduled by a prior request on the same signer). The original auto-close
|
|
286
|
+
// setting is restored before sendRequest, so the next response resumes
|
|
287
|
+
// normal close behaviour.
|
|
288
|
+
async #resolveNonce(nonce) {
|
|
289
|
+
const value = nonce();
|
|
290
|
+
await this.#signer.openChannel();
|
|
291
|
+
const previousAutoClose = this.#signer.autoCloseTransportChannel;
|
|
292
|
+
this.#signer.autoCloseTransportChannel = false;
|
|
293
|
+
try {
|
|
294
|
+
return await value;
|
|
295
|
+
}
|
|
296
|
+
finally {
|
|
297
|
+
this.#signer.autoCloseTransportChannel = previousAutoClose;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
176
300
|
// Memoized — only runs #hydrate once, returns the same promise on repeat calls.
|
|
177
301
|
#init() {
|
|
178
302
|
if (!this.#initPromise) {
|
|
@@ -287,6 +411,28 @@ async function restoreKey(storage, keyType) {
|
|
|
287
411
|
return null;
|
|
288
412
|
}
|
|
289
413
|
}
|
|
414
|
+
/**
|
|
415
|
+
* Loads a session key from a specific storage slot, deserializing by stored
|
|
416
|
+
* shape (`CryptoKeyPair` → ECDSA, JSON string → Ed25519). Unlike
|
|
417
|
+
* {@link restoreKey} it does not migrate from localStorage — it reads only the
|
|
418
|
+
* given slot, as used for a redirect flow's per-flow pending key.
|
|
419
|
+
* @param storage - The storage backend.
|
|
420
|
+
* @param storageKey - The slot to read.
|
|
421
|
+
*/
|
|
422
|
+
async function restoreKeyAt(storage, storageKey) {
|
|
423
|
+
const stored = await storage.get(storageKey);
|
|
424
|
+
if (!stored)
|
|
425
|
+
return null;
|
|
426
|
+
try {
|
|
427
|
+
if (typeof stored === 'object') {
|
|
428
|
+
return await ECDSAKeyIdentity.fromKeyPair(stored);
|
|
429
|
+
}
|
|
430
|
+
return Ed25519KeyIdentity.fromJSON(stored);
|
|
431
|
+
}
|
|
432
|
+
catch {
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
290
436
|
/**
|
|
291
437
|
* Converts a key into a format suitable for storage.
|
|
292
438
|
* @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": "
|
|
3
|
+
"version": "8.0.0",
|
|
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.
|
|
57
|
+
"@icp-sdk/signer": "^5.5.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,10 +199,20 @@ export class AuthClient {
|
|
|
167
199
|
identityProviderUrl.searchParams.set('openid', OPENID_PROVIDER_URLS[options.openIdProvider]);
|
|
168
200
|
}
|
|
169
201
|
|
|
170
|
-
const transport =
|
|
171
|
-
|
|
172
|
-
|
|
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,
|
|
@@ -223,10 +265,11 @@ export class AuthClient {
|
|
|
223
265
|
await this.#signer.openChannel();
|
|
224
266
|
|
|
225
267
|
const maxTimeToLive = options?.maxTimeToLive ?? DEFAULT_MAX_TIME_TO_LIVE;
|
|
268
|
+
const keyType = this.#options.keyType ?? ECDSA_KEY_LABEL;
|
|
226
269
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
270
|
+
const { key, pendingKeySlot } = this.#urlTransport
|
|
271
|
+
? await this.#ensureSessionKeyForRedirectFlow(this.#urlTransport, keyType)
|
|
272
|
+
: { key: await this.#ensureSessionKeyForWindowFlow(keyType) };
|
|
230
273
|
|
|
231
274
|
const delegationChain = await this.#signer.requestDelegation({
|
|
232
275
|
publicKey: key.getPublicKey(),
|
|
@@ -253,23 +296,85 @@ export class AuthClient {
|
|
|
253
296
|
await persistChain(this.#storage, this.#chain);
|
|
254
297
|
await persistKey(this.#storage, key);
|
|
255
298
|
|
|
299
|
+
// The flow is complete: the delegation is bound to this key and stored, so
|
|
300
|
+
// the per-flow pending copy is no longer needed.
|
|
301
|
+
if (pendingKeySlot !== undefined) {
|
|
302
|
+
await this.#storage.remove(pendingKeySlot);
|
|
303
|
+
}
|
|
304
|
+
|
|
256
305
|
return this.#identity;
|
|
257
306
|
}
|
|
258
307
|
|
|
308
|
+
// Window flow: sign-in completes in a single load, so a fresh session key per
|
|
309
|
+
// sign-in is enough (or the caller-provided identity), with nothing to
|
|
310
|
+
// persist for a later load.
|
|
311
|
+
async #ensureSessionKeyForWindowFlow(
|
|
312
|
+
keyType: BaseKeyType,
|
|
313
|
+
): Promise<SignIdentity | PartialIdentity> {
|
|
314
|
+
return this.#options.identity ?? (await generateKey(keyType));
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Redirect flow: `signIn` runs twice — once on the load that navigates to the
|
|
318
|
+
// identity provider, and again on the return load that replays the delegation
|
|
319
|
+
// minted for the FIRST load's key. Both runs must therefore use the same key.
|
|
320
|
+
// A per-flow key id is journaled via the transport (stable across the
|
|
321
|
+
// redirect) and the key is kept in storage under that id, so the return load
|
|
322
|
+
// restores the same key rather than generating a fresh one that would not
|
|
323
|
+
// match the replayed delegation. A caller-provided identity is already stable
|
|
324
|
+
// across the redirect, so it is used as-is with nothing persisted.
|
|
325
|
+
async #ensureSessionKeyForRedirectFlow(
|
|
326
|
+
transport: UrlTransport,
|
|
327
|
+
keyType: BaseKeyType,
|
|
328
|
+
): Promise<{ key: SignIdentity | PartialIdentity; pendingKeySlot?: string }> {
|
|
329
|
+
if (this.#options.identity !== undefined) {
|
|
330
|
+
return { key: this.#options.identity };
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
const keyId = await transport.memoize(() => globalThis.crypto.randomUUID());
|
|
334
|
+
const pendingKeySlot = `${PENDING_KEY_PREFIX}${keyId}`;
|
|
335
|
+
|
|
336
|
+
const restored = await restoreKeyAt(this.#storage, pendingKeySlot);
|
|
337
|
+
if (restored) {
|
|
338
|
+
return { key: restored, pendingKeySlot };
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const key = await generateKey(keyType);
|
|
342
|
+
await this.#storage.set(pendingKeySlot, serializeKey(key));
|
|
343
|
+
return { key, pendingKeySlot };
|
|
344
|
+
}
|
|
345
|
+
|
|
259
346
|
/**
|
|
260
347
|
* Requests signed identity attributes from the identity provider.
|
|
261
348
|
*
|
|
349
|
+
* The `nonce` is a callback that produces the 32-byte nonce (typically
|
|
350
|
+
* fetched from the RP canister), returning a promise resolving to it. It is a
|
|
351
|
+
* callback rather than a value so the redirect flow can journal the nonce and
|
|
352
|
+
* reuse the exact same bytes when the flow replays on the return load,
|
|
353
|
+
* instead of fetching a fresh single-use nonce that the signer never signed
|
|
354
|
+
* against.
|
|
355
|
+
*
|
|
356
|
+
* In 'window' mode the callback lets the identity provider window open while the
|
|
357
|
+
* nonce is still resolving, avoiding a perceived delay before the user sees
|
|
358
|
+
* the prompt; auto-close of the signer transport channel is temporarily
|
|
359
|
+
* disabled while awaiting so the window cannot be closed out from under the
|
|
360
|
+
* pending flow.
|
|
361
|
+
*
|
|
262
362
|
* @param params - Request parameters.
|
|
263
363
|
* @param params.keys - Attribute keys to request (e.g. `['email', 'name']`).
|
|
264
|
-
* @param params.nonce - 32-byte nonce issued by the RP canister
|
|
364
|
+
* @param params.nonce - Produces the 32-byte nonce issued by the RP canister,
|
|
365
|
+
* as a promise resolving to it.
|
|
265
366
|
* @returns Signed attribute data and signature.
|
|
266
367
|
* @throws When the identity provider returns an error or an invalid response.
|
|
267
368
|
*/
|
|
268
369
|
async requestAttributes(params: {
|
|
269
370
|
keys: string[];
|
|
270
|
-
nonce: Uint8Array
|
|
371
|
+
nonce: () => Promise<Uint8Array>;
|
|
271
372
|
}): Promise<SignedAttributes> {
|
|
272
|
-
|
|
373
|
+
// In redirect mode the nonce is journaled (base64, since the journal is
|
|
374
|
+
// JSON) so the replay on the return load signs against the same bytes.
|
|
375
|
+
const nonceBytes = this.#urlTransport
|
|
376
|
+
? fromBase64(await this.#urlTransport.memoize(async () => toBase64(await params.nonce())))
|
|
377
|
+
: await this.#resolveNonce(params.nonce);
|
|
273
378
|
|
|
274
379
|
const response = await this.#signer.sendRequest({
|
|
275
380
|
jsonrpc: '2.0',
|
|
@@ -297,6 +402,44 @@ export class AuthClient {
|
|
|
297
402
|
}
|
|
298
403
|
}
|
|
299
404
|
|
|
405
|
+
/**
|
|
406
|
+
* Runs and journals a piece of your own async work so its result stays stable
|
|
407
|
+
* across the `'redirect'` flow.
|
|
408
|
+
*
|
|
409
|
+
* In `'redirect'` mode the page unloads on each step and `signIn` /
|
|
410
|
+
* `requestAttributes` re-run on the return load, so a value you compute on the
|
|
411
|
+
* first visit (from `location`, a fetch, `crypto`, …) would otherwise be
|
|
412
|
+
* recomputed — and may differ — on the return. Wrap it in `memoize`: it runs
|
|
413
|
+
* `produce` once on the first visit, journals the result, and replays that
|
|
414
|
+
* result on the return load instead of re-running. Use it for a value the
|
|
415
|
+
* post-flow code depends on, e.g. the URL to navigate to once sign-in
|
|
416
|
+
* completes:
|
|
417
|
+
*
|
|
418
|
+
* ```ts
|
|
419
|
+
* const next = await authClient.memoize(
|
|
420
|
+
* () => new URLSearchParams(location.search).get('next') ?? '/',
|
|
421
|
+
* );
|
|
422
|
+
* await authClient.signIn();
|
|
423
|
+
* location.assign(next); // the value captured before the redirect
|
|
424
|
+
* ```
|
|
425
|
+
*
|
|
426
|
+
* Call `memoize` in a stable order relative to `signIn` / `requestAttributes`
|
|
427
|
+
* across loads (same order every load — branch only on values recovered from
|
|
428
|
+
* earlier results), and keep the result JSON-serializable, since the journal
|
|
429
|
+
* is JSON.
|
|
430
|
+
*
|
|
431
|
+
* In `'window'` mode there is no redirect, so this simply runs `produce` and
|
|
432
|
+
* returns its result without persisting anything.
|
|
433
|
+
* @param produce - Produces the value to journal on the first load.
|
|
434
|
+
* @returns The produced value, or the journaled value on a replay load.
|
|
435
|
+
*/
|
|
436
|
+
async memoize<T>(produce: () => T | Promise<T>): Promise<T> {
|
|
437
|
+
if (this.#urlTransport) {
|
|
438
|
+
return this.#urlTransport.memoize(produce);
|
|
439
|
+
}
|
|
440
|
+
return produce();
|
|
441
|
+
}
|
|
442
|
+
|
|
300
443
|
/**
|
|
301
444
|
* Clears the stored session and resets the client to an anonymous state.
|
|
302
445
|
*
|
|
@@ -318,6 +461,24 @@ export class AuthClient {
|
|
|
318
461
|
}
|
|
319
462
|
}
|
|
320
463
|
|
|
464
|
+
// Popup-mode nonce resolution. Start the fetch, then open the transport
|
|
465
|
+
// channel so the identity provider window is visible while we wait, and
|
|
466
|
+
// suspend auto-close so it can't fire mid-await (e.g. due to a close
|
|
467
|
+
// scheduled by a prior request on the same signer). The original auto-close
|
|
468
|
+
// setting is restored before sendRequest, so the next response resumes
|
|
469
|
+
// normal close behaviour.
|
|
470
|
+
async #resolveNonce(nonce: () => Promise<Uint8Array>): Promise<Uint8Array> {
|
|
471
|
+
const value = nonce();
|
|
472
|
+
await this.#signer.openChannel();
|
|
473
|
+
const previousAutoClose = this.#signer.autoCloseTransportChannel;
|
|
474
|
+
this.#signer.autoCloseTransportChannel = false;
|
|
475
|
+
try {
|
|
476
|
+
return await value;
|
|
477
|
+
} finally {
|
|
478
|
+
this.#signer.autoCloseTransportChannel = previousAutoClose;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
321
482
|
// Memoized — only runs #hydrate once, returns the same promise on repeat calls.
|
|
322
483
|
#init(): Promise<void> {
|
|
323
484
|
if (!this.#initPromise) {
|
|
@@ -446,6 +607,31 @@ async function restoreKey(
|
|
|
446
607
|
}
|
|
447
608
|
}
|
|
448
609
|
|
|
610
|
+
/**
|
|
611
|
+
* Loads a session key from a specific storage slot, deserializing by stored
|
|
612
|
+
* shape (`CryptoKeyPair` → ECDSA, JSON string → Ed25519). Unlike
|
|
613
|
+
* {@link restoreKey} it does not migrate from localStorage — it reads only the
|
|
614
|
+
* given slot, as used for a redirect flow's per-flow pending key.
|
|
615
|
+
* @param storage - The storage backend.
|
|
616
|
+
* @param storageKey - The slot to read.
|
|
617
|
+
*/
|
|
618
|
+
async function restoreKeyAt(
|
|
619
|
+
storage: AuthClientStorage,
|
|
620
|
+
storageKey: string,
|
|
621
|
+
): Promise<SignIdentity | PartialIdentity | null> {
|
|
622
|
+
const stored = await storage.get(storageKey);
|
|
623
|
+
if (!stored) return null;
|
|
624
|
+
|
|
625
|
+
try {
|
|
626
|
+
if (typeof stored === 'object') {
|
|
627
|
+
return await ECDSAKeyIdentity.fromKeyPair(stored);
|
|
628
|
+
}
|
|
629
|
+
return Ed25519KeyIdentity.fromJSON(stored);
|
|
630
|
+
} catch {
|
|
631
|
+
return null;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
449
635
|
/**
|
|
450
636
|
* Converts a key into a format suitable for storage.
|
|
451
637
|
* @param key - The key to serialize.
|