@iqauth/sdk 2.3.0 → 2.5.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.
Files changed (87) hide show
  1. package/README.md +110 -0
  2. package/dist/browser-session.d.mts +3 -2
  3. package/dist/browser-session.d.ts +3 -2
  4. package/dist/browser.d.mts +64 -29
  5. package/dist/browser.d.ts +64 -29
  6. package/dist/browser.js +782 -38
  7. package/dist/browser.mjs +43 -3
  8. package/dist/bundle-LUKDQYVQ.mjs +374 -0
  9. package/dist/chunk-3JULWS6F.mjs +106 -0
  10. package/dist/chunk-5T7GHBX6.mjs +1165 -0
  11. package/dist/{chunk-KGEPDXHU.mjs → chunk-6TDJJER7.mjs} +2 -2
  12. package/dist/{chunk-RACIPVLD.mjs → chunk-76W5TLQQ.mjs} +262 -220
  13. package/dist/{chunk-EKTNEZIH.mjs → chunk-BVV54LPI.mjs} +37 -5
  14. package/dist/chunk-LIZYFXH7.mjs +90 -0
  15. package/dist/chunk-MKKZULZR.mjs +241 -0
  16. package/dist/chunk-SL3KRS4W.mjs +54 -0
  17. package/dist/chunk-TKZTCPEK.mjs +232 -0
  18. package/dist/chunk-UKZLOHZG.mjs +83 -0
  19. package/dist/cli/index.js +144 -36
  20. package/dist/cli/index.mjs +1 -1
  21. package/dist/{client-DTX4hNdS.d.ts → client-BNQe3AgF.d.ts} +3 -62
  22. package/dist/{client-vdh2a9fJ.d.mts → client-kYlJFgPv.d.mts} +3 -62
  23. package/dist/doctor-YYNHNMLD.mjs +198 -0
  24. package/dist/{express-A0-dWEMy.d.mts → express-B6_1vBYZ.d.mts} +23 -2
  25. package/dist/{express-Bo_pJKHN.d.ts → express-CHpfa7D_.d.ts} +23 -2
  26. package/dist/express.d.mts +5 -4
  27. package/dist/express.d.ts +5 -4
  28. package/dist/express.js +36 -4
  29. package/dist/express.mjs +8 -8
  30. package/dist/fastify.js +2 -2
  31. package/dist/fastify.mjs +4 -4
  32. package/dist/hono.js +2 -2
  33. package/dist/hono.mjs +4 -4
  34. package/dist/index.d.mts +8 -3
  35. package/dist/index.d.ts +8 -3
  36. package/dist/index.js +500 -4
  37. package/dist/index.mjs +29 -9
  38. package/dist/locales.d.mts +53 -0
  39. package/dist/locales.d.ts +53 -0
  40. package/dist/locales.js +1202 -0
  41. package/dist/locales.mjs +29 -0
  42. package/dist/mobile.d.mts +3 -2
  43. package/dist/mobile.d.ts +3 -2
  44. package/dist/next.d.mts +1 -1
  45. package/dist/next.d.ts +1 -1
  46. package/dist/next.js +2 -2
  47. package/dist/next.mjs +1 -1
  48. package/dist/provisioningBridge-88xjOS2n.d.mts +86 -0
  49. package/dist/provisioningBridge-DnTfzdZK.d.ts +86 -0
  50. package/dist/react.d.mts +1349 -10
  51. package/dist/react.d.ts +1349 -10
  52. package/dist/react.js +2985 -567
  53. package/dist/react.mjs +1517 -94
  54. package/dist/reverify-4UEJXUS6.mjs +16 -0
  55. package/dist/server/handlers.d.mts +10 -1
  56. package/dist/server/handlers.d.ts +10 -1
  57. package/dist/server/handlers.js +2 -2
  58. package/dist/server/handlers.mjs +1 -1
  59. package/dist/server.d.mts +5 -3
  60. package/dist/server.d.ts +5 -3
  61. package/dist/server.js +89 -4
  62. package/dist/server.mjs +12 -8
  63. package/dist/service.d.mts +3 -2
  64. package/dist/service.d.ts +3 -2
  65. package/dist/signIn-CCY4JE5G.mjs +15 -0
  66. package/dist/{signIn-Cd0P4y9d.d.mts → signIn-CiIBTJIh.d.mts} +224 -4
  67. package/dist/{signIn-DKakyzeu.d.ts → signIn-OCr88Zf8.d.ts} +224 -4
  68. package/dist/test.d.mts +86 -0
  69. package/dist/test.d.ts +86 -0
  70. package/dist/test.js +289 -0
  71. package/dist/test.mjs +9 -0
  72. package/dist/tokens-DCyzzn8L.d.mts +63 -0
  73. package/dist/tokens-aHiGFr_E.d.ts +63 -0
  74. package/dist/types-6bNdxesb.d.mts +196 -0
  75. package/dist/types-6bNdxesb.d.ts +196 -0
  76. package/dist/{types-Cxl3bQHt.d.mts → types-DZAflmmq.d.mts} +6 -0
  77. package/dist/{types-Cxl3bQHt.d.ts → types-DZAflmmq.d.ts} +6 -0
  78. package/dist/webhooks.d.mts +61 -0
  79. package/dist/webhooks.d.ts +61 -0
  80. package/dist/webhooks.js +119 -0
  81. package/dist/webhooks.mjs +11 -0
  82. package/dist/ws.d.mts +73 -0
  83. package/dist/ws.d.ts +73 -0
  84. package/dist/ws.js +397 -0
  85. package/dist/ws.mjs +12 -0
  86. package/package.json +22 -2
  87. package/dist/doctor-A5E7LSFW.mjs +0 -90
