@tinfoilsh/passkey-kit 0.1.0 → 0.2.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.
Files changed (50) hide show
  1. package/README.md +138 -81
  2. package/dist/crypto.d.ts +11 -54
  3. package/dist/crypto.d.ts.map +1 -1
  4. package/dist/crypto.js +146 -97
  5. package/dist/crypto.js.map +1 -1
  6. package/dist/errors.d.ts +11 -21
  7. package/dist/errors.d.ts.map +1 -1
  8. package/dist/errors.js +10 -27
  9. package/dist/errors.js.map +1 -1
  10. package/dist/index.d.ts +7 -10
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +4 -7
  13. package/dist/index.js.map +1 -1
  14. package/dist/kit.d.ts +2 -62
  15. package/dist/kit.d.ts.map +1 -1
  16. package/dist/kit.js +331 -155
  17. package/dist/kit.js.map +1 -1
  18. package/dist/storage.d.ts +15 -29
  19. package/dist/storage.d.ts.map +1 -1
  20. package/dist/storage.js +113 -62
  21. package/dist/storage.js.map +1 -1
  22. package/dist/support.d.ts +2 -14
  23. package/dist/support.d.ts.map +1 -1
  24. package/dist/support.js +32 -47
  25. package/dist/support.js.map +1 -1
  26. package/dist/types.d.ts +85 -89
  27. package/dist/types.d.ts.map +1 -1
  28. package/dist/webauthn.d.ts +10 -33
  29. package/dist/webauthn.d.ts.map +1 -1
  30. package/dist/webauthn.js +89 -177
  31. package/dist/webauthn.js.map +1 -1
  32. package/dist/wrapped-key-record-codec.d.ts +4 -0
  33. package/dist/wrapped-key-record-codec.d.ts.map +1 -0
  34. package/dist/wrapped-key-record-codec.js +89 -0
  35. package/dist/wrapped-key-record-codec.js.map +1 -0
  36. package/package.json +4 -2
  37. package/src/crypto.ts +171 -137
  38. package/src/errors.ts +29 -33
  39. package/src/index.ts +26 -41
  40. package/src/kit.ts +431 -260
  41. package/src/storage.ts +126 -60
  42. package/src/support.ts +36 -50
  43. package/src/types.ts +99 -99
  44. package/src/webauthn.ts +121 -237
  45. package/src/wrapped-key-record-codec.ts +93 -0
  46. package/dist/protocol.d.ts +0 -13
  47. package/dist/protocol.d.ts.map +0 -1
  48. package/dist/protocol.js +0 -13
  49. package/dist/protocol.js.map +0 -1
  50. package/src/protocol.ts +0 -15
