@omni2fa/core 0.6.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 (75) hide show
  1. package/dist/Interfaces/IOmni2Fa.d.ts +18 -0
  2. package/dist/Interfaces/IOmni2Fa.d.ts.map +1 -0
  3. package/dist/client/Interfaces/ClientCall.d.ts +5 -0
  4. package/dist/client/Interfaces/ClientCall.d.ts.map +1 -0
  5. package/dist/client/Interfaces/ClientCallError.d.ts +9 -0
  6. package/dist/client/Interfaces/ClientCallError.d.ts.map +1 -0
  7. package/dist/client/Interfaces/ClientCallResult.d.ts +6 -0
  8. package/dist/client/Interfaces/ClientCallResult.d.ts.map +1 -0
  9. package/dist/client/Interfaces/IOmni2FaClient.d.ts +26 -0
  10. package/dist/client/Interfaces/IOmni2FaClient.d.ts.map +1 -0
  11. package/dist/client/Omni2FaClient.d.ts +36 -0
  12. package/dist/client/Omni2FaClient.d.ts.map +1 -0
  13. package/dist/client/Omni2FaClientConfig.d.ts +20 -0
  14. package/dist/client/Omni2FaClientConfig.d.ts.map +1 -0
  15. package/dist/createOmni2Fa.d.ts +8 -0
  16. package/dist/createOmni2Fa.d.ts.map +1 -0
  17. package/dist/errors/Omni2FaApiError.d.ts +12 -0
  18. package/dist/errors/Omni2FaApiError.d.ts.map +1 -0
  19. package/dist/errors/codes.d.ts +20 -0
  20. package/dist/errors/codes.d.ts.map +1 -0
  21. package/dist/errors/messages.d.ts +2 -0
  22. package/dist/errors/messages.d.ts.map +1 -0
  23. package/dist/index.cjs +2 -0
  24. package/dist/index.cjs.map +1 -0
  25. package/dist/index.d.ts +39 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +915 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/machines/challenge/ChallengeContext.d.ts +16 -0
  30. package/dist/machines/challenge/ChallengeContext.d.ts.map +1 -0
  31. package/dist/machines/challenge/ChallengeEvent.d.ts +16 -0
  32. package/dist/machines/challenge/ChallengeEvent.d.ts.map +1 -0
  33. package/dist/machines/challenge/challengeMachine.d.ts +105 -0
  34. package/dist/machines/challenge/challengeMachine.d.ts.map +1 -0
  35. package/dist/machines/emailEnrollment/EmailEnrollmentContext.d.ts +15 -0
  36. package/dist/machines/emailEnrollment/EmailEnrollmentContext.d.ts.map +1 -0
  37. package/dist/machines/emailEnrollment/EmailEnrollmentEvent.d.ts +14 -0
  38. package/dist/machines/emailEnrollment/EmailEnrollmentEvent.d.ts.map +1 -0
  39. package/dist/machines/emailEnrollment/emailEnrollmentMachine.d.ts +71 -0
  40. package/dist/machines/emailEnrollment/emailEnrollmentMachine.d.ts.map +1 -0
  41. package/dist/machines/methods/MethodsContext.d.ts +8 -0
  42. package/dist/machines/methods/MethodsContext.d.ts.map +1 -0
  43. package/dist/machines/methods/MethodsEvent.d.ts +10 -0
  44. package/dist/machines/methods/MethodsEvent.d.ts.map +1 -0
  45. package/dist/machines/methods/methodsMachine.d.ts +43 -0
  46. package/dist/machines/methods/methodsMachine.d.ts.map +1 -0
  47. package/dist/machines/totpEnrollment/TotpEnrollmentContext.d.ts +12 -0
  48. package/dist/machines/totpEnrollment/TotpEnrollmentContext.d.ts.map +1 -0
  49. package/dist/machines/totpEnrollment/TotpEnrollmentEvent.d.ts +11 -0
  50. package/dist/machines/totpEnrollment/TotpEnrollmentEvent.d.ts.map +1 -0
  51. package/dist/machines/totpEnrollment/totpEnrollmentMachine.d.ts +50 -0
  52. package/dist/machines/totpEnrollment/totpEnrollmentMachine.d.ts.map +1 -0
  53. package/dist/machines/webauthnEnrollment/WebAuthnEnrollmentContext.d.ts +12 -0
  54. package/dist/machines/webauthnEnrollment/WebAuthnEnrollmentContext.d.ts.map +1 -0
  55. package/dist/machines/webauthnEnrollment/WebAuthnEnrollmentEvent.d.ts +10 -0
  56. package/dist/machines/webauthnEnrollment/WebAuthnEnrollmentEvent.d.ts.map +1 -0
  57. package/dist/machines/webauthnEnrollment/webauthnEnrollmentMachine.d.ts +47 -0
  58. package/dist/machines/webauthnEnrollment/webauthnEnrollmentMachine.d.ts.map +1 -0
  59. package/dist/storage/Interfaces/IStorage.d.ts +10 -0
  60. package/dist/storage/Interfaces/IStorage.d.ts.map +1 -0
  61. package/dist/storage/LocalStorageStorage.d.ts +8 -0
  62. package/dist/storage/LocalStorageStorage.d.ts.map +1 -0
  63. package/dist/storage/MemoryStorage.d.ts +9 -0
  64. package/dist/storage/MemoryStorage.d.ts.map +1 -0
  65. package/dist/storage/SessionStorageStorage.d.ts +8 -0
  66. package/dist/storage/SessionStorageStorage.d.ts.map +1 -0
  67. package/dist/types/api.d.ts +1075 -0
  68. package/dist/types/api.d.ts.map +1 -0
  69. package/dist/types/dtos.d.ts +29 -0
  70. package/dist/types/dtos.d.ts.map +1 -0
  71. package/dist/webauthn/base64url.d.ts +4 -0
  72. package/dist/webauthn/base64url.d.ts.map +1 -0
  73. package/dist/webauthn/ceremony.d.ts +5 -0
  74. package/dist/webauthn/ceremony.d.ts.map +1 -0
  75. package/package.json +62 -0
