@passflow/core 0.17.0 → 0.19.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.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1021 -716
- package/dist/index.mjs.map +1 -1
- package/dist/lib/api/auth.d.ts +3 -1
- package/dist/lib/api/auth.d.ts.map +1 -1
- package/dist/lib/api/model.d.ts +50 -0
- package/dist/lib/api/model.d.ts.map +1 -1
- package/dist/lib/api/two-factor.d.ts +16 -7
- package/dist/lib/api/two-factor.d.ts.map +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/passflow.d.ts +49 -4
- package/dist/lib/passflow.d.ts.map +1 -1
- package/dist/lib/pkce.d.ts +13 -0
- package/dist/lib/pkce.d.ts.map +1 -0
- package/dist/lib/services/auth-service.d.ts +56 -1
- package/dist/lib/services/auth-service.d.ts.map +1 -1
- package/dist/lib/services/two-factor-service.d.ts +40 -7
- package/dist/lib/services/two-factor-service.d.ts.map +1 -1
- package/dist/lib/store.d.ts.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -1
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import B from "axios";
|
|
2
|
-
import { v4 as
|
|
3
|
-
import { startAuthentication as
|
|
4
|
-
const
|
|
5
|
-
version:
|
|
6
|
-
},
|
|
2
|
+
import { v4 as _t } from "uuid";
|
|
3
|
+
import { startAuthentication as Et, startRegistration as It } from "@simplewebauthn/browser";
|
|
4
|
+
const At = "0.19.0", Ct = {
|
|
5
|
+
version: At
|
|
6
|
+
}, V = "X-Passflow-Clientid", D = "Authorization", Rt = "X-Passflow-DeviceId", Pt = "X-Passflow-DeviceType", Ft = Ct.version, ei = ["id", "offline", "openid"], Mt = ["id", "offline", "tenant", "email", "oidc", "openid", "access:tenant:all"], qe = "https://auth.passflow.cloud", ti = "default", Ut = 500, Dt = 600, xt = 100, Ot = 6e4, Ne = 30, Lt = 3, $t = 30, qt = 200, Nt = (r) => {
|
|
7
7
|
const e = [];
|
|
8
8
|
let t;
|
|
9
9
|
for (t in r) {
|
|
@@ -18,14 +18,14 @@ const kt = "0.17.0", wt = {
|
|
|
18
18
|
}
|
|
19
19
|
return { raw: r, tenants: e };
|
|
20
20
|
};
|
|
21
|
-
function
|
|
21
|
+
function Vt(r) {
|
|
22
22
|
if (typeof window < "u" && typeof window.atob == "function")
|
|
23
23
|
return window.atob(r);
|
|
24
24
|
if (typeof Buffer < "u")
|
|
25
25
|
return Buffer.from(r, "base64").toString("utf-8");
|
|
26
26
|
throw new Error("No Base64 decoding method available in this environment");
|
|
27
27
|
}
|
|
28
|
-
class
|
|
28
|
+
class Kt {
|
|
29
29
|
constructor(e) {
|
|
30
30
|
this.storageManager = e;
|
|
31
31
|
}
|
|
@@ -54,19 +54,19 @@ class Dt {
|
|
|
54
54
|
return T(t);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
function C(r, e =
|
|
57
|
+
function C(r, e = Ne) {
|
|
58
58
|
return Math.floor(Date.now() / 1e3) + e > r.exp;
|
|
59
59
|
}
|
|
60
60
|
function T(r) {
|
|
61
61
|
const e = r.split(".")[1];
|
|
62
62
|
if (!e) throw new Error("Invalid token string");
|
|
63
|
-
const t = e.replace(/-/g, "+").replace(/_/g, "/"), s = t + "=".repeat((4 - t.length % 4) % 4), i =
|
|
63
|
+
const t = e.replace(/-/g, "+").replace(/_/g, "/"), s = t + "=".repeat((4 - t.length % 4) % 4), i = Vt(s), n = decodeURIComponent(
|
|
64
64
|
i.split("").map((a) => "%" + ("00" + a.charCodeAt(0).toString(16)).slice(-2)).join("")
|
|
65
65
|
), o = JSON.parse(n);
|
|
66
|
-
return o.membership = o.passflow_tm && o.type !== "invite" ?
|
|
66
|
+
return o.membership = o.passflow_tm && o.type !== "invite" ? Nt(o.passflow_tm) : void 0, o;
|
|
67
67
|
}
|
|
68
|
-
var b = /* @__PURE__ */ ((r) => (r.id_token = "id_token", r.access_token = "access", r.refresh_token = "refresh", r.invite_token = "invite", r.reset_token = "reset", r.web_cookie = "web-cookie", r.management = "management", r.signin = "signin", r.actor = "actor", r.two_factor = "2fa", r))(b || {}), A = /* @__PURE__ */ ((r) => (r.JsonBody = "json_body", r.Cookie = "cookie", r.Mobile = "mobile", r.BFF = "bff", r))(A || {}),
|
|
69
|
-
class
|
|
68
|
+
var b = /* @__PURE__ */ ((r) => (r.id_token = "id_token", r.access_token = "access", r.refresh_token = "refresh", r.invite_token = "invite", r.reset_token = "reset", r.web_cookie = "web-cookie", r.management = "management", r.signin = "signin", r.actor = "actor", r.two_factor = "2fa", r))(b || {}), A = /* @__PURE__ */ ((r) => (r.JsonBody = "json_body", r.Cookie = "cookie", r.Mobile = "mobile", r.BFF = "bff", r))(A || {}), Ve = /* @__PURE__ */ ((r) => (r.Unknown = "unknown", r.Valid = "valid", r.Invalid = "invalid", r))(Ve || {});
|
|
69
|
+
class Ke {
|
|
70
70
|
constructor(e) {
|
|
71
71
|
this.storageManager = e, this.mode = "json_body", this.sessionState = "unknown", this.isInitializedFlag = !1, this.STORAGE_PREFIX = "passflow_", this.DELIVERY_MODE_KEY = `${this.STORAGE_PREFIX}delivery_mode`, this.SESSION_STATE_KEY = `${this.STORAGE_PREFIX}session_state`, this.loadPersistedMode(), this.loadPersistedSessionState();
|
|
72
72
|
}
|
|
@@ -176,7 +176,7 @@ class Le {
|
|
|
176
176
|
loadPersistedSessionState() {
|
|
177
177
|
try {
|
|
178
178
|
const e = this.storageManager.storage.getItem(this.SESSION_STATE_KEY);
|
|
179
|
-
e && Object.values(
|
|
179
|
+
e && Object.values(Ve).includes(e) && (this.sessionState = e);
|
|
180
180
|
} catch {
|
|
181
181
|
}
|
|
182
182
|
}
|
|
@@ -217,7 +217,7 @@ class Le {
|
|
|
217
217
|
}
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
|
-
class
|
|
220
|
+
class Se {
|
|
221
221
|
constructor({ storage: e, prefix: t } = {}) {
|
|
222
222
|
this.keyStoragePrefix = "", this.scopes = `${this.keyStoragePrefix}tokens_scopes`, this.deviceId = `${this.keyStoragePrefix}passflowDeviceId`, this.invitationToken = `${this.keyStoragePrefix}passflowInvitationToken`, this.previousRedirectUrl = `${this.keyStoragePrefix}passflowPreviousRedirectUrl`, this.STORAGE_PREFIX = "passflow_", this.ID_TOKEN_KEY = `${this.STORAGE_PREFIX}id_token`, this.CSRF_TOKEN_KEY = `${this.STORAGE_PREFIX}csrf_token`, this.DELIVERY_MODE_KEY = `${this.STORAGE_PREFIX}delivery_mode`, this.storage = e ?? localStorage, this.keyStoragePrefix = t ? `${t}_` : "";
|
|
223
223
|
}
|
|
@@ -400,9 +400,9 @@ class me {
|
|
|
400
400
|
return `${this.keyStoragePrefix}${e}`;
|
|
401
401
|
}
|
|
402
402
|
}
|
|
403
|
-
class
|
|
403
|
+
class Be {
|
|
404
404
|
constructor(e) {
|
|
405
|
-
this.storageManager = e ?? new
|
|
405
|
+
this.storageManager = e ?? new Se();
|
|
406
406
|
}
|
|
407
407
|
getDeviceId() {
|
|
408
408
|
const e = this.storageManager.getDeviceId();
|
|
@@ -413,19 +413,19 @@ class $e {
|
|
|
413
413
|
return e;
|
|
414
414
|
}
|
|
415
415
|
generateUniqueDeviceId() {
|
|
416
|
-
return
|
|
416
|
+
return _t();
|
|
417
417
|
}
|
|
418
418
|
}
|
|
419
|
-
class
|
|
419
|
+
class Ge extends Error {
|
|
420
420
|
constructor(e = "Authentication popup was closed") {
|
|
421
421
|
super(e), this.name = "PopupClosedError";
|
|
422
422
|
}
|
|
423
423
|
}
|
|
424
|
-
class
|
|
424
|
+
class Bt {
|
|
425
425
|
constructor() {
|
|
426
426
|
this.passkeys = {
|
|
427
|
-
startRegistration: (e) =>
|
|
428
|
-
startAuthentication: (e) =>
|
|
427
|
+
startRegistration: (e) => It({ optionsJSON: e }),
|
|
428
|
+
startAuthentication: (e) => Et({ optionsJSON: e })
|
|
429
429
|
};
|
|
430
430
|
}
|
|
431
431
|
// ----------------------------------------------------------------
|
|
@@ -557,15 +557,15 @@ class xt {
|
|
|
557
557
|
'openAuthUrl: "deeplink" mode is not supported on web. Use "popup" or "redirect" instead, or provide a native platform adapter.'
|
|
558
558
|
)
|
|
559
559
|
);
|
|
560
|
-
const i = t.width ??
|
|
561
|
-
return a ? new Promise((h,
|
|
560
|
+
const i = t.width ?? Ut, n = t.height ?? Dt, o = t.expectedReturnOrigin ?? window.location.origin, a = window.open(e, "_blank", `width=${i},height=${n}`);
|
|
561
|
+
return a ? new Promise((h, u) => {
|
|
562
562
|
const m = Date.now(), d = setInterval(() => {
|
|
563
563
|
if (a.closed) {
|
|
564
|
-
clearInterval(d),
|
|
564
|
+
clearInterval(d), u(new Ge());
|
|
565
565
|
return;
|
|
566
566
|
}
|
|
567
|
-
if (Date.now() - m >
|
|
568
|
-
clearInterval(d), a.close(),
|
|
567
|
+
if (Date.now() - m > Ot) {
|
|
568
|
+
clearInterval(d), a.close(), u(new Error("Authentication popup timed out"));
|
|
569
569
|
return;
|
|
570
570
|
}
|
|
571
571
|
try {
|
|
@@ -575,7 +575,7 @@ class xt {
|
|
|
575
575
|
}
|
|
576
576
|
} catch {
|
|
577
577
|
}
|
|
578
|
-
},
|
|
578
|
+
}, xt);
|
|
579
579
|
}) : (window.location.href = e, new Promise(() => {
|
|
580
580
|
}));
|
|
581
581
|
}
|
|
@@ -633,94 +633,94 @@ class xt {
|
|
|
633
633
|
return "web";
|
|
634
634
|
}
|
|
635
635
|
}
|
|
636
|
-
const
|
|
636
|
+
const Y = new Bt(), Gt = /^[0-9]+$/, Ae = Object.freeze({ unorderable: !1, zero: !1 }), jt = (r) => Gt.test(r) ? Number.parseInt(r, 10) : void 0, re = (r) => {
|
|
637
637
|
if (!r)
|
|
638
|
-
return
|
|
638
|
+
return Ae;
|
|
639
639
|
const e = r.split(/\s+/).filter((i) => i !== "");
|
|
640
640
|
if (e.length === 0)
|
|
641
|
-
return
|
|
641
|
+
return Ae;
|
|
642
642
|
const t = [];
|
|
643
643
|
for (const i of e) {
|
|
644
|
-
const n =
|
|
644
|
+
const n = jt(i);
|
|
645
645
|
n !== void 0 && t.push(n);
|
|
646
646
|
}
|
|
647
647
|
if (t.length === 0)
|
|
648
648
|
return { raw: r, unorderable: !0, zero: !1 };
|
|
649
649
|
const s = Math.min(...t);
|
|
650
650
|
return s === 0 ? { raw: r, unorderable: !1, zero: !0 } : { level: s, raw: r, unorderable: !1, zero: !1 };
|
|
651
|
-
},
|
|
651
|
+
}, Ht = (r) => re(r).level, zt = "insufficient_user_authentication", Yt = "upgrade_required", Ce = /([A-Za-z0-9!#$%&'*+\-.^_`|~]+)\s*=\s*(?:"((?:[^"\\]|\\.)*)"|([^\s,]*))/g, Wt = (r) => r.replace(/\\(.)/g, "$1"), je = (r) => {
|
|
652
652
|
const e = {};
|
|
653
|
-
|
|
654
|
-
for (const t of r.matchAll(
|
|
653
|
+
Ce.lastIndex = 0;
|
|
654
|
+
for (const t of r.matchAll(Ce)) {
|
|
655
655
|
const s = t[1];
|
|
656
656
|
if (!s)
|
|
657
657
|
continue;
|
|
658
658
|
const i = t[2], n = t[3];
|
|
659
|
-
e[s.toLowerCase()] = i !== void 0 ?
|
|
659
|
+
e[s.toLowerCase()] = i !== void 0 ? Wt(i) : n ?? "";
|
|
660
660
|
}
|
|
661
661
|
return e;
|
|
662
|
-
},
|
|
662
|
+
}, He = (r) => {
|
|
663
663
|
if (r == null || r === "")
|
|
664
664
|
return { kind: "absent" };
|
|
665
665
|
const e = typeof r == "number" ? r : Number.parseInt(String(r), 10);
|
|
666
666
|
return Number.isFinite(e) && e > 0 ? { kind: "valid", value: e } : { kind: "invalid", raw: r };
|
|
667
|
-
},
|
|
668
|
-
const e =
|
|
667
|
+
}, ze = (r) => {
|
|
668
|
+
const e = He(r);
|
|
669
669
|
return e.kind === "valid" ? e.value : void 0;
|
|
670
|
-
},
|
|
670
|
+
}, Xt = (r, e) => {
|
|
671
671
|
if (!r || !/(^|[\s,])Bearer\b/i.test(r))
|
|
672
672
|
return;
|
|
673
|
-
const t =
|
|
674
|
-
if (t.error ===
|
|
673
|
+
const t = je(r);
|
|
674
|
+
if (t.error === zt)
|
|
675
675
|
return {
|
|
676
676
|
acrValues: t.acr_values || void 0,
|
|
677
|
-
maxAge:
|
|
677
|
+
maxAge: ze(t.max_age),
|
|
678
678
|
status: e
|
|
679
679
|
};
|
|
680
|
-
},
|
|
680
|
+
}, Jt = (r, e) => {
|
|
681
681
|
if (!r || typeof r != "object")
|
|
682
682
|
return;
|
|
683
683
|
const t = r;
|
|
684
|
-
if (t.error ===
|
|
684
|
+
if (t.error === Yt)
|
|
685
685
|
return {
|
|
686
686
|
acrValues: typeof t.acr_values == "string" && t.acr_values ? t.acr_values : void 0,
|
|
687
|
-
maxAge:
|
|
687
|
+
maxAge: ze(t.max_age),
|
|
688
688
|
status: e
|
|
689
689
|
};
|
|
690
|
-
},
|
|
690
|
+
}, Re = (r, e, t) => ({
|
|
691
691
|
channel: r,
|
|
692
|
-
acr:
|
|
693
|
-
maxAge:
|
|
692
|
+
acr: re(e.acrValues),
|
|
693
|
+
maxAge: He(t),
|
|
694
694
|
raw: e.acrValues
|
|
695
|
-
}),
|
|
695
|
+
}), Zt = (r) => r ? je(r) : {}, be = (r, e) => {
|
|
696
696
|
const { status: t } = r;
|
|
697
697
|
if (t !== 401 && t !== 403)
|
|
698
698
|
return { diagnostics: [] };
|
|
699
|
-
const s = e?.requireChallengeChannel === "header", i = r.getHeader("www-authenticate"), n =
|
|
700
|
-
a.push({ status: t, url: "", reason:
|
|
699
|
+
const s = e?.requireChallengeChannel === "header", i = r.getHeader("www-authenticate"), n = Xt(i, t), o = s ? void 0 : Jt(r.body, t), a = [], h = (p, y) => {
|
|
700
|
+
a.push({ status: t, url: "", reason: p, ...y ? { detail: y } : {} });
|
|
701
701
|
};
|
|
702
702
|
if (!n && !o)
|
|
703
703
|
return s && h("header-required-but-absent", i ? { header: i } : void 0), { diagnostics: a };
|
|
704
|
-
const
|
|
705
|
-
if (n &&
|
|
706
|
-
const
|
|
707
|
-
|
|
708
|
-
}
|
|
709
|
-
const m = (
|
|
710
|
-
for (const
|
|
711
|
-
|
|
712
|
-
const d =
|
|
704
|
+
const u = [];
|
|
705
|
+
if (n && u.push(Re("header", n, Zt(i).max_age)), o) {
|
|
706
|
+
const p = r.body;
|
|
707
|
+
u.push(Re("body", o, p?.max_age));
|
|
708
|
+
}
|
|
709
|
+
const m = (p) => p;
|
|
710
|
+
for (const p of u)
|
|
711
|
+
p.acr.unorderable && h("channels-unorderable", { [m(p.channel)]: p.raw }), p.acr.zero && h("zero-constraint-ignored", { field: "acr_values", [m(p.channel)]: p.raw }), p.maxAge.kind === "invalid" && h("zero-constraint-ignored", { field: "max_age", [m(p.channel)]: String(p.maxAge.raw) });
|
|
712
|
+
const d = u.filter((p) => p.acr.level !== void 0);
|
|
713
713
|
let g, f;
|
|
714
|
-
for (const
|
|
715
|
-
const y =
|
|
716
|
-
g === void 0 || y > g ? (g = y, f =
|
|
714
|
+
for (const p of d) {
|
|
715
|
+
const y = p.acr.level;
|
|
716
|
+
g === void 0 || y > g ? (g = y, f = p.raw) : y === g && p.channel === "header" && (f = p.raw);
|
|
717
717
|
}
|
|
718
718
|
let v;
|
|
719
|
-
for (const
|
|
720
|
-
|
|
721
|
-
if (
|
|
722
|
-
const [
|
|
723
|
-
(I ||
|
|
719
|
+
for (const p of u)
|
|
720
|
+
p.maxAge.kind === "valid" && (v === void 0 || p.maxAge.value < v) && (v = p.maxAge.value);
|
|
721
|
+
if (u.length === 2) {
|
|
722
|
+
const [p, y] = u, I = p.acr.level !== void 0 && y.acr.level !== void 0 && p.acr.level !== y.acr.level, W = p.maxAge.kind === "valid" && y.maxAge.kind === "valid" && p.maxAge.value !== y.maxAge.value;
|
|
723
|
+
(I || W) && h("channels-disagree", { header: p.raw ?? y.raw, body: y.raw ?? p.raw });
|
|
724
724
|
}
|
|
725
725
|
return {
|
|
726
726
|
challenge: {
|
|
@@ -728,19 +728,19 @@ const z = new xt(), Ot = /^[0-9]+$/, be = Object.freeze({ unorderable: !1, zero:
|
|
|
728
728
|
requiredLevel: g,
|
|
729
729
|
maxAge: v,
|
|
730
730
|
status: t,
|
|
731
|
-
channels:
|
|
731
|
+
channels: u.map((p) => p.channel)
|
|
732
732
|
},
|
|
733
733
|
diagnostics: a
|
|
734
734
|
};
|
|
735
|
-
},
|
|
735
|
+
}, Qt = (r, e, t) => be({ status: r, getHeader: e, body: t }).challenge, Ye = "__passflowUpgradeTransaction", We = "__passflowUpgradeReplayed", Xe = (r, e) => typeof r == "object" && r !== null && r[e] === !0, Je = (r) => ({
|
|
736
736
|
...r ?? {},
|
|
737
|
-
[
|
|
738
|
-
}),
|
|
737
|
+
[Ye]: !0
|
|
738
|
+
}), Ze = (r) => Xe(r, Ye), er = (r) => ({
|
|
739
739
|
...r,
|
|
740
|
-
[
|
|
741
|
-
}),
|
|
742
|
-
var
|
|
743
|
-
const
|
|
740
|
+
[We]: !0
|
|
741
|
+
}), tr = (r) => Xe(r, We);
|
|
742
|
+
var U = /* @__PURE__ */ ((r) => (r.GET = "get", r.POST = "post", r.PUT = "put", r.PATCH = "patch", r.DELETE = "delete", r))(U || {}), l = /* @__PURE__ */ ((r) => (r.signin = "/auth/login", r.signup = "/auth/register", r.pkceExchange = "/auth/pkce_exchange", r.signInWithProvider = "/auth/federated/start/", r.passwordless = "/auth/passwordless/start", r.passwordlessComplete = "/auth/passwordless/complete", r.logout = "/user/logout", r.refresh = "/auth/refresh", r.validateSession = "/user/me", r.sendPasswordResetEmail = "/auth/password/reset", r.resetPassword = "/auth/password/change", r.appSettings = "/app/settings", r.passkeyRegisterStart = "/auth/passkey/register/start", r.passkeyRegisterComplete = "/auth/passkey/register/complete", r.passkeyAuthenticateStart = "/auth/passkey/authenticate/start", r.passkeyAuthenticateComplete = "/auth/passkey/authenticate/complete", r.passkeyValidate = "/auth/validate", r.settingsAll = "/settings", r.settingsPasswordPolicy = "/settings/password", r.settingsPasskey = "/settings/passkey", r.userPasskey = "/user/passkey", r.addUserPasskey = "/user/passkey/add/start", r.completeAddUserPasskey = "/user/passkey/add/complete", r.joinInvitation = "/user/tenant/join", r.tenantPath = "/user/tenant", r.invitationsPath = "/user/tenant/:tenantID/invitations", r.requestInvitation = "/user/invite", r.invitationDelete = "/user/invite/:invitationID", r.invitationResend = "/user/invite/:invitationID/resend", r.invitationGetLink = "/user/invite/:invitationID/link", r.twoFactor = "/user/2fa", r.twoFactorStatus = "/user/2fa/status", r.twoFactorSetupBegin = "/user/2fa/setup/begin", r.twoFactorSetupConfirm = "/user/2fa/setup/confirm", r.twoFactorVerify = "/auth/2fa/verify", r.twoFactorRecovery = "/auth/2fa/recovery", r.twoFactorRegenerateCodes = "/user/2fa/recovery-codes/regenerate", r.twoFactorSetupMagicLink = "/auth/2fa-setup", r.TwoFactorMethodsAvailable = "/v2/user/2fa/methods/available", r.TwoFactorMethodsRegistered = "/v2/user/2fa/methods", r.TwoFactorSetupStart = "/v2/user/2fa/setup/start", r.TwoFactorSetupComplete = "/v2/user/2fa/setup/complete", r.TwoFactorMethodRemove = "/v2/user/2fa/methods/:id", r.TwoFactorChallenge = "/v2/auth/2fa/challenge", r.TwoFactorVerifyV2 = "/v2/auth/2fa/verify", r.TwoFactorAlternative = "/v2/auth/2fa/alternative", r.TwoFactorTrustedDevices = "/v2/user/2fa/trusted-devices", r.TwoFactorTrustedDeviceRevoke = "/v2/user/2fa/trusted-devices/:id", r.cliAuthStatus = "/cli/auth/status/:sessionId", r.cliAuthComplete = "/cli/auth/complete", r.upgradeStart = "/auth/upgrade/start", r))(l || {}), P = /* @__PURE__ */ ((r) => (r.passkeyRegisterStart = "/admin/auth/passkey/register/start", r.passkeyRegisterComplete = "/admin/auth/passkey/register/complete", r.passkeyAuthenticateStart = "/admin/auth/passkey/authenticate/start", r.passkeyAuthenticateComplete = "/admin/auth/passkey/authenticate/complete", r.passkeyValidate = "/admin/auth/validate", r.logout = "/admin/auth/logout", r))(P || {});
|
|
743
|
+
const Qe = (r) => {
|
|
744
744
|
if (!r)
|
|
745
745
|
return null;
|
|
746
746
|
try {
|
|
@@ -755,21 +755,21 @@ class w extends Error {
|
|
|
755
755
|
super(), this.id = e?.id ?? "unknown", this.message = e?.message ?? e ?? "Something went wrong", this.status = e?.status ?? 500, this.location = e?.location ?? "unknown", this.time = e?.time ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
756
756
|
}
|
|
757
757
|
}
|
|
758
|
-
var
|
|
759
|
-
function
|
|
758
|
+
var rr = /* @__PURE__ */ ((r) => (r.google = "google", r.facebook = "facebook", r))(rr || {}), sr = /* @__PURE__ */ ((r) => (r.web = "web", r.ios = "ios", r.android = "android", r))(sr || {});
|
|
759
|
+
function ri(r) {
|
|
760
760
|
return r;
|
|
761
761
|
}
|
|
762
|
-
function
|
|
762
|
+
function F(r, e) {
|
|
763
763
|
let t = r;
|
|
764
764
|
return Object.entries(e).forEach(([s, i]) => {
|
|
765
765
|
t = t.replace(`:${s}`, i);
|
|
766
766
|
}), t;
|
|
767
767
|
}
|
|
768
|
-
var
|
|
769
|
-
const
|
|
768
|
+
var ir = /* @__PURE__ */ ((r) => (r.Disabled = "disabled", r.Optional = "optional", r.Required = "required", r))(ir || {});
|
|
769
|
+
const nr = 3, or = 1e3, ar = (r) => (e) => {
|
|
770
770
|
const t = r.headers?.[e] ?? r.headers?.[e.toLowerCase()];
|
|
771
771
|
return Array.isArray(t) ? t.join(", ") : t;
|
|
772
|
-
},
|
|
772
|
+
}, et = (r) => Qt(r.status, ar(r), r.data), cr = (r) => et(r) !== void 0;
|
|
773
773
|
class E {
|
|
774
774
|
constructor(e, t, s) {
|
|
775
775
|
this.refreshPromise = null, this.isRefreshing = !1, this.defaultHeaders = {
|
|
@@ -777,17 +777,17 @@ class E {
|
|
|
777
777
|
"Content-Type": "application/json"
|
|
778
778
|
}, this.nonAccessTokenEndpoints = ["/auth/", "/settings", "/settings/"], this.protectedEndpoints = ["logout", "refresh", "upgrade"];
|
|
779
779
|
const { url: i, appId: n, keyStoragePrefix: o } = e;
|
|
780
|
-
this._platform = e.platform ??
|
|
780
|
+
this._platform = e.platform ?? Y, this.url = i || qe, this.upgradeDomain = Qe(i), this.storageManager = t ?? new Se({
|
|
781
781
|
prefix: o ?? ""
|
|
782
|
-
}), this.deviceService = s ?? new
|
|
782
|
+
}), this.deviceService = s ?? new Be(this.storageManager), this.tokenService = new Kt(this.storageManager), this.tokenDeliveryManager = new Ke(this.storageManager), n && (this.appId = n, this.defaultHeaders = {
|
|
783
783
|
...this.defaultHeaders,
|
|
784
|
-
[
|
|
784
|
+
[V]: n
|
|
785
785
|
});
|
|
786
786
|
const a = this.deviceService.getDeviceId();
|
|
787
787
|
this.defaultHeaders = {
|
|
788
788
|
...this.defaultHeaders,
|
|
789
|
-
[
|
|
790
|
-
[
|
|
789
|
+
[Rt]: a,
|
|
790
|
+
[Pt]: this._platform.getDeviceType()
|
|
791
791
|
}, this.detectCookieSupport(), this.instance = B.create({
|
|
792
792
|
baseURL: this.url,
|
|
793
793
|
headers: { ...this.defaultHeaders }
|
|
@@ -806,36 +806,36 @@ class E {
|
|
|
806
806
|
}
|
|
807
807
|
return h;
|
|
808
808
|
}
|
|
809
|
-
const
|
|
810
|
-
if (
|
|
811
|
-
const m = T(
|
|
812
|
-
if (C(m,
|
|
809
|
+
const u = this.storageManager.getTokens();
|
|
810
|
+
if (u?.access_token) {
|
|
811
|
+
const m = T(u.access_token);
|
|
812
|
+
if (C(m, Ne) && u.refresh_token)
|
|
813
813
|
try {
|
|
814
814
|
if (this.refreshPromise) {
|
|
815
815
|
const d = await this.refreshPromise;
|
|
816
|
-
return d?.data?.access_token && (h.headers[
|
|
816
|
+
return d?.data?.access_token && (h.headers[D] = `Bearer ${d.data.access_token}`), h;
|
|
817
817
|
}
|
|
818
818
|
this.refreshPromise = this.refreshTokens();
|
|
819
819
|
try {
|
|
820
820
|
const d = await this.refreshPromise;
|
|
821
|
-
return d?.data?.access_token && (h.headers[
|
|
821
|
+
return d?.data?.access_token && (h.headers[D] = `Bearer ${d.data.access_token}`), h;
|
|
822
822
|
} finally {
|
|
823
823
|
this.refreshPromise = null;
|
|
824
824
|
}
|
|
825
825
|
} catch (d) {
|
|
826
826
|
return this.refreshPromise = null, this.isRefreshing = !1, this.storageManager.deleteTokens(), Promise.reject(d);
|
|
827
827
|
}
|
|
828
|
-
return h.headers[
|
|
828
|
+
return h.headers[D] = `Bearer ${u.access_token}`, h;
|
|
829
829
|
}
|
|
830
830
|
return h;
|
|
831
831
|
}), this.instance.interceptors.response.use(
|
|
832
832
|
(h) => h,
|
|
833
833
|
async (h) => {
|
|
834
834
|
if (h.response?.status === 401 && !this.isUpgradeTransactionError(h) && this.tokenDeliveryManager.setSessionInvalid(), h.response && this.upgradeHandler) {
|
|
835
|
-
const
|
|
836
|
-
if (
|
|
835
|
+
const u = et(h.response);
|
|
836
|
+
if (u)
|
|
837
837
|
try {
|
|
838
|
-
return await this.upgradeHandler(h,
|
|
838
|
+
return await this.upgradeHandler(h, u);
|
|
839
839
|
} catch (m) {
|
|
840
840
|
if (m !== h)
|
|
841
841
|
throw m;
|
|
@@ -854,7 +854,7 @@ class E {
|
|
|
854
854
|
* speak upgrade vocabulary", which is unsound in both directions.
|
|
855
855
|
*/
|
|
856
856
|
isUpgradeTransactionError(e) {
|
|
857
|
-
return
|
|
857
|
+
return Ze(e.config) || e.response !== void 0 && cr(e.response);
|
|
858
858
|
}
|
|
859
859
|
/**
|
|
860
860
|
* Installs (or clears) the handler consulted when a response carries an
|
|
@@ -915,7 +915,7 @@ class E {
|
|
|
915
915
|
scopes: t
|
|
916
916
|
}, i = await this.instance.post(l.refresh, s, {
|
|
917
917
|
headers: {
|
|
918
|
-
[
|
|
918
|
+
[D]: `Bearer ${e.refresh_token}`
|
|
919
919
|
}
|
|
920
920
|
});
|
|
921
921
|
return i.data && this.storageManager.saveTokens(i.data), this.isRefreshing = !1, i;
|
|
@@ -929,17 +929,17 @@ class E {
|
|
|
929
929
|
if (!["GET", "HEAD", "OPTIONS"].includes(s || ""))
|
|
930
930
|
return Promise.reject(e);
|
|
931
931
|
const n = t._retryCount || 0;
|
|
932
|
-
if (n >=
|
|
932
|
+
if (n >= nr)
|
|
933
933
|
return Promise.reject(e);
|
|
934
|
-
let o =
|
|
934
|
+
let o = or * Math.pow(2, n);
|
|
935
935
|
const a = e.response?.headers?.["retry-after"];
|
|
936
936
|
if (a) {
|
|
937
937
|
const h = Number.parseInt(a, 10);
|
|
938
938
|
if (!Number.isNaN(h))
|
|
939
939
|
o = h * 1e3;
|
|
940
940
|
else {
|
|
941
|
-
const
|
|
942
|
-
Number.isNaN(
|
|
941
|
+
const u = new Date(a);
|
|
942
|
+
Number.isNaN(u.getTime()) || (o = Math.max(0, u.getTime() - Date.now()));
|
|
943
943
|
}
|
|
944
944
|
}
|
|
945
945
|
return await new Promise((h) => setTimeout(h, o)), t._retryCount = n + 1, this.instance.request(t);
|
|
@@ -972,19 +972,19 @@ class E {
|
|
|
972
972
|
})).data;
|
|
973
973
|
}
|
|
974
974
|
get(e, t) {
|
|
975
|
-
return this.send(
|
|
975
|
+
return this.send(U.GET, e, t);
|
|
976
976
|
}
|
|
977
977
|
post(e, t, s) {
|
|
978
|
-
return this.send(
|
|
978
|
+
return this.send(U.POST, e, { data: t, ...s });
|
|
979
979
|
}
|
|
980
980
|
put(e, t, s) {
|
|
981
|
-
return this.send(
|
|
981
|
+
return this.send(U.PUT, e, { data: t, ...s });
|
|
982
982
|
}
|
|
983
983
|
patch(e, t, s) {
|
|
984
|
-
return this.send(
|
|
984
|
+
return this.send(U.PATCH, e, { data: t, ...s });
|
|
985
985
|
}
|
|
986
986
|
delete(e, t) {
|
|
987
|
-
return this.send(
|
|
987
|
+
return this.send(U.DELETE, e, t);
|
|
988
988
|
}
|
|
989
989
|
/**
|
|
990
990
|
* Update the appId and propagate it to axios headers.
|
|
@@ -995,11 +995,11 @@ class E {
|
|
|
995
995
|
setAppId(e) {
|
|
996
996
|
this.appId = e, this.defaultHeaders = {
|
|
997
997
|
...this.defaultHeaders,
|
|
998
|
-
[
|
|
999
|
-
}, this.instance.defaults.headers.common[
|
|
998
|
+
[V]: e
|
|
999
|
+
}, this.instance.defaults.headers.common[V] = e;
|
|
1000
1000
|
}
|
|
1001
1001
|
}
|
|
1002
|
-
class
|
|
1002
|
+
class hr {
|
|
1003
1003
|
constructor(e, t, s) {
|
|
1004
1004
|
this.axiosClient = new E(e, t, s);
|
|
1005
1005
|
}
|
|
@@ -1010,7 +1010,8 @@ class tr {
|
|
|
1010
1010
|
return this.axiosClient.get(l.appSettings);
|
|
1011
1011
|
}
|
|
1012
1012
|
}
|
|
1013
|
-
|
|
1013
|
+
const M = { withCredentials: !0 };
|
|
1014
|
+
class dr {
|
|
1014
1015
|
constructor(e, t, s) {
|
|
1015
1016
|
this.axiosClient = new E(e, t, s);
|
|
1016
1017
|
}
|
|
@@ -1041,13 +1042,13 @@ class rr {
|
|
|
1041
1042
|
...i ? { upgrade: i } : {}
|
|
1042
1043
|
}, o = {
|
|
1043
1044
|
headers: {
|
|
1044
|
-
[
|
|
1045
|
+
[D]: `Bearer ${e}`
|
|
1045
1046
|
}
|
|
1046
1047
|
};
|
|
1047
1048
|
return this.axiosClient.post(
|
|
1048
1049
|
l.refresh,
|
|
1049
1050
|
n,
|
|
1050
|
-
i ?
|
|
1051
|
+
i ? Je(o) : o
|
|
1051
1052
|
);
|
|
1052
1053
|
}
|
|
1053
1054
|
signIn(e, t, s) {
|
|
@@ -1058,7 +1059,8 @@ class rr {
|
|
|
1058
1059
|
};
|
|
1059
1060
|
return this.axiosClient.post(
|
|
1060
1061
|
l.signin,
|
|
1061
|
-
i
|
|
1062
|
+
i,
|
|
1063
|
+
M
|
|
1062
1064
|
);
|
|
1063
1065
|
}
|
|
1064
1066
|
signUp(e) {
|
|
@@ -1069,7 +1071,16 @@ class rr {
|
|
|
1069
1071
|
};
|
|
1070
1072
|
return this.axiosClient.post(
|
|
1071
1073
|
l.signup,
|
|
1072
|
-
i
|
|
1074
|
+
i,
|
|
1075
|
+
M
|
|
1076
|
+
);
|
|
1077
|
+
}
|
|
1078
|
+
/** Redeems the code a PKCE sign-in answered with for the tokens it stands for. */
|
|
1079
|
+
pkceExchange(e, t) {
|
|
1080
|
+
return this.axiosClient.post(
|
|
1081
|
+
l.pkceExchange,
|
|
1082
|
+
{ authz_code: e, verifier: t },
|
|
1083
|
+
M
|
|
1073
1084
|
);
|
|
1074
1085
|
}
|
|
1075
1086
|
passwordlessSignIn(e, t, s) {
|
|
@@ -1087,11 +1098,12 @@ class rr {
|
|
|
1087
1098
|
passwordlessSignInComplete(e) {
|
|
1088
1099
|
return this.axiosClient.post(
|
|
1089
1100
|
l.passwordlessComplete,
|
|
1090
|
-
e
|
|
1101
|
+
e,
|
|
1102
|
+
M
|
|
1091
1103
|
);
|
|
1092
1104
|
}
|
|
1093
1105
|
logOut(e, t, s = !1) {
|
|
1094
|
-
const i = s ? void 0 : { refresh_token: t, device: e }, n = s ?
|
|
1106
|
+
const i = s ? void 0 : { refresh_token: t, device: e }, n = s ? P.logout : l.logout;
|
|
1095
1107
|
return this.axiosClient.post(n, i);
|
|
1096
1108
|
}
|
|
1097
1109
|
validateSession() {
|
|
@@ -1103,15 +1115,16 @@ class rr {
|
|
|
1103
1115
|
e
|
|
1104
1116
|
);
|
|
1105
1117
|
}
|
|
1106
|
-
resetPassword(e, t, s) {
|
|
1107
|
-
const
|
|
1118
|
+
resetPassword(e, t, s, i) {
|
|
1119
|
+
const n = {
|
|
1108
1120
|
password: e,
|
|
1109
|
-
scopes: t
|
|
1121
|
+
scopes: t,
|
|
1122
|
+
...i ? { code_challenge: i } : {}
|
|
1110
1123
|
};
|
|
1111
|
-
return this.axiosClient.post(l.resetPassword,
|
|
1124
|
+
return this.axiosClient.post(l.resetPassword, n, {
|
|
1112
1125
|
headers: {
|
|
1113
|
-
[
|
|
1114
|
-
[
|
|
1126
|
+
[D]: `Bearer ${s}`,
|
|
1127
|
+
[V]: void 0
|
|
1115
1128
|
}
|
|
1116
1129
|
});
|
|
1117
1130
|
}
|
|
@@ -1121,7 +1134,7 @@ class rr {
|
|
|
1121
1134
|
create_tenant: n ?? !1,
|
|
1122
1135
|
device: t,
|
|
1123
1136
|
os: s
|
|
1124
|
-
}, a = i ?
|
|
1137
|
+
}, a = i ? P.passkeyRegisterStart : l.passkeyRegisterStart;
|
|
1125
1138
|
return this.axiosClient.post(a, o);
|
|
1126
1139
|
}
|
|
1127
1140
|
passkeyRegisterComplete(e, t, s, i = !1) {
|
|
@@ -1129,8 +1142,12 @@ class rr {
|
|
|
1129
1142
|
challenge_id: s,
|
|
1130
1143
|
device: t,
|
|
1131
1144
|
passkey_data: e
|
|
1132
|
-
}, o = i ?
|
|
1133
|
-
return this.axiosClient.post(
|
|
1145
|
+
}, o = i ? P.passkeyRegisterComplete : l.passkeyRegisterComplete;
|
|
1146
|
+
return this.axiosClient.post(
|
|
1147
|
+
o,
|
|
1148
|
+
n,
|
|
1149
|
+
M
|
|
1150
|
+
);
|
|
1134
1151
|
}
|
|
1135
1152
|
passkeyAuthenticateStart(e, t, s, i = !1) {
|
|
1136
1153
|
const n = {
|
|
@@ -1138,7 +1155,7 @@ class rr {
|
|
|
1138
1155
|
user_id: e.user_id ?? "",
|
|
1139
1156
|
device: t,
|
|
1140
1157
|
os: s
|
|
1141
|
-
}, o = i ?
|
|
1158
|
+
}, o = i ? P.passkeyAuthenticateStart : l.passkeyAuthenticateStart;
|
|
1142
1159
|
return this.axiosClient.post(
|
|
1143
1160
|
o,
|
|
1144
1161
|
n
|
|
@@ -1149,8 +1166,12 @@ class rr {
|
|
|
1149
1166
|
challenge_id: s,
|
|
1150
1167
|
device: t,
|
|
1151
1168
|
passkey_data: e
|
|
1152
|
-
}, o = i ?
|
|
1153
|
-
return this.axiosClient.post(
|
|
1169
|
+
}, o = i ? P.passkeyAuthenticateComplete : l.passkeyAuthenticateComplete;
|
|
1170
|
+
return this.axiosClient.post(
|
|
1171
|
+
o,
|
|
1172
|
+
n,
|
|
1173
|
+
M
|
|
1174
|
+
);
|
|
1154
1175
|
}
|
|
1155
1176
|
passkeyValidate(e, t, s, i = !1, n) {
|
|
1156
1177
|
const o = {
|
|
@@ -1159,12 +1180,12 @@ class rr {
|
|
|
1159
1180
|
challenge_id: s
|
|
1160
1181
|
};
|
|
1161
1182
|
let a = l.passkeyValidate;
|
|
1162
|
-
!n && i && (a =
|
|
1163
|
-
const h = n ? { [
|
|
1183
|
+
!n && i && (a = P.passkeyValidate);
|
|
1184
|
+
const h = n ? { [V]: n } : {};
|
|
1164
1185
|
return this.axiosClient.post(a, o, { headers: h });
|
|
1165
1186
|
}
|
|
1166
1187
|
}
|
|
1167
|
-
class
|
|
1188
|
+
class si {
|
|
1168
1189
|
constructor(e, t, s) {
|
|
1169
1190
|
this.axiosClient = new E(e, t, s);
|
|
1170
1191
|
}
|
|
@@ -1172,14 +1193,14 @@ class Hs {
|
|
|
1172
1193
|
this.axiosClient.setAppId(e);
|
|
1173
1194
|
}
|
|
1174
1195
|
getCLIAuthStatus(e) {
|
|
1175
|
-
const t =
|
|
1196
|
+
const t = F(l.cliAuthStatus, { sessionId: e });
|
|
1176
1197
|
return this.axiosClient.get(t);
|
|
1177
1198
|
}
|
|
1178
1199
|
completeCLIAuth(e) {
|
|
1179
1200
|
return this.axiosClient.post(l.cliAuthComplete, e);
|
|
1180
1201
|
}
|
|
1181
1202
|
}
|
|
1182
|
-
class
|
|
1203
|
+
class lr {
|
|
1183
1204
|
constructor(e, t, s) {
|
|
1184
1205
|
this.axiosClient = new E(e, t, s);
|
|
1185
1206
|
}
|
|
@@ -1205,7 +1226,7 @@ class sr {
|
|
|
1205
1226
|
getInvitations(e) {
|
|
1206
1227
|
const t = {};
|
|
1207
1228
|
e.groupID && (t.group_id = e.groupID.toString()), e.skip !== void 0 && (t.skip = e.skip.toString()), e.limit !== void 0 && (t.limit = e.limit.toString());
|
|
1208
|
-
const s =
|
|
1229
|
+
const s = F(l.invitationsPath, {
|
|
1209
1230
|
tenantID: e.tenantID
|
|
1210
1231
|
});
|
|
1211
1232
|
return this.axiosClient.get(s, { params: t }).then((i) => ({
|
|
@@ -1219,7 +1240,7 @@ class sr {
|
|
|
1219
1240
|
* @returns Promise with success response
|
|
1220
1241
|
*/
|
|
1221
1242
|
deleteInvitation(e) {
|
|
1222
|
-
const t =
|
|
1243
|
+
const t = F(l.invitationDelete, {
|
|
1223
1244
|
invitationID: e
|
|
1224
1245
|
});
|
|
1225
1246
|
return this.axiosClient.delete(t);
|
|
@@ -1230,7 +1251,7 @@ class sr {
|
|
|
1230
1251
|
* @returns Promise with success response
|
|
1231
1252
|
*/
|
|
1232
1253
|
resendInvitation(e) {
|
|
1233
|
-
const t =
|
|
1254
|
+
const t = F(l.invitationResend, {
|
|
1234
1255
|
invitationID: e
|
|
1235
1256
|
});
|
|
1236
1257
|
return this.axiosClient.post(t, {});
|
|
@@ -1241,13 +1262,13 @@ class sr {
|
|
|
1241
1262
|
* @returns Promise with the link
|
|
1242
1263
|
*/
|
|
1243
1264
|
getInvitationLink(e) {
|
|
1244
|
-
const t =
|
|
1265
|
+
const t = F(l.invitationGetLink, {
|
|
1245
1266
|
invitationID: e
|
|
1246
1267
|
});
|
|
1247
1268
|
return this.axiosClient.get(t);
|
|
1248
1269
|
}
|
|
1249
1270
|
}
|
|
1250
|
-
class
|
|
1271
|
+
class ur {
|
|
1251
1272
|
constructor(e, t, s) {
|
|
1252
1273
|
this.axiosClient = new E(e, t, s);
|
|
1253
1274
|
}
|
|
@@ -1264,7 +1285,7 @@ class ir {
|
|
|
1264
1285
|
return this.axiosClient.get(l.settingsPasskey);
|
|
1265
1286
|
}
|
|
1266
1287
|
}
|
|
1267
|
-
class
|
|
1288
|
+
class pr {
|
|
1268
1289
|
constructor(e, t, s) {
|
|
1269
1290
|
this.axiosClient = new E(e, t, s);
|
|
1270
1291
|
}
|
|
@@ -1497,7 +1518,11 @@ class nr {
|
|
|
1497
1518
|
return this.axiosClient.delete(i);
|
|
1498
1519
|
}
|
|
1499
1520
|
}
|
|
1500
|
-
|
|
1521
|
+
const ge = (r) => r ? { headers: { Authorization: `Bearer ${r}` } } : {}, ne = (r) => ({
|
|
1522
|
+
withCredentials: !0,
|
|
1523
|
+
...ge(r)
|
|
1524
|
+
});
|
|
1525
|
+
class fr {
|
|
1501
1526
|
constructor(e, t, s) {
|
|
1502
1527
|
this.axiosClient = new E(e, t, s);
|
|
1503
1528
|
}
|
|
@@ -1536,15 +1561,11 @@ class or {
|
|
|
1536
1561
|
* Uses tfa_token as Bearer token for authentication
|
|
1537
1562
|
*/
|
|
1538
1563
|
verify(e) {
|
|
1539
|
-
const { tfa_token: t, code: s } = e;
|
|
1564
|
+
const { tfa_token: t, code: s, trust_device: i } = e;
|
|
1540
1565
|
return this.axiosClient.post(
|
|
1541
1566
|
l.twoFactorVerify,
|
|
1542
|
-
{ code: s },
|
|
1543
|
-
|
|
1544
|
-
headers: {
|
|
1545
|
-
Authorization: `Bearer ${t}`
|
|
1546
|
-
}
|
|
1547
|
-
}
|
|
1567
|
+
{ code: s, ...i ? { trust_device: !0 } : {} },
|
|
1568
|
+
ne(t)
|
|
1548
1569
|
);
|
|
1549
1570
|
}
|
|
1550
1571
|
/**
|
|
@@ -1553,15 +1574,11 @@ class or {
|
|
|
1553
1574
|
* Uses tfa_token as Bearer token for authentication
|
|
1554
1575
|
*/
|
|
1555
1576
|
useRecoveryCode(e) {
|
|
1556
|
-
const { tfa_token: t, recovery_code: s } = e;
|
|
1577
|
+
const { tfa_token: t, recovery_code: s, trust_device: i } = e;
|
|
1557
1578
|
return this.axiosClient.post(
|
|
1558
1579
|
l.twoFactorRecovery,
|
|
1559
|
-
{ recovery_code: s },
|
|
1560
|
-
|
|
1561
|
-
headers: {
|
|
1562
|
-
Authorization: `Bearer ${t}`
|
|
1563
|
-
}
|
|
1564
|
-
}
|
|
1580
|
+
{ recovery_code: s, ...i ? { trust_device: !0 } : {} },
|
|
1581
|
+
ne(t)
|
|
1565
1582
|
);
|
|
1566
1583
|
}
|
|
1567
1584
|
/**
|
|
@@ -1711,56 +1728,72 @@ class or {
|
|
|
1711
1728
|
* DELETE /v2/user/2fa/methods/:id
|
|
1712
1729
|
*/
|
|
1713
1730
|
removeMethod(e) {
|
|
1714
|
-
const t =
|
|
1731
|
+
const t = F(l.TwoFactorMethodRemove, { id: e });
|
|
1715
1732
|
return this.axiosClient.delete(t);
|
|
1716
1733
|
}
|
|
1717
1734
|
/**
|
|
1718
1735
|
* Request 2FA challenge during login
|
|
1719
1736
|
* POST /v2/auth/2fa/challenge
|
|
1737
|
+
* `tfaToken`, when given, goes as the Bearer token the route is gated on.
|
|
1720
1738
|
*/
|
|
1721
|
-
requestChallenge(e) {
|
|
1739
|
+
requestChallenge(e, t) {
|
|
1722
1740
|
return this.axiosClient.post(
|
|
1723
1741
|
l.TwoFactorChallenge,
|
|
1724
|
-
e
|
|
1742
|
+
e,
|
|
1743
|
+
ge(t)
|
|
1725
1744
|
);
|
|
1726
1745
|
}
|
|
1727
1746
|
/**
|
|
1728
1747
|
* Verify 2FA challenge (v2)
|
|
1729
|
-
* POST /v2/auth/2fa/verify
|
|
1748
|
+
* POST /v2/auth/2fa/verify (the server's verify-challenge)
|
|
1749
|
+
*
|
|
1750
|
+
* `tfaToken` is the 2FA token the first factor returned; the route is gated
|
|
1751
|
+
* on it, so it goes as the Bearer token when given.
|
|
1730
1752
|
*/
|
|
1731
|
-
verifyV2(e) {
|
|
1753
|
+
verifyV2(e, t) {
|
|
1754
|
+
const { trust_device: s, ...i } = e;
|
|
1732
1755
|
return this.axiosClient.post(
|
|
1733
1756
|
l.TwoFactorVerifyV2,
|
|
1734
|
-
|
|
1757
|
+
{ ...i, ...s ? { trust_device: !0 } : {} },
|
|
1758
|
+
ne(t)
|
|
1735
1759
|
);
|
|
1736
1760
|
}
|
|
1737
1761
|
/**
|
|
1738
1762
|
* Switch to alternative 2FA method during challenge
|
|
1739
1763
|
* POST /v2/auth/2fa/alternative
|
|
1764
|
+
* `tfaToken`, when given, goes as the Bearer token the route is gated on.
|
|
1740
1765
|
*/
|
|
1741
|
-
switchToAlternative(e) {
|
|
1766
|
+
switchToAlternative(e, t) {
|
|
1742
1767
|
return this.axiosClient.post(
|
|
1743
1768
|
l.TwoFactorAlternative,
|
|
1744
|
-
e
|
|
1769
|
+
e,
|
|
1770
|
+
ge(t)
|
|
1745
1771
|
);
|
|
1746
1772
|
}
|
|
1747
1773
|
/**
|
|
1748
|
-
*
|
|
1774
|
+
* List the devices the user trusted on this app
|
|
1749
1775
|
* GET /v2/user/2fa/trusted-devices
|
|
1776
|
+
*
|
|
1777
|
+
* Sent with credentials so the server sees this device's trust cookie and
|
|
1778
|
+
* can mark it `current`.
|
|
1750
1779
|
*/
|
|
1751
|
-
getTrustedDevices() {
|
|
1752
|
-
return this.axiosClient.get(
|
|
1780
|
+
async getTrustedDevices() {
|
|
1781
|
+
return (await this.axiosClient.get(
|
|
1782
|
+
l.TwoFactorTrustedDevices,
|
|
1783
|
+
{ withCredentials: !0 }
|
|
1784
|
+
))?.devices ?? [];
|
|
1753
1785
|
}
|
|
1754
1786
|
/**
|
|
1755
1787
|
* Revoke trusted device
|
|
1756
1788
|
* DELETE /v2/user/2fa/trusted-devices/:id
|
|
1789
|
+
* The server answers 404 when the user has no such device.
|
|
1757
1790
|
*/
|
|
1758
1791
|
revokeTrustedDevice(e) {
|
|
1759
|
-
const t =
|
|
1792
|
+
const t = F(l.TwoFactorTrustedDeviceRevoke, { id: e });
|
|
1760
1793
|
return this.axiosClient.delete(t);
|
|
1761
1794
|
}
|
|
1762
1795
|
}
|
|
1763
|
-
class
|
|
1796
|
+
class gr {
|
|
1764
1797
|
constructor(e, t, s) {
|
|
1765
1798
|
this.axiosClient = new E(e, t, s);
|
|
1766
1799
|
}
|
|
@@ -1782,11 +1815,11 @@ class ar {
|
|
|
1782
1815
|
return this.axiosClient.post(
|
|
1783
1816
|
l.upgradeStart,
|
|
1784
1817
|
e,
|
|
1785
|
-
|
|
1818
|
+
Je({})
|
|
1786
1819
|
);
|
|
1787
1820
|
}
|
|
1788
1821
|
}
|
|
1789
|
-
class
|
|
1822
|
+
class vr {
|
|
1790
1823
|
constructor(e, t, s) {
|
|
1791
1824
|
this.axiosClient = new E(e, t, s);
|
|
1792
1825
|
}
|
|
@@ -1831,8 +1864,27 @@ class cr {
|
|
|
1831
1864
|
});
|
|
1832
1865
|
}
|
|
1833
1866
|
}
|
|
1867
|
+
const X = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_", mr = 32, tt = (r) => {
|
|
1868
|
+
let e = "";
|
|
1869
|
+
for (let t = 0; t < r.length; t += 3) {
|
|
1870
|
+
const s = r[t], i = r[t + 1], n = r[t + 2];
|
|
1871
|
+
e += X.charAt(s >> 2), e += X.charAt((s & 3) << 4 | (i ?? 0) >> 4), i !== void 0 && (e += X.charAt((i & 15) << 2 | (n ?? 0) >> 6)), n !== void 0 && (e += X.charAt(n & 63));
|
|
1872
|
+
}
|
|
1873
|
+
return e;
|
|
1874
|
+
}, rt = () => {
|
|
1875
|
+
const r = globalThis.crypto;
|
|
1876
|
+
if (!r?.subtle)
|
|
1877
|
+
throw new Error("PKCE needs the Web Crypto API, which is available only in a secure context (https or localhost)");
|
|
1878
|
+
return r;
|
|
1879
|
+
}, yr = async (r) => {
|
|
1880
|
+
const e = await rt().subtle.digest("SHA-256", new TextEncoder().encode(r));
|
|
1881
|
+
return tt(new Uint8Array(e));
|
|
1882
|
+
}, kr = async () => {
|
|
1883
|
+
const r = tt(rt().getRandomValues(new Uint8Array(mr)));
|
|
1884
|
+
return { verifier: r, challenge: await yr(r) };
|
|
1885
|
+
};
|
|
1834
1886
|
var c = /* @__PURE__ */ ((r) => (r.SignIn = "signin", r.SignInStart = "signin:start", r.Register = "register", r.RegisterStart = "register:start", r.SignOut = "signout", r.SessionRestored = "session:restored", r.SessionExpired = "session:expired", r.Error = "error", r.Refresh = "refresh", r.RefreshStart = "refresh:start", r.TokenCacheExpired = "token-cache-expired", r.TwoFactorRequired = "2fa:required", r.TwoFactorSetupStarted = "2fa:setup_started", r.TwoFactorEnabled = "2fa:enabled", r.TwoFactorDisabled = "2fa:disabled", r.TwoFactorVerified = "2fa:verified", r.TwoFactorRecoveryUsed = "2fa:recovery_used", r.TwoFactorRecoveryCodesLow = "2fa:recovery_low", r.TwoFactorRecoveryCodesExhausted = "2fa:recovery_exhausted", r.TwoFactorSetupMagicLinkValidated = "2fa:magic_link_validated", r.TwoFactorSetupMagicLinkFailed = "2fa:magic_link_failed", r.TwoFactorChallengeReceived = "two_factor_challenge_received", r.TwoFactorMethodSwitched = "two_factor_method_switched", r.TwoFactorDeviceTrusted = "two_factor_device_trusted", r))(c || {});
|
|
1835
|
-
class
|
|
1887
|
+
class wr {
|
|
1836
1888
|
constructor() {
|
|
1837
1889
|
this.subscribers = /* @__PURE__ */ new Map();
|
|
1838
1890
|
}
|
|
@@ -1886,18 +1938,18 @@ const k = {
|
|
|
1886
1938
|
twoFactorNotEnabled: "error.2fa.not_enabled",
|
|
1887
1939
|
notImplemented: "error.not.implemented",
|
|
1888
1940
|
tokenInvalid: "error.api.request.token.invalid"
|
|
1889
|
-
},
|
|
1941
|
+
}, Sr = Object.freeze([
|
|
1890
1942
|
k.twoFactorCodeInvalid,
|
|
1891
1943
|
k.twoFactorNotEnabled,
|
|
1892
1944
|
k.challengeInvalid,
|
|
1893
1945
|
k.challengeSessionMismatch,
|
|
1894
1946
|
k.challengeTooManyAttempts
|
|
1895
|
-
]),
|
|
1947
|
+
]), br = Object.freeze([k.tokenInvalid]), Tr = Object.freeze([
|
|
1896
1948
|
"wrong_code",
|
|
1897
1949
|
"challenge_spent",
|
|
1898
1950
|
"not_registered",
|
|
1899
1951
|
"prepare_not_required"
|
|
1900
|
-
]),
|
|
1952
|
+
]), _r = (r) => Tr.includes(r), Er = {
|
|
1901
1953
|
wrong_code: "That code was not accepted. Try again.",
|
|
1902
1954
|
challenge_spent: "That verification challenge is no longer valid. Start again.",
|
|
1903
1955
|
exhausted: "Too many attempts. Try again later.",
|
|
@@ -1912,17 +1964,17 @@ const k = {
|
|
|
1912
1964
|
};
|
|
1913
1965
|
class _ extends Error {
|
|
1914
1966
|
constructor(e) {
|
|
1915
|
-
super(e.message ||
|
|
1967
|
+
super(e.message || Er[e.kind]), this.name = "UpgradeTransportError", this.code = "upgrade_transport", this.kind = e.kind, this.status = e.status, this.errorId = e.errorId, this.retryable = _r(e.kind), e.cause !== void 0 && (this.cause = e.cause);
|
|
1916
1968
|
}
|
|
1917
1969
|
}
|
|
1918
|
-
const
|
|
1970
|
+
const Ir = Object.freeze([
|
|
1919
1971
|
"upgrade_transport",
|
|
1920
1972
|
"upgrade_insufficient",
|
|
1921
1973
|
"upgrade_unavailable",
|
|
1922
1974
|
"upgrade_session_changed",
|
|
1923
1975
|
"upgrade_cancelled",
|
|
1924
1976
|
"upgrade_unsatisfiable"
|
|
1925
|
-
]),
|
|
1977
|
+
]), st = (r) => typeof r == "object" && r !== null && typeof r.code == "string" && Ir.includes(r.code), Ar = (r) => r instanceof _ || typeof r == "object" && r !== null && r.code === "upgrade_transport", Cr = (r) => {
|
|
1926
1978
|
if (typeof r != "object" || r === null)
|
|
1927
1979
|
return { hasResponse: !1, message: typeof r == "string" ? r : void 0 };
|
|
1928
1980
|
const e = r, t = e.response, s = t?.data, i = typeof s?.error?.id == "string" ? s.error.id : void 0;
|
|
@@ -1932,7 +1984,7 @@ const gr = Object.freeze([
|
|
|
1932
1984
|
message: typeof e.message == "string" ? e.message : void 0,
|
|
1933
1985
|
hasResponse: t !== void 0 || typeof e.status == "number"
|
|
1934
1986
|
};
|
|
1935
|
-
},
|
|
1987
|
+
}, Rr = (r, e) => {
|
|
1936
1988
|
switch (r) {
|
|
1937
1989
|
case k.twoFactorCodeInvalid:
|
|
1938
1990
|
return "wrong_code";
|
|
@@ -1981,13 +2033,13 @@ const gr = Object.freeze([
|
|
|
1981
2033
|
default:
|
|
1982
2034
|
return;
|
|
1983
2035
|
}
|
|
1984
|
-
},
|
|
2036
|
+
}, Pr = (r, e) => r === void 0 ? "network" : r === 501 ? "unavailable" : r === 400 ? "fatal" : r === 401 || r === 403 ? e === "start" ? "challenge_spent" : "session_changed" : r >= 500 ? "network" : "fatal", Pe = (r, e) => {
|
|
1985
2037
|
if (r instanceof _)
|
|
1986
2038
|
return r;
|
|
1987
|
-
const t =
|
|
2039
|
+
const t = Cr(r);
|
|
1988
2040
|
if (!t.hasResponse)
|
|
1989
2041
|
return new _({ kind: "network", message: t.message, cause: r });
|
|
1990
|
-
const s =
|
|
2042
|
+
const s = Rr(t.errorId, e) ?? Pr(t.status, e);
|
|
1991
2043
|
return new _({
|
|
1992
2044
|
kind: s,
|
|
1993
2045
|
message: t.message,
|
|
@@ -1995,8 +2047,8 @@ const gr = Object.freeze([
|
|
|
1995
2047
|
errorId: t.errorId,
|
|
1996
2048
|
cause: r
|
|
1997
2049
|
});
|
|
1998
|
-
},
|
|
1999
|
-
class
|
|
2050
|
+
}, ii = (r) => r.errorId !== void 0 && Sr.includes(r.errorId), Fr = (r) => r.errorId !== void 0 && br.includes(r.errorId);
|
|
2051
|
+
class G extends Error {
|
|
2000
2052
|
constructor(e, t, s) {
|
|
2001
2053
|
super(s ?? "The session was elevated, but this action requires a higher assurance level"), this.name = "UpgradeInsufficientError", this.code = "upgrade_insufficient", this.obtained = e, this.required = t;
|
|
2002
2054
|
}
|
|
@@ -2006,51 +2058,69 @@ class j extends Error {
|
|
|
2006
2058
|
super(e), this.name = "UpgradeUnavailableError", this.code = "upgrade_unavailable";
|
|
2007
2059
|
}
|
|
2008
2060
|
}
|
|
2009
|
-
class
|
|
2061
|
+
class q extends Error {
|
|
2010
2062
|
constructor(e = "The session changed during verification") {
|
|
2011
2063
|
super(e), this.name = "UpgradeSessionChangedError", this.code = "upgrade_session_changed";
|
|
2012
2064
|
}
|
|
2013
2065
|
}
|
|
2014
|
-
const
|
|
2066
|
+
const Mr = (r) => {
|
|
2015
2067
|
if (!(!r || typeof r.sub != "string" || r.sub === ""))
|
|
2016
2068
|
return typeof r.sid == "string" && r.sid !== "" ? { sub: r.sub, sid: r.sid } : { sub: r.sub };
|
|
2017
|
-
},
|
|
2018
|
-
function
|
|
2069
|
+
}, Ur = (r, e) => !e || e.sub !== r.sub ? !1 : r.sid !== void 0 && e.sid !== void 0 ? r.sid === e.sid : !0;
|
|
2070
|
+
function J(r) {
|
|
2019
2071
|
if (!r || typeof r != "string") return !1;
|
|
2020
2072
|
const e = r.split(".");
|
|
2021
2073
|
if (e.length !== 3) return !1;
|
|
2022
2074
|
const t = /^[A-Za-z0-9_-]+$/;
|
|
2023
2075
|
return e.every((s) => t.test(s) && s.length > 0);
|
|
2024
2076
|
}
|
|
2025
|
-
function
|
|
2026
|
-
return r.replace(/<[^>]*>/g, "").substring(0,
|
|
2077
|
+
function Dr(r) {
|
|
2078
|
+
return r.replace(/<[^>]*>/g, "").substring(0, qt);
|
|
2027
2079
|
}
|
|
2028
|
-
function
|
|
2080
|
+
function oe(r) {
|
|
2029
2081
|
if (!r || typeof r != "string") return !1;
|
|
2030
2082
|
const e = r.trim();
|
|
2031
2083
|
return e.length === 0 ? !1 : /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);
|
|
2032
2084
|
}
|
|
2033
|
-
function
|
|
2085
|
+
function ae(r) {
|
|
2034
2086
|
if (!r || typeof r != "string") return !1;
|
|
2035
2087
|
const e = r.trim();
|
|
2036
2088
|
return /^\+[1-9]\d{1,14}$/.test(e);
|
|
2037
2089
|
}
|
|
2038
|
-
function
|
|
2090
|
+
function xr(r) {
|
|
2039
2091
|
if (!r || typeof r != "string") return !1;
|
|
2040
2092
|
const e = r.trim();
|
|
2041
|
-
return e.length <
|
|
2093
|
+
return e.length < Lt || e.length > $t ? !1 : /^[a-zA-Z0-9_-]+$/.test(e);
|
|
2042
2094
|
}
|
|
2043
|
-
function
|
|
2095
|
+
function Z(r, e = 6) {
|
|
2044
2096
|
return !r || typeof r != "string" ? !1 : (e === 8 ? /^\d{8}$/ : /^\d{6}$/).test(r);
|
|
2045
2097
|
}
|
|
2046
|
-
function
|
|
2098
|
+
function Or(r) {
|
|
2047
2099
|
if (!r || typeof r != "string") return null;
|
|
2048
2100
|
const e = r.toUpperCase().replace(/\s+/g, "");
|
|
2049
2101
|
return /^[A-Z0-9-]{4,16}$/.test(e) ? e : null;
|
|
2050
2102
|
}
|
|
2051
|
-
class
|
|
2052
|
-
|
|
2053
|
-
|
|
2103
|
+
class Lr {
|
|
2104
|
+
error(e, ...t) {
|
|
2105
|
+
console.error(e, ...t);
|
|
2106
|
+
}
|
|
2107
|
+
warn(e, ...t) {
|
|
2108
|
+
console.warn(e, ...t);
|
|
2109
|
+
}
|
|
2110
|
+
info(e, ...t) {
|
|
2111
|
+
console.info(e, ...t);
|
|
2112
|
+
}
|
|
2113
|
+
debug(e, ...t) {
|
|
2114
|
+
console.debug(e, ...t);
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2117
|
+
function it() {
|
|
2118
|
+
return new Lr();
|
|
2119
|
+
}
|
|
2120
|
+
const ce = "passflow_2fa_pkce", $r = 300 * 1e3;
|
|
2121
|
+
class qr {
|
|
2122
|
+
constructor(e, t, s, i, n, o, a, h, u, m, d, g = Y, f) {
|
|
2123
|
+
this.authApi = e, this.deviceService = t, this.storageManager = s, this.subscribeStore = i, this.tokenCacheService = n, this.scopes = o, this.createTenantForNewUser = a, this.url = h, this.sessionCallbacks = u, this.appId = m, this.platform = g, this.readPkceEnabled = f, this.tokenExchangeConfig = d, this.tokenDeliveryManager = new Ke(s), d?.enabled && this.tokenDeliveryManager.setMode(A.BFF), this.initializeSession();
|
|
2054
2124
|
}
|
|
2055
2125
|
/**
|
|
2056
2126
|
* Initialize session state on page load for cookie/BFF mode
|
|
@@ -2090,8 +2160,112 @@ class Ir {
|
|
|
2090
2160
|
* In BFF mode, forwards tokens to BFF server
|
|
2091
2161
|
*/
|
|
2092
2162
|
async processAuthResponse(e, t) {
|
|
2163
|
+
if (e.code && !e.access_token)
|
|
2164
|
+
throw new Error("A PKCE authorization code was not exchanged, so there are no tokens to apply");
|
|
2093
2165
|
this.tokenExchangeConfig?.enabled || "token_delivery" in e && e.token_delivery && this.tokenDeliveryManager.setMode(e.token_delivery), this.tokenDeliveryManager.setSessionValid(), this.tokenDeliveryManager.isBFFMode() && this.tokenExchangeConfig?.callbackUrl && await this.forwardTokensToBFF(e), e.scopes = t, this.storageManager.saveTokens(e, this.tokenDeliveryManager.getMode()), this.tokenCacheService.setTokensCache(e), e.csrf_token && this.storageManager.setCsrfToken(e.csrf_token);
|
|
2094
2166
|
}
|
|
2167
|
+
/**
|
|
2168
|
+
* Reports whether a sign-in response is still waiting on its second factor,
|
|
2169
|
+
* and when it is, hands the 2FA token on.
|
|
2170
|
+
*
|
|
2171
|
+
* Every sign-in path can end this way: the server answers with a
|
|
2172
|
+
* `tfa_token` (or `requires_2fa`) in place of tokens. That response is not
|
|
2173
|
+
* a session, so on `true` the caller returns it as it is — without
|
|
2174
|
+
* `processAuthResponse`, a `SignIn`/`Register` event or a session check.
|
|
2175
|
+
* The `TwoFactorRequired` event is what the TwoFactorService listens to, so
|
|
2176
|
+
* its verify and recovery calls can carry the token. On a PKCE sign-in the
|
|
2177
|
+
* server keeps the login's challenge, so the second factor's answer is a code:
|
|
2178
|
+
* the verifier stays here for `completePkceSignIn`, off the public event.
|
|
2179
|
+
*/
|
|
2180
|
+
handlePendingSecondFactor(e, t, s, i) {
|
|
2181
|
+
return e.requires_2fa !== !0 && !e.tfa_token ? !1 : (s ? this.rememberPkceSignIn(s.verifier, i) : this.forgetPkceSignIn(), this.subscribeStore.notify(c.TwoFactorRequired, {
|
|
2182
|
+
email: t || "",
|
|
2183
|
+
challengeId: e.challenge_id || "",
|
|
2184
|
+
tfaToken: e.tfa_token || ""
|
|
2185
|
+
}), !0);
|
|
2186
|
+
}
|
|
2187
|
+
/**
|
|
2188
|
+
* Keeps the verifier in memory, which is where it is read from first. The copy
|
|
2189
|
+
* in sessionStorage is only for a redirect or reload during the second factor,
|
|
2190
|
+
* which would otherwise lose the sign-in.
|
|
2191
|
+
*/
|
|
2192
|
+
rememberPkceSignIn(e, t) {
|
|
2193
|
+
if (this.pendingPkce = { verifier: e, scopes: t, expiresAt: Date.now() + $r }, !(typeof sessionStorage > "u"))
|
|
2194
|
+
try {
|
|
2195
|
+
sessionStorage.setItem(ce, JSON.stringify(this.pendingPkce));
|
|
2196
|
+
} catch {
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
readPendingPkce() {
|
|
2200
|
+
if (!this.pendingPkce && typeof sessionStorage < "u")
|
|
2201
|
+
try {
|
|
2202
|
+
const e = sessionStorage.getItem(ce);
|
|
2203
|
+
this.pendingPkce = e ? JSON.parse(e) : void 0;
|
|
2204
|
+
} catch {
|
|
2205
|
+
this.pendingPkce = void 0;
|
|
2206
|
+
}
|
|
2207
|
+
return this.pendingPkce && Date.now() >= this.pendingPkce.expiresAt && this.forgetPkceSignIn(), this.pendingPkce;
|
|
2208
|
+
}
|
|
2209
|
+
/** Whether a PKCE sign-in is waiting for the code its second factor answers with. */
|
|
2210
|
+
hasPendingPkceSignIn() {
|
|
2211
|
+
return this.readPendingPkce() !== void 0;
|
|
2212
|
+
}
|
|
2213
|
+
/** Drops the verifier of a pending sign-in. `TwoFactorService` calls this with its own state. */
|
|
2214
|
+
forgetPkceSignIn() {
|
|
2215
|
+
if (this.pendingPkce = void 0, !(typeof sessionStorage > "u"))
|
|
2216
|
+
try {
|
|
2217
|
+
sessionStorage.removeItem(ce);
|
|
2218
|
+
} catch {
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
/**
|
|
2222
|
+
* The proof key for a sign-in on a PKCE app, undefined on any other app.
|
|
2223
|
+
*
|
|
2224
|
+
* It is sent whether or not the sign-in has a parent: the parent is added to
|
|
2225
|
+
* the request outside this SDK, so it is not visible here, and `pkce.Challenge`
|
|
2226
|
+
* on the server wants it under a device parent and ignores it under an OIDC one.
|
|
2227
|
+
* When the setting cannot be read the sign-in goes out without a challenge, and
|
|
2228
|
+
* a PKCE app refuses it with its own error.
|
|
2229
|
+
*/
|
|
2230
|
+
async startPkce() {
|
|
2231
|
+
let e = !1;
|
|
2232
|
+
try {
|
|
2233
|
+
e = await this.readPkceEnabled?.() ?? !1;
|
|
2234
|
+
} catch (t) {
|
|
2235
|
+
it().warn("Passflow: could not read the app settings, so this sign-in sends no PKCE challenge", t);
|
|
2236
|
+
return;
|
|
2237
|
+
}
|
|
2238
|
+
return e ? kr() : void 0;
|
|
2239
|
+
}
|
|
2240
|
+
/**
|
|
2241
|
+
* Swaps a code in a sign-in's answer for what the code stands for; any other
|
|
2242
|
+
* answer passes through. That can still be a 2FA token: the server re-runs its
|
|
2243
|
+
* gate at the exchange unless the code records a passed second factor.
|
|
2244
|
+
*/
|
|
2245
|
+
async exchangeCode(e, t) {
|
|
2246
|
+
return !e.code || !t ? e : await this.authApi.pkceExchange(e.code, t.verifier);
|
|
2247
|
+
}
|
|
2248
|
+
/**
|
|
2249
|
+
* Finishes a PKCE sign-in whose code came from its second factor: redeems the
|
|
2250
|
+
* code with the first factor's verifier and applies the tokens. `TwoFactorService`
|
|
2251
|
+
* is the caller, and clears the pending state once this has succeeded.
|
|
2252
|
+
*/
|
|
2253
|
+
async completePkceSignIn(e) {
|
|
2254
|
+
const t = this.readPendingPkce();
|
|
2255
|
+
if (!t)
|
|
2256
|
+
throw new Error("The sign-in answered with a PKCE code, but its verifier is gone");
|
|
2257
|
+
const s = await this.authApi.pkceExchange(e, t.verifier);
|
|
2258
|
+
return await this.processAuthResponse(s, t.scopes ?? this.scopes), s;
|
|
2259
|
+
}
|
|
2260
|
+
/**
|
|
2261
|
+
* Applies tokens that were issued outside this service, honouring the delivery
|
|
2262
|
+
* mode: this is the one place they reach the BFF and browser storage, so no
|
|
2263
|
+
* caller saves them itself. An answer that carries no tokens is left alone.
|
|
2264
|
+
*/
|
|
2265
|
+
async applyTokens(e) {
|
|
2266
|
+
const t = e;
|
|
2267
|
+
!t.access_token && !t.id_token && !t.token_delivery || await this.processAuthResponse(t, t.scopes ?? this.readPendingPkce()?.scopes ?? this.scopes);
|
|
2268
|
+
}
|
|
2095
2269
|
/**
|
|
2096
2270
|
* Forward tokens to BFF server for httpOnly cookie storage
|
|
2097
2271
|
*/
|
|
@@ -2117,7 +2291,7 @@ class Ir {
|
|
|
2117
2291
|
throw new Error(`BFF token storage failed: ${t.status}`);
|
|
2118
2292
|
}
|
|
2119
2293
|
async signIn(e) {
|
|
2120
|
-
if ("email" in e && e.email && !
|
|
2294
|
+
if ("email" in e && e.email && !oe(e.email)) {
|
|
2121
2295
|
const i = new Error("Invalid email format"), n = {
|
|
2122
2296
|
message: "Invalid email format",
|
|
2123
2297
|
originalError: i,
|
|
@@ -2125,7 +2299,7 @@ class Ir {
|
|
|
2125
2299
|
};
|
|
2126
2300
|
throw this.subscribeStore.notify(c.Error, n), i;
|
|
2127
2301
|
}
|
|
2128
|
-
if ("username" in e && e.username && !
|
|
2302
|
+
if ("username" in e && e.username && !xr(e.username)) {
|
|
2129
2303
|
const i = new Error(
|
|
2130
2304
|
"Invalid username format. Username must be 3-30 characters and contain only letters, numbers, underscores, and hyphens"
|
|
2131
2305
|
), n = {
|
|
@@ -2135,7 +2309,7 @@ class Ir {
|
|
|
2135
2309
|
};
|
|
2136
2310
|
throw this.subscribeStore.notify(c.Error, n), i;
|
|
2137
2311
|
}
|
|
2138
|
-
if ("phone" in e && e.phone && !
|
|
2312
|
+
if ("phone" in e && e.phone && !ae(e.phone)) {
|
|
2139
2313
|
const i = new Error("Invalid phone number format. Phone must be in E.164 format (e.g., +12345678901)"), n = {
|
|
2140
2314
|
message: "Invalid phone number format. Phone must be in E.164 format (e.g., +12345678901)",
|
|
2141
2315
|
originalError: i,
|
|
@@ -2147,15 +2321,14 @@ class Ir {
|
|
|
2147
2321
|
const t = this.deviceService.getDeviceId(), s = this.platform.getDeviceType();
|
|
2148
2322
|
e.scopes = e.scopes ?? this.scopes;
|
|
2149
2323
|
try {
|
|
2150
|
-
const i = await this.authApi.signIn(e, t, s);
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
tokens: i,
|
|
2324
|
+
const i = await this.startPkce(), n = await this.authApi.signIn(i ? { ...e, code_challenge: i.challenge } : e, t, s);
|
|
2325
|
+
if (this.handlePendingSecondFactor(n, e.email, i, e.scopes))
|
|
2326
|
+
return n;
|
|
2327
|
+
const o = await this.exchangeCode(n, i);
|
|
2328
|
+
return this.handlePendingSecondFactor(o, e.email) || (await this.processAuthResponse(o, e.scopes), this.subscribeStore.notify(c.SignIn, {
|
|
2329
|
+
tokens: o,
|
|
2157
2330
|
parsedTokens: this.tokenCacheService.getParsedTokens()
|
|
2158
|
-
}), await this.submitSessionCheck(),
|
|
2331
|
+
}), await this.submitSessionCheck()), o;
|
|
2159
2332
|
} catch (i) {
|
|
2160
2333
|
const n = {
|
|
2161
2334
|
message: i instanceof Error ? i.message : "Sign in failed",
|
|
@@ -2166,7 +2339,7 @@ class Ir {
|
|
|
2166
2339
|
}
|
|
2167
2340
|
}
|
|
2168
2341
|
async signUp(e) {
|
|
2169
|
-
if (e.user.email && !
|
|
2342
|
+
if (e.user.email && !oe(e.user.email)) {
|
|
2170
2343
|
const t = new Error("Invalid email format"), s = {
|
|
2171
2344
|
message: "Invalid email format",
|
|
2172
2345
|
originalError: t,
|
|
@@ -2174,7 +2347,7 @@ class Ir {
|
|
|
2174
2347
|
};
|
|
2175
2348
|
throw this.subscribeStore.notify(c.Error, s), t;
|
|
2176
2349
|
}
|
|
2177
|
-
if (e.user.phone_number && !
|
|
2350
|
+
if (e.user.phone_number && !ae(e.user.phone_number)) {
|
|
2178
2351
|
const t = new Error("Invalid phone number format. Phone must be in E.164 format (e.g., +12345678901)"), s = {
|
|
2179
2352
|
message: "Invalid phone number format. Phone must be in E.164 format (e.g., +12345678901)",
|
|
2180
2353
|
originalError: t,
|
|
@@ -2184,11 +2357,14 @@ class Ir {
|
|
|
2184
2357
|
}
|
|
2185
2358
|
this.subscribeStore.notify(c.RegisterStart, { email: e.user.email }), e.scopes = e.scopes ?? this.scopes, e.create_tenant = this.createTenantForNewUser;
|
|
2186
2359
|
try {
|
|
2187
|
-
const t = await this.authApi.signUp(e);
|
|
2188
|
-
|
|
2189
|
-
|
|
2360
|
+
const t = await this.startPkce(), s = await this.authApi.signUp(t ? { ...e, code_challenge: t.challenge } : e);
|
|
2361
|
+
if (this.handlePendingSecondFactor(s, e.user.email, t, e.scopes))
|
|
2362
|
+
return s;
|
|
2363
|
+
const i = await this.exchangeCode(s, t);
|
|
2364
|
+
return this.handlePendingSecondFactor(i, e.user.email) || (await this.processAuthResponse(i, e.scopes), this.subscribeStore.notify(c.Register, {
|
|
2365
|
+
tokens: i,
|
|
2190
2366
|
parsedTokens: this.tokenCacheService.getParsedTokens()
|
|
2191
|
-
}), await this.submitSessionCheck(),
|
|
2367
|
+
}), await this.submitSessionCheck()), i;
|
|
2192
2368
|
} catch (t) {
|
|
2193
2369
|
const s = {
|
|
2194
2370
|
message: t instanceof Error ? t.message : "Sign up failed",
|
|
@@ -2199,7 +2375,7 @@ class Ir {
|
|
|
2199
2375
|
}
|
|
2200
2376
|
}
|
|
2201
2377
|
async passwordlessSignIn(e) {
|
|
2202
|
-
if (e.email && !
|
|
2378
|
+
if (e.email && !oe(e.email)) {
|
|
2203
2379
|
const i = new Error("Invalid email format"), n = {
|
|
2204
2380
|
message: "Invalid email format",
|
|
2205
2381
|
originalError: i,
|
|
@@ -2207,7 +2383,7 @@ class Ir {
|
|
|
2207
2383
|
};
|
|
2208
2384
|
throw this.subscribeStore.notify(c.Error, n), i;
|
|
2209
2385
|
}
|
|
2210
|
-
if (e.phone && !
|
|
2386
|
+
if (e.phone && !ae(e.phone)) {
|
|
2211
2387
|
const i = new Error("Invalid phone number format. Phone must be in E.164 format (e.g., +12345678901)"), n = {
|
|
2212
2388
|
message: "Invalid phone number format. Phone must be in E.164 format (e.g., +12345678901)",
|
|
2213
2389
|
originalError: i,
|
|
@@ -2232,10 +2408,10 @@ class Ir {
|
|
|
2232
2408
|
this.subscribeStore.notify(c.SignInStart, {}), e.scopes = e.scopes ?? this.scopes, e.device = this.deviceService.getDeviceId();
|
|
2233
2409
|
try {
|
|
2234
2410
|
const t = await this.authApi.passwordlessSignInComplete(e);
|
|
2235
|
-
return await this.processAuthResponse(t, e.scopes), this.subscribeStore.notify(c.SignIn, {
|
|
2411
|
+
return this.handlePendingSecondFactor(t) || (await this.processAuthResponse(t, e.scopes), this.subscribeStore.notify(c.SignIn, {
|
|
2236
2412
|
tokens: t,
|
|
2237
2413
|
parsedTokens: this.tokenCacheService.getParsedTokens()
|
|
2238
|
-
}), await this.submitSessionCheck(), t;
|
|
2414
|
+
}), await this.submitSessionCheck()), t;
|
|
2239
2415
|
} catch (t) {
|
|
2240
2416
|
const s = {
|
|
2241
2417
|
message: t instanceof Error ? t.message : "Passwordless sign in failed",
|
|
@@ -2263,7 +2439,7 @@ class Ir {
|
|
|
2263
2439
|
} catch {
|
|
2264
2440
|
}
|
|
2265
2441
|
}
|
|
2266
|
-
this.storageManager.deleteTokens(), this.storageManager.clearIdToken(), this.storageManager.clearCsrfToken(), this.tokenDeliveryManager.reset(), this.subscribeStore.notify(c.SignOut, {});
|
|
2442
|
+
this.forgetPkceSignIn(), this.storageManager.deleteTokens(), this.storageManager.clearIdToken(), this.storageManager.clearCsrfToken(), this.tokenDeliveryManager.reset(), this.subscribeStore.notify(c.SignOut, {});
|
|
2267
2443
|
}
|
|
2268
2444
|
/**
|
|
2269
2445
|
* The session and user identity this client currently holds, or `undefined`
|
|
@@ -2275,13 +2451,12 @@ class Ir {
|
|
|
2275
2451
|
* nothing to read and the answer is `undefined`.
|
|
2276
2452
|
*/
|
|
2277
2453
|
readSessionPin() {
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
}
|
|
2454
|
+
try {
|
|
2455
|
+
const e = this.storageManager.getToken(b.access_token);
|
|
2456
|
+
return e ? Mr(T(e)) : void 0;
|
|
2457
|
+
} catch {
|
|
2458
|
+
return;
|
|
2459
|
+
}
|
|
2285
2460
|
}
|
|
2286
2461
|
/**
|
|
2287
2462
|
* Refuses to APPLY tokens that belong to a different principal (§13.4
|
|
@@ -2305,10 +2480,10 @@ class Ir {
|
|
|
2305
2480
|
* state — two different axes.
|
|
2306
2481
|
*/
|
|
2307
2482
|
assertSessionPin(e) {
|
|
2308
|
-
if (e && !
|
|
2483
|
+
if (e && !Ur(e, this.readSessionPin()))
|
|
2309
2484
|
throw console.warn(
|
|
2310
2485
|
"[passflow] the session or user changed while a step-up upgrade was in flight; the elevated tokens were discarded and the live session was left untouched."
|
|
2311
|
-
), new
|
|
2486
|
+
), new q("The session changed during verification, so the elevated tokens were discarded");
|
|
2312
2487
|
}
|
|
2313
2488
|
/**
|
|
2314
2489
|
* Refreshes the session, optionally committing an assurance upgrade.
|
|
@@ -2424,11 +2599,17 @@ class Ir {
|
|
|
2424
2599
|
this.subscribeStore.notify(c.SignInStart, {});
|
|
2425
2600
|
const i = new URLSearchParams(this.platform.getCurrentUrl()?.search ?? "").get("token") ?? void 0, n = t ?? this.scopes;
|
|
2426
2601
|
try {
|
|
2427
|
-
const o = await this.authApi.resetPassword(e, n, i);
|
|
2428
|
-
|
|
2429
|
-
|
|
2602
|
+
const o = await this.startPkce(), a = o ? await this.authApi.resetPassword(e, n, i, o.challenge) : await this.authApi.resetPassword(e, n, i);
|
|
2603
|
+
if (this.handlePendingSecondFactor(a, void 0, o, n))
|
|
2604
|
+
return a;
|
|
2605
|
+
const h = await this.exchangeCode(a, o);
|
|
2606
|
+
if (this.handlePendingSecondFactor(h))
|
|
2607
|
+
return h;
|
|
2608
|
+
const u = a.redirect_url ? { ...h, redirect_url: a.redirect_url } : h;
|
|
2609
|
+
return await this.processAuthResponse(u, n), this.subscribeStore.notify(c.SignIn, {
|
|
2610
|
+
tokens: u,
|
|
2430
2611
|
parsedTokens: this.tokenCacheService.getParsedTokens()
|
|
2431
|
-
}), await this.submitSessionCheck(),
|
|
2612
|
+
}), await this.submitSessionCheck(), u;
|
|
2432
2613
|
} catch (o) {
|
|
2433
2614
|
const a = {
|
|
2434
2615
|
message: o instanceof Error ? o.message : "Password reset failed",
|
|
@@ -2444,20 +2625,23 @@ class Ir {
|
|
|
2444
2625
|
const t = this.deviceService.getDeviceId(), s = this.platform.getDeviceType();
|
|
2445
2626
|
e.scopes = e.scopes ?? this.scopes, e.create_tenant = this.createTenantForNewUser;
|
|
2446
2627
|
try {
|
|
2447
|
-
const { challenge_id:
|
|
2448
|
-
|
|
2449
|
-
const o = await this.platform.passkeys.startRegistration(n);
|
|
2450
|
-
if (!o) throw new Error("Passkey registration was not completed");
|
|
2451
|
-
const a = await this.authApi.passkeyRegisterComplete(
|
|
2452
|
-
o,
|
|
2628
|
+
const i = await this.startPkce(), { challenge_id: n, publicKey: o } = await this.authApi.passkeyRegisterStart(
|
|
2629
|
+
i ? { ...e, code_challenge: i.challenge } : e,
|
|
2453
2630
|
t,
|
|
2454
|
-
|
|
2631
|
+
s,
|
|
2455
2632
|
!this.appId
|
|
2456
2633
|
);
|
|
2457
|
-
|
|
2458
|
-
|
|
2634
|
+
o.user.id = this.platform.btoa(o.user.id);
|
|
2635
|
+
const a = await this.platform.passkeys.startRegistration(o);
|
|
2636
|
+
if (!a) throw new Error("Passkey registration was not completed");
|
|
2637
|
+
const h = await this.authApi.passkeyRegisterComplete(a, t, n, !this.appId);
|
|
2638
|
+
if (this.handlePendingSecondFactor(h, void 0, i, e.scopes))
|
|
2639
|
+
return h;
|
|
2640
|
+
const u = await this.exchangeCode(h, i);
|
|
2641
|
+
return this.handlePendingSecondFactor(u) || (await this.processAuthResponse(u, e.scopes), this.subscribeStore.notify(c.Register, {
|
|
2642
|
+
tokens: u,
|
|
2459
2643
|
parsedTokens: this.tokenCacheService.getParsedTokens()
|
|
2460
|
-
}), await this.submitSessionCheck(),
|
|
2644
|
+
}), await this.submitSessionCheck()), u;
|
|
2461
2645
|
} catch (i) {
|
|
2462
2646
|
const n = {
|
|
2463
2647
|
message: i instanceof Error ? i.message : "Passkey registration failed",
|
|
@@ -2473,18 +2657,21 @@ class Ir {
|
|
|
2473
2657
|
const t = this.deviceService.getDeviceId(), s = this.platform.getDeviceType();
|
|
2474
2658
|
e.scopes = e.scopes ?? this.scopes;
|
|
2475
2659
|
try {
|
|
2476
|
-
const
|
|
2477
|
-
|
|
2478
|
-
const a = await this.authApi.passkeyAuthenticateComplete(
|
|
2479
|
-
o,
|
|
2660
|
+
const i = await this.startPkce(), { challenge_id: n, publicKey: o } = await this.authApi.passkeyAuthenticateStart(
|
|
2661
|
+
i ? { ...e, code_challenge: i.challenge } : e,
|
|
2480
2662
|
t,
|
|
2481
|
-
|
|
2663
|
+
s,
|
|
2482
2664
|
!this.appId
|
|
2483
|
-
);
|
|
2484
|
-
|
|
2485
|
-
|
|
2665
|
+
), a = await this.platform.passkeys.startAuthentication(o);
|
|
2666
|
+
if (!a) throw new Error("Passkey authentication was not completed");
|
|
2667
|
+
const h = await this.authApi.passkeyAuthenticateComplete(a, t, n, !this.appId);
|
|
2668
|
+
if (this.handlePendingSecondFactor(h, void 0, i, e.scopes))
|
|
2669
|
+
return h;
|
|
2670
|
+
const u = await this.exchangeCode(h, i);
|
|
2671
|
+
return this.handlePendingSecondFactor(u) || "access_token" in u && (await this.processAuthResponse(u, e.scopes), this.subscribeStore.notify(c.SignIn, {
|
|
2672
|
+
tokens: u,
|
|
2486
2673
|
parsedTokens: this.tokenCacheService.getParsedTokens()
|
|
2487
|
-
}), await this.submitSessionCheck()),
|
|
2674
|
+
}), await this.submitSessionCheck()), u;
|
|
2488
2675
|
} catch (i) {
|
|
2489
2676
|
const n = {
|
|
2490
2677
|
message: i instanceof Error ? i.message : "Passkey authentication failed",
|
|
@@ -2514,20 +2701,23 @@ class Ir {
|
|
|
2514
2701
|
const n = await this.platform.openAuthUrl(i, {
|
|
2515
2702
|
mode: "popup",
|
|
2516
2703
|
expectedReturnOrigin: this.platform.getCurrentUrl()?.origin ?? ""
|
|
2517
|
-
}), o = new URLSearchParams(n.
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2704
|
+
}), o = new URLSearchParams(n.callbackHash.replace(/^#/, ""));
|
|
2705
|
+
if (this.handlePendingSecondFactor({ tfa_token: o.get("tfa_token") ?? void 0 }))
|
|
2706
|
+
return;
|
|
2707
|
+
const a = new URLSearchParams(n.callbackSearch), h = a.get("access_token") || "", u = a.get("refresh_token") || "", m = a.get("id_token") || "", d = {
|
|
2708
|
+
access_token: h,
|
|
2709
|
+
refresh_token: u || void 0,
|
|
2710
|
+
id_token: m || void 0,
|
|
2521
2711
|
scopes: t
|
|
2522
2712
|
};
|
|
2523
|
-
await this.processAuthResponse(
|
|
2524
|
-
tokens:
|
|
2713
|
+
await this.processAuthResponse(d, t), this.subscribeStore.notify(c.SignIn, {
|
|
2714
|
+
tokens: d,
|
|
2525
2715
|
parsedTokens: this.tokenCacheService.getParsedTokens()
|
|
2526
2716
|
}), this.platform.navigateTo(this.platform.getCurrentUrl()?.origin ?? "");
|
|
2527
2717
|
} catch (n) {
|
|
2528
2718
|
const o = {
|
|
2529
2719
|
message: n instanceof Error ? n.message : "Authentication failed",
|
|
2530
|
-
code: n instanceof
|
|
2720
|
+
code: n instanceof Ge ? "POPUP_CLOSED" : "AUTH_FAILED",
|
|
2531
2721
|
originalError: n
|
|
2532
2722
|
};
|
|
2533
2723
|
this.subscribeStore.notify(c.Error, o);
|
|
@@ -2547,8 +2737,8 @@ class Ir {
|
|
|
2547
2737
|
appId: n ?? this.appId ?? "",
|
|
2548
2738
|
redirectto: s ?? this.platform.getCurrentUrl()?.href ?? "",
|
|
2549
2739
|
scopes: a.join(",")
|
|
2550
|
-
},
|
|
2551
|
-
return o.search =
|
|
2740
|
+
}, u = new URLSearchParams(h);
|
|
2741
|
+
return o.search = u.toString(), o.toString();
|
|
2552
2742
|
} catch (t) {
|
|
2553
2743
|
const s = {
|
|
2554
2744
|
message: t instanceof Error ? t.message : "Failed to create auth redirect URL",
|
|
@@ -2628,7 +2818,7 @@ class Ir {
|
|
|
2628
2818
|
}
|
|
2629
2819
|
}
|
|
2630
2820
|
}
|
|
2631
|
-
class
|
|
2821
|
+
class Nr {
|
|
2632
2822
|
constructor(e) {
|
|
2633
2823
|
this.invitationApi = e;
|
|
2634
2824
|
}
|
|
@@ -2673,24 +2863,7 @@ class Ar {
|
|
|
2673
2863
|
return this.invitationApi.getInvitationLink(e);
|
|
2674
2864
|
}
|
|
2675
2865
|
}
|
|
2676
|
-
class
|
|
2677
|
-
error(e, ...t) {
|
|
2678
|
-
console.error(e, ...t);
|
|
2679
|
-
}
|
|
2680
|
-
warn(e, ...t) {
|
|
2681
|
-
console.warn(e, ...t);
|
|
2682
|
-
}
|
|
2683
|
-
info(e, ...t) {
|
|
2684
|
-
console.info(e, ...t);
|
|
2685
|
-
}
|
|
2686
|
-
debug(e, ...t) {
|
|
2687
|
-
console.debug(e, ...t);
|
|
2688
|
-
}
|
|
2689
|
-
}
|
|
2690
|
-
function Rr() {
|
|
2691
|
-
return new Cr();
|
|
2692
|
-
}
|
|
2693
|
-
class Fr {
|
|
2866
|
+
class Vr {
|
|
2694
2867
|
constructor(e) {
|
|
2695
2868
|
this.data = this.normalize(e);
|
|
2696
2869
|
}
|
|
@@ -2760,9 +2933,9 @@ class Fr {
|
|
|
2760
2933
|
return this.data;
|
|
2761
2934
|
}
|
|
2762
2935
|
}
|
|
2763
|
-
class
|
|
2936
|
+
class Kr {
|
|
2764
2937
|
constructor(e, t, s) {
|
|
2765
|
-
this.tenantApi = e, this.scopes = t, this.logger = s ||
|
|
2938
|
+
this.tenantApi = e, this.scopes = t, this.logger = s || it();
|
|
2766
2939
|
}
|
|
2767
2940
|
/**
|
|
2768
2941
|
* Handle Passflow API errors
|
|
@@ -2832,7 +3005,7 @@ class Mr {
|
|
|
2832
3005
|
async getTenantUserMembership(e) {
|
|
2833
3006
|
try {
|
|
2834
3007
|
const t = await this.tenantApi.getTenantDetails(e);
|
|
2835
|
-
return new
|
|
3008
|
+
return new Vr(t);
|
|
2836
3009
|
} catch (t) {
|
|
2837
3010
|
this.handlePassflowError(t, `Get tenant user membership failed for tenant ID ${e}`);
|
|
2838
3011
|
}
|
|
@@ -3130,8 +3303,8 @@ class Mr {
|
|
|
3130
3303
|
}
|
|
3131
3304
|
}
|
|
3132
3305
|
}
|
|
3133
|
-
class
|
|
3134
|
-
constructor(e, t, s, i =
|
|
3306
|
+
class Br {
|
|
3307
|
+
constructor(e, t, s, i = Y) {
|
|
3135
3308
|
this.storageManager = e, this.authApi = t, this.subscribeStore = s, this.platform = i, this.checkInterval = null, this.CHECK_INTERVAL = 6e4, this.unsubscribeForeground = null, this.unsubscribeUnload = null, this.isRefreshing = !1, this.tokenExpiredFlag = !1, this.storageManager = e, this.authApi = t, this.setupLifecycleListeners();
|
|
3136
3309
|
}
|
|
3137
3310
|
initialize() {
|
|
@@ -3229,18 +3402,23 @@ class Pr {
|
|
|
3229
3402
|
return C(e);
|
|
3230
3403
|
}
|
|
3231
3404
|
}
|
|
3232
|
-
class
|
|
3233
|
-
constructor(e, t) {
|
|
3234
|
-
this.twoFactorApi = e, this.subscribeStore = t, this.PARTIAL_AUTH_TIMEOUT_MS = 300 * 1e3, this.SESSION_STORAGE_KEY = "passflow_2fa_challenge", this.totpDigits = 6;
|
|
3235
|
-
const
|
|
3236
|
-
onAuthChange: (
|
|
3237
|
-
if (
|
|
3238
|
-
const
|
|
3239
|
-
this.setPartialAuthState(
|
|
3405
|
+
class Gr {
|
|
3406
|
+
constructor(e, t, s) {
|
|
3407
|
+
this.twoFactorApi = e, this.subscribeStore = t, this.signInCompleter = s, this.PARTIAL_AUTH_TIMEOUT_MS = 300 * 1e3, this.SESSION_STORAGE_KEY = "passflow_2fa_challenge", this.totpDigits = 6;
|
|
3408
|
+
const i = {
|
|
3409
|
+
onAuthChange: (n, o) => {
|
|
3410
|
+
if (n === c.TwoFactorRequired) {
|
|
3411
|
+
const a = o;
|
|
3412
|
+
this.setPartialAuthState(a.email, a.challengeId, a.tfaToken);
|
|
3240
3413
|
}
|
|
3414
|
+
(n === c.SignIn || n === c.Register) && this.clearPartialAuthState();
|
|
3241
3415
|
}
|
|
3242
3416
|
};
|
|
3243
|
-
this.subscribeStore.subscribe(
|
|
3417
|
+
this.subscribeStore.subscribe(i, [
|
|
3418
|
+
c.TwoFactorRequired,
|
|
3419
|
+
c.SignIn,
|
|
3420
|
+
c.Register
|
|
3421
|
+
]);
|
|
3244
3422
|
}
|
|
3245
3423
|
/**
|
|
3246
3424
|
* Emit error event and throw the error
|
|
@@ -3282,7 +3460,7 @@ class Ur {
|
|
|
3282
3460
|
* Returns recovery codes that MUST be displayed to user
|
|
3283
3461
|
*/
|
|
3284
3462
|
async confirmSetup(e) {
|
|
3285
|
-
if (!
|
|
3463
|
+
if (!Z(e, this.totpDigits))
|
|
3286
3464
|
throw new Error(`Invalid TOTP code format. Code must be exactly ${this.totpDigits} digits.`);
|
|
3287
3465
|
try {
|
|
3288
3466
|
const t = await this.twoFactorApi.confirmSetup({ code: e });
|
|
@@ -3299,57 +3477,65 @@ class Ur {
|
|
|
3299
3477
|
/**
|
|
3300
3478
|
* Verify TOTP code during login
|
|
3301
3479
|
* Completes authentication if successful
|
|
3480
|
+
*
|
|
3481
|
+
* @param options.trustDevice - ask the server to trust this device for later sign-ins
|
|
3302
3482
|
*/
|
|
3303
|
-
async verify(e) {
|
|
3304
|
-
if (!
|
|
3483
|
+
async verify(e, t) {
|
|
3484
|
+
if (!Z(e, this.totpDigits))
|
|
3305
3485
|
throw new Error(`Invalid TOTP code format. Code must be exactly ${this.totpDigits} digits.`);
|
|
3306
3486
|
if (this.recoverPartialAuthState(), !this.isVerificationRequired())
|
|
3307
3487
|
throw new Error("2FA verification expired or not required. User must sign in first.");
|
|
3308
3488
|
if (!this.partialAuthState?.tfaToken)
|
|
3309
3489
|
throw new Error("No TFA token found. User must sign in first.");
|
|
3310
3490
|
try {
|
|
3311
|
-
const
|
|
3491
|
+
const s = await this.twoFactorApi.verify({
|
|
3312
3492
|
code: e,
|
|
3313
|
-
tfa_token: this.partialAuthState.tfaToken
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3493
|
+
tfa_token: this.partialAuthState.tfaToken,
|
|
3494
|
+
...t?.trustDevice ? { trust_device: !0 } : {}
|
|
3495
|
+
}), i = await this.finishSignIn(s);
|
|
3496
|
+
return this.subscribeStore.notify(c.TwoFactorVerified, { tokens: i }), i;
|
|
3497
|
+
} catch (s) {
|
|
3498
|
+
this.emitErrorAndThrow(s, "Verify 2FA code");
|
|
3318
3499
|
}
|
|
3319
3500
|
}
|
|
3320
3501
|
/**
|
|
3321
3502
|
* Use recovery code for authentication
|
|
3322
3503
|
* Completes authentication if successful
|
|
3504
|
+
*
|
|
3505
|
+
* @param options.trustDevice - ask the server to trust this device for later sign-ins
|
|
3323
3506
|
*/
|
|
3324
|
-
async useRecoveryCode(e) {
|
|
3507
|
+
async useRecoveryCode(e, t) {
|
|
3325
3508
|
try {
|
|
3326
|
-
const
|
|
3327
|
-
if (!
|
|
3509
|
+
const s = Or(e);
|
|
3510
|
+
if (!s)
|
|
3328
3511
|
throw new Error("Invalid recovery code format. Expected format: XXXX-XXXX or XXXXXXXX (alphanumeric).");
|
|
3329
3512
|
if (this.recoverPartialAuthState(), !this.isVerificationRequired())
|
|
3330
3513
|
throw new Error("2FA verification expired or not required. User must sign in first.");
|
|
3331
3514
|
if (!this.partialAuthState?.tfaToken)
|
|
3332
3515
|
throw new Error("No TFA token found. User must sign in first.");
|
|
3333
|
-
const
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3516
|
+
const i = await this.finishSignIn(
|
|
3517
|
+
await this.twoFactorApi.useRecoveryCode({
|
|
3518
|
+
recovery_code: s,
|
|
3519
|
+
tfa_token: this.partialAuthState.tfaToken,
|
|
3520
|
+
...t?.trustDevice ? { trust_device: !0 } : {}
|
|
3521
|
+
})
|
|
3522
|
+
);
|
|
3523
|
+
return i.remaining_recovery_codes === 0 ? this.subscribeStore.notify(c.TwoFactorRecoveryCodesExhausted, { tokens: i }) : i.remaining_recovery_codes <= 2 && this.subscribeStore.notify(c.TwoFactorRecoveryCodesLow, {
|
|
3524
|
+
tokens: i,
|
|
3525
|
+
remainingCodes: i.remaining_recovery_codes
|
|
3340
3526
|
}), this.subscribeStore.notify(c.TwoFactorRecoveryUsed, {
|
|
3341
|
-
tokens:
|
|
3342
|
-
remainingCodes:
|
|
3343
|
-
}), this.subscribeStore.notify(c.TwoFactorVerified, { tokens:
|
|
3344
|
-
} catch (
|
|
3345
|
-
this.emitErrorAndThrow(
|
|
3527
|
+
tokens: i,
|
|
3528
|
+
remainingCodes: i.remaining_recovery_codes
|
|
3529
|
+
}), this.subscribeStore.notify(c.TwoFactorVerified, { tokens: i }), i;
|
|
3530
|
+
} catch (s) {
|
|
3531
|
+
this.emitErrorAndThrow(s, "Use recovery code");
|
|
3346
3532
|
}
|
|
3347
3533
|
}
|
|
3348
3534
|
/**
|
|
3349
3535
|
* Disable 2FA (requires TOTP verification)
|
|
3350
3536
|
*/
|
|
3351
3537
|
async disable(e) {
|
|
3352
|
-
if (!
|
|
3538
|
+
if (!Z(e, this.totpDigits))
|
|
3353
3539
|
throw new Error(`Invalid TOTP code format. Code must be exactly ${this.totpDigits} digits.`);
|
|
3354
3540
|
try {
|
|
3355
3541
|
const t = await this.twoFactorApi.disable({ code: e });
|
|
@@ -3362,7 +3548,7 @@ class Ur {
|
|
|
3362
3548
|
* Regenerate recovery codes
|
|
3363
3549
|
*/
|
|
3364
3550
|
async regenerateRecoveryCodes(e) {
|
|
3365
|
-
if (!
|
|
3551
|
+
if (!Z(e, this.totpDigits))
|
|
3366
3552
|
throw new Error(`Invalid TOTP code format. Code must be exactly ${this.totpDigits} digits.`);
|
|
3367
3553
|
try {
|
|
3368
3554
|
const t = await this.twoFactorApi.regenerateRecoveryCodes({ code: e }), s = [...t.recovery_codes];
|
|
@@ -3400,12 +3586,40 @@ class Ur {
|
|
|
3400
3586
|
* Called on logout or successful verification
|
|
3401
3587
|
*/
|
|
3402
3588
|
clearPartialAuthState() {
|
|
3403
|
-
if (this.partialAuthState = void 0, typeof sessionStorage < "u")
|
|
3589
|
+
if (this.partialAuthState = void 0, this.signInCompleter?.forgetPkceSignIn(), typeof sessionStorage < "u")
|
|
3404
3590
|
try {
|
|
3405
3591
|
sessionStorage.removeItem(this.SESSION_STORAGE_KEY);
|
|
3406
3592
|
} catch {
|
|
3407
3593
|
}
|
|
3408
3594
|
}
|
|
3595
|
+
/**
|
|
3596
|
+
* Ends the pending sign-in with the second factor's answer. On a PKCE app that
|
|
3597
|
+
* answer is a code, redeemed and replaced by the tokens, so no caller or
|
|
3598
|
+
* subscriber ever gets a code where tokens belong. Tokens are applied once, by
|
|
3599
|
+
* the completer, in the app's delivery mode. The pending state goes only after
|
|
3600
|
+
* that has worked, except when no verifier can ever redeem the code.
|
|
3601
|
+
*/
|
|
3602
|
+
async finishSignIn(e) {
|
|
3603
|
+
const { code: t, ...s } = e;
|
|
3604
|
+
if (t && !this.signInCompleter?.hasPendingPkceSignIn()) {
|
|
3605
|
+
this.clearPartialAuthState();
|
|
3606
|
+
const n = new Error("The sign-in answered with a PKCE code, but its verifier is gone");
|
|
3607
|
+
throw n.id = "PKCE_VERIFIER_MISSING", n;
|
|
3608
|
+
}
|
|
3609
|
+
let i = e;
|
|
3610
|
+
if (t && this.signInCompleter) {
|
|
3611
|
+
const n = await this.signInCompleter.completePkceSignIn(t);
|
|
3612
|
+
i = { ...s, ...n };
|
|
3613
|
+
} else
|
|
3614
|
+
await this.signInCompleter?.applyTokens(i);
|
|
3615
|
+
return this.clearPartialAuthState(), i;
|
|
3616
|
+
}
|
|
3617
|
+
/**
|
|
3618
|
+
* The 2FA token of the sign-in waiting on its second factor, if any.
|
|
3619
|
+
*/
|
|
3620
|
+
pendingTfaToken() {
|
|
3621
|
+
return this.isVerificationRequired() && this.partialAuthState?.tfaToken || void 0;
|
|
3622
|
+
}
|
|
3409
3623
|
/**
|
|
3410
3624
|
* Attempt to recover partial auth state from sessionStorage
|
|
3411
3625
|
* Called before verification operations to handle page refresh
|
|
@@ -3564,7 +3778,7 @@ class Ur {
|
|
|
3564
3778
|
*/
|
|
3565
3779
|
async requestChallenge(e) {
|
|
3566
3780
|
try {
|
|
3567
|
-
const t = await this.twoFactorApi.requestChallenge(e);
|
|
3781
|
+
const t = await this.twoFactorApi.requestChallenge(e, this.pendingTfaToken());
|
|
3568
3782
|
return this.subscribeStore.notify(c.TwoFactorChallengeReceived, {
|
|
3569
3783
|
challengeId: t.challenge_id,
|
|
3570
3784
|
method: t.method,
|
|
@@ -3576,16 +3790,20 @@ class Ur {
|
|
|
3576
3790
|
}
|
|
3577
3791
|
/**
|
|
3578
3792
|
* Verify 2FA challenge (v2)
|
|
3793
|
+
* Set `trust_device` on the payload to ask the server to trust this device.
|
|
3579
3794
|
*/
|
|
3580
3795
|
async verifyV2(e) {
|
|
3581
3796
|
try {
|
|
3582
|
-
const t = await this.twoFactorApi.verifyV2(e);
|
|
3583
|
-
|
|
3797
|
+
const t = await this.twoFactorApi.verifyV2(e, this.pendingTfaToken());
|
|
3798
|
+
if (!t.success)
|
|
3799
|
+
return t;
|
|
3800
|
+
const s = await this.finishSignIn(t);
|
|
3801
|
+
return this.subscribeStore.notify(c.TwoFactorVerified, {
|
|
3584
3802
|
tokens: {
|
|
3585
|
-
access_token:
|
|
3586
|
-
refresh_token:
|
|
3803
|
+
access_token: s.access_token,
|
|
3804
|
+
refresh_token: s.refresh_token
|
|
3587
3805
|
}
|
|
3588
|
-
}),
|
|
3806
|
+
}), s.device_trusted && this.subscribeStore.notify(c.TwoFactorDeviceTrusted, {}), s;
|
|
3589
3807
|
} catch (t) {
|
|
3590
3808
|
this.emitErrorAndThrow(t, "Verify 2FA challenge");
|
|
3591
3809
|
}
|
|
@@ -3595,7 +3813,7 @@ class Ur {
|
|
|
3595
3813
|
*/
|
|
3596
3814
|
async switchToAlternative(e) {
|
|
3597
3815
|
try {
|
|
3598
|
-
const t = await this.twoFactorApi.switchToAlternative(e);
|
|
3816
|
+
const t = await this.twoFactorApi.switchToAlternative(e, this.pendingTfaToken());
|
|
3599
3817
|
return this.subscribeStore.notify(c.TwoFactorMethodSwitched, {
|
|
3600
3818
|
challengeId: t.challenge_id,
|
|
3601
3819
|
method: t.method,
|
|
@@ -3606,7 +3824,8 @@ class Ur {
|
|
|
3606
3824
|
}
|
|
3607
3825
|
}
|
|
3608
3826
|
/**
|
|
3609
|
-
*
|
|
3827
|
+
* List the devices the user trusted to skip the second factor on this app.
|
|
3828
|
+
* The one this request came from has `current: true`.
|
|
3610
3829
|
*/
|
|
3611
3830
|
async getTrustedDevices() {
|
|
3612
3831
|
try {
|
|
@@ -3616,7 +3835,8 @@ class Ur {
|
|
|
3616
3835
|
}
|
|
3617
3836
|
}
|
|
3618
3837
|
/**
|
|
3619
|
-
* Revoke trusted device
|
|
3838
|
+
* Revoke a trusted device; its next sign-in asks for the second factor again.
|
|
3839
|
+
* Rejects with the server's 404 when the user has no such device.
|
|
3620
3840
|
*/
|
|
3621
3841
|
async revokeTrustedDevice(e) {
|
|
3622
3842
|
try {
|
|
@@ -3626,8 +3846,8 @@ class Ur {
|
|
|
3626
3846
|
}
|
|
3627
3847
|
}
|
|
3628
3848
|
}
|
|
3629
|
-
class
|
|
3630
|
-
constructor(e, t, s =
|
|
3849
|
+
class jr {
|
|
3850
|
+
constructor(e, t, s = Y) {
|
|
3631
3851
|
this.userAPI = e, this.deviceService = t, this.platform = s;
|
|
3632
3852
|
}
|
|
3633
3853
|
/**
|
|
@@ -3678,85 +3898,85 @@ class Dr {
|
|
|
3678
3898
|
return await this.userAPI.addUserPasskeyComplete(h, i, o);
|
|
3679
3899
|
}
|
|
3680
3900
|
}
|
|
3681
|
-
class
|
|
3901
|
+
class x extends Error {
|
|
3682
3902
|
constructor(e, t, s = !1) {
|
|
3683
3903
|
super(t), this.name = "UpgradeFactorError", this.factor = e, this.cancelled = s;
|
|
3684
3904
|
}
|
|
3685
3905
|
}
|
|
3686
|
-
const
|
|
3906
|
+
const nt = (r, e) => {
|
|
3687
3907
|
const t = e?.trim();
|
|
3688
3908
|
if (!t)
|
|
3689
|
-
throw new
|
|
3909
|
+
throw new x(r, "A verification code is required");
|
|
3690
3910
|
return t;
|
|
3691
|
-
},
|
|
3911
|
+
}, Hr = {
|
|
3692
3912
|
type: "totp",
|
|
3693
3913
|
requiresPrepare: !1,
|
|
3694
3914
|
input: "code",
|
|
3695
|
-
assert: async ({ code: r }) => ({ code:
|
|
3696
|
-
},
|
|
3915
|
+
assert: async ({ code: r }) => ({ code: nt("totp", r) })
|
|
3916
|
+
}, zr = {
|
|
3697
3917
|
type: "recovery_codes",
|
|
3698
3918
|
requiresPrepare: !1,
|
|
3699
3919
|
input: "code",
|
|
3700
|
-
assert: async ({ code: r }) => ({ code:
|
|
3701
|
-
},
|
|
3920
|
+
assert: async ({ code: r }) => ({ code: nt("recovery_codes", r) })
|
|
3921
|
+
}, Yr = {
|
|
3702
3922
|
type: "passkey",
|
|
3703
3923
|
requiresPrepare: !0,
|
|
3704
3924
|
input: "none",
|
|
3705
3925
|
assert: async ({ prepared: r, platform: e }) => {
|
|
3706
3926
|
if (!r?.webauthn)
|
|
3707
|
-
throw new
|
|
3927
|
+
throw new x("passkey", "The upgrade challenge carried no WebAuthn options");
|
|
3708
3928
|
const t = e.passkeys;
|
|
3709
3929
|
if (!t)
|
|
3710
|
-
throw new
|
|
3930
|
+
throw new x("passkey", "This platform does not support passkeys");
|
|
3711
3931
|
let s;
|
|
3712
3932
|
try {
|
|
3713
3933
|
s = await t.startAuthentication(r.webauthn);
|
|
3714
3934
|
} catch (i) {
|
|
3715
|
-
throw new
|
|
3935
|
+
throw new x("passkey", i?.message || "Passkey verification was cancelled", !0);
|
|
3716
3936
|
}
|
|
3717
3937
|
if (!s)
|
|
3718
|
-
throw new
|
|
3938
|
+
throw new x("passkey", "Passkey verification was cancelled", !0);
|
|
3719
3939
|
return { challenge_id: r.challengeId, credential: s };
|
|
3720
3940
|
}
|
|
3721
|
-
},
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
]),
|
|
3941
|
+
}, Te = Object.freeze([
|
|
3942
|
+
Hr,
|
|
3943
|
+
Yr,
|
|
3944
|
+
zr
|
|
3945
|
+
]), Wr = (r = Te) => new Map(r.map((e) => [e.type, e])), Xr = 3, Jr = {
|
|
3726
3946
|
passkey: 0,
|
|
3727
3947
|
totp: 1,
|
|
3728
3948
|
email_otp: 2,
|
|
3729
3949
|
sms_otp: 3,
|
|
3730
3950
|
recovery_codes: 9
|
|
3731
|
-
},
|
|
3732
|
-
const t =
|
|
3951
|
+
}, Zr = (r) => r.requiredLevel ?? Ht(r.acrValues), Fe = (r, e) => {
|
|
3952
|
+
const t = Jr[r.type] ?? 5, s = e !== void 0 && e >= Xr, i = r.type === "passkey";
|
|
3733
3953
|
return (s && !i ? 100 : 0) + t;
|
|
3734
|
-
},
|
|
3735
|
-
const t =
|
|
3736
|
-
return [...r].sort((s, i) =>
|
|
3954
|
+
}, Qr = (r, e) => {
|
|
3955
|
+
const t = Zr(e);
|
|
3956
|
+
return [...r].sort((s, i) => Fe(s, t) - Fe(i, t));
|
|
3737
3957
|
};
|
|
3738
|
-
class
|
|
3958
|
+
class L extends Error {
|
|
3739
3959
|
constructor(e) {
|
|
3740
3960
|
super("Upgrade authentication was cancelled"), this.code = "upgrade_cancelled", this.name = "UpgradeCancelledError", e !== void 0 && (this.cause = e);
|
|
3741
3961
|
}
|
|
3742
3962
|
}
|
|
3743
|
-
class
|
|
3963
|
+
class te extends Error {
|
|
3744
3964
|
constructor(e = "No available authentication factor can satisfy this challenge") {
|
|
3745
3965
|
super(e), this.code = "upgrade_unsatisfiable", this.name = "UpgradeUnsatisfiableError";
|
|
3746
3966
|
}
|
|
3747
3967
|
}
|
|
3748
|
-
const
|
|
3968
|
+
const es = 4, ts = 3e4, rs = () => {
|
|
3749
3969
|
let r = () => {
|
|
3750
3970
|
}, e = () => {
|
|
3751
3971
|
};
|
|
3752
3972
|
return { promise: new Promise((s, i) => {
|
|
3753
3973
|
r = s, e = i;
|
|
3754
3974
|
}), resolve: r, reject: e };
|
|
3755
|
-
},
|
|
3975
|
+
}, H = (r) => ({
|
|
3756
3976
|
acrValues: r.acrValues,
|
|
3757
3977
|
level: r.requiredLevel,
|
|
3758
3978
|
maxAge: r.maxAge
|
|
3759
|
-
}),
|
|
3979
|
+
}), ss = (r, e) => e.level === void 0 ? !0 : r.level === void 0 ? !1 : r.level >= e.level, is = (r, e) => {
|
|
3760
3980
|
const t = r.requiredLevel === void 0 ? e.requiredLevel : e.requiredLevel === void 0 ? r.requiredLevel : Math.max(r.requiredLevel, e.requiredLevel), s = t === void 0 ? r.acrValues ?? e.acrValues : t === r.requiredLevel ? r.acrValues : e.acrValues, i = r.maxAge === void 0 ? e.maxAge : e.maxAge === void 0 ? r.maxAge : Math.min(r.maxAge, e.maxAge), n = Array.from(/* @__PURE__ */ new Set([...r.channels ?? [], ...e.channels ?? []]));
|
|
3761
3981
|
return {
|
|
3762
3982
|
acrValues: s,
|
|
@@ -3765,13 +3985,13 @@ const Kr = 4, jr = 3e4, Gr = () => {
|
|
|
3765
3985
|
status: r.status,
|
|
3766
3986
|
...n.length > 0 ? { channels: n } : {}
|
|
3767
3987
|
};
|
|
3768
|
-
},
|
|
3988
|
+
}, ns = (r, e) => {
|
|
3769
3989
|
const t = e.requiredLevel !== void 0 && (r.requiredLevel === void 0 || e.requiredLevel > r.requiredLevel), s = e.maxAge !== void 0 && (r.maxAge === void 0 || e.maxAge < r.maxAge);
|
|
3770
3990
|
return t || s;
|
|
3771
3991
|
};
|
|
3772
|
-
class
|
|
3992
|
+
class os {
|
|
3773
3993
|
constructor(e) {
|
|
3774
|
-
this.state = "idle", this.inFlight = null, this.requirement = null, this.selected = null, this.rankedRequirement = null, this.registrations = [], this.proof = null, this.pruned = /* @__PURE__ */ new Set(), this.openPrompt = null, this.transport = e.transport, this.prompt = e.prompt, this.platform = e.platform, this.available = e.factors ??
|
|
3994
|
+
this.state = "idle", this.inFlight = null, this.requirement = null, this.selected = null, this.rankedRequirement = null, this.registrations = [], this.proof = null, this.pruned = /* @__PURE__ */ new Set(), this.openPrompt = null, this.transport = e.transport, this.prompt = e.prompt, this.platform = e.platform, this.available = e.factors ?? Te, this.registry = Wr(this.available), this.maxAttempts = e.maxAttempts ?? es, this.readObtainedBar = e.readObtainedBar, this.onFlightSettled = e.onFlightSettled, this.settleTimeoutMs = e.replaySettleTimeoutMs ?? ts;
|
|
3775
3995
|
}
|
|
3776
3996
|
/** The current lifecycle state. Read-only. */
|
|
3777
3997
|
get currentState() {
|
|
@@ -3808,9 +4028,9 @@ class Wr {
|
|
|
3808
4028
|
/** Registers a waiter and the bar it arrived demanding. */
|
|
3809
4029
|
register(e, t) {
|
|
3810
4030
|
const s = t.kind === "imperative" && t.requested !== void 0, n = {
|
|
3811
|
-
demanded: t.kind === "imperative" && t.requested ? t.requested :
|
|
4031
|
+
demanded: t.kind === "imperative" && t.requested ? t.requested : H(e),
|
|
3812
4032
|
statedBar: s,
|
|
3813
|
-
settlement:
|
|
4033
|
+
settlement: rs(),
|
|
3814
4034
|
reported: !1,
|
|
3815
4035
|
entry: {
|
|
3816
4036
|
...t,
|
|
@@ -3838,13 +4058,13 @@ class Wr {
|
|
|
3838
4058
|
this.requirement = e;
|
|
3839
4059
|
return;
|
|
3840
4060
|
}
|
|
3841
|
-
const s =
|
|
3842
|
-
this.requirement =
|
|
4061
|
+
const s = ns(t, e);
|
|
4062
|
+
this.requirement = is(t, e), s && this.state === "collecting" && this.selected === null && this.openPrompt?.onRequirementRaised?.({ challenge: this.requirement, factors: this.offeredFactors() });
|
|
3843
4063
|
}
|
|
3844
4064
|
/** The factors to offer right now: ranked for the merged bar, minus what the server refused. */
|
|
3845
4065
|
offeredFactors() {
|
|
3846
4066
|
const e = this.available.filter((s) => !this.pruned.has(s.type)), t = this.requirement;
|
|
3847
|
-
return t ?
|
|
4067
|
+
return t ? Qr(e, t) : e;
|
|
3848
4068
|
}
|
|
3849
4069
|
/** The waiter's inbound edge. Idempotent — a second call is ignored. */
|
|
3850
4070
|
receiveReport(e, t) {
|
|
@@ -3912,8 +4132,8 @@ class Wr {
|
|
|
3912
4132
|
*/
|
|
3913
4133
|
release(e, t) {
|
|
3914
4134
|
if (e.entry.kind === "imperative") {
|
|
3915
|
-
if (e.statedBar && !
|
|
3916
|
-
this.receiveReport(e, { outcome: "insufficient", obtained: t, required: e.demanded }), e.settlement.reject(new
|
|
4135
|
+
if (e.statedBar && !ss(t, e.demanded)) {
|
|
4136
|
+
this.receiveReport(e, { outcome: "insufficient", obtained: t, required: e.demanded }), e.settlement.reject(new G(t, e.demanded));
|
|
3917
4137
|
return;
|
|
3918
4138
|
}
|
|
3919
4139
|
this.receiveReport(e, { outcome: "replayed", obtained: t }), e.settlement.resolve({ waiter: e.entry, obtained: t });
|
|
@@ -3988,26 +4208,26 @@ class Wr {
|
|
|
3988
4208
|
for (let t = 0; t < this.maxAttempts; t++) {
|
|
3989
4209
|
const s = this.offeredFactors();
|
|
3990
4210
|
if (s.length === 0)
|
|
3991
|
-
return { status: "failed", reason: new
|
|
4211
|
+
return { status: "failed", reason: new te() };
|
|
3992
4212
|
const i = this.requirement;
|
|
3993
4213
|
let n;
|
|
3994
4214
|
try {
|
|
3995
4215
|
n = await this.collect(i, s, e);
|
|
3996
4216
|
} catch (a) {
|
|
3997
|
-
return { status: "failed", reason: new
|
|
4217
|
+
return { status: "failed", reason: new L(a) };
|
|
3998
4218
|
}
|
|
3999
4219
|
if (n.type === "cancel")
|
|
4000
|
-
return { status: "failed", reason: new
|
|
4220
|
+
return { status: "failed", reason: new L() };
|
|
4001
4221
|
const o = this.registry.get(n.factor);
|
|
4002
4222
|
if (!o) {
|
|
4003
|
-
e = new
|
|
4223
|
+
e = new te(`Unknown authentication factor: ${n.factor}`), this.state = "collecting", this.selected = null;
|
|
4004
4224
|
continue;
|
|
4005
4225
|
}
|
|
4006
4226
|
try {
|
|
4007
|
-
return await this.proveAndCommit(o, n.code), { status: "proven", obtained: this.readObtainedBar?.() ??
|
|
4227
|
+
return await this.proveAndCommit(o, n.code), { status: "proven", obtained: this.readObtainedBar?.() ?? H(this.rankedRequirement ?? i) };
|
|
4008
4228
|
} catch (a) {
|
|
4009
|
-
if (a instanceof
|
|
4010
|
-
return { status: "failed", reason: new
|
|
4229
|
+
if (a instanceof x && a.cancelled)
|
|
4230
|
+
return { status: "failed", reason: new L() };
|
|
4011
4231
|
const h = this.classifyProofFailure(a);
|
|
4012
4232
|
if (h)
|
|
4013
4233
|
return { status: "failed", reason: h };
|
|
@@ -4036,7 +4256,7 @@ class Wr {
|
|
|
4036
4256
|
}
|
|
4037
4257
|
/** Maps a proof failure to a terminal reason, or `undefined` when the user may retry. */
|
|
4038
4258
|
classifyProofFailure(e) {
|
|
4039
|
-
if (e instanceof
|
|
4259
|
+
if (e instanceof G || e instanceof j || e instanceof q)
|
|
4040
4260
|
return e;
|
|
4041
4261
|
if (e instanceof _)
|
|
4042
4262
|
switch (e.kind) {
|
|
@@ -4049,7 +4269,7 @@ class Wr {
|
|
|
4049
4269
|
case "network":
|
|
4050
4270
|
return e;
|
|
4051
4271
|
case "session_changed":
|
|
4052
|
-
return new
|
|
4272
|
+
return new q(e.message);
|
|
4053
4273
|
default:
|
|
4054
4274
|
return;
|
|
4055
4275
|
}
|
|
@@ -4060,14 +4280,14 @@ class Wr {
|
|
|
4060
4280
|
await this.transport.commit(e.type, i);
|
|
4061
4281
|
}
|
|
4062
4282
|
}
|
|
4063
|
-
const
|
|
4283
|
+
const ot = "https://passflow-relative.invalid", as = () => {
|
|
4064
4284
|
const r = globalThis, e = r.document?.baseURI;
|
|
4065
4285
|
if (typeof e == "string" && e !== "")
|
|
4066
4286
|
return e;
|
|
4067
4287
|
const t = r.location?.href;
|
|
4068
|
-
return typeof t == "string" && t !== "" && t !== "about:blank" ? t :
|
|
4069
|
-
},
|
|
4070
|
-
const t = e ===
|
|
4288
|
+
return typeof t == "string" && t !== "" && t !== "about:blank" ? t : ot;
|
|
4289
|
+
}, Me = (r, e = as()) => {
|
|
4290
|
+
const t = e === ot;
|
|
4071
4291
|
let s;
|
|
4072
4292
|
try {
|
|
4073
4293
|
s = new URL(e).origin;
|
|
@@ -4092,32 +4312,32 @@ const Ze = "https://passflow-relative.invalid", Xr = () => {
|
|
|
4092
4312
|
relativeToBase: s !== void 0 && i.origin === s,
|
|
4093
4313
|
sentinelBase: t
|
|
4094
4314
|
};
|
|
4095
|
-
},
|
|
4315
|
+
}, he = (r, e) => typeof e == "string" ? [r.toLowerCase(), e] : void 0, cs = (r) => {
|
|
4096
4316
|
const e = [];
|
|
4097
4317
|
if (r == null)
|
|
4098
4318
|
return Object.freeze(e);
|
|
4099
4319
|
const t = r;
|
|
4100
4320
|
if (typeof t.forEach == "function" && typeof t.entries == "function")
|
|
4101
4321
|
return r.forEach((s, i) => {
|
|
4102
|
-
const n =
|
|
4322
|
+
const n = he(i, s);
|
|
4103
4323
|
n && e.push(n);
|
|
4104
4324
|
}), Object.freeze(e);
|
|
4105
4325
|
if (Array.isArray(r)) {
|
|
4106
4326
|
for (const s of r)
|
|
4107
4327
|
if (Array.isArray(s) && s.length >= 2) {
|
|
4108
|
-
const i =
|
|
4328
|
+
const i = he(String(s[0]), s[1]);
|
|
4109
4329
|
i && e.push(i);
|
|
4110
4330
|
}
|
|
4111
4331
|
return Object.freeze(e);
|
|
4112
4332
|
}
|
|
4113
4333
|
if (typeof r == "object")
|
|
4114
4334
|
for (const [s, i] of Object.entries(r)) {
|
|
4115
|
-
const n = Array.isArray(i) ? i.join(", ") : i, o =
|
|
4335
|
+
const n = Array.isArray(i) ? i.join(", ") : i, o = he(s, n);
|
|
4116
4336
|
o && e.push(o);
|
|
4117
4337
|
}
|
|
4118
4338
|
return Object.freeze(e);
|
|
4119
|
-
},
|
|
4120
|
-
const e = r.base === void 0 ?
|
|
4339
|
+
}, at = (r) => {
|
|
4340
|
+
const e = r.base === void 0 ? Me(r.url) : Me(r.url, r.base), t = {
|
|
4121
4341
|
raw: r.url,
|
|
4122
4342
|
href: e.href,
|
|
4123
4343
|
dispatchUrl: e.sentinelBase || !e.resolved ? r.url : e.href,
|
|
@@ -4126,25 +4346,25 @@ const Ze = "https://passflow-relative.invalid", Xr = () => {
|
|
|
4126
4346
|
resolved: e.resolved,
|
|
4127
4347
|
relativeToBase: e.relativeToBase,
|
|
4128
4348
|
method: (r.method ?? "GET").toUpperCase(),
|
|
4129
|
-
headers:
|
|
4349
|
+
headers: cs(r.headers),
|
|
4130
4350
|
bodyKind: r.bodyKind,
|
|
4131
4351
|
..."body" in r ? { body: r.body } : {}
|
|
4132
4352
|
};
|
|
4133
4353
|
return Object.freeze(t);
|
|
4134
|
-
},
|
|
4354
|
+
}, ct = (r, e) => {
|
|
4135
4355
|
if (!e || e.from === e.to)
|
|
4136
4356
|
return r;
|
|
4137
4357
|
let t = !1;
|
|
4138
4358
|
const s = r.map(([i, n]) => i === "authorization" && n === e.from ? (t = !0, [i, e.to]) : [i, n]);
|
|
4139
4359
|
return t ? Object.freeze(s) : r;
|
|
4140
|
-
},
|
|
4360
|
+
}, ht = (r) => {
|
|
4141
4361
|
const e = {};
|
|
4142
4362
|
for (const [t, s] of r)
|
|
4143
4363
|
e[t] = s;
|
|
4144
4364
|
return e;
|
|
4145
|
-
},
|
|
4146
|
-
|
|
4147
|
-
),
|
|
4365
|
+
}, hs = new Set(
|
|
4366
|
+
Te.filter((r) => !r.requiresPrepare).map((r) => r.type)
|
|
4367
|
+
), ds = (r) => {
|
|
4148
4368
|
if (!r || typeof r != "object" || !r.challenge_id || !r.expires_at)
|
|
4149
4369
|
throw new _({
|
|
4150
4370
|
kind: "protocol",
|
|
@@ -4157,16 +4377,16 @@ const Ze = "https://passflow-relative.invalid", Xr = () => {
|
|
|
4157
4377
|
webauthn: r.webauthn,
|
|
4158
4378
|
codeSentTo: r.code_sent_to
|
|
4159
4379
|
};
|
|
4160
|
-
},
|
|
4380
|
+
}, Ue = (r) => st(r) && !Ar(r), ls = (r) => ({
|
|
4161
4381
|
async prepare(e) {
|
|
4162
|
-
if (!
|
|
4382
|
+
if (!hs.has(e))
|
|
4163
4383
|
try {
|
|
4164
4384
|
const t = r.relyingPartyId?.(), s = await r.startUpgrade(t ? { method: e, relying_party_id: t } : { method: e });
|
|
4165
|
-
return
|
|
4385
|
+
return ds(s);
|
|
4166
4386
|
} catch (t) {
|
|
4167
|
-
if (
|
|
4387
|
+
if (Ue(t))
|
|
4168
4388
|
throw t;
|
|
4169
|
-
const s =
|
|
4389
|
+
const s = Pe(t, "start");
|
|
4170
4390
|
if (s.kind === "prepare_not_required")
|
|
4171
4391
|
return;
|
|
4172
4392
|
throw s;
|
|
@@ -4179,42 +4399,42 @@ const Ze = "https://passflow-relative.invalid", Xr = () => {
|
|
|
4179
4399
|
try {
|
|
4180
4400
|
await r.commitRefresh({ type: e, assertion: t });
|
|
4181
4401
|
} catch (i) {
|
|
4182
|
-
if (
|
|
4402
|
+
if (Ue(i))
|
|
4183
4403
|
throw i;
|
|
4184
|
-
const n =
|
|
4185
|
-
throw n.status === 401 &&
|
|
4404
|
+
const n = Pe(i, "refresh");
|
|
4405
|
+
throw n.status === 401 && Fr(n) && r.markSessionInvalid?.(), n;
|
|
4186
4406
|
}
|
|
4187
4407
|
}
|
|
4188
|
-
}),
|
|
4408
|
+
}), dt = (r) => typeof r == "function" ? r() : r, De = (r) => {
|
|
4189
4409
|
try {
|
|
4190
4410
|
return new URL(r);
|
|
4191
4411
|
} catch {
|
|
4192
4412
|
return;
|
|
4193
4413
|
}
|
|
4194
|
-
},
|
|
4414
|
+
}, ve = (r, e) => {
|
|
4195
4415
|
if (!e || e === "/")
|
|
4196
4416
|
return !0;
|
|
4197
4417
|
const t = e.replace(/\/+$/, "");
|
|
4198
4418
|
return r === t || r.startsWith(`${t}/`);
|
|
4199
|
-
},
|
|
4419
|
+
}, us = (r, e) => !e || r.origin === void 0 ? !1 : r.origin === e.origin && ve(r.pathname, e.pathPrefix), ps = (r, e) => {
|
|
4200
4420
|
for (const t of e) {
|
|
4201
4421
|
if (t === "")
|
|
4202
4422
|
continue;
|
|
4203
4423
|
if (t.startsWith("/")) {
|
|
4204
|
-
if (r.relativeToBase &&
|
|
4424
|
+
if (r.relativeToBase && ve(r.pathname, t))
|
|
4205
4425
|
return !0;
|
|
4206
4426
|
continue;
|
|
4207
4427
|
}
|
|
4208
|
-
const s =
|
|
4209
|
-
if (!(!s || r.origin === void 0) && r.origin === s.origin &&
|
|
4428
|
+
const s = De(t) ?? De(`https://${t}`);
|
|
4429
|
+
if (!(!s || r.origin === void 0) && r.origin === s.origin && ve(r.pathname, s.pathname))
|
|
4210
4430
|
return !0;
|
|
4211
4431
|
}
|
|
4212
4432
|
return !1;
|
|
4213
|
-
},
|
|
4433
|
+
}, xe = (r, e, t) => us(r, e.passflow) || ps(r, e.backend) ? t ? t(r.href) !== !1 : !0 : !1, lt = (r) => {
|
|
4214
4434
|
const e = r.detail, t = e?.message ?? `[passflow] upgrade challenge not actioned: ${r.reason}`;
|
|
4215
4435
|
console.warn(t, { status: r.status, url: r.url, reason: r.reason, detail: e });
|
|
4216
|
-
},
|
|
4217
|
-
const t = e.onUpgradeDiagnostic ??
|
|
4436
|
+
}, fs = (r, e) => {
|
|
4437
|
+
const t = e.onUpgradeDiagnostic ?? lt;
|
|
4218
4438
|
return (s, i) => {
|
|
4219
4439
|
t({
|
|
4220
4440
|
status: r.status,
|
|
@@ -4223,12 +4443,12 @@ const Ze = "https://passflow-relative.invalid", Xr = () => {
|
|
|
4223
4443
|
detail: { method: r.request.method, ...i ?? {} }
|
|
4224
4444
|
});
|
|
4225
4445
|
};
|
|
4226
|
-
},
|
|
4227
|
-
const s = t.onUpgradeDiagnostic ??
|
|
4446
|
+
}, me = (r, e, t) => {
|
|
4447
|
+
const s = t.onUpgradeDiagnostic ?? lt;
|
|
4228
4448
|
for (const i of r)
|
|
4229
4449
|
s({ ...i, url: e.request.href, detail: { method: e.request.method, ...i.detail ?? {} } });
|
|
4230
|
-
},
|
|
4231
|
-
const t = e.requireChallengeChannel === "header", s = r.getHeader("content-type") ?? "", i = !t &&
|
|
4450
|
+
}, gs = /\bjson\b/i, ye = async (r, e) => {
|
|
4451
|
+
const t = e.requireChallengeChannel === "header", s = r.getHeader("content-type") ?? "", i = !t && gs.test(s);
|
|
4232
4452
|
let n;
|
|
4233
4453
|
if (i)
|
|
4234
4454
|
try {
|
|
@@ -4237,23 +4457,23 @@ const Ze = "https://passflow-relative.invalid", Xr = () => {
|
|
|
4237
4457
|
n = void 0;
|
|
4238
4458
|
}
|
|
4239
4459
|
const o = i ? { status: r.status, getHeader: (a) => r.getHeader(a) ?? void 0, body: n } : { status: r.status, getHeader: (a) => r.getHeader(a) ?? void 0 };
|
|
4240
|
-
return
|
|
4241
|
-
},
|
|
4460
|
+
return be(o, { requireChallengeChannel: e.requireChallengeChannel });
|
|
4461
|
+
}, vs = (r) => be(
|
|
4242
4462
|
{ status: r.status, getHeader: (e) => r.getHeader(e) ?? void 0 },
|
|
4243
4463
|
{ requireChallengeChannel: "header" }
|
|
4244
|
-
).challenge,
|
|
4464
|
+
).challenge, ms = (r, e) => e.passflow === null ? `[passflow] a 401/403 from ${r} carried an upgrade challenge, but no Passflow endpoint is configured — set \`url\` on the Passflow config.` : `[passflow] a 401/403 from ${r} carried an upgrade challenge, but that URL is not covered by the provider's \`backend\` prop — add it there to enable step-up for this API.`, ys = (r, e) => r instanceof L ? { kind: "cancelled" } : r instanceof te ? { kind: "unsatisfiable" } : r instanceof j ? { kind: "unavailable" } : r instanceof q ? { kind: "session-changed" } : r instanceof G ? { kind: "insufficient", obtained: r.obtained, required: r.required } : r instanceof _ ? r.kind === "exhausted" || r.kind === "attempts_exhausted" ? { kind: "exhausted", error: r } : r.kind === "unavailable" ? { kind: "unavailable" } : r.kind === "session_changed" ? { kind: "session-changed" } : { kind: "transport-failure", status: r.status, retryable: r.retryable, error: r } : {
|
|
4245
4465
|
kind: "transport-failure",
|
|
4246
4466
|
retryable: !1,
|
|
4247
4467
|
error: r instanceof Error ? r : new Error(String(r))
|
|
4248
|
-
},
|
|
4468
|
+
}, ks = async (r, e, t, s) => {
|
|
4249
4469
|
if (r.status !== 401 && r.status !== 403)
|
|
4250
4470
|
return { kind: "replayed", response: r };
|
|
4251
|
-
const { challenge: i, diagnostics: n } = await
|
|
4252
|
-
if (
|
|
4471
|
+
const { challenge: i, diagnostics: n } = await ye(r, e);
|
|
4472
|
+
if (me(n, r, e), !i)
|
|
4253
4473
|
return { kind: "replayed", response: r };
|
|
4254
|
-
const o =
|
|
4474
|
+
const o = H(i);
|
|
4255
4475
|
return s("elevated-insufficient", { obtained: t, required: o }), { kind: "insufficient", obtained: t, required: o, response: r };
|
|
4256
|
-
},
|
|
4476
|
+
}, ws = async (r, e) => {
|
|
4257
4477
|
if (!e)
|
|
4258
4478
|
return { aborted: !1, value: await r };
|
|
4259
4479
|
if (e.aborted)
|
|
@@ -4269,32 +4489,32 @@ const Ze = "https://passflow-relative.invalid", Xr = () => {
|
|
|
4269
4489
|
} finally {
|
|
4270
4490
|
t && e.removeEventListener?.("abort", t);
|
|
4271
4491
|
}
|
|
4272
|
-
},
|
|
4492
|
+
}, ut = async (r, e) => {
|
|
4273
4493
|
if (r.status !== 401 && r.status !== 403)
|
|
4274
4494
|
return { kind: "not-a-challenge" };
|
|
4275
4495
|
if (r.markers.upgradeTransaction)
|
|
4276
4496
|
return { kind: "not-a-challenge" };
|
|
4277
|
-
const t =
|
|
4497
|
+
const t = fs(r, e);
|
|
4278
4498
|
if (r.markers.replayed) {
|
|
4279
|
-
if (!
|
|
4499
|
+
if (!xe(r.request, e.scope, e.shouldIntercept))
|
|
4280
4500
|
return { kind: "not-a-challenge" };
|
|
4281
|
-
const { challenge: y, diagnostics: I } = await
|
|
4282
|
-
if (
|
|
4501
|
+
const { challenge: y, diagnostics: I } = await ye(r, e);
|
|
4502
|
+
if (me(I, r, e), !y)
|
|
4283
4503
|
return { kind: "not-a-challenge" };
|
|
4284
|
-
const
|
|
4285
|
-
return t("elevated-insufficient", { obtained:
|
|
4504
|
+
const W = e.readObtainedBar?.() ?? {}, Ie = H(y);
|
|
4505
|
+
return t("elevated-insufficient", { obtained: W, required: Ie }), { kind: "insufficient", obtained: W, required: Ie, response: r };
|
|
4286
4506
|
}
|
|
4287
|
-
if (!
|
|
4288
|
-
return
|
|
4507
|
+
if (!xe(r.request, e.scope, e.shouldIntercept))
|
|
4508
|
+
return vs(r) ? (t("challenge-out-of-scope", {
|
|
4289
4509
|
header: r.getHeader("www-authenticate") ?? void 0,
|
|
4290
|
-
message:
|
|
4510
|
+
message: ms(r.request.href, e.scope)
|
|
4291
4511
|
}), { kind: "out-of-scope" }) : { kind: "not-a-challenge" };
|
|
4292
|
-
const { challenge: s, diagnostics: i } = await
|
|
4293
|
-
if (
|
|
4294
|
-
const
|
|
4512
|
+
const { challenge: s, diagnostics: i } = await ye(r, e);
|
|
4513
|
+
if (me(i, r, e), !s) {
|
|
4514
|
+
const p = r.getHeader("www-authenticate");
|
|
4295
4515
|
return e.requireChallengeChannel !== "header" && t("no-channel", {
|
|
4296
|
-
...
|
|
4297
|
-
message: r.responseType === "cors" && !
|
|
4516
|
+
...p ? { header: p } : {},
|
|
4517
|
+
message: r.responseType === "cors" && !p ? `[passflow] a cross-origin ${r.status} from ${r.request.href} carried no readable challenge: \`WWW-Authenticate\` is not CORS-safelisted, so add \`Access-Control-Expose-Headers: WWW-Authenticate\` on that server, or have it emit the \`upgrade_required\` JSON body.` : `[passflow] a ${r.status} from ${r.request.href} carried no upgrade challenge on either channel; treated as an ordinary ${r.status}.`
|
|
4298
4518
|
}), { kind: "not-a-challenge" };
|
|
4299
4519
|
}
|
|
4300
4520
|
if (r.replayable === !1)
|
|
@@ -4304,45 +4524,45 @@ const Ze = "https://passflow-relative.invalid", Xr = () => {
|
|
|
4304
4524
|
const n = e.authorizationSwap?.(), o = { kind: "request", url: r.request.href, method: r.request.method };
|
|
4305
4525
|
let a, h;
|
|
4306
4526
|
try {
|
|
4307
|
-
a = Promise.resolve(e.elevate(s, o)), h = await
|
|
4308
|
-
} catch (
|
|
4309
|
-
return
|
|
4527
|
+
a = Promise.resolve(e.elevate(s, o)), h = await ws(a, r.signal);
|
|
4528
|
+
} catch (p) {
|
|
4529
|
+
return ys(p);
|
|
4310
4530
|
}
|
|
4311
4531
|
if (h.aborted)
|
|
4312
4532
|
return a?.then(
|
|
4313
|
-
(
|
|
4533
|
+
(p) => p?.waiter.report({ outcome: "failed" }),
|
|
4314
4534
|
() => {
|
|
4315
4535
|
}
|
|
4316
4536
|
), { kind: "aborted", reason: h.reason };
|
|
4317
|
-
const
|
|
4537
|
+
const u = h.value;
|
|
4318
4538
|
if (r.signal?.aborted)
|
|
4319
|
-
return
|
|
4320
|
-
const m =
|
|
4539
|
+
return u?.waiter.report({ outcome: "failed" }), { kind: "aborted", reason: r.signal.reason };
|
|
4540
|
+
const m = u?.obtained ?? e.readObtainedBar?.() ?? H(s), d = e.authorizationSwap?.(), g = d ? { from: n?.from ?? d.from, to: d.to } : void 0;
|
|
4321
4541
|
r.markers.replayed = !0;
|
|
4322
4542
|
let f;
|
|
4323
4543
|
try {
|
|
4324
4544
|
f = await r.replay(g ? { authorizationSwap: g } : void 0);
|
|
4325
|
-
} catch (
|
|
4326
|
-
if (
|
|
4327
|
-
return
|
|
4328
|
-
if (
|
|
4545
|
+
} catch (p) {
|
|
4546
|
+
if (p instanceof G)
|
|
4547
|
+
return u?.waiter.report({ outcome: "insufficient", obtained: p.obtained, required: p.required }), r.signal?.aborted ? { kind: "aborted", reason: r.signal.reason } : { kind: "insufficient", obtained: p.obtained, required: p.required };
|
|
4548
|
+
if (u?.waiter.report({ outcome: "failed" }), r.signal?.aborted)
|
|
4329
4549
|
return { kind: "aborted", reason: r.signal.reason };
|
|
4330
|
-
throw
|
|
4550
|
+
throw p;
|
|
4331
4551
|
}
|
|
4332
|
-
const v = await
|
|
4333
|
-
return v.kind === "insufficient" ?
|
|
4334
|
-
},
|
|
4552
|
+
const v = await ks(f, e, m, t);
|
|
4553
|
+
return v.kind === "insufficient" ? u?.waiter.report({ outcome: "insufficient", obtained: v.obtained, required: v.required }) : u?.waiter.report({ outcome: "replayed", obtained: m }), v;
|
|
4554
|
+
}, Ss = (r) => {
|
|
4335
4555
|
switch (r.kind) {
|
|
4336
4556
|
case "cancelled":
|
|
4337
|
-
return new
|
|
4557
|
+
return new L();
|
|
4338
4558
|
case "unsatisfiable":
|
|
4339
|
-
return new
|
|
4559
|
+
return new te();
|
|
4340
4560
|
case "unavailable":
|
|
4341
4561
|
return new j();
|
|
4342
4562
|
case "session-changed":
|
|
4343
|
-
return new
|
|
4563
|
+
return new q();
|
|
4344
4564
|
case "insufficient":
|
|
4345
|
-
return new
|
|
4565
|
+
return new G(r.obtained, r.required);
|
|
4346
4566
|
case "exhausted":
|
|
4347
4567
|
return r.error;
|
|
4348
4568
|
case "transport-failure":
|
|
@@ -4350,7 +4570,7 @@ const Ze = "https://passflow-relative.invalid", Xr = () => {
|
|
|
4350
4570
|
default:
|
|
4351
4571
|
return;
|
|
4352
4572
|
}
|
|
4353
|
-
},
|
|
4573
|
+
}, bs = (r, e, t) => {
|
|
4354
4574
|
switch (r.kind) {
|
|
4355
4575
|
case "replayed":
|
|
4356
4576
|
return { settle: "resolve", value: r.response.raw };
|
|
@@ -4361,47 +4581,47 @@ const Ze = "https://passflow-relative.invalid", Xr = () => {
|
|
|
4361
4581
|
case "aborted":
|
|
4362
4582
|
return { settle: "reject", error: r.reason };
|
|
4363
4583
|
case "cancelled":
|
|
4364
|
-
return t.onCancel === "reject" ? { settle: "reject", error: new
|
|
4584
|
+
return t.onCancel === "reject" ? { settle: "reject", error: new L() } : { settle: "resolve", value: de(e, r) };
|
|
4365
4585
|
case "insufficient":
|
|
4366
|
-
return { settle: "resolve", value:
|
|
4586
|
+
return { settle: "resolve", value: de(r.response?.raw ?? e, r) };
|
|
4367
4587
|
default:
|
|
4368
|
-
return { settle: "resolve", value:
|
|
4588
|
+
return { settle: "resolve", value: de(e, r) };
|
|
4369
4589
|
}
|
|
4370
|
-
},
|
|
4590
|
+
}, Ts = (r, e) => {
|
|
4371
4591
|
switch (r.kind) {
|
|
4372
4592
|
case "replayed":
|
|
4373
4593
|
return r.response.rejected ? { settle: "reject", error: r.response.raw ?? e } : { settle: "resolve", value: r.response.raw };
|
|
4374
4594
|
case "aborted":
|
|
4375
4595
|
return { settle: "reject", error: r.reason };
|
|
4376
4596
|
default:
|
|
4377
|
-
return { settle: "reject", error:
|
|
4597
|
+
return { settle: "reject", error: Ss(r) ?? e };
|
|
4378
4598
|
}
|
|
4379
|
-
},
|
|
4599
|
+
}, pt = /* @__PURE__ */ new WeakSet(), ft = /* @__PURE__ */ new WeakSet(), gt = /* @__PURE__ */ new WeakSet(), vt = /* @__PURE__ */ new WeakSet(), mt = /* @__PURE__ */ new WeakSet(), yt = /* @__PURE__ */ new WeakSet(), kt = /* @__PURE__ */ new WeakSet(), de = (r, e) => {
|
|
4380
4600
|
switch (e.kind) {
|
|
4381
4601
|
case "cancelled":
|
|
4382
|
-
|
|
4602
|
+
pt.add(r);
|
|
4383
4603
|
break;
|
|
4384
4604
|
case "exhausted":
|
|
4385
|
-
|
|
4605
|
+
ft.add(r);
|
|
4386
4606
|
break;
|
|
4387
4607
|
case "insufficient":
|
|
4388
|
-
|
|
4608
|
+
gt.add(r);
|
|
4389
4609
|
break;
|
|
4390
4610
|
case "unsatisfiable":
|
|
4391
|
-
|
|
4611
|
+
vt.add(r);
|
|
4392
4612
|
break;
|
|
4393
4613
|
case "unavailable":
|
|
4394
|
-
|
|
4614
|
+
mt.add(r);
|
|
4395
4615
|
break;
|
|
4396
4616
|
case "session-changed":
|
|
4397
|
-
|
|
4617
|
+
yt.add(r);
|
|
4398
4618
|
break;
|
|
4399
4619
|
case "transport-failure":
|
|
4400
|
-
|
|
4620
|
+
kt.add(r);
|
|
4401
4621
|
break;
|
|
4402
4622
|
}
|
|
4403
4623
|
return r;
|
|
4404
|
-
},
|
|
4624
|
+
}, ni = (r) => pt.has(r), oi = (r) => ft.has(r), ai = (r) => gt.has(r), ci = (r) => vt.has(r), hi = (r) => mt.has(r), di = (r) => yt.has(r), li = (r) => kt.has(r), _s = /* @__PURE__ */ new Set(["GET", "HEAD", "OPTIONS"]), se = (r) => typeof r == "object" && r !== null && typeof r.url == "string" && typeof r.clone == "function" && "method" in r, Es = (r) => typeof r == "string" ? r : se(r) ? r.url : String(r), Is = (r, e) => (e?.method ?? (se(r) ? r.method : void 0) ?? "GET").toUpperCase(), As = (r) => r == null ? "none" : typeof r == "string" ? "reusable" : typeof r.getReader == "function" ? "one-shot" : "reusable", Cs = (r) => {
|
|
4405
4625
|
if (typeof r == "string")
|
|
4406
4626
|
return r.length;
|
|
4407
4627
|
const e = r;
|
|
@@ -4409,7 +4629,7 @@ const Ze = "https://passflow-relative.invalid", Xr = () => {
|
|
|
4409
4629
|
return e.size;
|
|
4410
4630
|
if (typeof e?.byteLength == "number")
|
|
4411
4631
|
return e.byteLength;
|
|
4412
|
-
},
|
|
4632
|
+
}, ee = (r, e, t) => r === void 0 || r === "always" ? !0 : r === "idempotent-only" ? _s.has(e.method) : typeof r == "function" ? r(e) : !(r.maxBodyBytes !== void 0 && t !== void 0 && t > r.maxBodyBytes), N = (r, e, t, s, i) => ({
|
|
4413
4633
|
replayable: !1,
|
|
4414
4634
|
bodyKind: r,
|
|
4415
4635
|
reason: e,
|
|
@@ -4417,12 +4637,12 @@ const Ze = "https://passflow-relative.invalid", Xr = () => {
|
|
|
4417
4637
|
forwardInit: i,
|
|
4418
4638
|
snapshot: s,
|
|
4419
4639
|
replay: () => Promise.reject(new Error(`This request cannot be replayed: ${e}`))
|
|
4420
|
-
}),
|
|
4640
|
+
}), wt = (r, e) => ht(ct(r.headers, e?.authorizationSwap)), le = (r) => {
|
|
4421
4641
|
if (!r || !("headers" in r))
|
|
4422
4642
|
return r;
|
|
4423
4643
|
const { headers: e, ...t } = r;
|
|
4424
4644
|
return t;
|
|
4425
|
-
},
|
|
4645
|
+
}, Rs = (r, e) => e && "headers" in e && e.headers !== void 0 ? e.headers : se(r) ? r.headers : void 0, Ps = (r) => {
|
|
4426
4646
|
if (r === null || typeof r == "string")
|
|
4427
4647
|
return r;
|
|
4428
4648
|
if (typeof FormData < "u" && r instanceof FormData) {
|
|
@@ -4432,12 +4652,12 @@ const Ze = "https://passflow-relative.invalid", Xr = () => {
|
|
|
4432
4652
|
return e;
|
|
4433
4653
|
}
|
|
4434
4654
|
return typeof URLSearchParams < "u" && r instanceof URLSearchParams ? new URLSearchParams(r) : r instanceof ArrayBuffer ? r.slice(0) : ArrayBuffer.isView(r) ? new Uint8Array(r.buffer, r.byteOffset, r.byteLength).slice() : r;
|
|
4435
|
-
},
|
|
4436
|
-
const s =
|
|
4437
|
-
if (
|
|
4655
|
+
}, Oe = (r, e, t) => new Request(r, { headers: wt(e, t) }), Fs = (r, e, t) => {
|
|
4656
|
+
const s = Es(r), i = Is(r, e), n = Rs(r, e), o = (d, g) => at({ url: s, method: i, headers: n, bodyKind: d, ...g === void 0 ? {} : { body: g } });
|
|
4657
|
+
if (se(r)) {
|
|
4438
4658
|
if (r.body === null || r.body === void 0) {
|
|
4439
4659
|
const v = o("none");
|
|
4440
|
-
return
|
|
4660
|
+
return ee(t, { url: s, method: i, bodyKind: "none" }) ? {
|
|
4441
4661
|
replayable: !0,
|
|
4442
4662
|
bodyKind: "none",
|
|
4443
4663
|
forwardInput: r,
|
|
@@ -4446,17 +4666,17 @@ const Ze = "https://passflow-relative.invalid", Xr = () => {
|
|
|
4446
4666
|
// The snapshot's effective header set is applied to the `Request` and
|
|
4447
4667
|
// `init.headers` is dropped, so `fetch` has only one set to choose
|
|
4448
4668
|
// from. See `replayHeaders` for why that matters.
|
|
4449
|
-
replay: (y, I) => y(
|
|
4450
|
-
} :
|
|
4669
|
+
replay: (y, I) => y(Oe(r, v, I), le(e))
|
|
4670
|
+
} : N("none", "the replay policy refused this request", r, v, e);
|
|
4451
4671
|
}
|
|
4452
4672
|
const d = o("request-clone");
|
|
4453
|
-
if (!
|
|
4454
|
-
return
|
|
4673
|
+
if (!ee(t, { url: s, method: i, bodyKind: "request-clone" }))
|
|
4674
|
+
return N("request-clone", "the replay policy refused this request", r, d, e);
|
|
4455
4675
|
let f;
|
|
4456
4676
|
try {
|
|
4457
4677
|
f = r.clone();
|
|
4458
4678
|
} catch {
|
|
4459
|
-
return
|
|
4679
|
+
return N("one-shot", "the Request body was already consumed and cannot be cloned", r, d, e);
|
|
4460
4680
|
}
|
|
4461
4681
|
return {
|
|
4462
4682
|
replayable: !0,
|
|
@@ -4464,15 +4684,15 @@ const Ze = "https://passflow-relative.invalid", Xr = () => {
|
|
|
4464
4684
|
forwardInput: r,
|
|
4465
4685
|
forwardInit: e,
|
|
4466
4686
|
snapshot: d,
|
|
4467
|
-
replay: (v,
|
|
4687
|
+
replay: (v, p) => v(Oe(f, d, p), le(e))
|
|
4468
4688
|
};
|
|
4469
4689
|
}
|
|
4470
|
-
const a =
|
|
4690
|
+
const a = As(e?.body);
|
|
4471
4691
|
if (a === "one-shot")
|
|
4472
|
-
return
|
|
4473
|
-
if (!
|
|
4474
|
-
return
|
|
4475
|
-
const
|
|
4692
|
+
return N("one-shot", "a streaming request body is consumed by the first send", r, o("one-shot"), e);
|
|
4693
|
+
if (!ee(t, { url: s, method: i, bodyKind: a }, Cs(e?.body)))
|
|
4694
|
+
return N(a, "the replay policy refused this request", r, o(a), e);
|
|
4695
|
+
const u = e && "body" in e ? Ps(e.body ?? null) : void 0, m = o(a, u);
|
|
4476
4696
|
return {
|
|
4477
4697
|
replayable: !0,
|
|
4478
4698
|
bodyKind: a,
|
|
@@ -4497,22 +4717,22 @@ const Ze = "https://passflow-relative.invalid", Xr = () => {
|
|
|
4497
4717
|
// unchanged, so an abort during the replay behaves identically to an abort
|
|
4498
4718
|
// during the original.
|
|
4499
4719
|
replay: (d, g) => d(m.dispatchUrl, {
|
|
4500
|
-
...
|
|
4501
|
-
...
|
|
4502
|
-
headers:
|
|
4720
|
+
...le(e),
|
|
4721
|
+
...u === void 0 ? {} : { body: u },
|
|
4722
|
+
headers: wt(m, g),
|
|
4503
4723
|
method: m.method
|
|
4504
4724
|
})
|
|
4505
4725
|
};
|
|
4506
|
-
},
|
|
4507
|
-
if (!
|
|
4726
|
+
}, ie = (r) => typeof r == "object" && r !== null, Ms = (r) => (e) => {
|
|
4727
|
+
if (!ie(r))
|
|
4508
4728
|
return;
|
|
4509
4729
|
const s = r[e] ?? r[e.toLowerCase()] ?? (typeof r.get == "function" ? r.get(e) : void 0);
|
|
4510
4730
|
return Array.isArray(s) ? s.join(", ") : typeof s == "string" ? s : void 0;
|
|
4511
|
-
},
|
|
4731
|
+
}, Us = (r) => {
|
|
4512
4732
|
const e = r?.url ?? "", t = r?.baseURL;
|
|
4513
4733
|
return !t || /^([a-z][a-z\d+\-.]*:)?\/\//i.test(e) ? e : `${t.replace(/\/+$/, "")}/${e.replace(/^\/+/, "")}`;
|
|
4514
|
-
},
|
|
4515
|
-
const s =
|
|
4734
|
+
}, Ds = (r) => (r?.method ?? "GET").toUpperCase(), xs = (r) => r == null ? "none" : ie(r) && (typeof r.pipe == "function" || typeof r.getReader == "function") ? "one-shot" : "reusable", Os = (r, e, t) => {
|
|
4735
|
+
const s = ht(ct(e.headers, t?.authorizationSwap)), i = e.dispatchUrl === e.href && e.resolved;
|
|
4516
4736
|
return {
|
|
4517
4737
|
...r,
|
|
4518
4738
|
...i ? { baseURL: void 0 } : {},
|
|
@@ -4521,56 +4741,56 @@ const Ze = "https://passflow-relative.invalid", Xr = () => {
|
|
|
4521
4741
|
headers: s,
|
|
4522
4742
|
..."body" in e ? { data: e.body } : {}
|
|
4523
4743
|
};
|
|
4524
|
-
},
|
|
4525
|
-
const o = e ?? r?.config, a =
|
|
4526
|
-
url:
|
|
4527
|
-
method:
|
|
4744
|
+
}, ke = (r, e, t, s, i, n) => {
|
|
4745
|
+
const o = e ?? r?.config, a = xs(o?.data), h = n ?? at({
|
|
4746
|
+
url: Us(o),
|
|
4747
|
+
method: Ds(o),
|
|
4528
4748
|
headers: o?.headers,
|
|
4529
4749
|
bodyKind: a,
|
|
4530
4750
|
body: o?.data
|
|
4531
|
-
}),
|
|
4751
|
+
}), u = { url: h.href, method: h.method, bodyKind: a }, m = a !== "one-shot" && ee(i.replay, u);
|
|
4532
4752
|
return {
|
|
4533
4753
|
status: r?.status ?? 0,
|
|
4534
|
-
getHeader:
|
|
4754
|
+
getHeader: Ms(r?.headers),
|
|
4535
4755
|
// Pre-read by axios into `data`; nothing is consumed by reading it again,
|
|
4536
4756
|
// and the core still decides whether reading it is in scope.
|
|
4537
4757
|
readBody: async () => r?.data,
|
|
4538
4758
|
request: h,
|
|
4539
4759
|
replay: async (d) => {
|
|
4540
|
-
const g =
|
|
4760
|
+
const g = er(Os(o ?? {}, h, d));
|
|
4541
4761
|
try {
|
|
4542
4762
|
const f = await s(g);
|
|
4543
|
-
return
|
|
4763
|
+
return ke(f, f?.config ?? g, f, s, i, h);
|
|
4544
4764
|
} catch (f) {
|
|
4545
|
-
const v =
|
|
4546
|
-
if (!v.response || typeof v.response.status != "number" ||
|
|
4765
|
+
const v = ie(f) ? f : {};
|
|
4766
|
+
if (!v.response || typeof v.response.status != "number" || st(f))
|
|
4547
4767
|
throw f;
|
|
4548
|
-
return { ...
|
|
4768
|
+
return { ...ke(v.response, v.config ?? g, f, s, i, h), rejected: !0 };
|
|
4549
4769
|
}
|
|
4550
4770
|
},
|
|
4551
4771
|
markers: {
|
|
4552
|
-
...
|
|
4553
|
-
...
|
|
4772
|
+
...Ze(o) ? { upgradeTransaction: !0 } : {},
|
|
4773
|
+
...tr(o) ? { replayed: !0 } : {}
|
|
4554
4774
|
},
|
|
4555
4775
|
raw: t,
|
|
4556
4776
|
replayable: m,
|
|
4557
4777
|
replayUnsupportedReason: a === "one-shot" ? "a streaming request body is consumed by the first send" : "the replay policy refused this request",
|
|
4558
4778
|
signal: o?.signal
|
|
4559
4779
|
};
|
|
4560
|
-
},
|
|
4561
|
-
const s =
|
|
4780
|
+
}, St = (r, e) => async (t) => {
|
|
4781
|
+
const s = dt(r), i = ie(t) ? t : {}, n = ke(i.response, i.config, i.response, e, s), o = await ut(n, s), a = Ts(o, t);
|
|
4562
4782
|
if (a.settle === "reject")
|
|
4563
4783
|
throw a.error;
|
|
4564
4784
|
return a.value;
|
|
4565
|
-
},
|
|
4566
|
-
const s = r.request, i = typeof s == "function" ? (a) => s.call(r, a) : () => Promise.reject(new Error("Passflow: this client exposes no request() to replay through.")), n = r.interceptors.response.use(void 0,
|
|
4785
|
+
}, Ls = (r, e, t) => {
|
|
4786
|
+
const s = r.request, i = typeof s == "function" ? (a) => s.call(r, a) : () => Promise.reject(new Error("Passflow: this client exposes no request() to replay through.")), n = r.interceptors.response.use(void 0, St(e, i));
|
|
4567
4787
|
let o = !1;
|
|
4568
4788
|
return () => {
|
|
4569
4789
|
o || (o = !0, r.interceptors.response.eject(n));
|
|
4570
4790
|
};
|
|
4571
4791
|
};
|
|
4572
|
-
let
|
|
4573
|
-
const
|
|
4792
|
+
let ue = 0;
|
|
4793
|
+
const $s = (r, e) => {
|
|
4574
4794
|
const t = e?.signal ?? (typeof r == "object" && r !== null ? r.signal : void 0) ?? void 0;
|
|
4575
4795
|
if (t)
|
|
4576
4796
|
return {
|
|
@@ -4585,9 +4805,9 @@ const As = (r, e) => {
|
|
|
4585
4805
|
removeEventListener: (s, i) => t.removeEventListener(s, i)
|
|
4586
4806
|
} : {}
|
|
4587
4807
|
};
|
|
4588
|
-
},
|
|
4808
|
+
}, qs = (r) => (e) => r.headers?.get(e), bt = (r, e, t, s, i) => ({
|
|
4589
4809
|
status: r.status,
|
|
4590
|
-
getHeader:
|
|
4810
|
+
getHeader: qs(r),
|
|
4591
4811
|
// A CLONE, always. The response the caller receives must still have an unread
|
|
4592
4812
|
// body, and the core calls this only when the scope and the channel policy
|
|
4593
4813
|
// both permit a body read.
|
|
@@ -4600,7 +4820,7 @@ const As = (r, e) => {
|
|
|
4600
4820
|
request: e.snapshot,
|
|
4601
4821
|
replay: async (n) => {
|
|
4602
4822
|
const o = await e.replay(t, n);
|
|
4603
|
-
return
|
|
4823
|
+
return bt(o, e, t, s, i);
|
|
4604
4824
|
},
|
|
4605
4825
|
markers: s,
|
|
4606
4826
|
raw: r,
|
|
@@ -4608,89 +4828,89 @@ const As = (r, e) => {
|
|
|
4608
4828
|
replayUnsupportedReason: e.reason,
|
|
4609
4829
|
signal: i,
|
|
4610
4830
|
responseType: r.type
|
|
4611
|
-
}),
|
|
4831
|
+
}), pe = (r, e) => {
|
|
4612
4832
|
const t = (s, i) => {
|
|
4613
|
-
|
|
4833
|
+
ue += 1;
|
|
4614
4834
|
try {
|
|
4615
4835
|
return r(s, i);
|
|
4616
4836
|
} finally {
|
|
4617
|
-
|
|
4837
|
+
ue -= 1;
|
|
4618
4838
|
}
|
|
4619
4839
|
};
|
|
4620
4840
|
return async (s, i) => {
|
|
4621
|
-
if (
|
|
4841
|
+
if (ue > 0)
|
|
4622
4842
|
return t(s, i);
|
|
4623
|
-
const n =
|
|
4843
|
+
const n = dt(e), o = Fs(s, i, n.replay), a = await t(o.forwardInput, o.forwardInit), h = bt(a, o, t, {}, $s(s, i)), u = await ut(h, n), m = bs(u, a, n);
|
|
4624
4844
|
if (m.settle === "reject")
|
|
4625
4845
|
throw m.error;
|
|
4626
4846
|
return m.value;
|
|
4627
4847
|
};
|
|
4628
|
-
},
|
|
4848
|
+
}, Ns = (r, e) => {
|
|
4629
4849
|
const t = B.create(r);
|
|
4630
4850
|
return e(t), t;
|
|
4631
|
-
},
|
|
4632
|
-
class
|
|
4851
|
+
}, ui = 10, Vs = 20;
|
|
4852
|
+
class Ks extends Error {
|
|
4633
4853
|
constructor(e) {
|
|
4634
4854
|
super(
|
|
4635
4855
|
`Passflow fetch middleware '${e}' resolved without calling next(). Every registered middleware must delegate exactly once; swallowing a request would drop a caller's fetch inside the Passflow wrapper.`
|
|
4636
4856
|
), this.name = "FetchMiddlewareContractError", this.middlewareName = e;
|
|
4637
4857
|
}
|
|
4638
4858
|
}
|
|
4639
|
-
let
|
|
4640
|
-
const
|
|
4859
|
+
let O = [], Bs = 0, z = !1, K, $;
|
|
4860
|
+
const Tt = (r, e) => r.priority - e.priority || r.seq - e.seq, _e = () => typeof globalThis > "u" ? void 0 : globalThis, we = async (r, e, t, s) => {
|
|
4641
4861
|
if (e >= r.length) {
|
|
4642
|
-
const h =
|
|
4862
|
+
const h = K;
|
|
4643
4863
|
if (!h)
|
|
4644
4864
|
throw new Error("Passflow fetch registry: no captured fetch to delegate to.");
|
|
4645
4865
|
return h(t, s);
|
|
4646
4866
|
}
|
|
4647
4867
|
const i = r[e];
|
|
4648
4868
|
if (!i)
|
|
4649
|
-
return
|
|
4869
|
+
return we(r, r.length, t, s);
|
|
4650
4870
|
let n = !1;
|
|
4651
|
-
const o = (h,
|
|
4871
|
+
const o = (h, u) => (n = !0, we(r, e + 1, h, u)), a = await i.middleware(o, t, s);
|
|
4652
4872
|
if (!n)
|
|
4653
|
-
throw new
|
|
4873
|
+
throw new Ks(i.name);
|
|
4654
4874
|
return a;
|
|
4655
|
-
},
|
|
4656
|
-
const r =
|
|
4875
|
+
}, Gs = () => {
|
|
4876
|
+
const r = _e();
|
|
4657
4877
|
if (!r || typeof r.fetch != "function")
|
|
4658
4878
|
return !1;
|
|
4659
|
-
const e = r.fetch.bind(r), t = (s, i) =>
|
|
4660
|
-
return
|
|
4661
|
-
},
|
|
4662
|
-
const r =
|
|
4663
|
-
!r ||
|
|
4664
|
-
},
|
|
4665
|
-
if (!
|
|
4879
|
+
const e = r.fetch.bind(r), t = (s, i) => we([...O].sort(Tt), 0, s, i);
|
|
4880
|
+
return K = e, $ = t, r.fetch = t, z = !0, !0;
|
|
4881
|
+
}, js = () => {
|
|
4882
|
+
const r = _e();
|
|
4883
|
+
!r || !$ || r.fetch === $ && (K && (r.fetch = K), z = !1, $ = void 0, K = void 0);
|
|
4884
|
+
}, Hs = (r, e) => {
|
|
4885
|
+
if (!z && !Gs())
|
|
4666
4886
|
return () => {
|
|
4667
4887
|
};
|
|
4668
4888
|
const t = {
|
|
4669
4889
|
middleware: r,
|
|
4670
4890
|
name: e.name,
|
|
4671
4891
|
priority: e.priority,
|
|
4672
|
-
seq:
|
|
4892
|
+
seq: Bs++
|
|
4673
4893
|
};
|
|
4674
|
-
|
|
4894
|
+
O.push(t);
|
|
4675
4895
|
let s = !1;
|
|
4676
4896
|
return () => {
|
|
4677
|
-
s || (s = !0,
|
|
4897
|
+
s || (s = !0, O = O.filter((i) => i !== t), O.length === 0 && js());
|
|
4678
4898
|
};
|
|
4679
|
-
},
|
|
4680
|
-
const r =
|
|
4899
|
+
}, pi = () => {
|
|
4900
|
+
const r = _e();
|
|
4681
4901
|
return {
|
|
4682
|
-
installed:
|
|
4683
|
-
names: [...
|
|
4684
|
-
foreignPatch:
|
|
4902
|
+
installed: z,
|
|
4903
|
+
names: [...O].sort(Tt).map((e) => e.name),
|
|
4904
|
+
foreignPatch: z && !!r && !!$ && r.fetch !== $
|
|
4685
4905
|
};
|
|
4686
|
-
},
|
|
4906
|
+
}, zs = (r) => r === void 0 ? [] : (Array.isArray(r) ? r : [r]).filter((e) => e !== ""), Ys = (r) => {
|
|
4687
4907
|
let e;
|
|
4688
4908
|
const t = (d) => d !== void 0 && e === d, s = (d) => {
|
|
4689
4909
|
const g = () => {
|
|
4690
4910
|
if (!t(d()))
|
|
4691
4911
|
throw new _({ kind: "session_changed" });
|
|
4692
4912
|
};
|
|
4693
|
-
return
|
|
4913
|
+
return ls({
|
|
4694
4914
|
...r,
|
|
4695
4915
|
relyingPartyId: () => e?.options.relyingPartyId ?? r.relyingPartyId?.(),
|
|
4696
4916
|
startUpgrade: (f) => (g(), r.startUpgrade(f)),
|
|
@@ -4702,8 +4922,8 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
4702
4922
|
} : {}
|
|
4703
4923
|
});
|
|
4704
4924
|
}, i = (d, g) => {
|
|
4705
|
-
const f = {},
|
|
4706
|
-
controller: new
|
|
4925
|
+
const f = {}, p = {
|
|
4926
|
+
controller: new os({
|
|
4707
4927
|
transport: s(() => f.current),
|
|
4708
4928
|
prompt: d.prompt,
|
|
4709
4929
|
platform: r.platform,
|
|
@@ -4713,10 +4933,10 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
4713
4933
|
...d.onFlightSettled ? { onFlightSettled: d.onFlightSettled } : {}
|
|
4714
4934
|
}),
|
|
4715
4935
|
options: d,
|
|
4716
|
-
scope: { passflow: r.passflowDomain, backend:
|
|
4936
|
+
scope: { passflow: r.passflowDomain, backend: zs(d.backend) },
|
|
4717
4937
|
generation: g
|
|
4718
4938
|
};
|
|
4719
|
-
return f.current =
|
|
4939
|
+
return f.current = p, p;
|
|
4720
4940
|
}, n = async (d, g) => {
|
|
4721
4941
|
const f = e;
|
|
4722
4942
|
if (!f)
|
|
@@ -4724,7 +4944,7 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
4724
4944
|
f.controller.active || (f.pin = r.readSessionPin?.());
|
|
4725
4945
|
const v = await f.controller.elevate(d, g);
|
|
4726
4946
|
if (!t(f))
|
|
4727
|
-
throw new
|
|
4947
|
+
throw new q();
|
|
4728
4948
|
return v;
|
|
4729
4949
|
}, o = () => {
|
|
4730
4950
|
const d = e, g = d?.scope ?? { passflow: r.passflowDomain, backend: [] }, f = d?.options;
|
|
@@ -4742,16 +4962,16 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
4742
4962
|
};
|
|
4743
4963
|
let a;
|
|
4744
4964
|
return Object.defineProperties(async (d) => {
|
|
4745
|
-
const g = d?.acrValues === void 0 ? void 0 :
|
|
4965
|
+
const g = d?.acrValues === void 0 ? void 0 : re(d.acrValues).level, f = {
|
|
4746
4966
|
status: 401,
|
|
4747
4967
|
...d?.acrValues === void 0 ? {} : { acrValues: d.acrValues },
|
|
4748
4968
|
...g === void 0 ? {} : { requiredLevel: g },
|
|
4749
4969
|
...d?.maxAge === void 0 ? {} : { maxAge: d.maxAge }
|
|
4750
|
-
}, v = d?.acrValues !== void 0 || d?.maxAge !== void 0,
|
|
4970
|
+
}, v = d?.acrValues !== void 0 || d?.maxAge !== void 0, p = {
|
|
4751
4971
|
...d?.acrValues === void 0 ? {} : { acrValues: d.acrValues },
|
|
4752
4972
|
...g === void 0 ? {} : { level: g },
|
|
4753
4973
|
...d?.maxAge === void 0 ? {} : { maxAge: d.maxAge }
|
|
4754
|
-
}, I = (await n(f, { kind: "imperative", ...v ? { requested:
|
|
4974
|
+
}, I = (await n(f, { kind: "imperative", ...v ? { requested: p } : {} })).obtained.acrValues;
|
|
4755
4975
|
return { status: "elevated", ...I === void 0 ? {} : { acr: I } };
|
|
4756
4976
|
}, {
|
|
4757
4977
|
enable: { value: (d) => {
|
|
@@ -4759,11 +4979,11 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
4759
4979
|
const g = [];
|
|
4760
4980
|
if (r.attachInternalSeam) {
|
|
4761
4981
|
const v = r.attachInternalSeam;
|
|
4762
|
-
v((
|
|
4982
|
+
v((p) => St(o, p)), g.push(() => v(void 0));
|
|
4763
4983
|
}
|
|
4764
4984
|
d.interceptFetch && g.push(
|
|
4765
|
-
|
|
4766
|
-
priority:
|
|
4985
|
+
Hs((v, p, y) => pe(v, o)(p, y), {
|
|
4986
|
+
priority: Vs,
|
|
4767
4987
|
name: "passflow-upgrade"
|
|
4768
4988
|
})
|
|
4769
4989
|
), r.onSessionChange && g.push(
|
|
@@ -4796,19 +5016,19 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
4796
5016
|
enumerable: !0,
|
|
4797
5017
|
value: (d) => {
|
|
4798
5018
|
if (d)
|
|
4799
|
-
return
|
|
5019
|
+
return pe(d, o);
|
|
4800
5020
|
const g = typeof globalThis > "u" ? void 0 : globalThis;
|
|
4801
5021
|
if (!g || typeof g.fetch != "function")
|
|
4802
5022
|
throw new Error("Passflow: withAuth() needs a fetch to wrap — this runtime has none.");
|
|
4803
|
-
return
|
|
5023
|
+
return pe(g.fetch.bind(g), o);
|
|
4804
5024
|
}
|
|
4805
5025
|
},
|
|
4806
5026
|
attachAuth: {
|
|
4807
5027
|
enumerable: !0,
|
|
4808
|
-
value: (d) =>
|
|
5028
|
+
value: (d) => Ls(d, o)
|
|
4809
5029
|
}
|
|
4810
5030
|
});
|
|
4811
|
-
},
|
|
5031
|
+
}, Ee = class Ee {
|
|
4812
5032
|
constructor(e) {
|
|
4813
5033
|
this.doRefreshTokens = !1, this.session = async ({
|
|
4814
5034
|
createSession: n,
|
|
@@ -4818,10 +5038,10 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
4818
5038
|
this.createSessionCallback = n, this.expiredSessionCallback = o, this.doRefreshTokens = a, await this.submitSessionCheck();
|
|
4819
5039
|
};
|
|
4820
5040
|
const { url: t, appId: s, scopes: i } = e;
|
|
4821
|
-
this.url = t ||
|
|
5041
|
+
this.url = t || qe, this.appId = s, this.platform = e.platform ?? Y, this.storageManager = new Se({
|
|
4822
5042
|
prefix: e.keyStoragePrefix ?? "",
|
|
4823
5043
|
storage: this.platform.storage
|
|
4824
|
-
}), this.deviceService = new
|
|
5044
|
+
}), this.deviceService = new Be(this.storageManager), this.authApi = new dr(e, this.storageManager, this.deviceService), this.appApi = new hr(e, this.storageManager, this.deviceService), this.userApi = new vr(e, this.storageManager, this.deviceService), this.settingApi = new ur(e, this.storageManager, this.deviceService), this.tenantApi = new pr(e, this.storageManager, this.deviceService), this.invitationApi = new lr(e, this.storageManager, this.deviceService), this.twoFactorApi = new fr(e, this.storageManager, this.deviceService), this.upgradeApi = new gr(e, this.storageManager, this.deviceService), this.upgradeDomain = Qe(e.url), this.subscribeStore = new wr(), this.tokenCacheService = new Br(this.storageManager, this.authApi, this.subscribeStore, this.platform), this.scopes = i ?? Mt, this.createTenantForNewUser = e.createTenantForNewUser ?? !1, this.authService = new qr(
|
|
4825
5045
|
this.authApi,
|
|
4826
5046
|
this.deviceService,
|
|
4827
5047
|
this.storageManager,
|
|
@@ -4836,8 +5056,9 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
4836
5056
|
},
|
|
4837
5057
|
this.appId ?? "",
|
|
4838
5058
|
e.tokenExchange,
|
|
4839
|
-
this.platform
|
|
4840
|
-
|
|
5059
|
+
this.platform,
|
|
5060
|
+
() => this.readPkceEnabled()
|
|
5061
|
+
), this.userService = new jr(this.userApi, this.deviceService, this.platform), this.tenantService = new Kr(this.tenantApi, this.scopes), this.tenant = this.tenantService, this.invitationService = new Nr(this.invitationApi), this.twoFactorService = new Gr(this.twoFactorApi, this.subscribeStore, this.authService), this.twoFactor = this.twoFactorService, this.upgrade = Ys({
|
|
4841
5062
|
// The prepare round. The commit round is `/auth/refresh`, which must go
|
|
4842
5063
|
// through AuthService: it is the only path that STORES the rotated tokens,
|
|
4843
5064
|
// so posting directly would elevate the session on the server and leave
|
|
@@ -4872,6 +5093,22 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
4872
5093
|
get origin() {
|
|
4873
5094
|
return this.platform.getCurrentUrl()?.origin ?? "";
|
|
4874
5095
|
}
|
|
5096
|
+
/**
|
|
5097
|
+
* Whether the current app wants PKCE. A sign-in asks before a passkey ceremony,
|
|
5098
|
+
* where a round-trip eats into the browser's user-gesture window, so the answer
|
|
5099
|
+
* is kept for the appId. A failed read is not kept: the next sign-in asks again.
|
|
5100
|
+
*/
|
|
5101
|
+
readPkceEnabled() {
|
|
5102
|
+
if (!this.appId)
|
|
5103
|
+
return Promise.resolve(!1);
|
|
5104
|
+
if (!this.pkceEnabledRead) {
|
|
5105
|
+
const e = this.appApi.getAppSettings().then((t) => t.pkce_enabled);
|
|
5106
|
+
this.pkceEnabledRead = e, e.catch(() => {
|
|
5107
|
+
this.pkceEnabledRead === e && (this.pkceEnabledRead = void 0);
|
|
5108
|
+
});
|
|
5109
|
+
}
|
|
5110
|
+
return this.pkceEnabledRead;
|
|
5111
|
+
}
|
|
4875
5112
|
/**
|
|
4876
5113
|
* Update the appId and propagate it to all API clients.
|
|
4877
5114
|
* This ensures that all future API requests use the new appId in their headers.
|
|
@@ -4885,7 +5122,7 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
4885
5122
|
* ```
|
|
4886
5123
|
*/
|
|
4887
5124
|
setAppId(e) {
|
|
4888
|
-
this.appId = e, this.authApi.setAppId(e), this.appApi.setAppId(e), this.userApi.setAppId(e), this.settingApi.setAppId(e), this.tenantApi.setAppId(e), this.invitationApi.setAppId(e), this.twoFactorApi.setAppId(e), this.upgradeApi.setAppId(e), this.authService;
|
|
5125
|
+
this.appId = e, this.pkceEnabledRead = void 0, this.authApi.setAppId(e), this.appApi.setAppId(e), this.userApi.setAppId(e), this.settingApi.setAppId(e), this.tenantApi.setAppId(e), this.invitationApi.setAppId(e), this.twoFactorApi.setAppId(e), this.upgradeApi.setAppId(e), this.authService;
|
|
4889
5126
|
}
|
|
4890
5127
|
/**
|
|
4891
5128
|
* Wraps a `fetch`, returning a new function with step-up handling attached.
|
|
@@ -4945,7 +5182,7 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
4945
5182
|
* ```
|
|
4946
5183
|
*/
|
|
4947
5184
|
createClient(e) {
|
|
4948
|
-
return
|
|
5185
|
+
return Ns(e, (t) => this.upgrade.attachAuth(t));
|
|
4949
5186
|
}
|
|
4950
5187
|
/**
|
|
4951
5188
|
* The assurance bar the session currently holds, read from the `acr` claim of
|
|
@@ -4962,7 +5199,7 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
4962
5199
|
const t = T(e), s = typeof t.acr == "string" ? t.acr : void 0;
|
|
4963
5200
|
if (!s)
|
|
4964
5201
|
return;
|
|
4965
|
-
const i =
|
|
5202
|
+
const i = re(s).level;
|
|
4966
5203
|
return i === void 0 ? { acrValues: s } : { acrValues: s, level: i };
|
|
4967
5204
|
} catch {
|
|
4968
5205
|
return;
|
|
@@ -5101,34 +5338,38 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
5101
5338
|
const e = this.platform.getCurrentUrl();
|
|
5102
5339
|
let t = new URLSearchParams(e?.search ?? ""), s = !1;
|
|
5103
5340
|
if (!t.get("access_token") && e?.hash) {
|
|
5104
|
-
const
|
|
5105
|
-
|
|
5341
|
+
const u = new URLSearchParams(e.hash.substring(1));
|
|
5342
|
+
u.get("access_token") && (t = u, s = !0);
|
|
5343
|
+
}
|
|
5344
|
+
if (!t.get("access_token") && this.adoptTwoFactorTokenFromUrl(e)) {
|
|
5345
|
+
this.error = void 0;
|
|
5346
|
+
return;
|
|
5106
5347
|
}
|
|
5107
5348
|
const i = t.get("access_token"), n = t.get("refresh_token"), o = t.get("id_token"), a = t.get("scopes")?.split(",") ?? this.scopes;
|
|
5108
5349
|
let h;
|
|
5109
5350
|
if (i) {
|
|
5110
|
-
if (!
|
|
5111
|
-
const
|
|
5351
|
+
if (!J(i)) {
|
|
5352
|
+
const u = {
|
|
5112
5353
|
message: "Invalid access token format received",
|
|
5113
5354
|
code: "INVALID_TOKEN_FORMAT"
|
|
5114
5355
|
};
|
|
5115
|
-
this.subscribeStore.notify(c.Error,
|
|
5356
|
+
this.subscribeStore.notify(c.Error, u), this.cleanupUrlParams(s, e);
|
|
5116
5357
|
return;
|
|
5117
5358
|
}
|
|
5118
|
-
if (n && !
|
|
5119
|
-
const
|
|
5359
|
+
if (n && !J(n)) {
|
|
5360
|
+
const u = {
|
|
5120
5361
|
message: "Invalid refresh token format received",
|
|
5121
5362
|
code: "INVALID_TOKEN_FORMAT"
|
|
5122
5363
|
};
|
|
5123
|
-
this.subscribeStore.notify(c.Error,
|
|
5364
|
+
this.subscribeStore.notify(c.Error, u), this.cleanupUrlParams(s, e);
|
|
5124
5365
|
return;
|
|
5125
5366
|
}
|
|
5126
|
-
if (o && !
|
|
5127
|
-
const
|
|
5367
|
+
if (o && !J(o)) {
|
|
5368
|
+
const u = {
|
|
5128
5369
|
message: "Invalid ID token format received",
|
|
5129
5370
|
code: "INVALID_TOKEN_FORMAT"
|
|
5130
5371
|
};
|
|
5131
|
-
this.subscribeStore.notify(c.Error,
|
|
5372
|
+
this.subscribeStore.notify(c.Error, u), this.cleanupUrlParams(s, e);
|
|
5132
5373
|
return;
|
|
5133
5374
|
}
|
|
5134
5375
|
return h = {
|
|
@@ -5140,10 +5381,32 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
5140
5381
|
} else
|
|
5141
5382
|
this.error = this.checkErrorsFromURL();
|
|
5142
5383
|
}
|
|
5384
|
+
/**
|
|
5385
|
+
* Adopts a `#tfa_token=` fragment: the 2FA token goes to the TwoFactorService
|
|
5386
|
+
* through `TwoFactorRequired`, exactly as a password sign-in's does, and the
|
|
5387
|
+
* fragment is stripped from the URL. Nothing is saved as a session.
|
|
5388
|
+
*
|
|
5389
|
+
* @returns true when the URL carried a 2FA token
|
|
5390
|
+
*/
|
|
5391
|
+
adoptTwoFactorTokenFromUrl(e) {
|
|
5392
|
+
if (!e?.hash) return !1;
|
|
5393
|
+
const t = new URLSearchParams(e.hash.substring(1)), s = t.get("tfa_token");
|
|
5394
|
+
if (!s) return !1;
|
|
5395
|
+
t.delete("tfa_token");
|
|
5396
|
+
const i = t.toString();
|
|
5397
|
+
if (this.platform.replaceUrl(e.pathname + e.search + (i ? `#${i}` : "")), !J(s)) {
|
|
5398
|
+
const n = {
|
|
5399
|
+
message: "Invalid 2FA token format received",
|
|
5400
|
+
code: "INVALID_TOKEN_FORMAT"
|
|
5401
|
+
};
|
|
5402
|
+
return this.subscribeStore.notify(c.Error, n), !0;
|
|
5403
|
+
}
|
|
5404
|
+
return this.subscribeStore.notify(c.TwoFactorRequired, { email: "", challengeId: "", tfaToken: s }), !0;
|
|
5405
|
+
}
|
|
5143
5406
|
checkErrorsFromURL() {
|
|
5144
5407
|
const t = new URLSearchParams(this.platform.getCurrentUrl()?.search ?? "").get("error");
|
|
5145
5408
|
if (t) {
|
|
5146
|
-
const s =
|
|
5409
|
+
const s = Dr(t);
|
|
5147
5410
|
return new Error(s);
|
|
5148
5411
|
}
|
|
5149
5412
|
}
|
|
@@ -5846,7 +6109,7 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
5846
6109
|
async joinInvitation(e, t) {
|
|
5847
6110
|
try {
|
|
5848
6111
|
const s = await this.tenant.joinInvitation(e, t);
|
|
5849
|
-
return s.scopes = t ?? this.scopes,
|
|
6112
|
+
return s.scopes = t ?? this.scopes, await this.authService.applyTokens(s), s;
|
|
5850
6113
|
} catch (s) {
|
|
5851
6114
|
this.handleError(s, "Join invitation");
|
|
5852
6115
|
}
|
|
@@ -6123,6 +6386,8 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
6123
6386
|
* Completes the authentication process and saves tokens.
|
|
6124
6387
|
*
|
|
6125
6388
|
* @param code - 6-digit TOTP code from authenticator app
|
|
6389
|
+
* @param options - `trustDevice: true` asks the server to trust this device,
|
|
6390
|
+
* so later sign-ins from it skip the second factor where the app allows it
|
|
6126
6391
|
* @returns Promise with verification response containing tokens
|
|
6127
6392
|
* @throws {PassflowError} If verification fails
|
|
6128
6393
|
*
|
|
@@ -6130,20 +6395,20 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
6130
6395
|
* ```typescript
|
|
6131
6396
|
* // After signIn returns requires_2fa: true
|
|
6132
6397
|
* if (passflow.isTwoFactorVerificationRequired()) {
|
|
6133
|
-
* const response = await passflow.verifyTwoFactor('123456');
|
|
6398
|
+
* const response = await passflow.verifyTwoFactor('123456', { trustDevice: true });
|
|
6134
6399
|
* console.log('Authentication complete', response.access_token);
|
|
6135
6400
|
* }
|
|
6136
6401
|
* ```
|
|
6137
6402
|
*/
|
|
6138
|
-
async verifyTwoFactor(e) {
|
|
6403
|
+
async verifyTwoFactor(e, t) {
|
|
6139
6404
|
try {
|
|
6140
|
-
const
|
|
6141
|
-
return this.
|
|
6142
|
-
tokens:
|
|
6405
|
+
const s = await this.twoFactorService.verify(e, t);
|
|
6406
|
+
return this.subscribeStore.notify(c.SignIn, {
|
|
6407
|
+
tokens: s,
|
|
6143
6408
|
parsedTokens: this.tokenCacheService.getParsedTokens()
|
|
6144
|
-
}), await this.submitSessionCheck(),
|
|
6145
|
-
} catch (
|
|
6146
|
-
this.handleError(
|
|
6409
|
+
}), await this.submitSessionCheck(), s;
|
|
6410
|
+
} catch (s) {
|
|
6411
|
+
this.handleError(s, "Verify 2FA");
|
|
6147
6412
|
}
|
|
6148
6413
|
}
|
|
6149
6414
|
/**
|
|
@@ -6151,6 +6416,7 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
6151
6416
|
* Completes the authentication process and saves tokens.
|
|
6152
6417
|
*
|
|
6153
6418
|
* @param code - Recovery code from the list provided during setup
|
|
6419
|
+
* @param options - `trustDevice: true` asks the server to trust this device
|
|
6154
6420
|
* @returns Promise with recovery response containing tokens and remaining codes count
|
|
6155
6421
|
* @throws {PassflowError} If recovery code is invalid
|
|
6156
6422
|
*
|
|
@@ -6162,15 +6428,15 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
6162
6428
|
* console.log(`${result.remaining_recovery_codes} recovery codes remaining`);
|
|
6163
6429
|
* ```
|
|
6164
6430
|
*/
|
|
6165
|
-
async useTwoFactorRecoveryCode(e) {
|
|
6431
|
+
async useTwoFactorRecoveryCode(e, t) {
|
|
6166
6432
|
try {
|
|
6167
|
-
const
|
|
6168
|
-
return this.
|
|
6169
|
-
tokens:
|
|
6433
|
+
const s = await this.twoFactorService.useRecoveryCode(e, t);
|
|
6434
|
+
return this.subscribeStore.notify(c.SignIn, {
|
|
6435
|
+
tokens: s,
|
|
6170
6436
|
parsedTokens: this.tokenCacheService.getParsedTokens()
|
|
6171
|
-
}), await this.submitSessionCheck(),
|
|
6172
|
-
} catch (
|
|
6173
|
-
this.handleError(
|
|
6437
|
+
}), await this.submitSessionCheck(), s;
|
|
6438
|
+
} catch (s) {
|
|
6439
|
+
this.handleError(s, "Use 2FA recovery code");
|
|
6174
6440
|
}
|
|
6175
6441
|
}
|
|
6176
6442
|
/**
|
|
@@ -6216,6 +6482,45 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
6216
6482
|
this.handleError(t, "Regenerate 2FA recovery codes");
|
|
6217
6483
|
}
|
|
6218
6484
|
}
|
|
6485
|
+
/**
|
|
6486
|
+
* List the devices the signed-in user trusted to skip the second factor on
|
|
6487
|
+
* this app. The device making the request has `current: true`.
|
|
6488
|
+
*
|
|
6489
|
+
* @returns Promise with the trusted devices
|
|
6490
|
+
* @throws {PassflowError} If the request fails
|
|
6491
|
+
*
|
|
6492
|
+
* @example
|
|
6493
|
+
* ```typescript
|
|
6494
|
+
* const devices = await passflow.getTrustedDevices();
|
|
6495
|
+
* devices.forEach((d) => console.log(d.user_agent, d.current ? '(this device)' : ''));
|
|
6496
|
+
* ```
|
|
6497
|
+
*/
|
|
6498
|
+
async getTrustedDevices() {
|
|
6499
|
+
try {
|
|
6500
|
+
return await this.twoFactorService.getTrustedDevices();
|
|
6501
|
+
} catch (e) {
|
|
6502
|
+
this.handleError(e, "Get trusted devices");
|
|
6503
|
+
}
|
|
6504
|
+
}
|
|
6505
|
+
/**
|
|
6506
|
+
* Revoke one of the signed-in user's trusted devices. Its next sign-in
|
|
6507
|
+
* asks for the second factor again.
|
|
6508
|
+
*
|
|
6509
|
+
* @param id - The trusted device's `id` from `getTrustedDevices()`
|
|
6510
|
+
* @throws {PassflowError} If the request fails, including a 404 for an unknown id
|
|
6511
|
+
*
|
|
6512
|
+
* @example
|
|
6513
|
+
* ```typescript
|
|
6514
|
+
* await passflow.revokeTrustedDevice(device.id);
|
|
6515
|
+
* ```
|
|
6516
|
+
*/
|
|
6517
|
+
async revokeTrustedDevice(e) {
|
|
6518
|
+
try {
|
|
6519
|
+
await this.twoFactorService.revokeTrustedDevice(e);
|
|
6520
|
+
} catch (t) {
|
|
6521
|
+
this.handleError(t, "Revoke trusted device");
|
|
6522
|
+
}
|
|
6523
|
+
}
|
|
6219
6524
|
/**
|
|
6220
6525
|
* Check if 2FA verification is currently required (local state check).
|
|
6221
6526
|
* Returns true if user has signed in but needs to complete 2FA verification.
|
|
@@ -6327,8 +6632,8 @@ const gt = (r, e) => r.priority - e.priority || r.seq - e.seq, ke = () => typeof
|
|
|
6327
6632
|
this.twoFactorService.clearMagicLinkSession();
|
|
6328
6633
|
}
|
|
6329
6634
|
};
|
|
6330
|
-
|
|
6331
|
-
let
|
|
6635
|
+
Ee.version = Ft;
|
|
6636
|
+
let Le = Ee;
|
|
6332
6637
|
class S extends Error {
|
|
6333
6638
|
constructor(e) {
|
|
6334
6639
|
super(e.message), this.name = "M2MError", this.code = e.code, this.status = e.status ?? 400, this.errorUri = e.errorUri, this.rateLimitInfo = e.rateLimitInfo, this.headers = e.headers, this.cause = e.cause, this.timestamp = (/* @__PURE__ */ new Date()).toISOString(), Error.captureStackTrace && Error.captureStackTrace(this, S);
|
|
@@ -6424,7 +6729,7 @@ class S extends Error {
|
|
|
6424
6729
|
return this.status && (e += ` (HTTP ${this.status})`), e;
|
|
6425
6730
|
}
|
|
6426
6731
|
}
|
|
6427
|
-
class
|
|
6732
|
+
class $e extends S {
|
|
6428
6733
|
constructor(e, t) {
|
|
6429
6734
|
super({
|
|
6430
6735
|
code: "temporarily_unavailable",
|
|
@@ -6434,7 +6739,7 @@ class Ue extends S {
|
|
|
6434
6739
|
}), this.name = "M2MNetworkError";
|
|
6435
6740
|
}
|
|
6436
6741
|
}
|
|
6437
|
-
class
|
|
6742
|
+
class Q extends S {
|
|
6438
6743
|
constructor(e, t) {
|
|
6439
6744
|
super({
|
|
6440
6745
|
code: "invalid_request",
|
|
@@ -6444,7 +6749,7 @@ class X extends S {
|
|
|
6444
6749
|
}), this.name = "M2MTokenParseError";
|
|
6445
6750
|
}
|
|
6446
6751
|
}
|
|
6447
|
-
class
|
|
6752
|
+
class fe extends S {
|
|
6448
6753
|
constructor(e) {
|
|
6449
6754
|
super({
|
|
6450
6755
|
code: "invalid_request",
|
|
@@ -6453,7 +6758,7 @@ class de extends S {
|
|
|
6453
6758
|
}), this.name = "M2MConfigError";
|
|
6454
6759
|
}
|
|
6455
6760
|
}
|
|
6456
|
-
const
|
|
6761
|
+
const fi = {
|
|
6457
6762
|
InvalidRequest: "invalid_request",
|
|
6458
6763
|
InvalidClient: "invalid_client",
|
|
6459
6764
|
InvalidGrant: "invalid_grant",
|
|
@@ -6477,7 +6782,7 @@ const si = {
|
|
|
6477
6782
|
/** Content-Type for token requests */
|
|
6478
6783
|
CONTENT_TYPE: "application/x-www-form-urlencoded"
|
|
6479
6784
|
};
|
|
6480
|
-
class
|
|
6785
|
+
class Ws {
|
|
6481
6786
|
constructor() {
|
|
6482
6787
|
this.cache = /* @__PURE__ */ new Map();
|
|
6483
6788
|
}
|
|
@@ -6495,7 +6800,7 @@ class $s {
|
|
|
6495
6800
|
return this.cache.delete(e), Promise.resolve();
|
|
6496
6801
|
}
|
|
6497
6802
|
}
|
|
6498
|
-
const
|
|
6803
|
+
const Xs = {
|
|
6499
6804
|
shouldRetry(r, e) {
|
|
6500
6805
|
return e >= 3 ? !1 : r.code === "server_error" || r.code === "temporarily_unavailable" || r.code === "rate_limit_exceeded" || r.status !== void 0 && r.status >= 500;
|
|
6501
6806
|
},
|
|
@@ -6503,7 +6808,7 @@ const qs = {
|
|
|
6503
6808
|
return Math.pow(2, r - 1) * 1e3;
|
|
6504
6809
|
}
|
|
6505
6810
|
};
|
|
6506
|
-
class
|
|
6811
|
+
class gi {
|
|
6507
6812
|
/**
|
|
6508
6813
|
* Create a new M2M client
|
|
6509
6814
|
*
|
|
@@ -6521,11 +6826,11 @@ class ii {
|
|
|
6521
6826
|
*/
|
|
6522
6827
|
constructor(e) {
|
|
6523
6828
|
if (!e.url)
|
|
6524
|
-
throw new
|
|
6829
|
+
throw new fe("M2M client requires a URL");
|
|
6525
6830
|
if (!e.clientId)
|
|
6526
|
-
throw new
|
|
6831
|
+
throw new fe("M2M client requires a clientId");
|
|
6527
6832
|
if (!e.clientSecret)
|
|
6528
|
-
throw new
|
|
6833
|
+
throw new fe("M2M client requires a clientSecret");
|
|
6529
6834
|
const t = e.url.replace(/\/$/, "");
|
|
6530
6835
|
this.config = {
|
|
6531
6836
|
url: t,
|
|
@@ -6543,7 +6848,7 @@ class ii {
|
|
|
6543
6848
|
onTokenRequest: e.onTokenRequest,
|
|
6544
6849
|
onTokenResponse: e.onTokenResponse,
|
|
6545
6850
|
onError: e.onError
|
|
6546
|
-
}, this.cache = e.cache ?? new
|
|
6851
|
+
}, this.cache = e.cache ?? new Ws(), this.retryStrategy = e.retryStrategy ?? Xs, this.tokenEndpoint = `${t}${R.TOKEN_ENDPOINT}`;
|
|
6547
6852
|
}
|
|
6548
6853
|
/**
|
|
6549
6854
|
* Get the cache key for this client
|
|
@@ -6642,8 +6947,8 @@ class ii {
|
|
|
6642
6947
|
});
|
|
6643
6948
|
clearTimeout(i);
|
|
6644
6949
|
const o = {};
|
|
6645
|
-
n.headers.forEach((h,
|
|
6646
|
-
o[
|
|
6950
|
+
n.headers.forEach((h, u) => {
|
|
6951
|
+
o[u.toLowerCase()] = h;
|
|
6647
6952
|
});
|
|
6648
6953
|
const a = await n.json();
|
|
6649
6954
|
if (!n.ok) {
|
|
@@ -6663,7 +6968,7 @@ class ii {
|
|
|
6663
6968
|
}
|
|
6664
6969
|
return a;
|
|
6665
6970
|
} catch (n) {
|
|
6666
|
-
throw clearTimeout(i), n instanceof Error && n.name === "AbortError" ? new
|
|
6971
|
+
throw clearTimeout(i), n instanceof Error && n.name === "AbortError" ? new $e(`Request timed out after ${this.config.timeout}ms`) : n instanceof TypeError && n.message.includes("fetch") ? new $e(`Network error: ${n.message}`, n) : n instanceof S ? n : S.fromError(n instanceof Error ? n : new Error(String(n)));
|
|
6667
6972
|
}
|
|
6668
6973
|
}
|
|
6669
6974
|
/**
|
|
@@ -6758,14 +7063,14 @@ class ii {
|
|
|
6758
7063
|
try {
|
|
6759
7064
|
const t = e.split(".");
|
|
6760
7065
|
if (t.length !== 3)
|
|
6761
|
-
throw new
|
|
7066
|
+
throw new Q("Invalid JWT format: expected 3 parts");
|
|
6762
7067
|
const s = t[1];
|
|
6763
7068
|
if (!s)
|
|
6764
|
-
throw new
|
|
7069
|
+
throw new Q("Invalid JWT format: missing payload");
|
|
6765
7070
|
const i = atob(s.replace(/-/g, "+").replace(/_/g, "/")), n = JSON.parse(i);
|
|
6766
7071
|
return n.scopes && typeof n.scopes == "string" ? n.scopes = n.scopes.split(" ") : n.scopes || (n.scopes = []), n;
|
|
6767
7072
|
} catch (t) {
|
|
6768
|
-
throw t instanceof
|
|
7073
|
+
throw t instanceof Q ? t : new Q(`Failed to parse token: ${t instanceof Error ? t.message : "Unknown error"}`);
|
|
6769
7074
|
}
|
|
6770
7075
|
}
|
|
6771
7076
|
/**
|
|
@@ -6851,110 +7156,110 @@ class ii {
|
|
|
6851
7156
|
}
|
|
6852
7157
|
}
|
|
6853
7158
|
export {
|
|
6854
|
-
|
|
6855
|
-
|
|
6856
|
-
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
|
|
6868
|
-
|
|
6869
|
-
|
|
6870
|
-
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
|
|
7159
|
+
V as APP_ID_HEADER_KEY,
|
|
7160
|
+
D as AUTHORIZATION_HEADER_KEY,
|
|
7161
|
+
hr as AppAPI,
|
|
7162
|
+
dr as AuthAPI,
|
|
7163
|
+
qr as AuthService,
|
|
7164
|
+
si as CLIAuthAPI,
|
|
7165
|
+
ti as DEFAULT_GROUP_NAME,
|
|
7166
|
+
Mt as DEFAULT_SCOPES,
|
|
7167
|
+
Te as DEFAULT_UPGRADE_FACTORS,
|
|
7168
|
+
Rt as DEVICE_ID_HEADER_KEY,
|
|
7169
|
+
Pt as DEVICE_TYPE_HEADER_KEY,
|
|
7170
|
+
qt as ERROR_MESSAGE_MAX_LENGTH,
|
|
7171
|
+
ui as FETCH_PRIORITY_OIDC,
|
|
7172
|
+
Vs as FETCH_PRIORITY_UPGRADE,
|
|
7173
|
+
Ks as FetchMiddlewareContractError,
|
|
7174
|
+
zt as INSUFFICIENT_USER_AUTHENTICATION,
|
|
7175
|
+
lr as InvitationAPI,
|
|
7176
|
+
Nr as InvitationService,
|
|
7177
|
+
gi as M2MClient,
|
|
7178
|
+
fe as M2MConfigError,
|
|
6874
7179
|
S as M2MError,
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
7180
|
+
fi as M2MErrorCodes,
|
|
7181
|
+
$e as M2MNetworkError,
|
|
7182
|
+
Q as M2MTokenParseError,
|
|
6878
7183
|
R as M2M_DEFAULTS,
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
7184
|
+
ei as MINIMAL_DEFAULT_SCOPES,
|
|
7185
|
+
sr as OS,
|
|
7186
|
+
qe as PASSFLOW_CLOUD_URL,
|
|
7187
|
+
Dt as POPUP_HEIGHT,
|
|
7188
|
+
xt as POPUP_POLL_INTERVAL_MS,
|
|
7189
|
+
Ot as POPUP_TIMEOUT_MS,
|
|
7190
|
+
Ut as POPUP_WIDTH,
|
|
7191
|
+
Le as Passflow,
|
|
7192
|
+
P as PassflowAdminEndpointPaths,
|
|
6888
7193
|
l as PassflowEndpointPaths,
|
|
6889
7194
|
w as PassflowError,
|
|
6890
7195
|
c as PassflowEvent,
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
|
|
6895
|
-
|
|
6896
|
-
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
|
|
6900
|
-
|
|
6901
|
-
|
|
6902
|
-
|
|
6903
|
-
|
|
7196
|
+
Ge as PopupClosedError,
|
|
7197
|
+
rr as Providers,
|
|
7198
|
+
Sr as RECOVERABLE_COMMIT_ERROR_IDS,
|
|
7199
|
+
U as RequestMethod,
|
|
7200
|
+
Ft as SDK_VERSION,
|
|
7201
|
+
br as SESSION_INVALIDATING_COMMIT_ERROR_IDS,
|
|
7202
|
+
Ve as SessionState,
|
|
7203
|
+
ur as SettingAPI,
|
|
7204
|
+
Ne as TOKEN_EXPIRY_BUFFER_SECONDS,
|
|
7205
|
+
pr as TenantAPI,
|
|
7206
|
+
Kr as TenantService,
|
|
7207
|
+
Vr as TenantUserMembership,
|
|
7208
|
+
Br as TokenCacheService,
|
|
6904
7209
|
A as TokenDeliveryMode,
|
|
6905
7210
|
b as TokenType,
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
7211
|
+
fr as TwoFactorApiClient,
|
|
7212
|
+
ir as TwoFactorPolicy,
|
|
7213
|
+
Gr as TwoFactorService,
|
|
7214
|
+
Yt as UPGRADE_REQUIRED,
|
|
7215
|
+
$t as USERNAME_MAX_LENGTH,
|
|
7216
|
+
Lt as USERNAME_MIN_LENGTH,
|
|
7217
|
+
gr as UpgradeAPI,
|
|
7218
|
+
L as UpgradeCancelledError,
|
|
7219
|
+
os as UpgradeController,
|
|
6915
7220
|
k as UpgradeErrorIds,
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
7221
|
+
x as UpgradeFactorError,
|
|
7222
|
+
G as UpgradeInsufficientError,
|
|
7223
|
+
q as UpgradeSessionChangedError,
|
|
6919
7224
|
_ as UpgradeTransportError,
|
|
6920
7225
|
j as UpgradeUnavailableError,
|
|
6921
|
-
|
|
6922
|
-
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
|
|
7226
|
+
te as UpgradeUnsatisfiableError,
|
|
7227
|
+
vr as UserAPI,
|
|
7228
|
+
jr as UserService,
|
|
7229
|
+
Bt as WebAdapter,
|
|
7230
|
+
Pe as classifyUpgradeError,
|
|
7231
|
+
Wr as factorRegistry,
|
|
7232
|
+
pi as fetchRegistryState,
|
|
7233
|
+
ri as getOSFromDeviceType,
|
|
7234
|
+
Fr as invalidatesSessionOnCommit,
|
|
7235
|
+
ii as isRecoverableCommitFailure,
|
|
7236
|
+
_r as isRetryableUpgradeKind,
|
|
6932
7237
|
C as isTokenExpired,
|
|
6933
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
6946
|
-
|
|
7238
|
+
ni as isUpgradeCancelled,
|
|
7239
|
+
oi as isUpgradeExhausted,
|
|
7240
|
+
ai as isUpgradeInsufficient,
|
|
7241
|
+
di as isUpgradeSessionChanged,
|
|
7242
|
+
Ar as isUpgradeTransportError,
|
|
7243
|
+
li as isUpgradeTransportFailure,
|
|
7244
|
+
hi as isUpgradeUnavailable,
|
|
7245
|
+
ci as isUpgradeUnsatisfiable,
|
|
7246
|
+
oe as isValidEmail,
|
|
7247
|
+
J as isValidJWTFormat,
|
|
7248
|
+
ae as isValidPhoneNumber,
|
|
7249
|
+
xr as isValidUsername,
|
|
7250
|
+
Jt as parseChallengeBody,
|
|
7251
|
+
Xt as parseChallengeHeader,
|
|
6947
7252
|
T as parseToken,
|
|
6948
|
-
|
|
6949
|
-
|
|
6950
|
-
|
|
6951
|
-
|
|
6952
|
-
|
|
6953
|
-
|
|
6954
|
-
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
7253
|
+
Qt as parseUpgradeChallenge,
|
|
7254
|
+
Yr as passkeyFactor,
|
|
7255
|
+
F as pathWithParams,
|
|
7256
|
+
zr as recoveryCodesFactor,
|
|
7257
|
+
Hs as registerFetchMiddleware,
|
|
7258
|
+
Ht as requiredAcrLevel,
|
|
7259
|
+
Qe as resolveUpgradeDomain,
|
|
7260
|
+
Dr as sanitizeErrorMessage,
|
|
7261
|
+
Qr as selectFactors,
|
|
7262
|
+
Hr as totpFactor,
|
|
7263
|
+
Y as webAdapter
|
|
6959
7264
|
};
|
|
6960
7265
|
//# sourceMappingURL=index.mjs.map
|