package/dist/kit.js CHANGED
@@ -1,198 +1,374 @@
1
- /**
2
- * The main SDK entry point. `createPasskeyKit(config)` binds relying-party
3
- * configuration, protocol constants, and local persistence into a single
4
- * object exposing both high-level flows (enroll / unlock / rewrap) and the
5
- * lower-level ceremony + crypto building blocks.
6
- */
7
- import { base64ToBytes, bytesToBase64 } from "./codec.js";
8
- import { deriveKeyEncryptionKey as deriveKekFromPrf, unwrapCek, wrapCek, } from "./crypto.js";
9
- import { TINFOIL_HKDF_INFO_V1, TINFOIL_PRF_SALT_INPUT_V1 } from "./protocol.js";
10
- import { browserLocalStorageAdapter } from "./storage.js";
11
- import { detectPrfSupport } from "./support.js";
12
- import { authenticatePrfPasskey, createPrfPasskey, } from "./webauthn.js";
13
- const DEFAULT_STORAGE_KEYS = {
14
- prfResult: "tinfoil-secret-passkey-prf-output",
15
- localCredentialId: "tinfoil-local-passkey-credential-id",
16
- };
17
- const DEFAULT_WEBAUTHN_TIMEOUT_MS = 30000;
18
- // Internal hard timeout to guard against providers (e.g. some
19
- // password-manager browser extensions) that never resolve the
20
- // credentials.create/get promise. Kept tight so users aren't left staring
21
- // at an indefinite spinner; the WebAuthn flow itself should complete well
22
- // within this window once the provider actually prompts.
23
- const DEFAULT_STUCK_TIMEOUT_MS = 60000;
24
- export function createPasskeyKit(config) {
25
- const logger = config.logger ?? {};
26
- const storage = config.storage === undefined ? browserLocalStorageAdapter : config.storage;
27
- const storageKeys = {
28
- ...DEFAULT_STORAGE_KEYS,
29
- ...config.storageKeys,
1
+ import { copyAndValidateProfile, profilesEqual, unwrapKey, validateCredentialId, validateKey, validateWrappedKey, wrapKey, } from "./crypto.js";
2
+ import { invalidInput, PasskeyKeyError } from "./errors.js";
3
+ import { capability as detectCapability } from "./support.js";
4
+ import { createPrfCredential, evaluatePrfCredential, } from "./webauthn.js";
5
+ const DEFAULT_TIMEOUT_MS = 60000;
6
+ const MIN_TIMEOUT_MS = 1;
7
+ const MAX_TIMEOUT_MS = 2147483647;
8
+ function mapCeremonyError(error, operation) {
9
+ if (error instanceof PasskeyKeyError) {
10
+ if (error.operation)
11
+ return error;
12
+ return new PasskeyKeyError(error.category, error.message, {
13
+ cause: error.cause,
14
+ operation,
15
+ });
16
+ }
17
+ if (error instanceof DOMException && error.name === "NotAllowedError") {
18
+ return new PasskeyKeyError("cancelled", "the prompt was dismissed or no eligible credential was available", { cause: error, operation });
19
+ }
20
+ if (error instanceof DOMException && error.name === "AbortError") {
21
+ return new PasskeyKeyError("cancelled", "the passkey operation was cancelled", {
22
+ cause: error,
23
+ operation,
24
+ });
25
+ }
26
+ return new PasskeyKeyError("operation_failed", "the passkey operation failed", {
27
+ cause: error,
28
+ operation,
29
+ });
30
+ }
31
+ function context(profile, relyingPartyName, timeoutMs) {
32
+ return {
33
+ rpId: profile.relyingPartyId,
34
+ rpName: relyingPartyName,
35
+ prfInput: profile.prfSalt,
36
+ timeoutMs,
30
37
  };
31
- // Byte inputs are snapshotted so later caller-side buffer reuse cannot
32
- // silently change the PRF domain or KEK derivation between ceremonies.
33
- const prfSalt = typeof config.prfSaltInput === "string" || config.prfSaltInput === undefined
34
- ? new TextEncoder().encode(config.prfSaltInput ?? TINFOIL_PRF_SALT_INPUT_V1)
35
- : config.prfSaltInput.slice();
36
- const hkdfInfo = config.hkdfInfo === undefined
37
- ? TINFOIL_HKDF_INFO_V1
38
- : typeof config.hkdfInfo === "string"
39
- ? config.hkdfInfo
40
- : config.hkdfInfo.slice();
41
- let prfSupportCache = null;
42
- function cachePrfResult(result) {
43
- if (!storage)
44
- return;
45
- const entry = {
46
- credentialId: result.credentialId,
47
- prfOutput: bytesToBase64(new Uint8Array(result.prfOutput)),
38
+ }
39
+ function copyUser(user) {
40
+ if (!user || typeof user !== "object")
41
+ throw invalidInput("user is required");
42
+ return {
43
+ id: user.id instanceof Uint8Array ? user.id.slice() : user.id,
44
+ name: user.name,
45
+ displayName: user.displayName,
46
+ };
47
+ }
48
+ function copyWrappedKeys(wrappedKeys) {
49
+ if (!Array.isArray(wrappedKeys) || wrappedKeys.length === 0) {
50
+ throw invalidInput("at least one wrapped key is required");
51
+ }
52
+ return wrappedKeys.map((wrapped) => {
53
+ if (!wrapped || typeof wrapped !== "object") {
54
+ throw invalidInput("wrapped key is required");
55
+ }
56
+ return {
57
+ ...wrapped,
58
+ profile: copyAndValidateProfile(wrapped.profile),
48
59
  };
60
+ });
61
+ }
62
+ export function createPasskeyKeyManager(config) {
63
+ if (!config || typeof config !== "object")
64
+ throw invalidInput("manager config is required");
65
+ const profile = copyAndValidateProfile(config.profile);
66
+ if (typeof config.relyingPartyName !== "string" ||
67
+ config.relyingPartyName.length === 0) {
68
+ throw invalidInput("relyingPartyName must be a non-empty string");
69
+ }
70
+ const relyingPartyName = config.relyingPartyName;
71
+ if (config.timeoutMs !== undefined &&
72
+ (!Number.isFinite(config.timeoutMs) ||
73
+ config.timeoutMs < MIN_TIMEOUT_MS ||
74
+ config.timeoutMs > MAX_TIMEOUT_MS)) {
75
+ throw invalidInput(`timeoutMs must be between ${MIN_TIMEOUT_MS} and ${MAX_TIMEOUT_MS}`);
76
+ }
77
+ const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
78
+ let activeCeremony = null;
79
+ async function runCeremony(operation, callerSignal, perform) {
80
+ if (activeCeremony) {
81
+ throw new PasskeyKeyError("operation_in_progress", "another passkey ceremony is in progress", { operation });
82
+ }
83
+ if (callerSignal?.aborted) {
84
+ throw new PasskeyKeyError("cancelled", "the passkey operation was cancelled", {
85
+ cause: callerSignal.reason,
86
+ operation,
87
+ });
88
+ }
89
+ const token = Symbol(operation);
90
+ const controller = new AbortController();
91
+ let rejectInterruption;
92
+ const interrupted = new Promise((_, reject) => {
93
+ rejectInterruption = reject;
94
+ });
95
+ const cancel = (error) => {
96
+ rejectInterruption?.(error);
97
+ controller.abort(error);
98
+ };
99
+ activeCeremony = { token, operation, cancel };
100
+ const cancelFromCaller = () => cancel(new PasskeyKeyError("cancelled", "the passkey operation was cancelled", {
101
+ cause: callerSignal?.reason,
102
+ operation,
103
+ }));
104
+ callerSignal?.addEventListener("abort", cancelFromCaller, { once: true });
105
+ const timeout = setTimeout(() => cancel(new PasskeyKeyError("timeout", "the passkey operation timed out", {
106
+ operation,
107
+ })), timeoutMs);
49
108
  try {
50
- storage.setItem(storageKeys.prfResult, JSON.stringify(entry));
109
+ return await Promise.race([perform(controller.signal), interrupted]);
110
+ }
111
+ catch (error) {
112
+ throw mapCeremonyError(error, operation);
113
+ }
114
+ finally {
115
+ clearTimeout(timeout);
116
+ callerSignal?.removeEventListener("abort", cancelFromCaller);
117
+ if (activeCeremony?.token === token)
118
+ activeCeremony = null;
119
+ }
120
+ }
121
+ function recordSuccessfulCredential(result) {
122
+ try {
123
+ config.storage?.saveCachedPRFResult({
124
+ profile: copyAndValidateProfile(profile),
125
+ credentialId: result.credentialId,
126
+ prfOutput: result.prfOutput.slice(),
127
+ });
51
128
  }
52
129
  catch {
53
- // best-effort
130
+ // Storage is best-effort and cannot invalidate a successful ceremony.
131
+ }
132
+ if (result.isPlatformAuthenticator) {
133
+ try {
134
+ config.storage?.saveLocalCredentialId(result.credentialId);
135
+ }
136
+ catch {
137
+ // Storage is best-effort and cannot invalidate a successful ceremony.
138
+ }
54
139
  }
55
140
  }
56
- function getCachedPrfResult() {
57
- if (!storage)
141
+ function loadCachedResult() {
142
+ let result;
143
+ try {
144
+ result = config.storage?.loadCachedPRFResult() ?? null;
145
+ }
146
+ catch {
147
+ return null;
148
+ }
149
+ if (!result)
58
150
  return null;
151
+ let cachedProfile;
59
152
  try {
60
- const raw = storage.getItem(storageKeys.prfResult);
61
- if (!raw)
62
- return null;
63
- const entry = JSON.parse(raw);
64
- return {
65
- credentialId: entry.credentialId,
66
- prfOutput: base64ToBytes(entry.prfOutput).buffer,
67
- };
153
+ cachedProfile = copyAndValidateProfile(result.profile);
154
+ validateCredentialId(result.credentialId);
155
+ }
156
+ catch {
157
+ return null;
158
+ }
159
+ if (!profilesEqual(cachedProfile, profile) ||
160
+ !(result.prfOutput instanceof Uint8Array) ||
161
+ result.prfOutput.length !== 32)
162
+ return null;
163
+ return {
164
+ profile: cachedProfile,
165
+ credentialId: result.credentialId,
166
+ prfOutput: result.prfOutput.slice(),
167
+ };
168
+ }
169
+ function loadPreferredCredentialId() {
170
+ try {
171
+ return config.storage?.loadLocalCredentialId() ?? null;
68
172
  }
69
173
  catch {
70
174
  return null;
71
175
  }
72
176
  }
73
- function setLocalCredentialId(credentialId) {
74
- storage?.setItem(storageKeys.localCredentialId, credentialId);
177
+ function orderedCredentialIds(credentialIds, preferredCredentialId) {
178
+ if (!Array.isArray(credentialIds) || credentialIds.length === 0) {
179
+ throw invalidInput("at least one credentialId is required");
180
+ }
181
+ // Skip candidates that are not canonical base64url instead of
182
+ // failing the ceremony: one malformed ID (e.g. a legacy record
183
+ // written by another client) must not block assertion against
184
+ // the valid ones.
185
+ const unique = [...new Set(credentialIds)].filter((credentialId) => {
186
+ try {
187
+ validateCredentialId(credentialId);
188
+ return true;
189
+ }
190
+ catch {
191
+ return false;
192
+ }
193
+ });
194
+ if (unique.length === 0) {
195
+ throw invalidInput("no credentialId is valid unpadded base64url");
196
+ }
197
+ const preferred = preferredCredentialId ?? loadPreferredCredentialId();
198
+ if (!preferred || !unique.includes(preferred))
199
+ return unique;
200
+ return [preferred, ...unique.filter((credentialId) => credentialId !== preferred)];
201
+ }
202
+ function copyPRFOutput(prfResult, operation) {
203
+ if (!prfResult ||
204
+ typeof prfResult !== "object" ||
205
+ !(prfResult.output instanceof Uint8Array) ||
206
+ prfResult.output.length !== 32) {
207
+ throw invalidInput("prfResult.output must be exactly 32 bytes", operation);
208
+ }
209
+ return prfResult.output.slice();
210
+ }
211
+ async function wrapKeyWithPRFResult(input, operation = "wrapKeyWithPRFResult") {
212
+ if (!input || typeof input !== "object")
213
+ throw invalidInput("input is required", operation);
214
+ validateKey(input.keyMaterial, operation);
215
+ validateCredentialId(input.credentialId);
216
+ const keyMaterial = input.keyMaterial.slice();
217
+ const prfOutput = copyPRFOutput(input.prfResult, operation);
218
+ return wrapKey(profile, input.credentialId, prfOutput, keyMaterial, operation);
75
219
  }
76
- // Cross-device hybrid (QR-paired phone, etc.) reports
77
- // `authenticatorAttachment === 'cross-platform'` on the resulting
78
- // credential. Caching the cred id in that case would make this
79
- // device look like it has its own passkey when in reality the user
80
- // just borrowed another device's passkey for a one-shot unlock.
81
- // Per WebAuthn L3 §5.2.1, we only treat `authenticatorAttachment`
82
- // of `'platform'` as "this device truly owns this credential".
83
- function onPrfResult(result, credential) {
84
- cachePrfResult(result);
85
- if (credential.authenticatorAttachment === "platform") {
220
+ async function unwrapKeyWithPRFResult(input, operation = "unwrapKeyWithPRFResult") {
221
+ if (!input || typeof input !== "object")
222
+ throw invalidInput("input is required", operation);
223
+ const wrappedKey = {
224
+ ...input.wrappedKey,
225
+ profile: copyAndValidateProfile(input.wrappedKey?.profile),
226
+ };
227
+ validateWrappedKey(wrappedKey, profile);
228
+ const prfOutput = copyPRFOutput(input.prfResult, operation);
229
+ return unwrapKey(profile, prfOutput, wrappedKey, operation);
230
+ }
231
+ async function createAndWrapKey(input) {
232
+ if (!input || typeof input !== "object")
233
+ throw invalidInput("input is required");
234
+ validateKey(input.key, "createAndWrapKey");
235
+ const key = input.key.slice();
236
+ const user = copyUser(input.user);
237
+ const result = await runCeremony("createAndWrapKey", input.signal, (signal) => createPrfCredential(context(profile, relyingPartyName, timeoutMs), user, signal));
238
+ recordSuccessfulCredential(result);
239
+ const wrappedKey = await wrapKeyWithPRFResult({
240
+ keyMaterial: key,
241
+ credentialId: result.credentialId,
242
+ prfResult: { output: result.prfOutput },
243
+ }, "createAndWrapKey");
244
+ return { credentialId: result.credentialId, wrappedKey };
245
+ }
246
+ function prepareRecovery(input) {
247
+ if (!input || typeof input !== "object")
248
+ throw invalidInput("input is required");
249
+ // Skip malformed candidates (wrong profile, non-canonical
250
+ // credential ID, bad lengths) rather than failing the whole set,
251
+ // so one corrupt or foreign bundle cannot block recovery from the
252
+ // healthy ones. Throw only when no usable candidate remains.
253
+ if (!Array.isArray(input.wrappedKeys) || input.wrappedKeys.length === 0) {
254
+ throw invalidInput("at least one wrapped key is required");
255
+ }
256
+ const wrappedKeys = [];
257
+ for (const candidate of input.wrappedKeys) {
86
258
  try {
87
- setLocalCredentialId(result.credentialId);
259
+ const [wrapped] = copyWrappedKeys([candidate]);
260
+ validateWrappedKey(wrapped, profile);
261
+ wrappedKeys.push(wrapped);
88
262
  }
89
263
  catch {
90
- // best-effort: a throwing custom adapter must not discard the
91
- // ceremony result
264
+ // Skipped: malformed candidate.
92
265
  }
93
266
  }
267
+ if (wrappedKeys.length === 0) {
268
+ throw invalidInput("no wrapped key matches this profile and format");
269
+ }
270
+ return wrappedKeys;
94
271
  }
95
- const ceremonyContext = {
96
- rpId: config.rpId,
97
- rpName: config.rpName,
98
- prfSalt,
99
- webauthnTimeoutMs: config.webauthnTimeoutMs ?? DEFAULT_WEBAUTHN_TIMEOUT_MS,
100
- stuckTimeoutMs: config.stuckTimeoutMs ?? DEFAULT_STUCK_TIMEOUT_MS,
101
- errorMessages: config.errorMessages,
102
- logger,
103
- onPrfResult,
104
- };
105
- const deriveKek = (prfOutput) => deriveKekFromPrf(prfOutput, hkdfInfo);
106
- async function wrapWithPrfResult(prfResult, cek) {
107
- const kek = await deriveKek(prfResult.prfOutput);
108
- return wrapCek({ credentialId: prfResult.credentialId, kek, cek });
272
+ async function evaluateCredential(input, operation = "evaluateCredential") {
273
+ if (!input || typeof input !== "object")
274
+ throw invalidInput("input is required");
275
+ const interaction = input.interaction ?? "interactive";
276
+ if (interaction !== "interactive" && interaction !== "immediatelyAvailable") {
277
+ throw invalidInput("interaction must be interactive or immediatelyAvailable", operation);
278
+ }
279
+ if (interaction === "immediatelyAvailable") {
280
+ throw new PasskeyKeyError("unsupported", "immediatelyAvailable credential evaluation is not supported in browsers", { operation });
281
+ }
282
+ const credentialIds = orderedCredentialIds(input.credentialIds, input.preferredCredentialId);
283
+ const result = await runCeremony(operation, input.signal, (signal) => evaluatePrfCredential(context(profile, relyingPartyName, timeoutMs), credentialIds, signal));
284
+ recordSuccessfulCredential(result);
285
+ return {
286
+ credentialId: result.credentialId,
287
+ prfResult: { output: result.prfOutput.slice() },
288
+ };
109
289
  }
110
290
  return {
111
- async isPrfSupported() {
112
- if (prfSupportCache !== null)
113
- return prfSupportCache;
114
- prfSupportCache = await detectPrfSupport();
115
- return prfSupportCache;
116
- },
117
- resetPrfSupportCache() {
118
- prfSupportCache = null;
291
+ async capability(input) {
292
+ if (!input ||
293
+ typeof input !== "object" ||
294
+ (input.operation !== "enroll" && input.operation !== "recover")) {
295
+ throw invalidInput("operation must be enroll or recover", "capability");
296
+ }
297
+ return detectCapability(input.operation);
119
298
  },
120
- createPasskey(user) {
121
- return createPrfPasskey(ceremonyContext, user);
299
+ createAndWrapKey,
300
+ evaluateCredential(input) {
301
+ return evaluateCredential(input);
122
302
  },
123
- async authenticate(credentialIds, options = {}) {
124
- // An empty allowCredentials list would start a discoverable-passkey
125
- // ceremony against ANY credential, breaking the "only the supplied
126
- // ids" contract.
127
- if (credentialIds.length === 0)
128
- return null;
129
- return authenticatePrfPasskey(ceremonyContext, credentialIds, options);
303
+ wrapKeyWithPRFResult(input) {
304
+ return wrapKeyWithPRFResult(input);
130
305
  },
131
- deriveKek,
132
- async enroll(opts) {
133
- const prfResult = await createPrfPasskey(ceremonyContext, opts.user);
134
- if (!prfResult)
135
- return null;
136
- const wrappedCek = await wrapWithPrfResult(prfResult, opts.cek);
137
- return { credentialId: prfResult.credentialId, wrappedCek, prfResult };
306
+ unwrapKeyWithPRFResult(input) {
307
+ return unwrapKeyWithPRFResult(input);
138
308
  },
139
- async unlock(wrappedCeks) {
140
- if (wrappedCeks.length === 0)
141
- return null;
142
- const prfResult = await authenticatePrfPasskey(ceremonyContext, wrappedCeks.map((w) => w.credentialId));
143
- if (!prfResult)
144
- return null;
145
- const match = wrappedCeks.find((w) => w.credentialId === prfResult.credentialId);
146
- if (!match) {
147
- logger.error?.("assertion matched a credential with no wrapped CEK", undefined, { action: "unlock", credentialId: prfResult.credentialId });
148
- return null;
149
- }
150
- const kek = await deriveKek(prfResult.prfOutput);
151
- const cek = await unwrapCek(kek, match);
152
- return { credentialId: prfResult.credentialId, cek };
309
+ async recoverKey(input) {
310
+ const wrappedKeys = prepareRecovery(input);
311
+ const result = await evaluateCredential({
312
+ credentialIds: wrappedKeys.map((wrapped) => wrapped.credentialId),
313
+ preferredCredentialId: input.preferredCredentialId,
314
+ signal: input.signal,
315
+ interaction: input.interaction,
316
+ }, "recoverKey");
317
+ const wrapped = wrappedKeys.find((candidate) => candidate.credentialId === result.credentialId);
318
+ if (!wrapped)
319
+ throw invalidInput("credential has no matching wrapped key", "recoverKey");
320
+ return {
321
+ credentialId: result.credentialId,
322
+ key: await unwrapKeyWithPRFResult({ wrappedKey: wrapped, prfResult: result.prfResult }, "recoverKey"),
323
+ };
153
324
  },
154
- async unlockWithCachedPrf(wrappedCeks) {
155
- const cached = getCachedPrfResult();
325
+ async recoverKeyFromCache(input) {
326
+ const wrappedKeys = prepareRecovery(input);
327
+ const cached = loadCachedResult();
156
328
  if (!cached)
157
329
  return null;
158
- const match = wrappedCeks.find((w) => w.credentialId === cached.credentialId);
159
- if (!match)
330
+ const wrapped = wrappedKeys.find((candidate) => candidate.credentialId === cached.credentialId);
331
+ if (!wrapped)
160
332
  return null;
161
333
  try {
162
- const kek = await deriveKek(cached.prfOutput);
163
- const cek = await unwrapCek(kek, match);
164
- return { credentialId: cached.credentialId, cek };
165
- }
166
- catch (error) {
167
- logger.error?.("failed to unwrap CEK with cached PRF output", error, {
168
- action: "unlockWithCachedPrf",
334
+ return {
169
335
  credentialId: cached.credentialId,
170
- });
336
+ key: await unwrapKeyWithPRFResult({
337
+ wrappedKey: wrapped,
338
+ prfResult: { output: cached.prfOutput },
339
+ }, "recoverKeyFromCache"),
340
+ };
341
+ }
342
+ catch {
171
343
  return null;
172
344
  }
173
345
  },
174
- async rewrapWithCachedPrf(cek) {
175
- const cached = getCachedPrfResult();
346
+ async rewrapKeyFromCache(input) {
347
+ if (!input || typeof input !== "object")
348
+ throw invalidInput("input is required");
349
+ validateKey(input.key, "rewrapKeyFromCache");
350
+ const cached = loadCachedResult();
176
351
  if (!cached)
177
352
  return null;
178
- return wrapWithPrfResult(cached, cek);
179
- },
180
- wrapWithPrfResult,
181
- async unwrapWithPrfResult(prfResult, wrapped) {
182
- const kek = await deriveKek(prfResult.prfOutput);
183
- return unwrapCek(kek, wrapped);
184
- },
185
- getCachedPrfResult,
186
- clearCachedPrfResult() {
187
- storage?.removeItem(storageKeys.prfResult);
188
- },
189
- getLocalCredentialId() {
190
- return storage?.getItem(storageKeys.localCredentialId) ?? null;
353
+ return wrapKeyWithPRFResult({
354
+ keyMaterial: input.key,
355
+ credentialId: cached.credentialId,
356
+ prfResult: { output: cached.prfOutput },
357
+ }, "rewrapKeyFromCache");
191
358
  },
192
- setLocalCredentialId,
193
359
  clearLocalState() {
194
- storage?.removeItem(storageKeys.prfResult);
195
- storage?.removeItem(storageKeys.localCredentialId);
360
+ try {
361
+ config.storage?.clear();
362
+ }
363
+ catch {
364
+ // Storage is best-effort.
365
+ }
366
+ },
367
+ cancelActiveCeremony() {
368
+ const operation = activeCeremony?.operation;
369
+ activeCeremony?.cancel(new PasskeyKeyError("cancelled", "the passkey operation was cancelled", {
370
+ operation,
371
+ }));
196
372
  },
197
373
  };
198
374
  }
package/dist/kit.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"kit.js","sourceRoot":"","sources":["../src/kit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"kit.js","sourceRoot":"","sources":["../src/kit.ts"],"names":[],"mappings":"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"}
package/dist/storage.d.ts CHANGED
@@ -1,31 +1,17 @@
1
- /**
2
- * Pluggable local persistence for the SDK's device-side state: the cached
3
- * PRF output and the credential id this device owns. Adapters are
4
- * synchronous by design (mirroring the Web Storage API) so callers can
5
- * read cached state without awaiting.
6
- *
7
- * SECURITY: the PRF output cached through an adapter is raw key material —
8
- * anyone who can read it can re-derive the KEK and unwrap the CEK. The
9
- * default `localStorage` adapter stores it in plaintext, which is only as
10
- * strong as the origin's script-injection defenses (an XSS attacker could
11
- * equally just run the ceremony or exfiltrate decrypted data). Hosts with
12
- * stricter requirements should supply their own adapter with at-rest
13
- * protection, or pass `storage: null` to disable caching and re-prompt
14
- * biometrics instead.
15
- */
16
- export interface StorageAdapter {
17
- getItem(key: string): string | null;
18
- setItem(key: string, value: string): void;
19
- removeItem(key: string): void;
1
+ import type { PasskeyKeyProfile } from "./types.js";
2
+ export interface CachedPRFResult {
3
+ profile: PasskeyKeyProfile;
4
+ credentialId: string;
5
+ prfOutput: Uint8Array;
20
6
  }
21
- /**
22
- * Default adapter backed by `window.localStorage`. Every operation is
23
- * best-effort: quota errors, privacy-mode failures, blocked-storage
24
- * contexts (e.g. sandboxed frames, where even touching `localStorage`
25
- * throws), and SSR (no window) all degrade to no-ops so storage problems
26
- * never interrupt a passkey ceremony.
27
- */
28
- export declare const browserLocalStorageAdapter: StorageAdapter;
29
- /** In-memory adapter for tests and non-browser environments. */
30
- export declare function createMemoryStorageAdapter(): StorageAdapter;
7
+ export interface PasskeyKeyStorage {
8
+ loadCachedPRFResult(): CachedPRFResult | null;
9
+ saveCachedPRFResult(result: CachedPRFResult): void;
10
+ loadLocalCredentialId(): string | null;
11
+ saveLocalCredentialId(credentialId: string): void;
12
+ clear(): void;
13
+ }
14
+ export declare function createMemoryPasskeyKeyStorage(): PasskeyKeyStorage;
15
+ /** Stores raw PRF output unencrypted in localStorage under an explicit namespace. */
16
+ export declare function createInsecureBrowserLocalStoragePasskeyKeyStorage(namespace: string): PasskeyKeyStorage;
31
17
  //# sourceMappingURL=storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IACnC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACzC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAC9B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,EAAE,cAyBxC,CAAA;AAED,gEAAgE;AAChE,wBAAgB,0BAA0B,IAAI,cAAc,CAW3D"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,iBAAiB,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,UAAU,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,mBAAmB,IAAI,eAAe,GAAG,IAAI,CAAC;IAC9C,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IACnD,qBAAqB,IAAI,MAAM,GAAG,IAAI,CAAC;IACvC,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAClD,KAAK,IAAI,IAAI,CAAC;CACf;AAkBD,wBAAgB,6BAA6B,IAAI,iBAAiB,CAqBjE;AAWD,qFAAqF;AACrF,wBAAgB,kDAAkD,CAChE,SAAS,EAAE,MAAM,GAChB,iBAAiB,CAkEnB"}