@@ -0,0 +1,1075 @@
1
+ /**
2
+ * This file was auto-generated by openapi-typescript.
3
+ * Do not make direct changes to the file.
4
+ */
5
+ export interface paths {
6
+ "/methods": {
7
+ parameters: {
8
+ query?: never;
9
+ header?: never;
10
+ path?: never;
11
+ cookie?: never;
12
+ };
13
+ /** List active 2FA methods for the current user. */
14
+ get: operations["listMethods"];
15
+ put?: never;
16
+ post?: never;
17
+ delete?: never;
18
+ options?: never;
19
+ head?: never;
20
+ patch?: never;
21
+ trace?: never;
22
+ };
23
+ "/methods/{methodId}": {
24
+ parameters: {
25
+ query?: never;
26
+ header?: never;
27
+ path?: never;
28
+ cookie?: never;
29
+ };
30
+ get?: never;
31
+ put?: never;
32
+ post?: never;
33
+ /**
34
+ * Remove an enrolled 2FA method.
35
+ * @description Removes a single enrolled method. If this is the user's last method
36
+ * and the host has configured `AllowDisabling = false`, the request
37
+ * returns `409 LAST_METHOD_PROTECTED` — host policy decides whether
38
+ * to forbid removing the last method.
39
+ */
40
+ delete: operations["removeMethod"];
41
+ options?: never;
42
+ head?: never;
43
+ patch?: never;
44
+ trace?: never;
45
+ };
46
+ "/challenge/start": {
47
+ parameters: {
48
+ query?: never;
49
+ header?: never;
50
+ path?: never;
51
+ cookie?: never;
52
+ };
53
+ get?: never;
54
+ put?: never;
55
+ /**
56
+ * Start verification of a chosen method.
57
+ * @description After the host verifies the user's password and issues a pre-auth token,
58
+ * the frontend calls this with the picked method. Backend prepares
59
+ * method-specific challenge state — see response shape per type.
60
+ *
61
+ * For **TOTP** — this is a no-op acknowledgment; the user enters the code
62
+ * from their authenticator and the frontend goes straight to `/verify`.
63
+ *
64
+ * For **Email** (v0.2+) — backend sends an OTP email and returns confirmation.
65
+ *
66
+ * For **WebAuthn** (v0.3+) — backend returns assertion request options
67
+ * for `navigator.credentials.get()`.
68
+ */
69
+ post: operations["startChallenge"];
70
+ delete?: never;
71
+ options?: never;
72
+ head?: never;
73
+ patch?: never;
74
+ trace?: never;
75
+ };
76
+ "/challenge/resend": {
77
+ parameters: {
78
+ query?: never;
79
+ header?: never;
80
+ path?: never;
81
+ cookie?: never;
82
+ };
83
+ get?: never;
84
+ put?: never;
85
+ /**
86
+ * Re-send the login OTP for a method that delivers codes out-of-band (Email).
87
+ * @description For **Email** — re-sends the one-time code for the active login challenge of the
88
+ * given method, subject to a resend cooldown. For methods that don't deliver codes
89
+ * (TOTP, WebAuthn) this is not applicable and returns `400 VALIDATION_FAILED`.
90
+ */
91
+ post: operations["resendChallenge"];
92
+ delete?: never;
93
+ options?: never;
94
+ head?: never;
95
+ patch?: never;
96
+ trace?: never;
97
+ };
98
+ "/challenge/recovery-code": {
99
+ parameters: {
100
+ query?: never;
101
+ header?: never;
102
+ path?: never;
103
+ cookie?: never;
104
+ };
105
+ get?: never;
106
+ put?: never;
107
+ /**
108
+ * Complete login with a one-time recovery code instead of a 2FA method.
109
+ * @description Method-agnostic fallback. Consumes the recovery code (one-time use) and, on success,
110
+ * returns the verified `userId` exactly like `/challenge/verify`.
111
+ */
112
+ post: operations["verifyRecoveryCode"];
113
+ delete?: never;
114
+ options?: never;
115
+ head?: never;
116
+ patch?: never;
117
+ trace?: never;
118
+ };
119
+ "/challenge/verify": {
120
+ parameters: {
121
+ query?: never;
122
+ header?: never;
123
+ path?: never;
124
+ cookie?: never;
125
+ };
126
+ get?: never;
127
+ put?: never;
128
+ /**
129
+ * Verify the user's response to a challenge.
130
+ * @description Final step of the 2FA login flow. On success, the host application
131
+ * receives the `userId` and is responsible for minting its session JWT.
132
+ *
133
+ * Omni2FA does **not** issue session tokens — only verification results.
134
+ */
135
+ post: operations["verifyChallenge"];
136
+ delete?: never;
137
+ options?: never;
138
+ head?: never;
139
+ patch?: never;
140
+ trace?: never;
141
+ };
142
+ "/enroll/email/start": {
143
+ parameters: {
144
+ query?: never;
145
+ header?: never;
146
+ path?: never;
147
+ cookie?: never;
148
+ };
149
+ get?: never;
150
+ put?: never;
151
+ /**
152
+ * Begin Email OTP enrollment.
153
+ * @description The host supplies the destination email address — Omni2FA does not read it from a
154
+ * claim and does not own address verification (that is the host's responsibility). The
155
+ * server issues a one-time code, persists it as a pending enrollment, and emails it.
156
+ */
157
+ post: operations["startEmailEnrollment"];
158
+ delete?: never;
159
+ options?: never;
160
+ head?: never;
161
+ patch?: never;
162
+ trace?: never;
163
+ };
164
+ "/enroll/email/confirm": {
165
+ parameters: {
166
+ query?: never;
167
+ header?: never;
168
+ path?: never;
169
+ cookie?: never;
170
+ };
171
+ get?: never;
172
+ put?: never;
173
+ /** Confirm Email OTP enrollment by verifying the emailed code. */
174
+ post: operations["confirmEmailEnrollment"];
175
+ delete?: never;
176
+ options?: never;
177
+ head?: never;
178
+ patch?: never;
179
+ trace?: never;
180
+ };
181
+ "/enroll/email/resend": {
182
+ parameters: {
183
+ query?: never;
184
+ header?: never;
185
+ path?: never;
186
+ cookie?: never;
187
+ };
188
+ get?: never;
189
+ put?: never;
190
+ /** Re-send the enrollment OTP, subject to a resend cooldown. */
191
+ post: operations["resendEmailEnrollment"];
192
+ delete?: never;
193
+ options?: never;
194
+ head?: never;
195
+ patch?: never;
196
+ trace?: never;
197
+ };
198
+ "/enroll/webauthn/start": {
199
+ parameters: {
200
+ query?: never;
201
+ header?: never;
202
+ path?: never;
203
+ cookie?: never;
204
+ };
205
+ get?: never;
206
+ put?: never;
207
+ /**
208
+ * Begin WebAuthn enrollment — issue credential creation options.
209
+ * @description Returns `PublicKeyCredentialCreationOptions` (as `optionsJson`) for the browser to pass to
210
+ * `navigator.credentials.create()`. The pending ceremony is persisted; the browser attestation
211
+ * is posted back to `/confirm`.
212
+ */
213
+ post: operations["startWebAuthnEnrollment"];
214
+ delete?: never;
215
+ options?: never;
216
+ head?: never;
217
+ patch?: never;
218
+ trace?: never;
219
+ };
220
+ "/enroll/webauthn/confirm": {
221
+ parameters: {
222
+ query?: never;
223
+ header?: never;
224
+ path?: never;
225
+ cookie?: never;
226
+ };
227
+ get?: never;
228
+ put?: never;
229
+ /** Confirm WebAuthn enrollment by verifying the browser attestation. */
230
+ post: operations["confirmWebAuthnEnrollment"];
231
+ delete?: never;
232
+ options?: never;
233
+ head?: never;
234
+ patch?: never;
235
+ trace?: never;
236
+ };
237
+ "/enroll/totp/start": {
238
+ parameters: {
239
+ query?: never;
240
+ header?: never;
241
+ path?: never;
242
+ cookie?: never;
243
+ };
244
+ get?: never;
245
+ put?: never;
246
+ /**
247
+ * Begin TOTP enrollment.
248
+ * @description Generates a fresh secret, persists it as a pending enrollment,
249
+ * and returns the otpauth:// URI plus the base32 secret. The frontend
250
+ * renders the URI as a QR and shows the secret for manual entry.
251
+ */
252
+ post: operations["startTotpEnrollment"];
253
+ delete?: never;
254
+ options?: never;
255
+ head?: never;
256
+ patch?: never;
257
+ trace?: never;
258
+ };
259
+ "/enroll/totp/confirm": {
260
+ parameters: {
261
+ query?: never;
262
+ header?: never;
263
+ path?: never;
264
+ cookie?: never;
265
+ };
266
+ get?: never;
267
+ put?: never;
268
+ /**
269
+ * Confirm TOTP enrollment by verifying a code.
270
+ * @description User scans the QR and submits the first 6-digit code from their
271
+ * authenticator. Backend validates the code against the pending secret
272
+ * and persists the method on success.
273
+ */
274
+ post: operations["confirmTotpEnrollment"];
275
+ delete?: never;
276
+ options?: never;
277
+ head?: never;
278
+ patch?: never;
279
+ trace?: never;
280
+ };
281
+ "/recovery-codes/regenerate": {
282
+ parameters: {
283
+ query?: never;
284
+ header?: never;
285
+ path?: never;
286
+ cookie?: never;
287
+ };
288
+ get?: never;
289
+ put?: never;
290
+ /**
291
+ * Generate a fresh set of recovery codes, invalidating all previous ones.
292
+ * @description Returns the new plaintext codes **once**. Previous codes stop working immediately.
293
+ * The frontend must display them and instruct the user to save them — no second chance.
294
+ */
295
+ post: operations["regenerateRecoveryCodes"];
296
+ delete?: never;
297
+ options?: never;
298
+ head?: never;
299
+ patch?: never;
300
+ trace?: never;
301
+ };
302
+ }
303
+ export type webhooks = Record<string, never>;
304
+ export interface components {
305
+ schemas: {
306
+ /**
307
+ * @description The type of 2FA factor. Currently only `Totp` is implemented (v0.1).
308
+ * `Email` lands in v0.2, `WebAuthn` in v0.3.
309
+ * @enum {string}
310
+ */
311
+ TwoFactorMethodType: "Totp" | "Email" | "WebAuthn";
312
+ TwoFactorMethodDto: {
313
+ /** Format: uuid */
314
+ id: string;
315
+ type: components["schemas"]["TwoFactorMethodType"];
316
+ /** @description Optional human-readable label (e.g. "Personal authenticator", "YubiKey 5"). */
317
+ name?: string | null;
318
+ /** Format: date-time */
319
+ createdAt: string;
320
+ /** Format: date-time */
321
+ lastUsedAt?: string | null;
322
+ };
323
+ /**
324
+ * @description **Contract-only schema — not used by any Omni2FA endpoint.**
325
+ *
326
+ * Returned by the **host's** login endpoint (e.g. `POST /auth/login`)
327
+ * when the verified user has 2FA methods enrolled. Carries the
328
+ * short-lived pre-auth token (issued via the .NET helper
329
+ * `IPreAuthTokenIssuer.IssueAsync(userId)`) and the list of methods the
330
+ * user can pick from.
331
+ *
332
+ * This schema is published as part of the cross-stack contract so any
333
+ * host implementation (.NET, Python, Node, …) returns the same shape
334
+ * and any frontend can decode it identically. Because no Omni2FA-owned
335
+ * endpoint produces it, the `no-unused-components` linter rule is
336
+ * suppressed for this single schema in `.redocly.lint-ignore.yaml`.
337
+ */
338
+ PreAuthChallengeResponse: {
339
+ /** @description Short-lived JWT. Send as Bearer token to all `/challenge/*` endpoints. */
340
+ preAuthToken: string;
341
+ availableMethods: components["schemas"]["TwoFactorMethodDto"][];
342
+ /** Format: date-time */
343
+ expiresAt: string;
344
+ };
345
+ ChallengeStartRequest: {
346
+ /**
347
+ * Format: uuid
348
+ * @description ID of the method the user picked from `availableMethods`.
349
+ */
350
+ methodId: string;
351
+ };
352
+ /**
353
+ * @description Method-specific challenge payload. `type` discriminates the shape.
354
+ * For TOTP — empty payload (just confirms challenge started); `expiresAt` and
355
+ * `resendAvailableAt` are null. For Email — an OTP was sent; `expiresAt` is when
356
+ * it stops validating and `resendAvailableAt` is when a resend becomes allowed.
357
+ * WebAuthn assertion options will be added in v0.3.
358
+ */
359
+ ChallengeStartResponse: {
360
+ type: components["schemas"]["TwoFactorMethodType"];
361
+ /**
362
+ * Format: date-time
363
+ * @description For Email — when the sent code stops validating. Null for TOTP.
364
+ */
365
+ expiresAt?: string | null;
366
+ /**
367
+ * Format: date-time
368
+ * @description For Email — earliest time a resend is permitted. Null for TOTP.
369
+ */
370
+ resendAvailableAt?: string | null;
371
+ /**
372
+ * @description For WebAuthn — `PublicKeyCredentialRequestOptions` JSON to pass to
373
+ * `navigator.credentials.get()`. Null for TOTP and Email.
374
+ */
375
+ optionsJson?: string | null;
376
+ };
377
+ ChallengeResendRequest: {
378
+ /**
379
+ * Format: uuid
380
+ * @description The method whose active login OTP should be re-sent.
381
+ */
382
+ methodId: string;
383
+ };
384
+ ChallengeVerifyRequest: {
385
+ /** Format: uuid */
386
+ methodId: string;
387
+ /** @description For TOTP and Email — the 6-digit numeric code. Null for WebAuthn. */
388
+ code?: string | null;
389
+ /** @description For WebAuthn — the JSON from `navigator.credentials.get()`. Null for TOTP and Email. */
390
+ assertionResponseJson?: string | null;
391
+ };
392
+ VerifySuccessResponse: {
393
+ /** @description Always `true` on this response. Failures use `4xx` with `ErrorResponse`. */
394
+ verified: boolean;
395
+ /**
396
+ * @description Verified user's identifier, stringified. The host application casts
397
+ * this to its native userId type (Guid/long/int/email) and uses it to
398
+ * mint its final session JWT/cookie. Omni2FA does not issue session tokens.
399
+ */
400
+ userId: string;
401
+ };
402
+ EmailEnrollStartRequest: {
403
+ /**
404
+ * Format: email
405
+ * @description Destination address the OTP is sent to, supplied by the host. Omni2FA does not
406
+ * derive it from a claim and does not verify address ownership — that is host policy.
407
+ * @example alice@example.com
408
+ */
409
+ email: string;
410
+ };
411
+ EmailEnrollStartResponse: {
412
+ /**
413
+ * Format: uuid
414
+ * @description Identifier for the pending enrollment ceremony. Pass back in `confirm` / `resend`.
415
+ */
416
+ enrollmentId: string;
417
+ /**
418
+ * Format: date-time
419
+ * @description When the emailed code stops validating.
420
+ */
421
+ expiresAt: string;
422
+ /**
423
+ * Format: date-time
424
+ * @description Earliest time a resend is permitted (cooldown).
425
+ */
426
+ resendAvailableAt: string;
427
+ };
428
+ EmailEnrollConfirmRequest: {
429
+ /**
430
+ * Format: uuid
431
+ * @description Value returned from `/enroll/email/start`.
432
+ */
433
+ enrollmentId: string;
434
+ /**
435
+ * @description The numeric code from the enrollment email.
436
+ * @example 123456
437
+ */
438
+ code: string;
439
+ /** @description Optional human-readable label for this method. */
440
+ name?: string | null;
441
+ };
442
+ EmailEnrollResendRequest: {
443
+ /**
444
+ * Format: uuid
445
+ * @description Value returned from `/enroll/email/start`.
446
+ */
447
+ enrollmentId: string;
448
+ };
449
+ WebAuthnEnrollStartResponse: {
450
+ /**
451
+ * Format: uuid
452
+ * @description Identifier for the pending ceremony. Pass back in `confirm`.
453
+ */
454
+ enrollmentId: string;
455
+ /**
456
+ * @description `PublicKeyCredentialCreationOptions` JSON for `navigator.credentials.create()`.
457
+ * Challenge, user id, and excluded credential ids are base64url-encoded.
458
+ */
459
+ optionsJson: string;
460
+ };
461
+ WebAuthnEnrollConfirmRequest: {
462
+ /**
463
+ * Format: uuid
464
+ * @description Value returned from `/enroll/webauthn/start`.
465
+ */
466
+ enrollmentId: string;
467
+ /** @description The JSON produced by `navigator.credentials.create()`, base64url-encoded fields. */
468
+ attestationResponseJson: string;
469
+ /** @description Optional human-readable label for this credential (e.g. "YubiKey 5"). */
470
+ name?: string | null;
471
+ };
472
+ TotpEnrollStartResponse: {
473
+ /**
474
+ * Format: uuid
475
+ * @description Identifier for the pending enrollment ceremony. Pass back in `confirm`.
476
+ */
477
+ enrollmentId: string;
478
+ /**
479
+ * @description `otpauth://` URI for authenticator app QR code. Format:
480
+ * `otpauth://totp/{Issuer}:{accountLabel}?secret={base32}&issuer={Issuer}&algorithm=SHA1&digits=6&period=30`.
481
+ * @example otpauth://totp/MyApp:alice@example.com?secret=JBSWY3DPEHPK3PXP&issuer=MyApp&algorithm=SHA1&digits=6&period=30
482
+ */
483
+ otpAuthUri: string;
484
+ /**
485
+ * @description Base32-encoded TOTP secret. Shown to the user as a fallback to QR scanning.
486
+ * @example JBSWY3DPEHPK3PXP
487
+ */
488
+ secret: string;
489
+ };
490
+ TotpEnrollConfirmRequest: {
491
+ /**
492
+ * Format: uuid
493
+ * @description Value returned from `/enroll/totp/start`.
494
+ */
495
+ enrollmentId: string;
496
+ /**
497
+ * @description 6-digit code from the user's authenticator app.
498
+ * @example 123456
499
+ */
500
+ code: string;
501
+ /** @description Optional human-readable label for this method. */
502
+ name?: string | null;
503
+ };
504
+ MethodCreatedResponse: {
505
+ /**
506
+ * Format: uuid
507
+ * @description Identifier of the newly created method.
508
+ */
509
+ methodId: string;
510
+ /**
511
+ * @description Present only when this enrollment generated recovery codes (i.e. it was the user's
512
+ * first method). Plaintext, shown once — the frontend must display and have the user
513
+ * save them. Null on every subsequent enrollment.
514
+ */
515
+ recoveryCodes?: string[] | null;
516
+ };
517
+ RecoveryCodesResponse: {
518
+ /** @description Fresh plaintext codes, shown once. Previous codes are now invalid. */
519
+ recoveryCodes: string[];
520
+ };
521
+ RecoveryCodeVerifyRequest: {
522
+ /**
523
+ * @description A single unused recovery code. Dashes/spaces and case are normalized server-side.
524
+ * @example A1B2-C3D4-E5
525
+ */
526
+ recoveryCode: string;
527
+ };
528
+ /**
529
+ * @description Uniform error envelope returned by every non-2xx response. Frontends
530
+ * switch on `code` (machine-readable, stable). `message` is informational
531
+ * and may be localized.
532
+ * See `Core/protocol/ERROR_CODES.md` for the full catalogue.
533
+ */
534
+ ErrorResponse: {
535
+ /**
536
+ * @description Machine-readable error code, stable across versions.
537
+ * @example INVALID_CODE
538
+ */
539
+ code: string;
540
+ /**
541
+ * @description Human-readable message. May be localized by host.
542
+ * @example The code you entered is invalid.
543
+ */
544
+ message: string;
545
+ /** @description Optional structured context. Shape depends on `code`. */
546
+ details?: {
547
+ [key: string]: unknown;
548
+ } | null;
549
+ };
550
+ };
551
+ responses: {
552
+ /** @description Missing or invalid session token. */
553
+ Unauthorized: {
554
+ headers: {
555
+ [name: string]: unknown;
556
+ };
557
+ content: {
558
+ "application/json": components["schemas"]["ErrorResponse"];
559
+ };
560
+ };
561
+ /** @description Pre-auth token is missing, malformed, or expired. */
562
+ PreAuthInvalidOrExpired: {
563
+ headers: {
564
+ [name: string]: unknown;
565
+ };
566
+ content: {
567
+ "application/json": components["schemas"]["ErrorResponse"];
568
+ };
569
+ };
570
+ /** @description Request validation failed. */
571
+ BadRequest: {
572
+ headers: {
573
+ [name: string]: unknown;
574
+ };
575
+ content: {
576
+ "application/json": components["schemas"]["ErrorResponse"];
577
+ };
578
+ };
579
+ /**
580
+ * @description Rate limit exceeded. Default policy is 20 attempts per minute per IP
581
+ * on verify endpoints — see `docs/CODE_STYLE.md` rule 5 + ROADMAP v0.6.
582
+ */
583
+ TooManyRequests: {
584
+ headers: {
585
+ /** @description Seconds until the next attempt is allowed. */
586
+ "Retry-After"?: number;
587
+ [name: string]: unknown;
588
+ };
589
+ content: {
590
+ "application/json": components["schemas"]["ErrorResponse"];
591
+ };
592
+ };
593
+ };
594
+ parameters: {
595
+ /** @description Identifier of the enrolled method. */
596
+ MethodIdPath: string;
597
+ };
598
+ requestBodies: never;
599
+ headers: never;
600
+ pathItems: never;
601
+ }
602
+ export type $defs = Record<string, never>;
603
+ export interface operations {
604
+ listMethods: {
605
+ parameters: {
606
+ query?: never;
607
+ header?: never;
608
+ path?: never;
609
+ cookie?: never;
610
+ };
611
+ requestBody?: never;
612
+ responses: {
613
+ /** @description Array of active methods. Empty array if user has no 2FA enrolled. */
614
+ 200: {
615
+ headers: {
616
+ [name: string]: unknown;
617
+ };
618
+ content: {
619
+ "application/json": components["schemas"]["TwoFactorMethodDto"][];
620
+ };
621
+ };
622
+ 401: components["responses"]["Unauthorized"];
623
+ };
624
+ };
625
+ removeMethod: {
626
+ parameters: {
627
+ query?: never;
628
+ header?: never;
629
+ path: {
630
+ /** @description Identifier of the enrolled method. */
631
+ methodId: components["parameters"]["MethodIdPath"];
632
+ };
633
+ cookie?: never;
634
+ };
635
+ requestBody?: never;
636
+ responses: {
637
+ /** @description Method removed. */
638
+ 204: {
639
+ headers: {
640
+ [name: string]: unknown;
641
+ };
642
+ content?: never;
643
+ };
644
+ 401: components["responses"]["Unauthorized"];
645
+ /** @description Method not found, or does not belong to current user. */
646
+ 404: {
647
+ headers: {
648
+ [name: string]: unknown;
649
+ };
650
+ content: {
651
+ "application/json": components["schemas"]["ErrorResponse"];
652
+ };
653
+ };
654
+ /** @description Conflict — removing this method is forbidden by host policy. */
655
+ 409: {
656
+ headers: {
657
+ [name: string]: unknown;
658
+ };
659
+ content: {
660
+ "application/json": components["schemas"]["ErrorResponse"];
661
+ };
662
+ };
663
+ };
664
+ };
665
+ startChallenge: {
666
+ parameters: {
667
+ query?: never;
668
+ header?: never;
669
+ path?: never;
670
+ cookie?: never;
671
+ };
672
+ requestBody: {
673
+ content: {
674
+ "application/json": components["schemas"]["ChallengeStartRequest"];
675
+ };
676
+ };
677
+ responses: {
678
+ /** @description Challenge prepared. Response shape depends on method type. */
679
+ 200: {
680
+ headers: {
681
+ [name: string]: unknown;
682
+ };
683
+ content: {
684
+ "application/json": components["schemas"]["ChallengeStartResponse"];
685
+ };
686
+ };
687
+ 400: components["responses"]["BadRequest"];
688
+ 401: components["responses"]["PreAuthInvalidOrExpired"];
689
+ /** @description Method not found, or does not belong to current pre-auth user. */
690
+ 404: {
691
+ headers: {
692
+ [name: string]: unknown;
693
+ };
694
+ content: {
695
+ "application/json": components["schemas"]["ErrorResponse"];
696
+ };
697
+ };
698
+ 429: components["responses"]["TooManyRequests"];
699
+ };
700
+ };
701
+ resendChallenge: {
702
+ parameters: {
703
+ query?: never;
704
+ header?: never;
705
+ path?: never;
706
+ cookie?: never;
707
+ };
708
+ requestBody: {
709
+ content: {
710
+ "application/json": components["schemas"]["ChallengeResendRequest"];
711
+ };
712
+ };
713
+ responses: {
714
+ /** @description A fresh code was sent (or the previous one re-sent). */
715
+ 200: {
716
+ headers: {
717
+ [name: string]: unknown;
718
+ };
719
+ content: {
720
+ "application/json": components["schemas"]["ChallengeStartResponse"];
721
+ };
722
+ };
723
+ 400: components["responses"]["BadRequest"];
724
+ 401: components["responses"]["PreAuthInvalidOrExpired"];
725
+ /** @description No active challenge for the given method under the current pre-auth user. */
726
+ 404: {
727
+ headers: {
728
+ [name: string]: unknown;
729
+ };
730
+ content: {
731
+ "application/json": components["schemas"]["ErrorResponse"];
732
+ };
733
+ };
734
+ 429: components["responses"]["TooManyRequests"];
735
+ };
736
+ };
737
+ verifyRecoveryCode: {
738
+ parameters: {
739
+ query?: never;
740
+ header?: never;
741
+ path?: never;
742
+ cookie?: never;
743
+ };
744
+ requestBody: {
745
+ content: {
746
+ "application/json": components["schemas"]["RecoveryCodeVerifyRequest"];
747
+ };
748
+ };
749
+ responses: {
750
+ /** @description Recovery code accepted. */
751
+ 200: {
752
+ headers: {
753
+ [name: string]: unknown;
754
+ };
755
+ content: {
756
+ "application/json": components["schemas"]["VerifySuccessResponse"];
757
+ };
758
+ };
759
+ 400: components["responses"]["BadRequest"];
760
+ /** @description Code invalid, already used, or pre-auth invalid/expired. */
761
+ 401: {
762
+ headers: {
763
+ [name: string]: unknown;
764
+ };
765
+ content: {
766
+ "application/json": components["schemas"]["ErrorResponse"];
767
+ };
768
+ };
769
+ 429: components["responses"]["TooManyRequests"];
770
+ };
771
+ };
772
+ verifyChallenge: {
773
+ parameters: {
774
+ query?: never;
775
+ header?: never;
776
+ path?: never;
777
+ cookie?: never;
778
+ };
779
+ requestBody: {
780
+ content: {
781
+ "application/json": components["schemas"]["ChallengeVerifyRequest"];
782
+ };
783
+ };
784
+ responses: {
785
+ /** @description Verification succeeded. */
786
+ 200: {
787
+ headers: {
788
+ [name: string]: unknown;
789
+ };
790
+ content: {
791
+ "application/json": components["schemas"]["VerifySuccessResponse"];
792
+ };
793
+ };
794
+ 400: components["responses"]["BadRequest"];
795
+ /** @description Code invalid, pre-auth invalid/expired, or challenge consumed/missing. */
796
+ 401: {
797
+ headers: {
798
+ [name: string]: unknown;
799
+ };
800
+ content: {
801
+ "application/json": components["schemas"]["ErrorResponse"];
802
+ };
803
+ };
804
+ 429: components["responses"]["TooManyRequests"];
805
+ };
806
+ };
807
+ startEmailEnrollment: {
808
+ parameters: {
809
+ query?: never;
810
+ header?: never;
811
+ path?: never;
812
+ cookie?: never;
813
+ };
814
+ requestBody: {
815
+ content: {
816
+ "application/json": components["schemas"]["EmailEnrollStartRequest"];
817
+ };
818
+ };
819
+ responses: {
820
+ /** @description Enrollment started, OTP emailed. */
821
+ 200: {
822
+ headers: {
823
+ [name: string]: unknown;
824
+ };
825
+ content: {
826
+ "application/json": components["schemas"]["EmailEnrollStartResponse"];
827
+ };
828
+ };
829
+ 400: components["responses"]["BadRequest"];
830
+ 401: components["responses"]["Unauthorized"];
831
+ /** @description An Email method is already enrolled for this user. */
832
+ 409: {
833
+ headers: {
834
+ [name: string]: unknown;
835
+ };
836
+ content: {
837
+ "application/json": components["schemas"]["ErrorResponse"];
838
+ };
839
+ };
840
+ };
841
+ };
842
+ confirmEmailEnrollment: {
843
+ parameters: {
844
+ query?: never;
845
+ header?: never;
846
+ path?: never;
847
+ cookie?: never;
848
+ };
849
+ requestBody: {
850
+ content: {
851
+ "application/json": components["schemas"]["EmailEnrollConfirmRequest"];
852
+ };
853
+ };
854
+ responses: {
855
+ /** @description Email method enrolled. */
856
+ 200: {
857
+ headers: {
858
+ [name: string]: unknown;
859
+ };
860
+ content: {
861
+ "application/json": components["schemas"]["MethodCreatedResponse"];
862
+ };
863
+ };
864
+ 400: components["responses"]["BadRequest"];
865
+ 401: components["responses"]["Unauthorized"];
866
+ /** @description No pending Email enrollment for this user, or it has expired. */
867
+ 404: {
868
+ headers: {
869
+ [name: string]: unknown;
870
+ };
871
+ content: {
872
+ "application/json": components["schemas"]["ErrorResponse"];
873
+ };
874
+ };
875
+ 429: components["responses"]["TooManyRequests"];
876
+ };
877
+ };
878
+ resendEmailEnrollment: {
879
+ parameters: {
880
+ query?: never;
881
+ header?: never;
882
+ path?: never;
883
+ cookie?: never;
884
+ };
885
+ requestBody: {
886
+ content: {
887
+ "application/json": components["schemas"]["EmailEnrollResendRequest"];
888
+ };
889
+ };
890
+ responses: {
891
+ /** @description A fresh code was sent. */
892
+ 200: {
893
+ headers: {
894
+ [name: string]: unknown;
895
+ };
896
+ content: {
897
+ "application/json": components["schemas"]["EmailEnrollStartResponse"];
898
+ };
899
+ };
900
+ 400: components["responses"]["BadRequest"];
901
+ 401: components["responses"]["Unauthorized"];
902
+ /** @description No pending Email enrollment for this user, or it has expired. */
903
+ 404: {
904
+ headers: {
905
+ [name: string]: unknown;
906
+ };
907
+ content: {
908
+ "application/json": components["schemas"]["ErrorResponse"];
909
+ };
910
+ };
911
+ 429: components["responses"]["TooManyRequests"];
912
+ };
913
+ };
914
+ startWebAuthnEnrollment: {
915
+ parameters: {
916
+ query?: never;
917
+ header?: never;
918
+ path?: never;
919
+ cookie?: never;
920
+ };
921
+ requestBody?: never;
922
+ responses: {
923
+ /** @description Creation options issued. */
924
+ 200: {
925
+ headers: {
926
+ [name: string]: unknown;
927
+ };
928
+ content: {
929
+ "application/json": components["schemas"]["WebAuthnEnrollStartResponse"];
930
+ };
931
+ };
932
+ 401: components["responses"]["Unauthorized"];
933
+ /** @description The per-user WebAuthn credential cap has been reached. */
934
+ 409: {
935
+ headers: {
936
+ [name: string]: unknown;
937
+ };
938
+ content: {
939
+ "application/json": components["schemas"]["ErrorResponse"];
940
+ };
941
+ };
942
+ };
943
+ };
944
+ confirmWebAuthnEnrollment: {
945
+ parameters: {
946
+ query?: never;
947
+ header?: never;
948
+ path?: never;
949
+ cookie?: never;
950
+ };
951
+ requestBody: {
952
+ content: {
953
+ "application/json": components["schemas"]["WebAuthnEnrollConfirmRequest"];
954
+ };
955
+ };
956
+ responses: {
957
+ /** @description WebAuthn credential enrolled. */
958
+ 200: {
959
+ headers: {
960
+ [name: string]: unknown;
961
+ };
962
+ content: {
963
+ "application/json": components["schemas"]["MethodCreatedResponse"];
964
+ };
965
+ };
966
+ 400: components["responses"]["BadRequest"];
967
+ /** @description Attestation failed verification, or no pending enrollment. */
968
+ 401: {
969
+ headers: {
970
+ [name: string]: unknown;
971
+ };
972
+ content: {
973
+ "application/json": components["schemas"]["ErrorResponse"];
974
+ };
975
+ };
976
+ /** @description No pending WebAuthn enrollment for this user, or it has expired. */
977
+ 404: {
978
+ headers: {
979
+ [name: string]: unknown;
980
+ };
981
+ content: {
982
+ "application/json": components["schemas"]["ErrorResponse"];
983
+ };
984
+ };
985
+ };
986
+ };
987
+ startTotpEnrollment: {
988
+ parameters: {
989
+ query?: never;
990
+ header?: never;
991
+ path?: never;
992
+ cookie?: never;
993
+ };
994
+ requestBody?: never;
995
+ responses: {
996
+ /** @description Enrollment ceremony started. */
997
+ 200: {
998
+ headers: {
999
+ [name: string]: unknown;
1000
+ };
1001
+ content: {
1002
+ "application/json": components["schemas"]["TotpEnrollStartResponse"];
1003
+ };
1004
+ };
1005
+ 401: components["responses"]["Unauthorized"];
1006
+ /** @description TOTP method already enrolled for this user. */
1007
+ 409: {
1008
+ headers: {
1009
+ [name: string]: unknown;
1010
+ };
1011
+ content: {
1012
+ "application/json": components["schemas"]["ErrorResponse"];
1013
+ };
1014
+ };
1015
+ };
1016
+ };
1017
+ confirmTotpEnrollment: {
1018
+ parameters: {
1019
+ query?: never;
1020
+ header?: never;
1021
+ path?: never;
1022
+ cookie?: never;
1023
+ };
1024
+ requestBody: {
1025
+ content: {
1026
+ "application/json": components["schemas"]["TotpEnrollConfirmRequest"];
1027
+ };
1028
+ };
1029
+ responses: {
1030
+ /** @description TOTP enrolled. */
1031
+ 200: {
1032
+ headers: {
1033
+ [name: string]: unknown;
1034
+ };
1035
+ content: {
1036
+ "application/json": components["schemas"]["MethodCreatedResponse"];
1037
+ };
1038
+ };
1039
+ 400: components["responses"]["BadRequest"];
1040
+ 401: components["responses"]["Unauthorized"];
1041
+ /** @description No pending TOTP enrollment for this user, or it has expired. */
1042
+ 404: {
1043
+ headers: {
1044
+ [name: string]: unknown;
1045
+ };
1046
+ content: {
1047
+ "application/json": components["schemas"]["ErrorResponse"];
1048
+ };
1049
+ };
1050
+ 429: components["responses"]["TooManyRequests"];
1051
+ };
1052
+ };
1053
+ regenerateRecoveryCodes: {
1054
+ parameters: {
1055
+ query?: never;
1056
+ header?: never;
1057
+ path?: never;
1058
+ cookie?: never;
1059
+ };
1060
+ requestBody?: never;
1061
+ responses: {
1062
+ /** @description New codes generated. */
1063
+ 200: {
1064
+ headers: {
1065
+ [name: string]: unknown;
1066
+ };
1067
+ content: {
1068
+ "application/json": components["schemas"]["RecoveryCodesResponse"];
1069
+ };
1070
+ };
1071
+ 401: components["responses"]["Unauthorized"];
1072
+ };
1073
+ };
1074
+ }
1075
+ //# sourceMappingURL=api.d.ts.map