package/dist/browser.js CHANGED
@@ -3,6 +3,9 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __esm = (fn, res) => function __init() {
7
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ };
6
9
  var __export = (target, all) => {
7
10
  for (var name in all)
8
11
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -17,28 +20,426 @@ var __copyProps = (to, from, except, desc) => {
17
20
  };
18
21
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
22
 
23
+ // ../../node_modules/@simplewebauthn/browser/dist/bundle/index.js
24
+ var bundle_exports = {};
25
+ __export(bundle_exports, {
26
+ WebAuthnAbortService: () => WebAuthnAbortService,
27
+ WebAuthnError: () => WebAuthnError,
28
+ base64URLStringToBuffer: () => base64URLStringToBuffer,
29
+ browserSupportsWebAuthn: () => browserSupportsWebAuthn,
30
+ browserSupportsWebAuthnAutofill: () => browserSupportsWebAuthnAutofill,
31
+ bufferToBase64URLString: () => bufferToBase64URLString,
32
+ platformAuthenticatorIsAvailable: () => platformAuthenticatorIsAvailable,
33
+ startAuthentication: () => startAuthentication,
34
+ startRegistration: () => startRegistration
35
+ });
36
+ function bufferToBase64URLString(buffer) {
37
+ const bytes = new Uint8Array(buffer);
38
+ let str = "";
39
+ for (const charCode of bytes) {
40
+ str += String.fromCharCode(charCode);
41
+ }
42
+ const base64String = btoa(str);
43
+ return base64String.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
44
+ }
45
+ function base64URLStringToBuffer(base64URLString) {
46
+ const base64 = base64URLString.replace(/-/g, "+").replace(/_/g, "/");
47
+ const padLength = (4 - base64.length % 4) % 4;
48
+ const padded = base64.padEnd(base64.length + padLength, "=");
49
+ const binary = atob(padded);
50
+ const buffer = new ArrayBuffer(binary.length);
51
+ const bytes = new Uint8Array(buffer);
52
+ for (let i = 0; i < binary.length; i++) {
53
+ bytes[i] = binary.charCodeAt(i);
54
+ }
55
+ return buffer;
56
+ }
57
+ function browserSupportsWebAuthn() {
58
+ return window?.PublicKeyCredential !== void 0 && typeof window.PublicKeyCredential === "function";
59
+ }
60
+ function toPublicKeyCredentialDescriptor(descriptor) {
61
+ const { id } = descriptor;
62
+ return {
63
+ ...descriptor,
64
+ id: base64URLStringToBuffer(id),
65
+ transports: descriptor.transports
66
+ };
67
+ }
68
+ function isValidDomain(hostname) {
69
+ return hostname === "localhost" || /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i.test(hostname);
70
+ }
71
+ function identifyRegistrationError({ error, options }) {
72
+ const { publicKey } = options;
73
+ if (!publicKey) {
74
+ throw Error("options was missing required publicKey property");
75
+ }
76
+ if (error.name === "AbortError") {
77
+ if (options.signal instanceof AbortSignal) {
78
+ return new WebAuthnError({
79
+ message: "Registration ceremony was sent an abort signal",
80
+ code: "ERROR_CEREMONY_ABORTED",
81
+ cause: error
82
+ });
83
+ }
84
+ } else if (error.name === "ConstraintError") {
85
+ if (publicKey.authenticatorSelection?.requireResidentKey === true) {
86
+ return new WebAuthnError({
87
+ message: "Discoverable credentials were required but no available authenticator supported it",
88
+ code: "ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT",
89
+ cause: error
90
+ });
91
+ } else if (options.mediation === "conditional" && publicKey.authenticatorSelection?.userVerification === "required") {
92
+ return new WebAuthnError({
93
+ message: "User verification was required during automatic registration but it could not be performed",
94
+ code: "ERROR_AUTO_REGISTER_USER_VERIFICATION_FAILURE",
95
+ cause: error
96
+ });
97
+ } else if (publicKey.authenticatorSelection?.userVerification === "required") {
98
+ return new WebAuthnError({
99
+ message: "User verification was required but no available authenticator supported it",
100
+ code: "ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT",
101
+ cause: error
102
+ });
103
+ }
104
+ } else if (error.name === "InvalidStateError") {
105
+ return new WebAuthnError({
106
+ message: "The authenticator was previously registered",
107
+ code: "ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED",
108
+ cause: error
109
+ });
110
+ } else if (error.name === "NotAllowedError") {
111
+ return new WebAuthnError({
112
+ message: error.message,
113
+ code: "ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",
114
+ cause: error
115
+ });
116
+ } else if (error.name === "NotSupportedError") {
117
+ const validPubKeyCredParams = publicKey.pubKeyCredParams.filter((param) => param.type === "public-key");
118
+ if (validPubKeyCredParams.length === 0) {
119
+ return new WebAuthnError({
120
+ message: 'No entry in pubKeyCredParams was of type "public-key"',
121
+ code: "ERROR_MALFORMED_PUBKEYCREDPARAMS",
122
+ cause: error
123
+ });
124
+ }
125
+ return new WebAuthnError({
126
+ message: "No available authenticator supported any of the specified pubKeyCredParams algorithms",
127
+ code: "ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG",
128
+ cause: error
129
+ });
130
+ } else if (error.name === "SecurityError") {
131
+ const effectiveDomain = window.location.hostname;
132
+ if (!isValidDomain(effectiveDomain)) {
133
+ return new WebAuthnError({
134
+ message: `${window.location.hostname} is an invalid domain`,
135
+ code: "ERROR_INVALID_DOMAIN",
136
+ cause: error
137
+ });
138
+ } else if (publicKey.rp.id !== effectiveDomain) {
139
+ return new WebAuthnError({
140
+ message: `The RP ID "${publicKey.rp.id}" is invalid for this domain`,
141
+ code: "ERROR_INVALID_RP_ID",
142
+ cause: error
143
+ });
144
+ }
145
+ } else if (error.name === "TypeError") {
146
+ if (publicKey.user.id.byteLength < 1 || publicKey.user.id.byteLength > 64) {
147
+ return new WebAuthnError({
148
+ message: "User ID was not between 1 and 64 characters",
149
+ code: "ERROR_INVALID_USER_ID_LENGTH",
150
+ cause: error
151
+ });
152
+ }
153
+ } else if (error.name === "UnknownError") {
154
+ return new WebAuthnError({
155
+ message: "The authenticator was unable to process the specified options, or could not create a new credential",
156
+ code: "ERROR_AUTHENTICATOR_GENERAL_ERROR",
157
+ cause: error
158
+ });
159
+ }
160
+ return error;
161
+ }
162
+ function toAuthenticatorAttachment(attachment) {
163
+ if (!attachment) {
164
+ return;
165
+ }
166
+ if (attachments.indexOf(attachment) < 0) {
167
+ return;
168
+ }
169
+ return attachment;
170
+ }
171
+ async function startRegistration(options) {
172
+ const { optionsJSON, useAutoRegister = false } = options;
173
+ if (!browserSupportsWebAuthn()) {
174
+ throw new Error("WebAuthn is not supported in this browser");
175
+ }
176
+ const publicKey = {
177
+ ...optionsJSON,
178
+ challenge: base64URLStringToBuffer(optionsJSON.challenge),
179
+ user: {
180
+ ...optionsJSON.user,
181
+ id: base64URLStringToBuffer(optionsJSON.user.id)
182
+ },
183
+ excludeCredentials: optionsJSON.excludeCredentials?.map(toPublicKeyCredentialDescriptor)
184
+ };
185
+ const createOptions = {};
186
+ if (useAutoRegister) {
187
+ createOptions.mediation = "conditional";
188
+ }
189
+ createOptions.publicKey = publicKey;
190
+ createOptions.signal = WebAuthnAbortService.createNewAbortSignal();
191
+ let credential;
192
+ try {
193
+ credential = await navigator.credentials.create(createOptions);
194
+ } catch (err) {
195
+ throw identifyRegistrationError({ error: err, options: createOptions });
196
+ }
197
+ if (!credential) {
198
+ throw new Error("Registration was not completed");
199
+ }
200
+ const { id, rawId, response, type } = credential;
201
+ let transports = void 0;
202
+ if (typeof response.getTransports === "function") {
203
+ transports = response.getTransports();
204
+ }
205
+ let responsePublicKeyAlgorithm = void 0;
206
+ if (typeof response.getPublicKeyAlgorithm === "function") {
207
+ try {
208
+ responsePublicKeyAlgorithm = response.getPublicKeyAlgorithm();
209
+ } catch (error) {
210
+ warnOnBrokenImplementation("getPublicKeyAlgorithm()", error);
211
+ }
212
+ }
213
+ let responsePublicKey = void 0;
214
+ if (typeof response.getPublicKey === "function") {
215
+ try {
216
+ const _publicKey = response.getPublicKey();
217
+ if (_publicKey !== null) {
218
+ responsePublicKey = bufferToBase64URLString(_publicKey);
219
+ }
220
+ } catch (error) {
221
+ warnOnBrokenImplementation("getPublicKey()", error);
222
+ }
223
+ }
224
+ let responseAuthenticatorData;
225
+ if (typeof response.getAuthenticatorData === "function") {
226
+ try {
227
+ responseAuthenticatorData = bufferToBase64URLString(response.getAuthenticatorData());
228
+ } catch (error) {
229
+ warnOnBrokenImplementation("getAuthenticatorData()", error);
230
+ }
231
+ }
232
+ return {
233
+ id,
234
+ rawId: bufferToBase64URLString(rawId),
235
+ response: {
236
+ attestationObject: bufferToBase64URLString(response.attestationObject),
237
+ clientDataJSON: bufferToBase64URLString(response.clientDataJSON),
238
+ transports,
239
+ publicKeyAlgorithm: responsePublicKeyAlgorithm,
240
+ publicKey: responsePublicKey,
241
+ authenticatorData: responseAuthenticatorData
242
+ },
243
+ type,
244
+ clientExtensionResults: credential.getClientExtensionResults(),
245
+ authenticatorAttachment: toAuthenticatorAttachment(credential.authenticatorAttachment)
246
+ };
247
+ }
248
+ function warnOnBrokenImplementation(methodName, cause) {
249
+ console.warn(`The browser extension that intercepted this WebAuthn API call incorrectly implemented ${methodName}. You should report this error to them.
250
+ `, cause);
251
+ }
252
+ function browserSupportsWebAuthnAutofill() {
253
+ if (!browserSupportsWebAuthn()) {
254
+ return new Promise((resolve) => resolve(false));
255
+ }
256
+ const globalPublicKeyCredential = window.PublicKeyCredential;
257
+ if (globalPublicKeyCredential.isConditionalMediationAvailable === void 0) {
258
+ return new Promise((resolve) => resolve(false));
259
+ }
260
+ return globalPublicKeyCredential.isConditionalMediationAvailable();
261
+ }
262
+ function identifyAuthenticationError({ error, options }) {
263
+ const { publicKey } = options;
264
+ if (!publicKey) {
265
+ throw Error("options was missing required publicKey property");
266
+ }
267
+ if (error.name === "AbortError") {
268
+ if (options.signal instanceof AbortSignal) {
269
+ return new WebAuthnError({
270
+ message: "Authentication ceremony was sent an abort signal",
271
+ code: "ERROR_CEREMONY_ABORTED",
272
+ cause: error
273
+ });
274
+ }
275
+ } else if (error.name === "NotAllowedError") {
276
+ return new WebAuthnError({
277
+ message: error.message,
278
+ code: "ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",
279
+ cause: error
280
+ });
281
+ } else if (error.name === "SecurityError") {
282
+ const effectiveDomain = window.location.hostname;
283
+ if (!isValidDomain(effectiveDomain)) {
284
+ return new WebAuthnError({
285
+ message: `${window.location.hostname} is an invalid domain`,
286
+ code: "ERROR_INVALID_DOMAIN",
287
+ cause: error
288
+ });
289
+ } else if (publicKey.rpId !== effectiveDomain) {
290
+ return new WebAuthnError({
291
+ message: `The RP ID "${publicKey.rpId}" is invalid for this domain`,
292
+ code: "ERROR_INVALID_RP_ID",
293
+ cause: error
294
+ });
295
+ }
296
+ } else if (error.name === "UnknownError") {
297
+ return new WebAuthnError({
298
+ message: "The authenticator was unable to process the specified options, or could not create a new assertion signature",
299
+ code: "ERROR_AUTHENTICATOR_GENERAL_ERROR",
300
+ cause: error
301
+ });
302
+ }
303
+ return error;
304
+ }
305
+ async function startAuthentication(options) {
306
+ const { optionsJSON, useBrowserAutofill = false, verifyBrowserAutofillInput = true } = options;
307
+ if (!browserSupportsWebAuthn()) {
308
+ throw new Error("WebAuthn is not supported in this browser");
309
+ }
310
+ let allowCredentials;
311
+ if (optionsJSON.allowCredentials?.length !== 0) {
312
+ allowCredentials = optionsJSON.allowCredentials?.map(toPublicKeyCredentialDescriptor);
313
+ }
314
+ const publicKey = {
315
+ ...optionsJSON,
316
+ challenge: base64URLStringToBuffer(optionsJSON.challenge),
317
+ allowCredentials
318
+ };
319
+ const getOptions = {};
320
+ if (useBrowserAutofill) {
321
+ if (!await browserSupportsWebAuthnAutofill()) {
322
+ throw Error("Browser does not support WebAuthn autofill");
323
+ }
324
+ const eligibleInputs = document.querySelectorAll("input[autocomplete$='webauthn']");
325
+ if (eligibleInputs.length < 1 && verifyBrowserAutofillInput) {
326
+ throw Error('No <input> with "webauthn" as the only or last value in its `autocomplete` attribute was detected');
327
+ }
328
+ getOptions.mediation = "conditional";
329
+ publicKey.allowCredentials = [];
330
+ }
331
+ getOptions.publicKey = publicKey;
332
+ getOptions.signal = WebAuthnAbortService.createNewAbortSignal();
333
+ let credential;
334
+ try {
335
+ credential = await navigator.credentials.get(getOptions);
336
+ } catch (err) {
337
+ throw identifyAuthenticationError({ error: err, options: getOptions });
338
+ }
339
+ if (!credential) {
340
+ throw new Error("Authentication was not completed");
341
+ }
342
+ const { id, rawId, response, type } = credential;
343
+ let userHandle = void 0;
344
+ if (response.userHandle) {
345
+ userHandle = bufferToBase64URLString(response.userHandle);
346
+ }
347
+ return {
348
+ id,
349
+ rawId: bufferToBase64URLString(rawId),
350
+ response: {
351
+ authenticatorData: bufferToBase64URLString(response.authenticatorData),
352
+ clientDataJSON: bufferToBase64URLString(response.clientDataJSON),
353
+ signature: bufferToBase64URLString(response.signature),
354
+ userHandle
355
+ },
356
+ type,
357
+ clientExtensionResults: credential.getClientExtensionResults(),
358
+ authenticatorAttachment: toAuthenticatorAttachment(credential.authenticatorAttachment)
359
+ };
360
+ }
361
+ function platformAuthenticatorIsAvailable() {
362
+ if (!browserSupportsWebAuthn()) {
363
+ return new Promise((resolve) => resolve(false));
364
+ }
365
+ return PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable();
366
+ }
367
+ var WebAuthnError, BaseWebAuthnAbortService, WebAuthnAbortService, attachments;
368
+ var init_bundle = __esm({
369
+ "../../node_modules/@simplewebauthn/browser/dist/bundle/index.js"() {
370
+ "use strict";
371
+ WebAuthnError = class extends Error {
372
+ constructor({ message, code, cause, name }) {
373
+ super(message, { cause });
374
+ this.name = name ?? cause.name;
375
+ this.code = code;
376
+ }
377
+ };
378
+ BaseWebAuthnAbortService = class {
379
+ createNewAbortSignal() {
380
+ if (this.controller) {
381
+ const abortError = new Error("Cancelling existing WebAuthn API call for new one");
382
+ abortError.name = "AbortError";
383
+ this.controller.abort(abortError);
384
+ }
385
+ const newController = new AbortController();
386
+ this.controller = newController;
387
+ return newController.signal;
388
+ }
389
+ cancelCeremony() {
390
+ if (this.controller) {
391
+ const abortError = new Error("Manually cancelling existing WebAuthn API call");
392
+ abortError.name = "AbortError";
393
+ this.controller.abort(abortError);
394
+ this.controller = void 0;
395
+ }
396
+ }
397
+ };
398
+ WebAuthnAbortService = new BaseWebAuthnAbortService();
399
+ attachments = ["cross-platform", "platform"];
400
+ }
401
+ });
402
+
20
403
  // src/browser.ts
21
404
  var browser_exports = {};
22
405
  __export(browser_exports, {
406
+ AccountRegistry: () => AccountRegistry,
23
407
  ErrorCodes: () => ErrorCodes,
24
408
  IQAuthError: () => IQAuthError,
409
+ MultiAccountTokenStore: () => MultiAccountTokenStore,
410
+ PRIOR_SESSION_STORAGE_KEY: () => PRIOR_SESSION_STORAGE_KEY,
25
411
  REFRESH_COOKIE: () => REFRESH_COOKIE,
26
412
  SessionManager: () => SessionManager,
413
+ beginPasskeyAuthentication: () => beginPasskeyAuthentication,
414
+ beginPasskeyRegistration: () => beginPasskeyRegistration,
27
415
  buildSignInUrl: () => buildSignInUrl,
28
416
  clearCookie: () => clearCookie,
29
417
  createPkcePair: () => createPkcePair,
30
418
  encodePublishableKey: () => encodePublishableKey,
419
+ enrollPasskey: () => enrollPasskey,
420
+ enterImpersonation: () => enterImpersonation,
421
+ exitImpersonation: () => exitImpersonation,
422
+ finishPasskeyAuthentication: () => finishPasskeyAuthentication,
423
+ finishPasskeyRegistration: () => finishPasskeyRegistration,
31
424
  getCookie: () => getCookie,
32
425
  handleAuthCallback: () => handleAuthCallback,
33
426
  isPublishableKey: () => isPublishableKey,
34
427
  isSecretKey: () => isSecretKey,
428
+ linkProvider: () => linkProvider,
429
+ listLinkedIdentities: () => listLinkedIdentities,
35
430
  parsePublishableKey: () => parsePublishableKey,
36
431
  randomUrlSafe: () => randomUrlSafe,
37
432
  redirectToSignIn: () => redirectToSignIn,
433
+ requestMagicLink: () => requestMagicLink,
434
+ reverify: () => reverify,
38
435
  s256Challenge: () => s256Challenge,
39
436
  setCookie: () => setCookie,
40
437
  signIn: () => signIn,
41
- signOut: () => signOut
438
+ signInWithPasskey: () => signInWithPasskey,
439
+ signOut: () => signOut,
440
+ unlinkProvider: () => unlinkProvider,
441
+ verifyMagicLink: () => verifyMagicLink,
442
+ withReverification: () => withReverification
42
443
  });
43
444
  module.exports = __toCommonJS(browser_exports);
44
445
 
@@ -257,6 +658,20 @@ function clearPkce(state) {
257
658
  // src/browser/sessionManager.ts
258
659
  var DEFAULT_REFRESH_PATH = "/api/v1/auth/refresh";
259
660
  var DEFAULT_USERINFO_PATH = "/api/v1/auth/me";
661
+ async function readAuthErrorCode(res) {
662
+ try {
663
+ const cloned = res.clone();
664
+ const data = await cloned.json().catch(() => null);
665
+ if (!data || typeof data !== "object") return null;
666
+ const err = data.error;
667
+ if (err && typeof err.code === "string") {
668
+ return { code: err.code, message: typeof err.message === "string" ? err.message : void 0 };
669
+ }
670
+ return null;
671
+ } catch {
672
+ return null;
673
+ }
674
+ }
260
675
  function decodeClaims(token) {
261
676
  try {
262
677
  const parts = token.split(".");
@@ -290,11 +705,11 @@ var EMPTY = {
290
705
  error: null,
291
706
  version: 0
292
707
  };
293
- function defaultCookieStore() {
708
+ function defaultCookieStore(name = REFRESH_COOKIE) {
294
709
  return {
295
- read: () => getCookie(REFRESH_COOKIE),
296
- write: (token) => setCookie(REFRESH_COOKIE, token, { maxAgeSeconds: 60 * 60 * 24 * 30 }),
297
- clear: () => clearCookie(REFRESH_COOKIE)
710
+ read: () => getCookie(name),
711
+ write: (token) => setCookie(name, token, { maxAgeSeconds: 60 * 60 * 24 * 30 }),
712
+ clear: () => clearCookie(name)
298
713
  };
299
714
  }
300
715
  var NO_OP_STORE = {
@@ -323,7 +738,8 @@ var SessionManager = class {
323
738
  this.useCookies = options.useCookies ?? true;
324
739
  this.serverManagedSession = options.serverManagedSession ?? false;
325
740
  this.proactiveRefresh = this.serverManagedSession ? false : options.proactiveRefresh ?? true;
326
- this.tokenStore = options.tokenStore ?? (this.serverManagedSession ? NO_OP_STORE : this.useCookies ? defaultCookieStore() : NO_OP_STORE);
741
+ this.refreshCookieName = options.cookieNames?.refresh ?? REFRESH_COOKIE;
742
+ this.tokenStore = options.tokenStore ?? (this.serverManagedSession ? NO_OP_STORE : this.useCookies ? defaultCookieStore(this.refreshCookieName) : NO_OP_STORE);
327
743
  this.crossTabLockTimeoutMs = options.crossTabLockTimeoutMs ?? 4e3;
328
744
  this.fetchImpl = options.fetchImpl ?? (typeof fetch !== "undefined" ? fetch.bind(globalThis) : (() => {
329
745
  throw new Error("global fetch is not available; pass fetchImpl");
@@ -351,6 +767,10 @@ var SessionManager = class {
351
767
  get issuerUrl() {
352
768
  return this.issuer;
353
769
  }
770
+ /** Cookie name the SDK uses for the refresh token (overridable via `cookieNames.refresh`). */
771
+ get refreshCookie() {
772
+ return this.refreshCookieName;
773
+ }
354
774
  getSnapshot() {
355
775
  return this.snapshot;
356
776
  }
@@ -457,7 +877,7 @@ var SessionManager = class {
457
877
  return false;
458
878
  }
459
879
  if (data.refreshToken) {
460
- await Promise.resolve(this.tokenStore.write(data.refreshToken));
880
+ await Promise.resolve(this.tokenStore.write(data.refreshToken, { claims: decodeClaims(data.accessToken) }));
461
881
  }
462
882
  this.applyAccessToken(data.accessToken);
463
883
  this.broadcast("session:refresh");
@@ -501,7 +921,7 @@ var SessionManager = class {
501
921
  const claims = decodeClaims(accessToken);
502
922
  const user = claimsToSessionUser(claims);
503
923
  if (refreshToken) {
504
- void Promise.resolve(this.tokenStore.write(refreshToken));
924
+ void Promise.resolve(this.tokenStore.write(refreshToken, { claims }));
505
925
  }
506
926
  this.update({
507
927
  status: user ? "authenticated" : "unauthenticated",
@@ -535,33 +955,39 @@ var SessionManager = class {
535
955
  */
536
956
  async fetch(input, init = {}) {
537
957
  const exec = async (token2) => {
538
- const headers = new Headers(init.headers || {});
539
- if (token2) headers.set("Authorization", `Bearer ${token2}`);
958
+ const headers2 = new Headers(init.headers || {});
959
+ if (token2) headers2.set("Authorization", `Bearer ${token2}`);
540
960
  return this.fetchImpl(input, {
541
961
  ...init,
542
- headers,
962
+ headers: headers2,
543
963
  credentials: init.credentials ?? "include"
544
964
  });
545
965
  };
546
966
  let token = await this.getToken();
547
967
  let res = await exec(token);
548
968
  if (res.status !== 401) return res;
969
+ const initialErr = await readAuthErrorCode(res);
970
+ if (initialErr && (initialErr.code === "SESSION_EXPIRED_INACTIVITY" || initialErr.code === "SESSION_EXPIRED_MAX_DURATION" || initialErr.code === "SESSION_INVALID")) {
971
+ this.signOutLocal("unauthenticated");
972
+ throw new IQAuthError(initialErr.code, initialErr.message || "Session expired", 401);
973
+ }
549
974
  const refreshed = await this.refresh();
550
975
  if (!refreshed) {
551
976
  this.signOutLocal("unauthenticated");
552
977
  throw new IQAuthError(
553
- "TOKEN_EXPIRED",
554
- "Session refresh failed; user must sign in again",
978
+ initialErr?.code || "TOKEN_EXPIRED",
979
+ initialErr?.message || "Session refresh failed; user must sign in again",
555
980
  401
556
981
  );
557
982
  }
558
983
  token = this.snapshot.accessToken;
559
984
  res = await exec(token);
560
985
  if (res.status === 401) {
986
+ const secondErr = await readAuthErrorCode(res);
561
987
  this.signOutLocal("unauthenticated");
562
988
  throw new IQAuthError(
563
- "TOKEN_EXPIRED",
564
- "Authenticated request failed twice with 401; aborting",
989
+ secondErr?.code || "TOKEN_EXPIRED",
990
+ secondErr?.message || "Authenticated request failed twice with 401; aborting",
565
991
  401
566
992
  );
567
993
  }
@@ -589,6 +1015,14 @@ var SessionManager = class {
589
1015
  });
590
1016
  this.broadcast("session:signout");
591
1017
  }
1018
+ /**
1019
+ * Replace the refresh-token store at runtime. Used by the F22
1020
+ * `<MultisessionAppSupport>` wrapper to swap in a `MultiAccountTokenStore`
1021
+ * after the manager has already been constructed by `<IQAuthProvider>`.
1022
+ */
1023
+ setTokenStore(store) {
1024
+ this.tokenStore = store;
1025
+ }
592
1026
  destroy() {
593
1027
  if (this.proactiveTimer) clearTimeout(this.proactiveTimer);
594
1028
  this.proactiveTimer = null;
@@ -681,6 +1115,217 @@ var SessionManager = class {
681
1115
  }
682
1116
  };
683
1117
 
1118
+ // src/browser/passwordless.ts
1119
+ function url(base, path) {
1120
+ return `${base.replace(/\/+$/, "")}${path}`;
1121
+ }
1122
+ function headers(o) {
1123
+ const h = { "Content-Type": "application/json" };
1124
+ if (o.cookieSession !== false) h["x-iqauth-session"] = "cookie";
1125
+ return h;
1126
+ }
1127
+ async function postJson(u, body, h) {
1128
+ const r = await fetch(u, {
1129
+ method: "POST",
1130
+ credentials: "include",
1131
+ headers: h,
1132
+ body: JSON.stringify(body)
1133
+ });
1134
+ const p = await r.json().catch(() => ({}));
1135
+ if (!r.ok) {
1136
+ const msg = p?.error?.message || `Request failed (${r.status})`;
1137
+ throw new Error(msg);
1138
+ }
1139
+ return p.data;
1140
+ }
1141
+ async function requestMagicLink(opts, input) {
1142
+ await postJson(url(opts.iqAuthBaseUrl, "/api/v1/auth/magic-link/request"), input, headers(opts));
1143
+ return { ok: true };
1144
+ }
1145
+ async function verifyMagicLink(opts, token) {
1146
+ return postJson(url(opts.iqAuthBaseUrl, "/api/v1/auth/magic-link/verify"), { token }, headers(opts));
1147
+ }
1148
+ async function beginPasskeyAuthentication(opts, input = {}) {
1149
+ return postJson(url(opts.iqAuthBaseUrl, "/api/v1/auth/passkeys/authentication/options"), input, headers(opts));
1150
+ }
1151
+ async function finishPasskeyAuthentication(opts, response) {
1152
+ return postJson(url(opts.iqAuthBaseUrl, "/api/v1/auth/passkeys/authentication/verify"), { response }, headers(opts));
1153
+ }
1154
+ async function beginPasskeyRegistration(opts) {
1155
+ return postJson(url(opts.iqAuthBaseUrl, "/api/v1/auth/passkeys/registration/options"), {}, headers(opts));
1156
+ }
1157
+ async function finishPasskeyRegistration(opts, response, name) {
1158
+ return postJson(url(opts.iqAuthBaseUrl, "/api/v1/auth/passkeys/registration/verify"), { response, name }, headers(opts));
1159
+ }
1160
+ async function signInWithPasskey(opts, input = {}) {
1161
+ const mod = await Promise.resolve().then(() => (init_bundle(), bundle_exports));
1162
+ const options = await beginPasskeyAuthentication(opts, input);
1163
+ const response = await mod.startAuthentication({ optionsJSON: options });
1164
+ return finishPasskeyAuthentication(opts, response);
1165
+ }
1166
+ async function enrollPasskey(opts, name) {
1167
+ const mod = await Promise.resolve().then(() => (init_bundle(), bundle_exports));
1168
+ const options = await beginPasskeyRegistration(opts);
1169
+ const response = await mod.startRegistration({ optionsJSON: options });
1170
+ return finishPasskeyRegistration(opts, response, name);
1171
+ }
1172
+ async function listLinkedIdentities(opts) {
1173
+ const r = await fetch(url(opts.iqAuthBaseUrl, "/api/v1/auth/identities"), { credentials: "include" });
1174
+ const p = await r.json().catch(() => ({}));
1175
+ if (!r.ok) throw new Error(p?.error?.message || `Request failed (${r.status})`);
1176
+ return p?.data?.identities ?? [];
1177
+ }
1178
+ async function linkProvider(opts, input) {
1179
+ await postJson(url(opts.iqAuthBaseUrl, "/api/v1/auth/identities/link"), input, headers(opts));
1180
+ return { ok: true };
1181
+ }
1182
+ async function unlinkProvider(opts, input) {
1183
+ await postJson(url(opts.iqAuthBaseUrl, "/api/v1/auth/identities/unlink"), input, headers(opts));
1184
+ return { ok: true };
1185
+ }
1186
+
1187
+ // src/browser/accountRegistry.ts
1188
+ var STORAGE_PREFIX = "iqauth.accounts.";
1189
+ var COOKIE_PREFIX = "iqauth_rt_";
1190
+ var COOKIE_MAX_AGE = 60 * 60 * 24 * 30;
1191
+ function isBrowser2() {
1192
+ return typeof window !== "undefined" && typeof localStorage !== "undefined";
1193
+ }
1194
+ function storageKey(appId) {
1195
+ return STORAGE_PREFIX + appId;
1196
+ }
1197
+ function readState(appId) {
1198
+ if (!isBrowser2()) return { accounts: [], activeAccountId: null };
1199
+ try {
1200
+ const raw = localStorage.getItem(storageKey(appId));
1201
+ if (!raw) return { accounts: [], activeAccountId: null };
1202
+ const parsed = JSON.parse(raw);
1203
+ return {
1204
+ accounts: Array.isArray(parsed.accounts) ? parsed.accounts : [],
1205
+ activeAccountId: parsed.activeAccountId ?? null
1206
+ };
1207
+ } catch {
1208
+ return { accounts: [], activeAccountId: null };
1209
+ }
1210
+ }
1211
+ function writeState(appId, state) {
1212
+ if (!isBrowser2()) return;
1213
+ try {
1214
+ localStorage.setItem(storageKey(appId), JSON.stringify(state));
1215
+ } catch {
1216
+ }
1217
+ }
1218
+ var AccountRegistry = class {
1219
+ constructor(appId) {
1220
+ this.appId = appId;
1221
+ this.listeners = /* @__PURE__ */ new Set();
1222
+ this.storageHandler = null;
1223
+ if (isBrowser2()) {
1224
+ this.storageHandler = (ev) => {
1225
+ if (ev.key === storageKey(this.appId)) {
1226
+ for (const l of this.listeners) l();
1227
+ }
1228
+ };
1229
+ window.addEventListener("storage", this.storageHandler);
1230
+ }
1231
+ }
1232
+ destroy() {
1233
+ if (this.storageHandler && isBrowser2()) {
1234
+ window.removeEventListener("storage", this.storageHandler);
1235
+ }
1236
+ this.listeners.clear();
1237
+ }
1238
+ list() {
1239
+ return readState(this.appId).accounts.slice();
1240
+ }
1241
+ active() {
1242
+ return readState(this.appId).activeAccountId;
1243
+ }
1244
+ get(accountId) {
1245
+ return readState(this.appId).accounts.find((a) => a.accountId === accountId) ?? null;
1246
+ }
1247
+ upsert(rec) {
1248
+ const state = readState(this.appId);
1249
+ const idx = state.accounts.findIndex((a) => a.accountId === rec.accountId);
1250
+ if (idx >= 0) state.accounts[idx] = { ...state.accounts[idx], ...rec };
1251
+ else state.accounts.push(rec);
1252
+ writeState(this.appId, state);
1253
+ this.notify();
1254
+ }
1255
+ setActive(accountId) {
1256
+ const state = readState(this.appId);
1257
+ state.activeAccountId = accountId;
1258
+ writeState(this.appId, state);
1259
+ this.notify();
1260
+ }
1261
+ remove(accountId) {
1262
+ const state = readState(this.appId);
1263
+ state.accounts = state.accounts.filter((a) => a.accountId !== accountId);
1264
+ if (state.activeAccountId === accountId) state.activeAccountId = state.accounts[0]?.accountId ?? null;
1265
+ writeState(this.appId, state);
1266
+ clearCookie(COOKIE_PREFIX + accountId);
1267
+ this.notify();
1268
+ }
1269
+ subscribe(listener) {
1270
+ this.listeners.add(listener);
1271
+ return () => this.listeners.delete(listener);
1272
+ }
1273
+ /**
1274
+ * Read the refresh token for a specific account from its per-account
1275
+ * cookie. Used by `MultiAccountTokenStore.read()`.
1276
+ */
1277
+ readRefreshToken(accountId) {
1278
+ return getCookie(COOKIE_PREFIX + accountId);
1279
+ }
1280
+ /**
1281
+ * Persist a refresh token to the per-account cookie. Caller is the
1282
+ * SessionManager via `MultiAccountTokenStore.write()`.
1283
+ */
1284
+ writeRefreshToken(accountId, token, opts = {}) {
1285
+ setCookie(COOKIE_PREFIX + accountId, token, { maxAgeSeconds: COOKIE_MAX_AGE, ...opts });
1286
+ }
1287
+ clearRefreshToken(accountId) {
1288
+ clearCookie(COOKIE_PREFIX + accountId);
1289
+ }
1290
+ notify() {
1291
+ for (const l of this.listeners) l();
1292
+ }
1293
+ };
1294
+ var MultiAccountTokenStore = class {
1295
+ constructor(registry, fallback) {
1296
+ this.registry = registry;
1297
+ this.fallback = fallback;
1298
+ }
1299
+ read() {
1300
+ const id = this.registry.active();
1301
+ if (id) return this.registry.readRefreshToken(id);
1302
+ return this.fallback.read();
1303
+ }
1304
+ write(token, ctx) {
1305
+ let id = this.registry.active();
1306
+ if (!id) {
1307
+ const sub = ctx?.claims?.sub;
1308
+ if (sub) {
1309
+ id = sub;
1310
+ this.registry.setActive(sub);
1311
+ }
1312
+ }
1313
+ if (id) {
1314
+ this.registry.writeRefreshToken(id, token);
1315
+ return;
1316
+ }
1317
+ return this.fallback.write(token);
1318
+ }
1319
+ clear() {
1320
+ const id = this.registry.active();
1321
+ if (id) {
1322
+ this.registry.clearRefreshToken(id);
1323
+ return;
1324
+ }
1325
+ return this.fallback.clear();
1326
+ }
1327
+ };
1328
+
684
1329
  // src/browser/pkce.ts
685
1330
  function getCrypto() {
686
1331
  if (typeof globalThis !== "undefined" && globalThis.crypto) {
@@ -741,34 +1386,35 @@ async function buildSignInUrl(manager, opts = {}) {
741
1386
  returnTo,
742
1387
  createdAt: Date.now()
743
1388
  });
744
- const url = new URL(opts.signInPath ?? DEFAULT_SIGN_IN_PATH, manager.issuerUrl);
745
- url.searchParams.set("response_type", "code");
746
- url.searchParams.set("app", manager.appKey);
747
- url.searchParams.set("publishable_key", manager.publishableKey.raw);
748
- url.searchParams.set("redirect_uri", redirectUri);
749
- url.searchParams.set("state", pkce.state);
750
- url.searchParams.set("nonce", pkce.nonce);
751
- url.searchParams.set("code_challenge", pkce.codeChallenge);
752
- url.searchParams.set("code_challenge_method", "S256");
753
- url.searchParams.set("scope", opts.scope ?? "openid profile email");
754
- url.searchParams.set("return_to", returnTo);
755
- return url.toString();
1389
+ const url2 = new URL(opts.signInPath ?? DEFAULT_SIGN_IN_PATH, manager.issuerUrl);
1390
+ url2.searchParams.set("response_type", "code");
1391
+ url2.searchParams.set("app", manager.appKey);
1392
+ url2.searchParams.set("publishable_key", manager.publishableKey.raw);
1393
+ url2.searchParams.set("redirect_uri", redirectUri);
1394
+ url2.searchParams.set("state", pkce.state);
1395
+ url2.searchParams.set("nonce", pkce.nonce);
1396
+ url2.searchParams.set("code_challenge", pkce.codeChallenge);
1397
+ url2.searchParams.set("code_challenge_method", "S256");
1398
+ url2.searchParams.set("scope", opts.scope ?? "openid profile email");
1399
+ url2.searchParams.set("return_to", returnTo);
1400
+ if (opts.prompt) url2.searchParams.set("prompt", opts.prompt);
1401
+ return url2.toString();
756
1402
  }
757
1403
  async function redirectToSignIn(manager, opts = {}) {
758
- const url = await buildSignInUrl(manager, opts);
1404
+ const url2 = await buildSignInUrl(manager, opts);
759
1405
  if (typeof window === "undefined") {
760
1406
  throw new Error("redirectToSignIn requires a browser environment");
761
1407
  }
762
- window.location.assign(url);
1408
+ window.location.assign(url2);
763
1409
  }
764
1410
  async function signIn(manager, opts = {}) {
765
1411
  return redirectToSignIn(manager, opts);
766
1412
  }
767
1413
  async function handleAuthCallback(manager, options = {}) {
768
- const url = new URL(options.url ?? (typeof window !== "undefined" ? window.location.href : ""));
769
- const code = url.searchParams.get("code");
770
- const state = url.searchParams.get("state");
771
- const errorParam = url.searchParams.get("error");
1414
+ const url2 = new URL(options.url ?? (typeof window !== "undefined" ? window.location.href : ""));
1415
+ const code = url2.searchParams.get("code");
1416
+ const state = url2.searchParams.get("state");
1417
+ const errorParam = url2.searchParams.get("error");
772
1418
  if (errorParam) {
773
1419
  return { ok: false, returnTo: "/", error: errorParam };
774
1420
  }
@@ -807,7 +1453,8 @@ async function handleAuthCallback(manager, options = {}) {
807
1453
  return { ok: false, returnTo: record.returnTo, error: "missing_access_token" };
808
1454
  }
809
1455
  if (tokens.refresh_token) {
810
- setCookie(REFRESH_COOKIE, tokens.refresh_token, { maxAgeSeconds: 60 * 60 * 24 * 30 });
1456
+ const cookieName = options.cookieNames?.refresh ?? manager.refreshCookie ?? REFRESH_COOKIE;
1457
+ setCookie(cookieName, tokens.refresh_token, { maxAgeSeconds: 60 * 60 * 24 * 30 });
811
1458
  }
812
1459
  manager.applyAccessToken(tokens.access_token, tokens.refresh_token);
813
1460
  return { ok: true, returnTo: record.returnTo };
@@ -816,8 +1463,8 @@ async function signOut(manager, opts = {}) {
816
1463
  if (!opts.localOnly) {
817
1464
  const issuer = manager.issuerUrl.replace(/\/$/, "");
818
1465
  try {
819
- const url = `${issuer}${opts.logoutPath ?? DEFAULT_LOGOUT_PATH}`;
820
- await manager.fetch(url, { method: "POST" }).catch(() => void 0);
1466
+ const url2 = `${issuer}${opts.logoutPath ?? DEFAULT_LOGOUT_PATH}`;
1467
+ await manager.fetch(url2, { method: "POST" }).catch(() => void 0);
821
1468
  } catch {
822
1469
  }
823
1470
  if (opts.endSsoSession !== false) {
@@ -830,31 +1477,128 @@ async function signOut(manager, opts = {}) {
830
1477
  }
831
1478
  }
832
1479
  }
833
- clearCookie(REFRESH_COOKIE);
1480
+ clearCookie(manager.refreshCookie ?? REFRESH_COOKIE);
834
1481
  manager.signOutLocal();
835
1482
  if (opts.returnTo && typeof window !== "undefined") {
836
1483
  window.location.assign(opts.returnTo);
837
1484
  }
838
1485
  }
1486
+
1487
+ // src/browser/reverify.ts
1488
+ var PRIOR_SESSION_STORAGE_KEY = "iqauth_prior_admin_session";
1489
+ function enterImpersonation(manager, actorAccessToken) {
1490
+ if (typeof window === "undefined") return;
1491
+ const current = manager.getSnapshot().accessToken;
1492
+ if (current) {
1493
+ const envelope = { accessToken: current, savedAt: Date.now() };
1494
+ try {
1495
+ window.sessionStorage.setItem(PRIOR_SESSION_STORAGE_KEY, JSON.stringify(envelope));
1496
+ } catch {
1497
+ }
1498
+ }
1499
+ manager.applyAccessToken(actorAccessToken);
1500
+ }
1501
+ function exitImpersonation(manager) {
1502
+ if (typeof window === "undefined") return false;
1503
+ let raw = null;
1504
+ try {
1505
+ raw = window.sessionStorage.getItem(PRIOR_SESSION_STORAGE_KEY);
1506
+ } catch {
1507
+ return false;
1508
+ }
1509
+ if (!raw) return false;
1510
+ try {
1511
+ const envelope = JSON.parse(raw);
1512
+ if (!envelope?.accessToken) return false;
1513
+ manager.applyAccessToken(envelope.accessToken);
1514
+ return true;
1515
+ } catch {
1516
+ return false;
1517
+ } finally {
1518
+ try {
1519
+ window.sessionStorage.removeItem(PRIOR_SESSION_STORAGE_KEY);
1520
+ } catch {
1521
+ }
1522
+ }
1523
+ }
1524
+ var DEFAULT_REVERIFY_PATH = "/api/v1/auth/reverify";
1525
+ async function reverify(manager, input, options = {}) {
1526
+ if (input.level === "password" && !input.password) {
1527
+ throw new IQAuthError("MISSING_PASSWORD", "password is required for level=password");
1528
+ }
1529
+ if (input.level === "mfa" && !input.totp) {
1530
+ throw new IQAuthError("MISSING_CODE", "totp code is required for level=mfa");
1531
+ }
1532
+ const issuer = manager.issuerUrl.replace(/\/$/, "");
1533
+ const url2 = `${issuer}${options.path ?? DEFAULT_REVERIFY_PATH}`;
1534
+ const res = await manager.fetch(url2, {
1535
+ method: "POST",
1536
+ headers: { "Content-Type": "application/json" },
1537
+ body: JSON.stringify(input)
1538
+ });
1539
+ let payload = null;
1540
+ try {
1541
+ payload = await res.json();
1542
+ } catch {
1543
+ }
1544
+ if (!res.ok || !payload?.success) {
1545
+ const code = payload?.error?.code ?? "REVERIFICATION_FAILED";
1546
+ const message = payload?.error?.message ?? `reverification failed (${res.status})`;
1547
+ throw new IQAuthError(code, message);
1548
+ }
1549
+ return {
1550
+ token: payload.data.reverificationToken,
1551
+ level: payload.data.level,
1552
+ expiresAt: new Date(payload.data.expiresAt)
1553
+ };
1554
+ }
1555
+ function withReverification(manager, token) {
1556
+ let used = false;
1557
+ return async (input, init = {}) => {
1558
+ if (used) throw new IQAuthError("REVERIFICATION_USED", "Reverification token already consumed");
1559
+ used = true;
1560
+ const headers2 = new Headers(init.headers);
1561
+ headers2.set("X-Reverification-Token", token);
1562
+ return manager.fetch(input, { ...init, headers: headers2 });
1563
+ };
1564
+ }
839
1565
  // Annotate the CommonJS export names for ESM import in node:
840
1566
  0 && (module.exports = {
1567
+ AccountRegistry,
841
1568
  ErrorCodes,
842
1569
  IQAuthError,
1570
+ MultiAccountTokenStore,
1571
+ PRIOR_SESSION_STORAGE_KEY,
843
1572
  REFRESH_COOKIE,
844
1573
  SessionManager,
1574
+ beginPasskeyAuthentication,
1575
+ beginPasskeyRegistration,
845
1576
  buildSignInUrl,
846
1577
  clearCookie,
847
1578
  createPkcePair,
848
1579
  encodePublishableKey,
1580
+ enrollPasskey,
1581
+ enterImpersonation,
1582
+ exitImpersonation,
1583
+ finishPasskeyAuthentication,
1584
+ finishPasskeyRegistration,
849
1585
  getCookie,
850
1586
  handleAuthCallback,
851
1587
  isPublishableKey,
852
1588
  isSecretKey,
1589
+ linkProvider,
1590
+ listLinkedIdentities,
853
1591
  parsePublishableKey,
854
1592
  randomUrlSafe,
855
1593
  redirectToSignIn,
1594
+ requestMagicLink,
1595
+ reverify,
856
1596
  s256Challenge,
857
1597
  setCookie,
858
1598
  signIn,
859
- signOut
1599
+ signInWithPasskey,
1600
+ signOut,
1601
+ unlinkProvider,
1602
+ verifyMagicLink,
1603
+ withReverification
860
1604
  });