@authowl/react 0.21.2 → 0.22.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/captcha-loader-VNULARCZ.js +68 -0
- package/dist/captcha-providers-STYFL25P.js +71 -0
- package/dist/index.cjs +389 -245
- package/dist/index.js +210 -220
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -933,6 +933,159 @@ var init_FormError = __esm({
|
|
|
933
933
|
}
|
|
934
934
|
});
|
|
935
935
|
|
|
936
|
+
// src/components/captcha-loader.ts
|
|
937
|
+
var captcha_loader_exports = {};
|
|
938
|
+
__export(captcha_loader_exports, {
|
|
939
|
+
loadCaptcha: () => loadCaptcha
|
|
940
|
+
});
|
|
941
|
+
function providerGlobal(adapter) {
|
|
942
|
+
const api = window[adapter.globalName];
|
|
943
|
+
return typeof api?.render === "function" ? api : void 0;
|
|
944
|
+
}
|
|
945
|
+
function loadCaptcha(adapter) {
|
|
946
|
+
const available = providerGlobal(adapter);
|
|
947
|
+
if (available) return Promise.resolve(available);
|
|
948
|
+
const cached = loaders.get(adapter.scriptUrl);
|
|
949
|
+
if (cached) return cached;
|
|
950
|
+
const loading = new Promise((resolve, reject) => {
|
|
951
|
+
const existing = document.querySelector(
|
|
952
|
+
`script[src="${adapter.scriptUrl}"]`
|
|
953
|
+
);
|
|
954
|
+
const script = existing ?? document.createElement("script");
|
|
955
|
+
let poll;
|
|
956
|
+
const cleanup = () => {
|
|
957
|
+
clearTimeout(timeout);
|
|
958
|
+
if (poll !== void 0) clearInterval(poll);
|
|
959
|
+
script.removeEventListener("load", loaded);
|
|
960
|
+
script.removeEventListener("error", failed);
|
|
961
|
+
};
|
|
962
|
+
const resolveWhenPublished = () => {
|
|
963
|
+
const api = providerGlobal(adapter);
|
|
964
|
+
if (!api) return false;
|
|
965
|
+
cleanup();
|
|
966
|
+
resolve(api);
|
|
967
|
+
return true;
|
|
968
|
+
};
|
|
969
|
+
const loaded = () => {
|
|
970
|
+
if (!resolveWhenPublished() && poll === void 0) {
|
|
971
|
+
poll = setInterval(resolveWhenPublished, GLOBAL_POLL_INTERVAL_MS);
|
|
972
|
+
}
|
|
973
|
+
};
|
|
974
|
+
const failed = () => {
|
|
975
|
+
cleanup();
|
|
976
|
+
if (!existing) script.remove();
|
|
977
|
+
reject(new Error(`${adapter.label} failed to load`));
|
|
978
|
+
};
|
|
979
|
+
const timeout = setTimeout(failed, SCRIPT_LOAD_TIMEOUT_MS);
|
|
980
|
+
script.addEventListener("load", loaded, { once: true });
|
|
981
|
+
script.addEventListener("error", failed, { once: true });
|
|
982
|
+
if (existing) {
|
|
983
|
+
loaded();
|
|
984
|
+
} else {
|
|
985
|
+
script.src = adapter.scriptUrl;
|
|
986
|
+
script.async = true;
|
|
987
|
+
script.defer = true;
|
|
988
|
+
const nonce = document.querySelector("script[nonce]")?.nonce;
|
|
989
|
+
if (nonce) script.nonce = nonce;
|
|
990
|
+
document.head.appendChild(script);
|
|
991
|
+
}
|
|
992
|
+
});
|
|
993
|
+
const retryable = loading.catch((error) => {
|
|
994
|
+
loaders.delete(adapter.scriptUrl);
|
|
995
|
+
throw error;
|
|
996
|
+
});
|
|
997
|
+
loaders.set(adapter.scriptUrl, retryable);
|
|
998
|
+
return retryable;
|
|
999
|
+
}
|
|
1000
|
+
var SCRIPT_LOAD_TIMEOUT_MS, GLOBAL_POLL_INTERVAL_MS, loaders;
|
|
1001
|
+
var init_captcha_loader = __esm({
|
|
1002
|
+
"src/components/captcha-loader.ts"() {
|
|
1003
|
+
"use strict";
|
|
1004
|
+
"use client";
|
|
1005
|
+
SCRIPT_LOAD_TIMEOUT_MS = 1e4;
|
|
1006
|
+
GLOBAL_POLL_INTERVAL_MS = 25;
|
|
1007
|
+
loaders = /* @__PURE__ */ new Map();
|
|
1008
|
+
}
|
|
1009
|
+
});
|
|
1010
|
+
|
|
1011
|
+
// src/components/captcha-providers.ts
|
|
1012
|
+
var captcha_providers_exports = {};
|
|
1013
|
+
__export(captcha_providers_exports, {
|
|
1014
|
+
CAPTCHA_ADAPTERS: () => CAPTCHA_ADAPTERS,
|
|
1015
|
+
captchaAdapterFor: () => captchaAdapterFor
|
|
1016
|
+
});
|
|
1017
|
+
function preferredTheme() {
|
|
1018
|
+
return typeof window !== "undefined" && window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
1019
|
+
}
|
|
1020
|
+
function teardown(api, widgetId) {
|
|
1021
|
+
if (api.remove) {
|
|
1022
|
+
try {
|
|
1023
|
+
api.remove(widgetId);
|
|
1024
|
+
return;
|
|
1025
|
+
} catch {
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
try {
|
|
1029
|
+
api.reset?.(widgetId);
|
|
1030
|
+
} catch {
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
function captchaAdapterFor(provider) {
|
|
1034
|
+
return CAPTCHA_ADAPTERS[provider] ?? null;
|
|
1035
|
+
}
|
|
1036
|
+
var CAPTCHA_ADAPTERS;
|
|
1037
|
+
var init_captcha_providers = __esm({
|
|
1038
|
+
"src/components/captcha-providers.ts"() {
|
|
1039
|
+
"use strict";
|
|
1040
|
+
"use client";
|
|
1041
|
+
CAPTCHA_ADAPTERS = {
|
|
1042
|
+
turnstile: {
|
|
1043
|
+
scriptUrl: "https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit",
|
|
1044
|
+
globalName: "turnstile",
|
|
1045
|
+
label: "Cloudflare Turnstile",
|
|
1046
|
+
invisibleRenderOptions: ({ siteKey, theme, action, language }) => ({
|
|
1047
|
+
sitekey: siteKey,
|
|
1048
|
+
theme,
|
|
1049
|
+
action,
|
|
1050
|
+
language,
|
|
1051
|
+
execution: "execute",
|
|
1052
|
+
appearance: "interaction-only",
|
|
1053
|
+
size: "flexible"
|
|
1054
|
+
}),
|
|
1055
|
+
teardown
|
|
1056
|
+
},
|
|
1057
|
+
hcaptcha: {
|
|
1058
|
+
scriptUrl: "https://js.hcaptcha.com/1/api.js?render=explicit",
|
|
1059
|
+
globalName: "hcaptcha",
|
|
1060
|
+
label: "hCaptcha",
|
|
1061
|
+
invisibleRenderOptions: ({ siteKey, theme }) => ({
|
|
1062
|
+
sitekey: siteKey,
|
|
1063
|
+
// 'auto' is Turnstile vocabulary. hCaptcha and reCAPTCHA take light|dark
|
|
1064
|
+
// only and silently fall back to light on anything else, which reads badly
|
|
1065
|
+
// in a dark application.
|
|
1066
|
+
theme: theme === "auto" ? preferredTheme() : theme,
|
|
1067
|
+
size: "invisible"
|
|
1068
|
+
}),
|
|
1069
|
+
teardown
|
|
1070
|
+
},
|
|
1071
|
+
"recaptcha-v2": {
|
|
1072
|
+
scriptUrl: "https://www.google.com/recaptcha/api.js?render=explicit",
|
|
1073
|
+
globalName: "grecaptcha",
|
|
1074
|
+
label: "reCAPTCHA",
|
|
1075
|
+
invisibleRenderOptions: ({ siteKey, theme }) => ({
|
|
1076
|
+
sitekey: siteKey,
|
|
1077
|
+
// 'auto' is Turnstile vocabulary. hCaptcha and reCAPTCHA take light|dark
|
|
1078
|
+
// only and silently fall back to light on anything else, which reads badly
|
|
1079
|
+
// in a dark application.
|
|
1080
|
+
theme: theme === "auto" ? preferredTheme() : theme,
|
|
1081
|
+
size: "invisible"
|
|
1082
|
+
}),
|
|
1083
|
+
teardown
|
|
1084
|
+
}
|
|
1085
|
+
};
|
|
1086
|
+
}
|
|
1087
|
+
});
|
|
1088
|
+
|
|
936
1089
|
// ../../node_modules/.pnpm/qrcode-generator@2.0.4/node_modules/qrcode-generator/dist/qrcode.mjs
|
|
937
1090
|
var qrcode, QRMode, QRErrorCorrectionLevel, QRMaskPattern, QRUtil, QRMath, qrPolynomial, QRRSBlock, qrBitBuffer, qrNumber, qrAlphaNum, qr8BitByte, qrKanji, byteArrayOutputStream, base64EncodeOutputStream, base64DecodeInputStream, gifImage, createDataURL, qrcode_default, stringToBytes;
|
|
938
1091
|
var init_qrcode = __esm({
|
|
@@ -3430,110 +3583,26 @@ function PasskeyButton({ redirectTo, onSignedIn }) {
|
|
|
3430
3583
|
}
|
|
3431
3584
|
|
|
3432
3585
|
// src/components/ForgotPassword.tsx
|
|
3433
|
-
var
|
|
3586
|
+
var React10 = __toESM(require("react"), 1);
|
|
3434
3587
|
init_hooks();
|
|
3435
3588
|
init_i18n();
|
|
3436
3589
|
init_use_submit_action();
|
|
3437
3590
|
init_Spinner();
|
|
3438
3591
|
|
|
3439
3592
|
// src/components/AuthChallenge.tsx
|
|
3440
|
-
var
|
|
3593
|
+
var React9 = __toESM(require("react"), 1);
|
|
3441
3594
|
init_hooks();
|
|
3442
3595
|
init_i18n();
|
|
3596
|
+
init_FormError();
|
|
3443
3597
|
|
|
3444
|
-
// src/components/
|
|
3445
|
-
var
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
var SCRIPT_LOAD_TIMEOUT_MS = 1e4;
|
|
3449
|
-
var LOCAL_TURNSTILE_TEST_TOKEN = "XXXX.DUMMY.TOKEN.XXXX";
|
|
3450
|
-
var loader = null;
|
|
3451
|
-
function loadTurnstile() {
|
|
3452
|
-
if (window.turnstile) return Promise.resolve(window.turnstile);
|
|
3453
|
-
if (loader) return loader;
|
|
3454
|
-
loader = new Promise((resolve, reject) => {
|
|
3455
|
-
const existing = document.querySelector(`script[src="${SCRIPT_URL}"]`);
|
|
3456
|
-
const script = existing ?? document.createElement("script");
|
|
3457
|
-
const cleanup = () => {
|
|
3458
|
-
clearTimeout(timeout);
|
|
3459
|
-
script.removeEventListener("load", loaded);
|
|
3460
|
-
script.removeEventListener("error", failed);
|
|
3461
|
-
};
|
|
3462
|
-
const loaded = () => {
|
|
3463
|
-
cleanup();
|
|
3464
|
-
if (window.turnstile) {
|
|
3465
|
-
resolve(window.turnstile);
|
|
3466
|
-
} else {
|
|
3467
|
-
reject(new Error("Turnstile unavailable"));
|
|
3468
|
-
}
|
|
3469
|
-
};
|
|
3470
|
-
const failed = () => {
|
|
3471
|
-
cleanup();
|
|
3472
|
-
if (!existing) script.remove();
|
|
3473
|
-
reject(new Error("Turnstile failed to load"));
|
|
3474
|
-
};
|
|
3475
|
-
const timeout = setTimeout(failed, SCRIPT_LOAD_TIMEOUT_MS);
|
|
3476
|
-
script.addEventListener("load", loaded, { once: true });
|
|
3477
|
-
script.addEventListener("error", failed, { once: true });
|
|
3478
|
-
if (!existing) {
|
|
3479
|
-
script.src = SCRIPT_URL;
|
|
3480
|
-
script.async = true;
|
|
3481
|
-
script.defer = true;
|
|
3482
|
-
const nonce = document.querySelector("script[nonce]")?.nonce;
|
|
3483
|
-
if (nonce) script.nonce = nonce;
|
|
3484
|
-
document.head.appendChild(script);
|
|
3485
|
-
}
|
|
3486
|
-
}).catch((error) => {
|
|
3487
|
-
loader = null;
|
|
3488
|
-
throw error;
|
|
3489
|
-
});
|
|
3490
|
-
return loader;
|
|
3491
|
-
}
|
|
3492
|
-
function Turnstile({
|
|
3493
|
-
siteKey,
|
|
3494
|
-
theme,
|
|
3495
|
-
onToken,
|
|
3496
|
-
onUnavailable
|
|
3497
|
-
}) {
|
|
3498
|
-
const container = React9.useRef(null);
|
|
3499
|
-
const callbacks = React9.useRef({ onToken, onUnavailable });
|
|
3500
|
-
callbacks.current = { onToken, onUnavailable };
|
|
3501
|
-
React9.useEffect(() => {
|
|
3502
|
-
callbacks.current.onToken(null);
|
|
3503
|
-
if (!siteKey) {
|
|
3504
|
-
callbacks.current.onToken(LOCAL_TURNSTILE_TEST_TOKEN);
|
|
3505
|
-
return;
|
|
3506
|
-
}
|
|
3507
|
-
let active = true;
|
|
3508
|
-
let widget = null;
|
|
3509
|
-
void loadTurnstile().then((api) => {
|
|
3510
|
-
if (!active || !container.current) return;
|
|
3511
|
-
const id = api.render(container.current, {
|
|
3512
|
-
sitekey: siteKey,
|
|
3513
|
-
theme: theme === "system" ? "auto" : theme,
|
|
3514
|
-
size: "flexible",
|
|
3515
|
-
callback: (token) => callbacks.current.onToken(token),
|
|
3516
|
-
"expired-callback": () => callbacks.current.onToken(null),
|
|
3517
|
-
"error-callback": () => {
|
|
3518
|
-
callbacks.current.onToken(null);
|
|
3519
|
-
callbacks.current.onUnavailable();
|
|
3520
|
-
}
|
|
3521
|
-
});
|
|
3522
|
-
widget = { api, id };
|
|
3523
|
-
}).catch(() => {
|
|
3524
|
-
if (active) callbacks.current.onUnavailable();
|
|
3525
|
-
});
|
|
3526
|
-
return () => {
|
|
3527
|
-
active = false;
|
|
3528
|
-
if (widget) widget.api.remove(widget.id);
|
|
3529
|
-
};
|
|
3530
|
-
}, [siteKey, theme]);
|
|
3531
|
-
if (!siteKey) return null;
|
|
3532
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "ba-turnstile", ref: container, "data-testid": "phoneotp-turnstile" });
|
|
3598
|
+
// src/components/captcha-provider-ids.ts
|
|
3599
|
+
var CAPTCHA_PROVIDER_IDS = ["turnstile", "hcaptcha", "recaptcha-v2"];
|
|
3600
|
+
function isSupportedCaptchaProvider(provider) {
|
|
3601
|
+
return CAPTCHA_PROVIDER_IDS.includes(provider);
|
|
3533
3602
|
}
|
|
3534
3603
|
|
|
3535
3604
|
// src/components/AuthChallenge.tsx
|
|
3536
|
-
var
|
|
3605
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
3537
3606
|
var AUTH_CHALLENGE_ACTIONS = {
|
|
3538
3607
|
signUp: "auth_signup",
|
|
3539
3608
|
signIn: "auth_signin",
|
|
@@ -3548,38 +3617,53 @@ var challengeError = {
|
|
|
3548
3617
|
code: "BOT_CHALLENGE_FAILED",
|
|
3549
3618
|
message: "Human verification failed."
|
|
3550
3619
|
};
|
|
3551
|
-
function
|
|
3620
|
+
function captchaTheme(root, fallback) {
|
|
3552
3621
|
const rendered = root?.dataset.authowlTheme;
|
|
3553
3622
|
if (rendered === "light" || rendered === "dark") return rendered;
|
|
3554
3623
|
if (fallback === "light" || fallback === "dark") return fallback;
|
|
3555
3624
|
return "auto";
|
|
3556
3625
|
}
|
|
3557
3626
|
function useAuthChallenge() {
|
|
3558
|
-
const { config, isLoading } = usePublicConfig();
|
|
3627
|
+
const { config, isLoading, retry } = usePublicConfig();
|
|
3559
3628
|
const t = useT();
|
|
3560
|
-
const container =
|
|
3561
|
-
const active =
|
|
3562
|
-
const [status, setStatus] =
|
|
3563
|
-
const
|
|
3564
|
-
const
|
|
3629
|
+
const container = React9.useRef(null);
|
|
3630
|
+
const active = React9.useRef(null);
|
|
3631
|
+
const [status, setStatus] = React9.useState("idle");
|
|
3632
|
+
const captcha = config?.captcha ?? null;
|
|
3633
|
+
const providerSupported = captcha ? isSupportedCaptchaProvider(captcha.provider) : false;
|
|
3634
|
+
const unavailableProvider = captcha && !providerSupported ? captcha.provider : null;
|
|
3635
|
+
const refetched = React9.useRef(null);
|
|
3636
|
+
const refetchIfConfigMayBeStale = React9.useCallback(() => {
|
|
3637
|
+
if (!config || refetched.current === config) return;
|
|
3638
|
+
refetched.current = config;
|
|
3639
|
+
retry();
|
|
3640
|
+
}, [config, retry]);
|
|
3641
|
+
const removeActive = React9.useCallback((reason) => {
|
|
3565
3642
|
const current = active.current;
|
|
3566
3643
|
active.current = null;
|
|
3567
3644
|
if (!current) return;
|
|
3568
|
-
current.
|
|
3645
|
+
current.adapter.teardown(current.api, current.id);
|
|
3569
3646
|
if (reason) current.reject(reason);
|
|
3570
3647
|
}, []);
|
|
3571
|
-
|
|
3572
|
-
() => () => removeActive(new Error("
|
|
3648
|
+
React9.useEffect(
|
|
3649
|
+
() => () => removeActive(new Error("Captcha challenge was cancelled")),
|
|
3573
3650
|
[removeActive]
|
|
3574
3651
|
);
|
|
3575
|
-
const tokenFor =
|
|
3652
|
+
const tokenFor = React9.useCallback(
|
|
3576
3653
|
async (action) => {
|
|
3577
|
-
if (!
|
|
3654
|
+
if (!captcha) return null;
|
|
3655
|
+
if (!providerSupported) throw new Error(`Unsupported captcha provider: ${captcha.provider}`);
|
|
3578
3656
|
setStatus("checking");
|
|
3579
|
-
removeActive(new Error("
|
|
3657
|
+
removeActive(new Error("Captcha challenge was replaced"));
|
|
3580
3658
|
try {
|
|
3581
|
-
const
|
|
3582
|
-
|
|
3659
|
+
const [{ loadCaptcha: loadCaptcha2 }, { captchaAdapterFor: captchaAdapterFor2 }] = await Promise.all([
|
|
3660
|
+
Promise.resolve().then(() => (init_captcha_loader(), captcha_loader_exports)),
|
|
3661
|
+
Promise.resolve().then(() => (init_captcha_providers(), captcha_providers_exports))
|
|
3662
|
+
]);
|
|
3663
|
+
const adapter = captchaAdapterFor2(captcha.provider);
|
|
3664
|
+
if (!adapter) throw new Error(`Unsupported captcha provider: ${captcha.provider}`);
|
|
3665
|
+
const api = await loadCaptcha2(adapter);
|
|
3666
|
+
if (!container.current) throw new Error("Captcha container unavailable");
|
|
3583
3667
|
return await new Promise((resolve, reject) => {
|
|
3584
3668
|
let settled = false;
|
|
3585
3669
|
const finish = (outcome) => {
|
|
@@ -3587,27 +3671,29 @@ function useAuthChallenge() {
|
|
|
3587
3671
|
settled = true;
|
|
3588
3672
|
const current = active.current;
|
|
3589
3673
|
active.current = null;
|
|
3590
|
-
if (current) current.
|
|
3674
|
+
if (current) current.adapter.teardown(current.api, current.id);
|
|
3591
3675
|
if ("token" in outcome) resolve(outcome.token);
|
|
3592
3676
|
else reject(outcome.error);
|
|
3593
3677
|
};
|
|
3594
|
-
const fail = () => finish({ error: new Error("
|
|
3678
|
+
const fail = () => finish({ error: new Error("Captcha challenge failed") });
|
|
3595
3679
|
const root = container.current.closest(".authowl-root");
|
|
3680
|
+
const optionalFailureCallbacks = captcha.provider === "turnstile" ? {
|
|
3681
|
+
"timeout-callback": fail,
|
|
3682
|
+
"unsupported-callback": fail
|
|
3683
|
+
} : {};
|
|
3596
3684
|
const id = api.render(container.current, {
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
language: root?.dataset.authowlLocale ?? config?.locale,
|
|
3685
|
+
...adapter.invisibleRenderOptions({
|
|
3686
|
+
siteKey: captcha.siteKey,
|
|
3687
|
+
theme: captchaTheme(root, config?.branding?.theme),
|
|
3688
|
+
action,
|
|
3689
|
+
language: root?.dataset.authowlLocale ?? config?.locale
|
|
3690
|
+
}),
|
|
3604
3691
|
callback: (token) => finish({ token }),
|
|
3605
3692
|
"expired-callback": fail,
|
|
3606
3693
|
"error-callback": fail,
|
|
3607
|
-
|
|
3608
|
-
"unsupported-callback": fail
|
|
3694
|
+
...optionalFailureCallbacks
|
|
3609
3695
|
});
|
|
3610
|
-
active.current = { api, id, reject };
|
|
3696
|
+
active.current = { adapter, api, id, reject };
|
|
3611
3697
|
try {
|
|
3612
3698
|
api.execute(id);
|
|
3613
3699
|
} catch {
|
|
@@ -3618,9 +3704,9 @@ function useAuthChallenge() {
|
|
|
3618
3704
|
setStatus("idle");
|
|
3619
3705
|
}
|
|
3620
3706
|
},
|
|
3621
|
-
[config?.branding?.theme, config?.locale,
|
|
3707
|
+
[captcha, config?.branding?.theme, config?.locale, providerSupported, removeActive]
|
|
3622
3708
|
);
|
|
3623
|
-
const run =
|
|
3709
|
+
const run = React9.useCallback(
|
|
3624
3710
|
async (action, request) => {
|
|
3625
3711
|
if (isLoading) {
|
|
3626
3712
|
return {
|
|
@@ -3630,41 +3716,44 @@ function useAuthChallenge() {
|
|
|
3630
3716
|
}
|
|
3631
3717
|
try {
|
|
3632
3718
|
const token = await tokenFor(action);
|
|
3633
|
-
|
|
3719
|
+
const result = await request(token ? { authChallengeToken: token } : void 0);
|
|
3720
|
+
if (result?.error?.code === challengeError.code) refetchIfConfigMayBeStale();
|
|
3721
|
+
return result;
|
|
3634
3722
|
} catch {
|
|
3635
3723
|
setStatus("failed");
|
|
3724
|
+
refetchIfConfigMayBeStale();
|
|
3636
3725
|
return {
|
|
3637
3726
|
data: null,
|
|
3638
3727
|
error: challengeError
|
|
3639
3728
|
};
|
|
3640
3729
|
}
|
|
3641
3730
|
},
|
|
3642
|
-
[isLoading, tokenFor]
|
|
3731
|
+
[isLoading, refetchIfConfigMayBeStale, tokenFor]
|
|
3643
3732
|
);
|
|
3644
|
-
const control =
|
|
3645
|
-
/* @__PURE__ */ (0,
|
|
3646
|
-
/* @__PURE__ */ (0,
|
|
3733
|
+
const control = captcha ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "ba-auth-challenge", "data-testid": "auth-challenge", children: [
|
|
3734
|
+
providerSupported ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "ba-turnstile", ref: container }) : null,
|
|
3735
|
+
unavailableProvider ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(FormError, { "data-testid": "auth-challenge-unsupported", children: t("authChallenge.error.unsupportedProvider", { provider: unavailableProvider }) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "ba-sr-only", role: "status", "aria-live": "polite", children: status === "checking" ? t("authChallenge.checking") : status === "failed" ? t("authChallenge.error.failed") : "" })
|
|
3647
3736
|
] }) : null;
|
|
3648
3737
|
return { run, control, configPending: isLoading };
|
|
3649
3738
|
}
|
|
3650
3739
|
|
|
3651
3740
|
// src/components/ForgotPassword.tsx
|
|
3652
3741
|
init_FormError();
|
|
3653
|
-
var
|
|
3742
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
3654
3743
|
function ForgotPassword({ resetPasswordUrl, onBack }) {
|
|
3655
3744
|
const t = useT();
|
|
3656
3745
|
const { requestPasswordReset } = usePasswordReset();
|
|
3657
3746
|
const { pending, error, run } = useSubmitAction();
|
|
3658
3747
|
const authChallenge = useAuthChallenge();
|
|
3659
|
-
const [email, setEmail] =
|
|
3660
|
-
const [sent, setSent] =
|
|
3748
|
+
const [email, setEmail] = React10.useState("");
|
|
3749
|
+
const [sent, setSent] = React10.useState(false);
|
|
3661
3750
|
if (sent) {
|
|
3662
|
-
return /* @__PURE__ */ (0,
|
|
3663
|
-
/* @__PURE__ */ (0,
|
|
3664
|
-
onBack && /* @__PURE__ */ (0,
|
|
3751
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ba-fields", "data-testid": "forgot-sent", children: [
|
|
3752
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "ba-muted", children: richMessage(t("forgotPassword.sent"), { email: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Bidi, { children: email }) }) }),
|
|
3753
|
+
onBack && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "ba-link-button", onClick: onBack, children: t("forgotPassword.backToSignIn") })
|
|
3665
3754
|
] });
|
|
3666
3755
|
}
|
|
3667
|
-
return /* @__PURE__ */ (0,
|
|
3756
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
3668
3757
|
"form",
|
|
3669
3758
|
{
|
|
3670
3759
|
method: "post",
|
|
@@ -3678,9 +3767,9 @@ function ForgotPassword({ resetPasswordUrl, onBack }) {
|
|
|
3678
3767
|
});
|
|
3679
3768
|
},
|
|
3680
3769
|
children: [
|
|
3681
|
-
/* @__PURE__ */ (0,
|
|
3770
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "ba-label", children: [
|
|
3682
3771
|
t("common.emailLabel"),
|
|
3683
|
-
/* @__PURE__ */ (0,
|
|
3772
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3684
3773
|
"input",
|
|
3685
3774
|
{
|
|
3686
3775
|
className: "ba-input",
|
|
@@ -3693,18 +3782,18 @@ function ForgotPassword({ resetPasswordUrl, onBack }) {
|
|
|
3693
3782
|
)
|
|
3694
3783
|
] }),
|
|
3695
3784
|
authChallenge.control,
|
|
3696
|
-
/* @__PURE__ */ (0,
|
|
3697
|
-
/* @__PURE__ */ (0,
|
|
3785
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(FormError, { children: error }),
|
|
3786
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3698
3787
|
"button",
|
|
3699
3788
|
{
|
|
3700
3789
|
className: "ba-button",
|
|
3701
3790
|
type: "submit",
|
|
3702
3791
|
disabled: pending || authChallenge.configPending,
|
|
3703
3792
|
"aria-busy": pending || void 0,
|
|
3704
|
-
children: /* @__PURE__ */ (0,
|
|
3793
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Busy, { busy: pending, label: t("common.sending"), children: t("forgotPassword.submit") })
|
|
3705
3794
|
}
|
|
3706
3795
|
),
|
|
3707
|
-
onBack && /* @__PURE__ */ (0,
|
|
3796
|
+
onBack && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "ba-link-button", onClick: onBack, children: t("forgotPassword.backToSignIn") })
|
|
3708
3797
|
]
|
|
3709
3798
|
}
|
|
3710
3799
|
);
|
|
@@ -3714,7 +3803,7 @@ function ForgotPassword({ resetPasswordUrl, onBack }) {
|
|
|
3714
3803
|
init_i18n();
|
|
3715
3804
|
init_Spinner();
|
|
3716
3805
|
init_FormError();
|
|
3717
|
-
var
|
|
3806
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
3718
3807
|
function OtpCodeForm({
|
|
3719
3808
|
email,
|
|
3720
3809
|
code,
|
|
@@ -3725,7 +3814,7 @@ function OtpCodeForm({
|
|
|
3725
3814
|
error
|
|
3726
3815
|
}) {
|
|
3727
3816
|
const t = useT();
|
|
3728
|
-
return /* @__PURE__ */ (0,
|
|
3817
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
3729
3818
|
"form",
|
|
3730
3819
|
{
|
|
3731
3820
|
method: "post",
|
|
@@ -3736,9 +3825,9 @@ function OtpCodeForm({
|
|
|
3736
3825
|
onSubmit();
|
|
3737
3826
|
},
|
|
3738
3827
|
children: [
|
|
3739
|
-
/* @__PURE__ */ (0,
|
|
3740
|
-
richMessage(t("emailOtp.codeLabel"), { email: /* @__PURE__ */ (0,
|
|
3741
|
-
/* @__PURE__ */ (0,
|
|
3828
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "ba-label", children: [
|
|
3829
|
+
richMessage(t("emailOtp.codeLabel"), { email: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Bidi, { children: email }) }),
|
|
3830
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
3742
3831
|
"input",
|
|
3743
3832
|
{
|
|
3744
3833
|
className: "ba-input",
|
|
@@ -3751,29 +3840,29 @@ function OtpCodeForm({
|
|
|
3751
3840
|
}
|
|
3752
3841
|
)
|
|
3753
3842
|
] }),
|
|
3754
|
-
/* @__PURE__ */ (0,
|
|
3755
|
-
/* @__PURE__ */ (0,
|
|
3756
|
-
/* @__PURE__ */ (0,
|
|
3843
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(FormError, { children: error }),
|
|
3844
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { className: "ba-button", type: "submit", disabled: pending, "aria-busy": pending || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Busy, { busy: pending, label: t("common.verifying"), children: t("emailOtp.verifySubmit") }) }),
|
|
3845
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "ba-link-button", onClick: onChangeEmail, children: t("emailOtp.changeEmail") })
|
|
3757
3846
|
]
|
|
3758
3847
|
}
|
|
3759
3848
|
);
|
|
3760
3849
|
}
|
|
3761
3850
|
|
|
3762
3851
|
// src/components/MFAChallenge.tsx
|
|
3763
|
-
var
|
|
3852
|
+
var React11 = __toESM(require("react"), 1);
|
|
3764
3853
|
init_hooks();
|
|
3765
3854
|
init_i18n();
|
|
3766
3855
|
init_use_submit_action();
|
|
3767
3856
|
init_Spinner();
|
|
3768
3857
|
init_FormError();
|
|
3769
|
-
var
|
|
3858
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
3770
3859
|
function MFAChallenge({ onVerified, allowTrustDevice = true }) {
|
|
3771
3860
|
const t = useT();
|
|
3772
3861
|
const { verifyTotp, verifyBackupCode, sendOtp, verifyOtp } = useMFA();
|
|
3773
3862
|
const { pending, error, setError, run } = useSubmitAction();
|
|
3774
|
-
const [mode, setMode] =
|
|
3775
|
-
const [code, setCode] =
|
|
3776
|
-
const [trustDevice, setTrustDevice] =
|
|
3863
|
+
const [mode, setMode] = React11.useState("totp");
|
|
3864
|
+
const [code, setCode] = React11.useState("");
|
|
3865
|
+
const [trustDevice, setTrustDevice] = React11.useState(false);
|
|
3777
3866
|
const switchMode = (next) => {
|
|
3778
3867
|
setMode(next);
|
|
3779
3868
|
setCode("");
|
|
@@ -3796,12 +3885,12 @@ function MFAChallenge({ onVerified, allowTrustDevice = true }) {
|
|
|
3796
3885
|
};
|
|
3797
3886
|
const hint = mode === "totp" ? t("mfa.challenge.totpHint") : mode === "backup" ? t("mfa.challenge.backupHint") : t("mfa.challenge.otpHint");
|
|
3798
3887
|
const label2 = mode === "totp" ? t("mfa.challenge.totpLabel") : mode === "backup" ? t("mfa.challenge.backupLabel") : t("mfa.challenge.otpLabel");
|
|
3799
|
-
return /* @__PURE__ */ (0,
|
|
3800
|
-
/* @__PURE__ */ (0,
|
|
3801
|
-
/* @__PURE__ */ (0,
|
|
3802
|
-
/* @__PURE__ */ (0,
|
|
3888
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("form", { method: "post", className: "ba-fields", "data-testid": "mfa-challenge", onSubmit: submit, children: [
|
|
3889
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h2", { className: "ba-title", children: t("mfa.challenge.title") }),
|
|
3890
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "ba-muted", children: hint }),
|
|
3891
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "ba-label", children: [
|
|
3803
3892
|
label2,
|
|
3804
|
-
/* @__PURE__ */ (0,
|
|
3893
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3805
3894
|
"input",
|
|
3806
3895
|
{
|
|
3807
3896
|
className: "ba-input",
|
|
@@ -3817,28 +3906,28 @@ function MFAChallenge({ onVerified, allowTrustDevice = true }) {
|
|
|
3817
3906
|
}
|
|
3818
3907
|
)
|
|
3819
3908
|
] }),
|
|
3820
|
-
mode !== "backup" && allowTrustDevice && /* @__PURE__ */ (0,
|
|
3821
|
-
/* @__PURE__ */ (0,
|
|
3822
|
-
/* @__PURE__ */ (0,
|
|
3823
|
-
/* @__PURE__ */ (0,
|
|
3909
|
+
mode !== "backup" && allowTrustDevice && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "ba-consent ba-consent-centered", children: [
|
|
3910
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "ba-checkbox-control", children: [
|
|
3911
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { className: "ba-checkbox", type: "checkbox", checked: trustDevice, onChange: (e) => setTrustDevice(e.target.checked) }),
|
|
3912
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ba-checkbox-visual", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ba-checkbox-check" }) })
|
|
3824
3913
|
] }),
|
|
3825
|
-
/* @__PURE__ */ (0,
|
|
3914
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: t("mfa.challenge.trustDevice", { days: 30 }) })
|
|
3826
3915
|
] }),
|
|
3827
|
-
/* @__PURE__ */ (0,
|
|
3828
|
-
/* @__PURE__ */ (0,
|
|
3829
|
-
mode !== "totp" && /* @__PURE__ */ (0,
|
|
3830
|
-
mode !== "backup" && /* @__PURE__ */ (0,
|
|
3831
|
-
/* @__PURE__ */ (0,
|
|
3916
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FormError, { children: error }),
|
|
3917
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { className: "ba-button", type: "submit", disabled: pending || !code, "aria-busy": pending || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Busy, { busy: pending, label: t("common.verifying"), children: t("mfa.challenge.submit") }) }),
|
|
3918
|
+
mode !== "totp" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "ba-link-button", onClick: () => switchMode("totp"), children: t("mfa.challenge.useTotp") }),
|
|
3919
|
+
mode !== "backup" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "ba-link-button", onClick: () => switchMode("backup"), children: t("mfa.challenge.useBackup") }),
|
|
3920
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "ba-link-button", disabled: pending, onClick: requestOtp, children: t(mode === "otp" ? "mfa.challenge.resendOtp" : "mfa.challenge.useEmailOtp") })
|
|
3832
3921
|
] });
|
|
3833
3922
|
}
|
|
3834
3923
|
|
|
3835
3924
|
// src/components/mfa-enrollment-step.tsx
|
|
3836
|
-
var
|
|
3925
|
+
var React14 = __toESM(require("react"), 1);
|
|
3837
3926
|
init_hooks();
|
|
3838
3927
|
init_i18n();
|
|
3839
3928
|
|
|
3840
3929
|
// src/components/MFAEnrollment.tsx
|
|
3841
|
-
var
|
|
3930
|
+
var React13 = __toESM(require("react"), 1);
|
|
3842
3931
|
init_hooks();
|
|
3843
3932
|
init_i18n();
|
|
3844
3933
|
init_use_submit_action();
|
|
@@ -3851,13 +3940,13 @@ function shouldDiscardSetup(args) {
|
|
|
3851
3940
|
}
|
|
3852
3941
|
|
|
3853
3942
|
// src/components/QrCode.tsx
|
|
3854
|
-
var
|
|
3943
|
+
var React12 = __toESM(require("react"), 1);
|
|
3855
3944
|
init_i18n();
|
|
3856
|
-
var
|
|
3945
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
3857
3946
|
function QrCode({ value, size = 200 }) {
|
|
3858
3947
|
const t = useT();
|
|
3859
|
-
const [path, setPath] =
|
|
3860
|
-
|
|
3948
|
+
const [path, setPath] = React12.useState(null);
|
|
3949
|
+
React12.useEffect(() => {
|
|
3861
3950
|
let active = true;
|
|
3862
3951
|
setPath(null);
|
|
3863
3952
|
void Promise.resolve().then(() => (init_qr(), qr_exports)).then(
|
|
@@ -3875,7 +3964,7 @@ function QrCode({ value, size = 200 }) {
|
|
|
3875
3964
|
if (!path) return null;
|
|
3876
3965
|
const margin = 4;
|
|
3877
3966
|
const dim = path.count + margin * 2;
|
|
3878
|
-
return /* @__PURE__ */ (0,
|
|
3967
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3879
3968
|
"svg",
|
|
3880
3969
|
{
|
|
3881
3970
|
width: size,
|
|
@@ -3886,8 +3975,8 @@ function QrCode({ value, size = 200 }) {
|
|
|
3886
3975
|
shapeRendering: "crispEdges",
|
|
3887
3976
|
className: "ba-qr",
|
|
3888
3977
|
children: [
|
|
3889
|
-
/* @__PURE__ */ (0,
|
|
3890
|
-
/* @__PURE__ */ (0,
|
|
3978
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("rect", { width: dim, height: dim, fill: "#ffffff" }),
|
|
3979
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("g", { transform: `translate(${margin} ${margin})`, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: path.d, fill: "#000000" }) })
|
|
3891
3980
|
]
|
|
3892
3981
|
}
|
|
3893
3982
|
);
|
|
@@ -3895,7 +3984,7 @@ function QrCode({ value, size = 200 }) {
|
|
|
3895
3984
|
|
|
3896
3985
|
// src/components/MFAEnrollment.tsx
|
|
3897
3986
|
init_FormError();
|
|
3898
|
-
var
|
|
3987
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3899
3988
|
function secretFromUri(uri) {
|
|
3900
3989
|
try {
|
|
3901
3990
|
return new URL(uri).searchParams.get("secret");
|
|
@@ -3908,11 +3997,11 @@ function MFAEnrollment({ onEnrolled, title }) {
|
|
|
3908
3997
|
const { enable, verifyTotp } = useMFA();
|
|
3909
3998
|
const { user, isLoaded } = useUser();
|
|
3910
3999
|
const { pending, error, run } = useSubmitAction();
|
|
3911
|
-
const [password, setPassword] =
|
|
3912
|
-
const [setup, setSetup] =
|
|
3913
|
-
const [code, setCode] =
|
|
3914
|
-
const [done, setDone] =
|
|
3915
|
-
const setupOwnerId =
|
|
4000
|
+
const [password, setPassword] = React13.useState("");
|
|
4001
|
+
const [setup, setSetup] = React13.useState(null);
|
|
4002
|
+
const [code, setCode] = React13.useState("");
|
|
4003
|
+
const [done, setDone] = React13.useState(false);
|
|
4004
|
+
const setupOwnerId = React13.useRef(null);
|
|
3916
4005
|
const userId = user?.id ?? null;
|
|
3917
4006
|
const stale = shouldDiscardSetup({
|
|
3918
4007
|
isLoaded,
|
|
@@ -3921,7 +4010,7 @@ function MFAEnrollment({ onEnrolled, title }) {
|
|
|
3921
4010
|
currentUserId: userId
|
|
3922
4011
|
});
|
|
3923
4012
|
const activeSetup = stale ? null : setup;
|
|
3924
|
-
|
|
4013
|
+
React13.useEffect(() => {
|
|
3925
4014
|
if (stale) {
|
|
3926
4015
|
setSetup(null);
|
|
3927
4016
|
setPassword("");
|
|
@@ -3929,22 +4018,22 @@ function MFAEnrollment({ onEnrolled, title }) {
|
|
|
3929
4018
|
}
|
|
3930
4019
|
}, [stale]);
|
|
3931
4020
|
if (done) {
|
|
3932
|
-
return /* @__PURE__ */ (0,
|
|
3933
|
-
/* @__PURE__ */ (0,
|
|
3934
|
-
/* @__PURE__ */ (0,
|
|
4021
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "ba-fields", "data-testid": "mfa-enroll-done", children: [
|
|
4022
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h2", { className: "ba-title", children: t("mfa.enroll.doneTitle") }),
|
|
4023
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "ba-muted", children: t("mfa.enroll.doneBody") })
|
|
3935
4024
|
] });
|
|
3936
4025
|
}
|
|
3937
4026
|
if (!activeSetup) {
|
|
3938
4027
|
if (!isLoaded) {
|
|
3939
|
-
return /* @__PURE__ */ (0,
|
|
4028
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "ba-fields", "data-testid": "mfa-enroll-loading", "aria-busy": "true", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "ba-skeleton" }) });
|
|
3940
4029
|
}
|
|
3941
4030
|
if (user?.twoFactorEnabled) {
|
|
3942
|
-
return /* @__PURE__ */ (0,
|
|
3943
|
-
/* @__PURE__ */ (0,
|
|
3944
|
-
/* @__PURE__ */ (0,
|
|
4031
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "ba-fields", "data-testid": "mfa-enroll-active", children: [
|
|
4032
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h2", { className: "ba-title", children: t("mfa.enroll.activeTitle") }),
|
|
4033
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "ba-muted", children: t("mfa.enroll.activeBody") })
|
|
3945
4034
|
] });
|
|
3946
4035
|
}
|
|
3947
|
-
return /* @__PURE__ */ (0,
|
|
4036
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
3948
4037
|
"form",
|
|
3949
4038
|
{
|
|
3950
4039
|
method: "post",
|
|
@@ -3961,11 +4050,11 @@ function MFAEnrollment({ onEnrolled, title }) {
|
|
|
3961
4050
|
});
|
|
3962
4051
|
},
|
|
3963
4052
|
children: [
|
|
3964
|
-
title !== null && /* @__PURE__ */ (0,
|
|
3965
|
-
/* @__PURE__ */ (0,
|
|
3966
|
-
/* @__PURE__ */ (0,
|
|
4053
|
+
title !== null && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h2", { className: "ba-title", children: title ?? t("mfa.enroll.title") }),
|
|
4054
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "ba-muted", children: t("mfa.enroll.passwordHint") }),
|
|
4055
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "ba-label", children: [
|
|
3967
4056
|
t("common.passwordLabel"),
|
|
3968
|
-
/* @__PURE__ */ (0,
|
|
4057
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3969
4058
|
"input",
|
|
3970
4059
|
{
|
|
3971
4060
|
className: "ba-input",
|
|
@@ -3977,29 +4066,29 @@ function MFAEnrollment({ onEnrolled, title }) {
|
|
|
3977
4066
|
}
|
|
3978
4067
|
)
|
|
3979
4068
|
] }),
|
|
3980
|
-
/* @__PURE__ */ (0,
|
|
3981
|
-
/* @__PURE__ */ (0,
|
|
4069
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(FormError, { children: error }),
|
|
4070
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { className: "ba-button", type: "submit", disabled: pending || !password, "aria-busy": pending || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Busy, { busy: pending, label: t("mfa.enroll.startPending"), children: t("common.continue") }) })
|
|
3982
4071
|
]
|
|
3983
4072
|
}
|
|
3984
4073
|
);
|
|
3985
4074
|
}
|
|
3986
4075
|
const secret = secretFromUri(activeSetup.totpURI);
|
|
3987
|
-
return /* @__PURE__ */ (0,
|
|
3988
|
-
/* @__PURE__ */ (0,
|
|
3989
|
-
/* @__PURE__ */ (0,
|
|
3990
|
-
/* @__PURE__ */ (0,
|
|
3991
|
-
secret && /* @__PURE__ */ (0,
|
|
3992
|
-
secret: /* @__PURE__ */ (0,
|
|
4076
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "ba-fields", "data-testid": "mfa-enroll-verify", children: [
|
|
4077
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h2", { className: "ba-title", children: t("mfa.enroll.scanQrTitle") }),
|
|
4078
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "ba-muted", children: t("mfa.enroll.scanQrHint") }),
|
|
4079
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(QrCode, { value: activeSetup.totpURI }),
|
|
4080
|
+
secret && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "ba-muted", children: richMessage(t("mfa.enroll.manualKey"), {
|
|
4081
|
+
secret: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("code", { className: "ba-code", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Bidi, { children: secret }) })
|
|
3993
4082
|
}) }),
|
|
3994
|
-
/* @__PURE__ */ (0,
|
|
3995
|
-
/* @__PURE__ */ (0,
|
|
3996
|
-
/* @__PURE__ */ (0,
|
|
4083
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
|
|
4084
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("p", { className: "ba-muted", children: [
|
|
4085
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("strong", { children: t("mfa.enroll.backupCodesWarningStrong") }),
|
|
3997
4086
|
" ",
|
|
3998
4087
|
t("mfa.enroll.backupCodesWarningRest")
|
|
3999
4088
|
] }),
|
|
4000
|
-
/* @__PURE__ */ (0,
|
|
4089
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("ul", { className: "ba-backup-codes", "data-testid": "mfa-backup-codes", children: activeSetup.backupCodes.map((c) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("code", { className: "ba-code", children: c }) }, c)) })
|
|
4001
4090
|
] }),
|
|
4002
|
-
/* @__PURE__ */ (0,
|
|
4091
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
4003
4092
|
"form",
|
|
4004
4093
|
{
|
|
4005
4094
|
method: "post",
|
|
@@ -4017,9 +4106,9 @@ function MFAEnrollment({ onEnrolled, title }) {
|
|
|
4017
4106
|
});
|
|
4018
4107
|
},
|
|
4019
4108
|
children: [
|
|
4020
|
-
/* @__PURE__ */ (0,
|
|
4109
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "ba-label", children: [
|
|
4021
4110
|
t("mfa.enroll.codeLabel"),
|
|
4022
|
-
/* @__PURE__ */ (0,
|
|
4111
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
4023
4112
|
"input",
|
|
4024
4113
|
{
|
|
4025
4114
|
className: "ba-input",
|
|
@@ -4031,8 +4120,8 @@ function MFAEnrollment({ onEnrolled, title }) {
|
|
|
4031
4120
|
}
|
|
4032
4121
|
)
|
|
4033
4122
|
] }),
|
|
4034
|
-
/* @__PURE__ */ (0,
|
|
4035
|
-
/* @__PURE__ */ (0,
|
|
4123
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(FormError, { children: error }),
|
|
4124
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { className: "ba-button", type: "submit", disabled: pending || !code, "aria-busy": pending || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Busy, { busy: pending, label: t("common.verifying"), children: t("mfa.enroll.activateSubmit") }) })
|
|
4036
4125
|
]
|
|
4037
4126
|
}
|
|
4038
4127
|
)
|
|
@@ -4040,13 +4129,13 @@ function MFAEnrollment({ onEnrolled, title }) {
|
|
|
4040
4129
|
}
|
|
4041
4130
|
|
|
4042
4131
|
// src/components/mfa-enrollment-step.tsx
|
|
4043
|
-
var
|
|
4132
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
4044
4133
|
function useConfirmedMfaPending(onUnknown = "pending") {
|
|
4045
4134
|
const client = useAuthClient();
|
|
4046
4135
|
const { needsMfaEnrollment } = useUser();
|
|
4047
4136
|
const { refetch } = useSession();
|
|
4048
|
-
const [confirmed, setConfirmed] =
|
|
4049
|
-
|
|
4137
|
+
const [confirmed, setConfirmed] = React14.useState(null);
|
|
4138
|
+
React14.useEffect(() => {
|
|
4050
4139
|
if (!needsMfaEnrollment) {
|
|
4051
4140
|
setConfirmed(null);
|
|
4052
4141
|
return;
|
|
@@ -4070,32 +4159,32 @@ function useConfirmedMfaPending(onUnknown = "pending") {
|
|
|
4070
4159
|
function MfaEnrollmentStep({ title }) {
|
|
4071
4160
|
const t = useT();
|
|
4072
4161
|
const { refetch } = useSession();
|
|
4073
|
-
return /* @__PURE__ */ (0,
|
|
4074
|
-
/* @__PURE__ */ (0,
|
|
4075
|
-
/* @__PURE__ */ (0,
|
|
4076
|
-
/* @__PURE__ */ (0,
|
|
4162
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
4163
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h2", { className: "ba-title", children: title ?? t("mfaGate.title") }),
|
|
4164
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "ba-muted", children: t("mfaGate.body") }),
|
|
4165
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MFAEnrollment, { onEnrolled: () => refetch({ query: { disableCookieCache: true } }) })
|
|
4077
4166
|
] });
|
|
4078
4167
|
}
|
|
4079
4168
|
|
|
4080
4169
|
// src/components/AuthOwlBadge.tsx
|
|
4081
4170
|
init_hooks();
|
|
4082
4171
|
init_i18n();
|
|
4083
|
-
var
|
|
4172
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
4084
4173
|
function OwlMark() {
|
|
4085
|
-
return /* @__PURE__ */ (0,
|
|
4086
|
-
/* @__PURE__ */ (0,
|
|
4087
|
-
/* @__PURE__ */ (0,
|
|
4088
|
-
/* @__PURE__ */ (0,
|
|
4089
|
-
/* @__PURE__ */ (0,
|
|
4090
|
-
/* @__PURE__ */ (0,
|
|
4091
|
-
/* @__PURE__ */ (0,
|
|
4174
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { className: "ba-badge-mark", viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", children: [
|
|
4175
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "12", cy: "12", r: "11", fill: "#F5B84C" }),
|
|
4176
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "8.4", cy: "10", r: "3", fill: "#fff" }),
|
|
4177
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "15.6", cy: "10", r: "3", fill: "#fff" }),
|
|
4178
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "8.4", cy: "10", r: "1.4", fill: "#1f1300" }),
|
|
4179
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "15.6", cy: "10", r: "1.4", fill: "#1f1300" }),
|
|
4180
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M12 13.1l1.5 2.1h-3z", fill: "#1f1300" })
|
|
4092
4181
|
] });
|
|
4093
4182
|
}
|
|
4094
4183
|
function AuthOwlBadge({ href = "https://authowl.dev", force } = {}) {
|
|
4095
4184
|
const t = useT();
|
|
4096
4185
|
const { config } = usePublicConfig();
|
|
4097
4186
|
if (!force && !config?.badge) return null;
|
|
4098
|
-
return /* @__PURE__ */ (0,
|
|
4187
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
4099
4188
|
"a",
|
|
4100
4189
|
{
|
|
4101
4190
|
className: "ba-badge",
|
|
@@ -4104,9 +4193,9 @@ function AuthOwlBadge({ href = "https://authowl.dev", force } = {}) {
|
|
|
4104
4193
|
rel: "noopener noreferrer",
|
|
4105
4194
|
"data-testid": "authowl-badge",
|
|
4106
4195
|
children: [
|
|
4107
|
-
/* @__PURE__ */ (0,
|
|
4108
|
-
/* @__PURE__ */ (0,
|
|
4109
|
-
brand: /* @__PURE__ */ (0,
|
|
4196
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(OwlMark, {}),
|
|
4197
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: richMessage(t("badge.securedBy"), {
|
|
4198
|
+
brand: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ba-badge-brand", children: "AuthOwl" })
|
|
4110
4199
|
}) })
|
|
4111
4200
|
]
|
|
4112
4201
|
}
|
|
@@ -4127,19 +4216,19 @@ init_i18n();
|
|
|
4127
4216
|
|
|
4128
4217
|
// src/components/ConsentDocLinks.tsx
|
|
4129
4218
|
init_i18n();
|
|
4130
|
-
var
|
|
4219
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
4131
4220
|
function ConsentDocLinks({ termsUrl, privacyUrl }) {
|
|
4132
4221
|
const t = useT();
|
|
4133
4222
|
if (!termsUrl && !privacyUrl) return null;
|
|
4134
|
-
return /* @__PURE__ */ (0,
|
|
4135
|
-
termsUrl && /* @__PURE__ */ (0,
|
|
4223
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
4224
|
+
termsUrl && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("a", { href: termsUrl, target: "_blank", rel: "noopener noreferrer", children: t("consent.termsOfService") }),
|
|
4136
4225
|
termsUrl && privacyUrl && t("consent.docJoiner"),
|
|
4137
|
-
privacyUrl && /* @__PURE__ */ (0,
|
|
4226
|
+
privacyUrl && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("a", { href: privacyUrl, target: "_blank", rel: "noopener noreferrer", children: t("consent.privacyPolicy") })
|
|
4138
4227
|
] });
|
|
4139
4228
|
}
|
|
4140
4229
|
|
|
4141
4230
|
// src/components/LegalConsentCheckbox.tsx
|
|
4142
|
-
var
|
|
4231
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
4143
4232
|
function LegalConsentCheckbox({
|
|
4144
4233
|
legal,
|
|
4145
4234
|
accepted,
|
|
@@ -4148,9 +4237,9 @@ function LegalConsentCheckbox({
|
|
|
4148
4237
|
}) {
|
|
4149
4238
|
const t = useT();
|
|
4150
4239
|
if (!legal.required) return null;
|
|
4151
|
-
return /* @__PURE__ */ (0,
|
|
4152
|
-
/* @__PURE__ */ (0,
|
|
4153
|
-
/* @__PURE__ */ (0,
|
|
4240
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { className: "ba-consent", "data-testid": testId, children: [
|
|
4241
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "ba-checkbox-control", children: [
|
|
4242
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4154
4243
|
"input",
|
|
4155
4244
|
{
|
|
4156
4245
|
className: "ba-checkbox",
|
|
@@ -4159,14 +4248,69 @@ function LegalConsentCheckbox({
|
|
|
4159
4248
|
onChange: (event) => onAcceptedChange(event.target.checked)
|
|
4160
4249
|
}
|
|
4161
4250
|
),
|
|
4162
|
-
/* @__PURE__ */ (0,
|
|
4251
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ba-checkbox-visual", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "ba-checkbox-check" }) })
|
|
4163
4252
|
] }),
|
|
4164
|
-
/* @__PURE__ */ (0,
|
|
4165
|
-
links: /* @__PURE__ */ (0,
|
|
4253
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: richMessage(t("signUp.consentLabel"), {
|
|
4254
|
+
links: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ConsentDocLinks, { termsUrl: legal.termsUrl, privacyUrl: legal.privacyUrl })
|
|
4166
4255
|
}) })
|
|
4167
4256
|
] });
|
|
4168
4257
|
}
|
|
4169
4258
|
|
|
4259
|
+
// src/components/Turnstile.tsx
|
|
4260
|
+
var React15 = __toESM(require("react"), 1);
|
|
4261
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
4262
|
+
var LOCAL_TURNSTILE_TEST_TOKEN = "XXXX.DUMMY.TOKEN.XXXX";
|
|
4263
|
+
async function loadTurnstile() {
|
|
4264
|
+
const [{ loadCaptcha: loadCaptcha2 }, { CAPTCHA_ADAPTERS: CAPTCHA_ADAPTERS2 }] = await Promise.all([
|
|
4265
|
+
Promise.resolve().then(() => (init_captcha_loader(), captcha_loader_exports)),
|
|
4266
|
+
Promise.resolve().then(() => (init_captcha_providers(), captcha_providers_exports))
|
|
4267
|
+
]);
|
|
4268
|
+
const adapter = CAPTCHA_ADAPTERS2.turnstile;
|
|
4269
|
+
return { api: await loadCaptcha2(adapter), adapter };
|
|
4270
|
+
}
|
|
4271
|
+
function Turnstile({
|
|
4272
|
+
siteKey,
|
|
4273
|
+
theme,
|
|
4274
|
+
onToken,
|
|
4275
|
+
onUnavailable
|
|
4276
|
+
}) {
|
|
4277
|
+
const container = React15.useRef(null);
|
|
4278
|
+
const callbacks = React15.useRef({ onToken, onUnavailable });
|
|
4279
|
+
callbacks.current = { onToken, onUnavailable };
|
|
4280
|
+
React15.useEffect(() => {
|
|
4281
|
+
callbacks.current.onToken(null);
|
|
4282
|
+
if (!siteKey) {
|
|
4283
|
+
callbacks.current.onToken(LOCAL_TURNSTILE_TEST_TOKEN);
|
|
4284
|
+
return;
|
|
4285
|
+
}
|
|
4286
|
+
let active = true;
|
|
4287
|
+
let widget = null;
|
|
4288
|
+
void loadTurnstile().then(({ api, adapter }) => {
|
|
4289
|
+
if (!active || !container.current) return;
|
|
4290
|
+
const id = api.render(container.current, {
|
|
4291
|
+
sitekey: siteKey,
|
|
4292
|
+
theme: theme === "system" ? "auto" : theme,
|
|
4293
|
+
size: "flexible",
|
|
4294
|
+
callback: (token) => callbacks.current.onToken(token),
|
|
4295
|
+
"expired-callback": () => callbacks.current.onToken(null),
|
|
4296
|
+
"error-callback": () => {
|
|
4297
|
+
callbacks.current.onToken(null);
|
|
4298
|
+
callbacks.current.onUnavailable();
|
|
4299
|
+
}
|
|
4300
|
+
});
|
|
4301
|
+
widget = { api, adapter, id };
|
|
4302
|
+
}).catch(() => {
|
|
4303
|
+
if (active) callbacks.current.onUnavailable();
|
|
4304
|
+
});
|
|
4305
|
+
return () => {
|
|
4306
|
+
active = false;
|
|
4307
|
+
if (widget) widget.adapter.teardown(widget.api, widget.id);
|
|
4308
|
+
};
|
|
4309
|
+
}, [siteKey, theme]);
|
|
4310
|
+
if (!siteKey) return null;
|
|
4311
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "ba-turnstile", ref: container, "data-testid": "phoneotp-turnstile" });
|
|
4312
|
+
}
|
|
4313
|
+
|
|
4170
4314
|
// src/components/PhoneOTP.tsx
|
|
4171
4315
|
init_use_submit_action();
|
|
4172
4316
|
init_Spinner();
|
|
@@ -6671,9 +6815,9 @@ function formatSessionTime(date, locale) {
|
|
|
6671
6815
|
// src/components/user-profile/use-account-resource.ts
|
|
6672
6816
|
var React38 = __toESM(require("react"), 1);
|
|
6673
6817
|
init_i18n();
|
|
6674
|
-
function useAccountResource(
|
|
6675
|
-
const loaderRef = React38.useRef(
|
|
6676
|
-
loaderRef.current =
|
|
6818
|
+
function useAccountResource(loader, failure) {
|
|
6819
|
+
const loaderRef = React38.useRef(loader);
|
|
6820
|
+
loaderRef.current = loader;
|
|
6677
6821
|
const failureRef = React38.useRef(failure);
|
|
6678
6822
|
failureRef.current = failure;
|
|
6679
6823
|
const toServerError = useServerError();
|