@omni2fa/core 0.7.3 → 0.8.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.
package/dist/index.js CHANGED
@@ -52,15 +52,33 @@ const a = {
52
52
  function T(t) {
53
53
  return S[t] ?? S[a.Unknown];
54
54
  }
55
- const F = "omni2fa:preauth", L = "omni2fa:session", b = "http://omni2fa.local";
56
- class K {
55
+ const W = "X-Omni2FA-StepUp", F = "omni2fa:preauth", K = "omni2fa:session";
56
+ function b(t) {
57
+ let e = t;
58
+ const r = /^[a-zA-Z][a-zA-Z\d+\-.]*:\/\//.exec(e);
59
+ if (r) {
60
+ e = e.slice(r[0].length);
61
+ const l = e.indexOf("/");
62
+ e = l === -1 ? "/" : e.slice(l);
63
+ } else if (e.startsWith("//")) {
64
+ e = e.slice(2);
65
+ const l = e.indexOf("/");
66
+ e = l === -1 ? "/" : e.slice(l);
67
+ }
68
+ const n = e.indexOf("#");
69
+ n !== -1 && (e = e.slice(0, n));
70
+ const o = e.indexOf("?");
71
+ return o !== -1 && (e = e.slice(0, o)), e.startsWith("/") ? e : `/${e}`;
72
+ }
73
+ class $ {
57
74
  storage;
58
75
  preAuthKey;
59
76
  sessionKey;
60
77
  basePath;
61
78
  inner;
79
+ stepUpHandler = null;
62
80
  constructor(e) {
63
- this.storage = e.storage ?? new _(), this.preAuthKey = e.preAuthStorageKey ?? F, this.sessionKey = e.sessionStorageKey ?? L, this.basePath = new URL(e.baseUrl, b).pathname.replace(/\/$/, ""), this.inner = J({
81
+ this.storage = e.storage ?? new _(), this.preAuthKey = e.preAuthStorageKey ?? F, this.sessionKey = e.sessionStorageKey ?? K, this.basePath = b(e.baseUrl).replace(/\/$/, ""), this.inner = J({
64
82
  baseUrl: e.baseUrl,
65
83
  fetch: e.fetch ?? globalThis.fetch.bind(globalThis),
66
84
  ...e.credentials ? { credentials: e.credentials } : {}
@@ -75,7 +93,7 @@ class K {
75
93
  }
76
94
  /** Pre-auth endpoints are exactly the ones mounted under <c>{basePath}/challenge/</c>. */
77
95
  isPreAuthEndpoint(e) {
78
- const r = new URL(e, b).pathname;
96
+ const r = b(e);
79
97
  return (r.startsWith(this.basePath) ? r.slice(this.basePath.length) : r).startsWith("/challenge/");
80
98
  }
81
99
  setPreAuthToken(e) {
@@ -90,6 +108,23 @@ class K {
90
108
  getSessionToken() {
91
109
  return this.storage.get(this.sessionKey);
92
110
  }
111
+ setStepUpHandler(e) {
112
+ this.stepUpHandler = e;
113
+ }
114
+ /**
115
+ * Run a request and, if it comes back 403 STEP_UP_REQUIRED with a handler registered, confirm 2FA
116
+ * and retry once with the step-up header. Used by the library's own sensitive endpoints; other calls
117
+ * invoke openapi-fetch directly.
118
+ */
119
+ async sendWithStepUp(e) {
120
+ const r = await e({});
121
+ if (r.error !== void 0 && r.response.status === 403 && r.error.code === a.StepUpRequired && this.stepUpHandler !== null) {
122
+ const n = r.error.details?.availableMethods ?? [], o = await this.stepUpHandler(n);
123
+ if (o)
124
+ return e({ [W]: o });
125
+ }
126
+ return r;
127
+ }
93
128
  setToken(e, r) {
94
129
  r === null || r.length === 0 ? this.storage.remove(e) : this.storage.set(e, r);
95
130
  }
@@ -98,11 +133,13 @@ class K {
98
133
  return this.toCall(e, r, n);
99
134
  }
100
135
  async removeMethod(e) {
101
- const { error: r, response: n } = await this.inner.DELETE("/methods/{methodId}", { params: { path: { methodId: e } } });
136
+ const { error: r, response: n } = await this.sendWithStepUp(
137
+ (o) => this.inner.DELETE("/methods/{methodId}", { params: { path: { methodId: e } }, headers: o })
138
+ );
102
139
  return r ? this.errorCall(r, n) : { ok: !0, value: void 0 };
103
140
  }
104
141
  async startTotpEnrollment() {
105
- const { data: e, error: r, response: n } = await this.inner.POST("/enroll/totp/start");
142
+ const { data: e, error: r, response: n } = await this.sendWithStepUp((o) => this.inner.POST("/enroll/totp/start", { headers: o }));
106
143
  return this.toCall(e, r, n);
107
144
  }
108
145
  async confirmTotpEnrollment(e) {
@@ -110,7 +147,7 @@ class K {
110
147
  return this.toCall(r, n, o);
111
148
  }
112
149
  async startEmailEnrollment(e) {
113
- const { data: r, error: n, response: o } = await this.inner.POST("/enroll/email/start", { body: e });
150
+ const { data: r, error: n, response: o } = await this.sendWithStepUp((l) => this.inner.POST("/enroll/email/start", { body: e, headers: l }));
114
151
  return this.toCall(r, n, o);
115
152
  }
116
153
  async confirmEmailEnrollment(e) {
@@ -122,7 +159,7 @@ class K {
122
159
  return this.toCall(r, n, o);
123
160
  }
124
161
  async startWebAuthnEnrollment() {
125
- const { data: e, error: r, response: n } = await this.inner.POST("/enroll/webauthn/start");
162
+ const { data: e, error: r, response: n } = await this.sendWithStepUp((o) => this.inner.POST("/enroll/webauthn/start", { headers: o }));
126
163
  return this.toCall(e, r, n);
127
164
  }
128
165
  async confirmWebAuthnEnrollment(e) {
@@ -158,7 +195,7 @@ class K {
158
195
  return this.toCall(r, n, o);
159
196
  }
160
197
  async regenerateRecoveryCodes() {
161
- const { data: e, error: r, response: n } = await this.inner.POST("/recovery-codes/regenerate");
198
+ const { data: e, error: r, response: n } = await this.sendWithStepUp((o) => this.inner.POST("/recovery-codes/regenerate", { headers: o }));
162
199
  return this.toCall(e, r, n);
163
200
  }
164
201
  toCall(e, r, n) {
@@ -180,7 +217,7 @@ class K {
180
217
  };
181
218
  }
182
219
  }
183
- class te {
220
+ class ne {
184
221
  get(e) {
185
222
  return globalThis.sessionStorage?.getItem(e) ?? null;
186
223
  }
@@ -191,7 +228,7 @@ class te {
191
228
  globalThis.sessionStorage?.removeItem(e);
192
229
  }
193
230
  }
194
- class ne {
231
+ class oe {
195
232
  get(e) {
196
233
  return globalThis.localStorage?.getItem(e) ?? null;
197
234
  }
@@ -210,7 +247,7 @@ class s extends Error {
210
247
  super(r), this.name = "Omni2FaApiError", this.code = e, this.httpStatus = n, this.details = o;
211
248
  }
212
249
  }
213
- const W = {
250
+ const L = {
214
251
  enrollmentId: null,
215
252
  otpAuthUri: null,
216
253
  secret: null,
@@ -219,7 +256,7 @@ const W = {
219
256
  errorCode: null,
220
257
  errorMessage: null
221
258
  };
222
- function $(t) {
259
+ function H(t) {
223
260
  return h({
224
261
  types: {
225
262
  context: {},
@@ -246,7 +283,7 @@ function $(t) {
246
283
  }).createMachine({
247
284
  id: "totpEnrollment",
248
285
  initial: "idle",
249
- context: W,
286
+ context: L,
250
287
  states: {
251
288
  idle: {
252
289
  on: {
@@ -314,7 +351,7 @@ function y({ context: t }) {
314
351
  function k(t, e) {
315
352
  e instanceof s ? (t.errorCode = e.code, t.errorMessage = e.message) : (t.errorCode = "UNKNOWN", t.errorMessage = e instanceof Error ? e.message : null);
316
353
  }
317
- const H = {
354
+ const V = {
318
355
  enrollmentId: null,
319
356
  email: null,
320
357
  expiresAt: null,
@@ -324,7 +361,7 @@ const H = {
324
361
  errorCode: null,
325
362
  errorMessage: null
326
363
  };
327
- function V(t) {
364
+ function Y(t) {
328
365
  return h({
329
366
  types: {
330
367
  context: {},
@@ -357,7 +394,7 @@ function V(t) {
357
394
  }).createMachine({
358
395
  id: "emailEnrollment",
359
396
  initial: "idle",
360
- context: H,
397
+ context: V,
361
398
  states: {
362
399
  idle: {
363
400
  on: {
@@ -463,15 +500,15 @@ function d(t) {
463
500
  r += String.fromCharCode(n);
464
501
  return btoa(r).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
465
502
  }
466
- function D(t) {
503
+ function R(t) {
467
504
  return (t ?? []).map((e) => ({ ...e, id: m(e.id) }));
468
505
  }
469
- async function Y(t) {
506
+ async function q(t) {
470
507
  const e = JSON.parse(t), r = {
471
508
  ...e,
472
509
  challenge: m(e.challenge),
473
510
  user: { ...e.user, id: m(e.user.id) },
474
- excludeCredentials: D(e.excludeCredentials)
511
+ excludeCredentials: R(e.excludeCredentials)
475
512
  // Cast through unknown: the spread carries Fido2's index-signature fields the DOM type omits.
476
513
  }, n = await navigator.credentials.create({ publicKey: r });
477
514
  if (n === null)
@@ -492,7 +529,7 @@ async function P(t) {
492
529
  const e = JSON.parse(t), r = {
493
530
  ...e,
494
531
  challenge: m(e.challenge),
495
- allowCredentials: D(e.allowCredentials)
532
+ allowCredentials: R(e.allowCredentials)
496
533
  }, n = await navigator.credentials.get({ publicKey: r });
497
534
  if (n === null)
498
535
  throw new Error("WebAuthn authentication produced no credential.");
@@ -510,7 +547,7 @@ async function P(t) {
510
547
  }
511
548
  });
512
549
  }
513
- const q = {
550
+ const z = {
514
551
  enrollmentId: null,
515
552
  optionsJson: null,
516
553
  name: null,
@@ -533,7 +570,7 @@ function B(t) {
533
570
  return e.value;
534
571
  }),
535
572
  registerAndConfirm: i(async ({ input: e }) => {
536
- const r = await Y(e.optionsJson), n = await t.confirmWebAuthnEnrollment({
573
+ const r = await q(e.optionsJson), n = await t.confirmWebAuthnEnrollment({
537
574
  enrollmentId: e.enrollmentId,
538
575
  attestationResponseJson: r,
539
576
  name: e.name
@@ -546,7 +583,7 @@ function B(t) {
546
583
  }).createMachine({
547
584
  id: "webauthnEnrollment",
548
585
  initial: "idle",
549
- context: q,
586
+ context: z,
550
587
  states: {
551
588
  idle: {
552
589
  on: {
@@ -567,7 +604,7 @@ function B(t) {
567
604
  },
568
605
  onError: {
569
606
  target: "failed",
570
- actions: ({ context: e, event: r }) => U(e, r.error)
607
+ actions: ({ context: e, event: r }) => O(e, r.error)
571
608
  }
572
609
  }
573
610
  },
@@ -586,28 +623,28 @@ function B(t) {
586
623
  },
587
624
  onError: {
588
625
  target: "failed",
589
- actions: ({ context: e, event: r }) => U(e, r.error)
626
+ actions: ({ context: e, event: r }) => O(e, r.error)
590
627
  }
591
628
  }
592
629
  },
593
630
  enrolled: {
594
631
  on: {
595
- reset: { target: "idle", actions: O }
632
+ reset: { target: "idle", actions: U }
596
633
  }
597
634
  },
598
635
  failed: {
599
636
  on: {
600
637
  retry: { target: "starting" },
601
- reset: { target: "idle", actions: O }
638
+ reset: { target: "idle", actions: U }
602
639
  }
603
640
  }
604
641
  }
605
642
  });
606
643
  }
607
- function O({ context: t }) {
644
+ function U({ context: t }) {
608
645
  t.enrollmentId = null, t.optionsJson = null, t.name = null, t.methodId = null, t.recoveryCodes = null, t.errorCode = null, t.errorMessage = null;
609
646
  }
610
- function U(t, e) {
647
+ function O(t, e) {
611
648
  e instanceof s ? (t.errorCode = e.code, t.errorMessage = e.message) : (t.errorCode = "UNKNOWN", t.errorMessage = e instanceof Error ? e.message : null);
612
649
  }
613
650
  const G = {
@@ -809,7 +846,7 @@ const j = {
809
846
  errorCode: null,
810
847
  errorMessage: null
811
848
  };
812
- function z(t) {
849
+ function Z(t) {
813
850
  return h({
814
851
  types: {
815
852
  context: {},
@@ -895,7 +932,7 @@ function Q({ context: t }) {
895
932
  function N(t, e) {
896
933
  e instanceof s ? (t.errorCode = e.code, t.errorMessage = e.message) : (t.errorCode = "UNKNOWN", t.errorMessage = e instanceof Error ? e.message : null);
897
934
  }
898
- const Z = {
935
+ const x = {
899
936
  methodId: null,
900
937
  methodType: null,
901
938
  stepUpToken: null,
@@ -905,7 +942,7 @@ const Z = {
905
942
  errorCode: null,
906
943
  errorMessage: null
907
944
  };
908
- function x(t) {
945
+ function ee(t) {
909
946
  return h({
910
947
  types: {
911
948
  context: {},
@@ -940,7 +977,7 @@ function x(t) {
940
977
  }).createMachine({
941
978
  id: "stepup",
942
979
  initial: "idle",
943
- context: Z,
980
+ context: x,
944
981
  states: {
945
982
  idle: {
946
983
  on: {
@@ -983,7 +1020,7 @@ function x(t) {
983
1020
  },
984
1021
  onDone: {
985
1022
  target: "verified",
986
- actions: ({ context: e, event: r }) => R(e, r.output.stepUpToken)
1023
+ actions: ({ context: e, event: r }) => D(e, r.output.stepUpToken)
987
1024
  },
988
1025
  onError: {
989
1026
  target: "failed",
@@ -1025,7 +1062,7 @@ function x(t) {
1025
1062
  },
1026
1063
  onDone: {
1027
1064
  target: "verified",
1028
- actions: ({ context: e, event: r }) => R(e, r.output.stepUpToken)
1065
+ actions: ({ context: e, event: r }) => D(e, r.output.stepUpToken)
1029
1066
  },
1030
1067
  onError: {
1031
1068
  target: "awaitingCode",
@@ -1050,7 +1087,7 @@ function x(t) {
1050
1087
  function I(t, e) {
1051
1088
  t.methodType = e.type, t.expiresAt = e.expiresAt ?? null, t.resendAvailableAt = e.resendAvailableAt ?? null, t.optionsJson = e.optionsJson ?? null, t.errorCode = null, t.errorMessage = null;
1052
1089
  }
1053
- function R(t, e) {
1090
+ function D(t, e) {
1054
1091
  t.stepUpToken = e, t.errorCode = null, t.errorMessage = null;
1055
1092
  }
1056
1093
  function A({ context: t }) {
@@ -1059,9 +1096,8 @@ function A({ context: t }) {
1059
1096
  function g(t, e) {
1060
1097
  e instanceof s ? (t.errorCode = e.code, t.errorMessage = e.message) : (t.errorCode = "UNKNOWN", t.errorMessage = e instanceof Error ? e.message : null);
1061
1098
  }
1062
- const oe = "X-Omni2FA-StepUp";
1063
1099
  function se(t) {
1064
- const e = new K(t), r = u($(e)), n = u(V(e)), o = u(B(e)), l = u(X(e)), p = u(x(e)), f = u(z(e));
1100
+ const e = new $(t), r = u(H(e)), n = u(Y(e)), o = u(B(e)), l = u(X(e)), p = u(ee(e)), f = u(Z(e));
1065
1101
  return r.start(), n.start(), o.start(), l.start(), p.start(), f.start(), {
1066
1102
  client: e,
1067
1103
  totpEnrollment: r,
@@ -1076,22 +1112,22 @@ function se(t) {
1076
1112
  };
1077
1113
  }
1078
1114
  export {
1079
- ne as LocalStorageStorage,
1115
+ oe as LocalStorageStorage,
1080
1116
  _ as MemoryStorage,
1081
1117
  s as Omni2FaApiError,
1082
- K as Omni2FaClient,
1118
+ $ as Omni2FaClient,
1083
1119
  a as Omni2FaErrorCodes,
1084
- oe as STEP_UP_HEADER,
1085
- te as SessionStorageStorage,
1120
+ W as STEP_UP_HEADER,
1121
+ ne as SessionStorageStorage,
1086
1122
  X as createChallengeMachine,
1087
- V as createEmailEnrollmentMachine,
1088
- z as createMethodsMachine,
1123
+ Y as createEmailEnrollmentMachine,
1124
+ Z as createMethodsMachine,
1089
1125
  se as createOmni2Fa,
1090
- x as createStepUpMachine,
1091
- $ as createTotpEnrollmentMachine,
1126
+ ee as createStepUpMachine,
1127
+ H as createTotpEnrollmentMachine,
1092
1128
  B as createWebAuthnEnrollmentMachine,
1093
1129
  T as getDefaultMessage,
1094
1130
  P as startAuthentication,
1095
- Y as startRegistration
1131
+ q as startRegistration
1096
1132
  };
1097
1133
  //# sourceMappingURL=index.js.map