@authowl/react 0.21.2 → 0.23.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/{TeamsSection-ZQDNMWV3.js → TeamsSection-NV64O5I4.js} +1 -1
- package/dist/captcha-loader-VNULARCZ.js +68 -0
- package/dist/captcha-providers-STYFL25P.js +71 -0
- package/dist/{chunk-PUJV7S6G.js → chunk-E5ZOQHXY.js} +97 -51
- package/dist/index.cjs +730 -498
- package/dist/index.d.cts +23 -3
- package/dist/index.d.ts +23 -3
- package/dist/index.js +253 -227
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -737,6 +737,42 @@ var init_InvitationPrompt = __esm({
|
|
|
737
737
|
}
|
|
738
738
|
});
|
|
739
739
|
|
|
740
|
+
// src/last-used-method.ts
|
|
741
|
+
function useLastUsedSignInMethod() {
|
|
742
|
+
const { config } = usePublicConfig();
|
|
743
|
+
const projectId = config?.environmentId ?? null;
|
|
744
|
+
return React5.useMemo(
|
|
745
|
+
() => projectId ? (0, import_core2.readLastUsedSignInMethod)(projectId) : null,
|
|
746
|
+
[projectId]
|
|
747
|
+
);
|
|
748
|
+
}
|
|
749
|
+
function useSignInMethodRecorder() {
|
|
750
|
+
const { config } = usePublicConfig();
|
|
751
|
+
const projectId = config?.environmentId ?? null;
|
|
752
|
+
return React5.useCallback(
|
|
753
|
+
(method, pending) => {
|
|
754
|
+
if (!projectId) return;
|
|
755
|
+
(pending ? import_core2.rememberPendingSignInMethod : import_core2.recordLastUsedSignInMethod)(projectId, method);
|
|
756
|
+
},
|
|
757
|
+
[projectId]
|
|
758
|
+
);
|
|
759
|
+
}
|
|
760
|
+
function useConfirmPendingSignInMethod(loaded, signedIn, projectId) {
|
|
761
|
+
React5.useEffect(() => {
|
|
762
|
+
if (loaded && projectId) (0, import_core2.settlePendingSignInMethod)(projectId, signedIn);
|
|
763
|
+
}, [loaded, projectId, signedIn]);
|
|
764
|
+
}
|
|
765
|
+
var React5, import_core2;
|
|
766
|
+
var init_last_used_method = __esm({
|
|
767
|
+
"src/last-used-method.ts"() {
|
|
768
|
+
"use strict";
|
|
769
|
+
"use client";
|
|
770
|
+
React5 = __toESM(require("react"), 1);
|
|
771
|
+
import_core2 = require("@authowl/core");
|
|
772
|
+
init_hooks();
|
|
773
|
+
}
|
|
774
|
+
});
|
|
775
|
+
|
|
740
776
|
// src/provider.tsx
|
|
741
777
|
function warnPublicConfigFailed(resolved, error) {
|
|
742
778
|
let origin = resolved.apiUrl;
|
|
@@ -752,6 +788,12 @@ function warnPublicConfigFailed(resolved, error) {
|
|
|
752
788
|
`[AuthOwl] Could not load this project's public config from ${origin} (${reason}). Authentication UI is unavailable until the request succeeds. Likely causes: the API is unreachable, \`apiUrl\` is wrong, or the publishable key points at a missing/mismatched project. Check \`apiUrl\` and \`publishableKey\` on <AuthOwlProvider>. (This warning is dev-only.)`
|
|
753
789
|
);
|
|
754
790
|
}
|
|
791
|
+
function LastUsedMethodSync() {
|
|
792
|
+
const { config } = usePublicConfig();
|
|
793
|
+
const { isLoaded, isSignedIn } = useUser();
|
|
794
|
+
useConfirmPendingSignInMethod(isLoaded, isSignedIn, config?.environmentId ?? null);
|
|
795
|
+
return null;
|
|
796
|
+
}
|
|
755
797
|
function detectLocale() {
|
|
756
798
|
if (typeof document !== "undefined") {
|
|
757
799
|
const root = document.documentElement;
|
|
@@ -763,9 +805,9 @@ function detectLocale() {
|
|
|
763
805
|
return "en";
|
|
764
806
|
}
|
|
765
807
|
function resolveLocale(prop, autoDetected, configLocale) {
|
|
766
|
-
if (prop !== "auto" && (0,
|
|
808
|
+
if (prop !== "auto" && (0, import_core3.isLocale)(prop)) return prop;
|
|
767
809
|
if (prop === "auto") return autoDetected ?? "en";
|
|
768
|
-
return (0,
|
|
810
|
+
return (0, import_core3.isLocale)(configLocale) ? configLocale : "en";
|
|
769
811
|
}
|
|
770
812
|
function AuthOwlProvider({
|
|
771
813
|
publishableKey,
|
|
@@ -776,21 +818,21 @@ function AuthOwlProvider({
|
|
|
776
818
|
invitationPrompt = true,
|
|
777
819
|
children
|
|
778
820
|
}) {
|
|
779
|
-
const fetchRef =
|
|
821
|
+
const fetchRef = React6.useRef(fetch);
|
|
780
822
|
fetchRef.current = fetch;
|
|
781
|
-
const resolved =
|
|
782
|
-
() => (0,
|
|
823
|
+
const resolved = React6.useMemo(
|
|
824
|
+
() => (0, import_core3.resolveConfig)({ publishableKey, apiUrl, fetch: fetchRef.current }),
|
|
783
825
|
[publishableKey, apiUrl]
|
|
784
826
|
);
|
|
785
|
-
const client =
|
|
786
|
-
const [config, setConfig] =
|
|
787
|
-
const [configState, setConfigState] =
|
|
788
|
-
const [configAttempt, setConfigAttempt] =
|
|
789
|
-
const retryPublicConfig =
|
|
790
|
-
|
|
827
|
+
const client = React6.useMemo(() => (0, import_core3.createAuthOwlClient)(resolved), [resolved]);
|
|
828
|
+
const [config, setConfig] = React6.useState(null);
|
|
829
|
+
const [configState, setConfigState] = React6.useState("loading");
|
|
830
|
+
const [configAttempt, setConfigAttempt] = React6.useState(0);
|
|
831
|
+
const retryPublicConfig = React6.useCallback(() => setConfigAttempt((attempt) => attempt + 1), []);
|
|
832
|
+
React6.useEffect(() => {
|
|
791
833
|
let active = true;
|
|
792
834
|
setConfigState("loading");
|
|
793
|
-
(0,
|
|
835
|
+
(0, import_core3.getPublicConfig)(resolved).then((c) => {
|
|
794
836
|
if (!active) return;
|
|
795
837
|
setConfig(c);
|
|
796
838
|
setConfigState("ready");
|
|
@@ -805,15 +847,18 @@ function AuthOwlProvider({
|
|
|
805
847
|
};
|
|
806
848
|
}, [resolved, configAttempt]);
|
|
807
849
|
const merged = resolveAppearance(appearance, config);
|
|
808
|
-
const [autoLocale, setAutoLocale] =
|
|
809
|
-
|
|
850
|
+
const [autoLocale, setAutoLocale] = React6.useState(null);
|
|
851
|
+
React6.useEffect(() => {
|
|
810
852
|
if (localeProp === "auto") setAutoLocale(detectLocale());
|
|
811
853
|
}, [localeProp]);
|
|
812
854
|
const locale = resolveLocale(localeProp, autoLocale, config?.locale);
|
|
813
|
-
|
|
814
|
-
(0,
|
|
855
|
+
React6.useEffect(() => {
|
|
856
|
+
return (0, import_core3.setActiveLocale)(resolved.decoded.projectId, locale);
|
|
857
|
+
}, [locale, resolved.decoded.projectId]);
|
|
858
|
+
React6.useEffect(() => {
|
|
859
|
+
(0, import_core3.captureInvitationClaim)();
|
|
815
860
|
}, []);
|
|
816
|
-
const ctxValue =
|
|
861
|
+
const ctxValue = React6.useMemo(
|
|
817
862
|
() => ({ client, appearance, config, configState, retryPublicConfig, locale }),
|
|
818
863
|
[client, appearance, config, configState, retryPublicConfig, locale]
|
|
819
864
|
);
|
|
@@ -823,43 +868,46 @@ function AuthOwlProvider({
|
|
|
823
868
|
className: "authowl-root",
|
|
824
869
|
"data-authowl-theme": merged.theme,
|
|
825
870
|
"data-authowl-locale": locale,
|
|
826
|
-
dir: (0,
|
|
871
|
+
dir: (0, import_core3.directionFor)(locale),
|
|
827
872
|
style: { display: "contents", ...merged.style },
|
|
828
873
|
children: [
|
|
829
874
|
children,
|
|
875
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LastUsedMethodSync, {}),
|
|
830
876
|
invitationPrompt ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(InvitationPrompt, {}) : null
|
|
831
877
|
]
|
|
832
878
|
}
|
|
833
879
|
) });
|
|
834
880
|
}
|
|
835
881
|
function useAuthOwlContext() {
|
|
836
|
-
const v =
|
|
882
|
+
const v = React6.useContext(Context);
|
|
837
883
|
if (!v) {
|
|
838
884
|
throw new Error("AuthOwl hooks must be used inside <AuthOwlProvider>");
|
|
839
885
|
}
|
|
840
886
|
return v;
|
|
841
887
|
}
|
|
842
|
-
var
|
|
888
|
+
var React6, import_core3, import_jsx_runtime4, warnedConfigProjects, Context;
|
|
843
889
|
var init_provider = __esm({
|
|
844
890
|
"src/provider.tsx"() {
|
|
845
891
|
"use strict";
|
|
846
892
|
"use client";
|
|
847
|
-
|
|
848
|
-
|
|
893
|
+
React6 = __toESM(require("react"), 1);
|
|
894
|
+
import_core3 = require("@authowl/core");
|
|
849
895
|
init_appearance();
|
|
850
896
|
init_InvitationPrompt();
|
|
897
|
+
init_last_used_method();
|
|
898
|
+
init_hooks();
|
|
851
899
|
import_jsx_runtime4 = require("react/jsx-runtime");
|
|
852
900
|
warnedConfigProjects = /* @__PURE__ */ new Set();
|
|
853
|
-
Context =
|
|
901
|
+
Context = React6.createContext(null);
|
|
854
902
|
}
|
|
855
903
|
});
|
|
856
904
|
|
|
857
905
|
// src/components/use-submit-action.ts
|
|
858
906
|
function useSubmitAction() {
|
|
859
|
-
const [pending, setPending] =
|
|
860
|
-
const [error, setError] =
|
|
907
|
+
const [pending, setPending] = React7.useState(false);
|
|
908
|
+
const [error, setError] = React7.useState(null);
|
|
861
909
|
const toMessage = useServerError();
|
|
862
|
-
const run =
|
|
910
|
+
const run = React7.useCallback(
|
|
863
911
|
async (action, { failure, onSuccess, mapError, keepPendingOnSuccess }) => {
|
|
864
912
|
setError(null);
|
|
865
913
|
setPending(true);
|
|
@@ -881,12 +929,12 @@ function useSubmitAction() {
|
|
|
881
929
|
);
|
|
882
930
|
return { pending, error, setError, run };
|
|
883
931
|
}
|
|
884
|
-
var
|
|
932
|
+
var React7;
|
|
885
933
|
var init_use_submit_action = __esm({
|
|
886
934
|
"src/components/use-submit-action.ts"() {
|
|
887
935
|
"use strict";
|
|
888
936
|
"use client";
|
|
889
|
-
|
|
937
|
+
React7 = __toESM(require("react"), 1);
|
|
890
938
|
init_i18n();
|
|
891
939
|
}
|
|
892
940
|
});
|
|
@@ -933,6 +981,159 @@ var init_FormError = __esm({
|
|
|
933
981
|
}
|
|
934
982
|
});
|
|
935
983
|
|
|
984
|
+
// src/components/captcha-loader.ts
|
|
985
|
+
var captcha_loader_exports = {};
|
|
986
|
+
__export(captcha_loader_exports, {
|
|
987
|
+
loadCaptcha: () => loadCaptcha
|
|
988
|
+
});
|
|
989
|
+
function providerGlobal(adapter) {
|
|
990
|
+
const api = window[adapter.globalName];
|
|
991
|
+
return typeof api?.render === "function" ? api : void 0;
|
|
992
|
+
}
|
|
993
|
+
function loadCaptcha(adapter) {
|
|
994
|
+
const available = providerGlobal(adapter);
|
|
995
|
+
if (available) return Promise.resolve(available);
|
|
996
|
+
const cached = loaders.get(adapter.scriptUrl);
|
|
997
|
+
if (cached) return cached;
|
|
998
|
+
const loading = new Promise((resolve, reject) => {
|
|
999
|
+
const existing = document.querySelector(
|
|
1000
|
+
`script[src="${adapter.scriptUrl}"]`
|
|
1001
|
+
);
|
|
1002
|
+
const script = existing ?? document.createElement("script");
|
|
1003
|
+
let poll;
|
|
1004
|
+
const cleanup = () => {
|
|
1005
|
+
clearTimeout(timeout);
|
|
1006
|
+
if (poll !== void 0) clearInterval(poll);
|
|
1007
|
+
script.removeEventListener("load", loaded);
|
|
1008
|
+
script.removeEventListener("error", failed);
|
|
1009
|
+
};
|
|
1010
|
+
const resolveWhenPublished = () => {
|
|
1011
|
+
const api = providerGlobal(adapter);
|
|
1012
|
+
if (!api) return false;
|
|
1013
|
+
cleanup();
|
|
1014
|
+
resolve(api);
|
|
1015
|
+
return true;
|
|
1016
|
+
};
|
|
1017
|
+
const loaded = () => {
|
|
1018
|
+
if (!resolveWhenPublished() && poll === void 0) {
|
|
1019
|
+
poll = setInterval(resolveWhenPublished, GLOBAL_POLL_INTERVAL_MS);
|
|
1020
|
+
}
|
|
1021
|
+
};
|
|
1022
|
+
const failed = () => {
|
|
1023
|
+
cleanup();
|
|
1024
|
+
if (!existing) script.remove();
|
|
1025
|
+
reject(new Error(`${adapter.label} failed to load`));
|
|
1026
|
+
};
|
|
1027
|
+
const timeout = setTimeout(failed, SCRIPT_LOAD_TIMEOUT_MS);
|
|
1028
|
+
script.addEventListener("load", loaded, { once: true });
|
|
1029
|
+
script.addEventListener("error", failed, { once: true });
|
|
1030
|
+
if (existing) {
|
|
1031
|
+
loaded();
|
|
1032
|
+
} else {
|
|
1033
|
+
script.src = adapter.scriptUrl;
|
|
1034
|
+
script.async = true;
|
|
1035
|
+
script.defer = true;
|
|
1036
|
+
const nonce = document.querySelector("script[nonce]")?.nonce;
|
|
1037
|
+
if (nonce) script.nonce = nonce;
|
|
1038
|
+
document.head.appendChild(script);
|
|
1039
|
+
}
|
|
1040
|
+
});
|
|
1041
|
+
const retryable = loading.catch((error) => {
|
|
1042
|
+
loaders.delete(adapter.scriptUrl);
|
|
1043
|
+
throw error;
|
|
1044
|
+
});
|
|
1045
|
+
loaders.set(adapter.scriptUrl, retryable);
|
|
1046
|
+
return retryable;
|
|
1047
|
+
}
|
|
1048
|
+
var SCRIPT_LOAD_TIMEOUT_MS, GLOBAL_POLL_INTERVAL_MS, loaders;
|
|
1049
|
+
var init_captcha_loader = __esm({
|
|
1050
|
+
"src/components/captcha-loader.ts"() {
|
|
1051
|
+
"use strict";
|
|
1052
|
+
"use client";
|
|
1053
|
+
SCRIPT_LOAD_TIMEOUT_MS = 1e4;
|
|
1054
|
+
GLOBAL_POLL_INTERVAL_MS = 25;
|
|
1055
|
+
loaders = /* @__PURE__ */ new Map();
|
|
1056
|
+
}
|
|
1057
|
+
});
|
|
1058
|
+
|
|
1059
|
+
// src/components/captcha-providers.ts
|
|
1060
|
+
var captcha_providers_exports = {};
|
|
1061
|
+
__export(captcha_providers_exports, {
|
|
1062
|
+
CAPTCHA_ADAPTERS: () => CAPTCHA_ADAPTERS,
|
|
1063
|
+
captchaAdapterFor: () => captchaAdapterFor
|
|
1064
|
+
});
|
|
1065
|
+
function preferredTheme() {
|
|
1066
|
+
return typeof window !== "undefined" && window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
1067
|
+
}
|
|
1068
|
+
function teardown(api, widgetId) {
|
|
1069
|
+
if (api.remove) {
|
|
1070
|
+
try {
|
|
1071
|
+
api.remove(widgetId);
|
|
1072
|
+
return;
|
|
1073
|
+
} catch {
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
try {
|
|
1077
|
+
api.reset?.(widgetId);
|
|
1078
|
+
} catch {
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
function captchaAdapterFor(provider) {
|
|
1082
|
+
return CAPTCHA_ADAPTERS[provider] ?? null;
|
|
1083
|
+
}
|
|
1084
|
+
var CAPTCHA_ADAPTERS;
|
|
1085
|
+
var init_captcha_providers = __esm({
|
|
1086
|
+
"src/components/captcha-providers.ts"() {
|
|
1087
|
+
"use strict";
|
|
1088
|
+
"use client";
|
|
1089
|
+
CAPTCHA_ADAPTERS = {
|
|
1090
|
+
turnstile: {
|
|
1091
|
+
scriptUrl: "https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit",
|
|
1092
|
+
globalName: "turnstile",
|
|
1093
|
+
label: "Cloudflare Turnstile",
|
|
1094
|
+
invisibleRenderOptions: ({ siteKey, theme, action, language }) => ({
|
|
1095
|
+
sitekey: siteKey,
|
|
1096
|
+
theme,
|
|
1097
|
+
action,
|
|
1098
|
+
language,
|
|
1099
|
+
execution: "execute",
|
|
1100
|
+
appearance: "interaction-only",
|
|
1101
|
+
size: "flexible"
|
|
1102
|
+
}),
|
|
1103
|
+
teardown
|
|
1104
|
+
},
|
|
1105
|
+
hcaptcha: {
|
|
1106
|
+
scriptUrl: "https://js.hcaptcha.com/1/api.js?render=explicit",
|
|
1107
|
+
globalName: "hcaptcha",
|
|
1108
|
+
label: "hCaptcha",
|
|
1109
|
+
invisibleRenderOptions: ({ siteKey, theme }) => ({
|
|
1110
|
+
sitekey: siteKey,
|
|
1111
|
+
// 'auto' is Turnstile vocabulary. hCaptcha and reCAPTCHA take light|dark
|
|
1112
|
+
// only and silently fall back to light on anything else, which reads badly
|
|
1113
|
+
// in a dark application.
|
|
1114
|
+
theme: theme === "auto" ? preferredTheme() : theme,
|
|
1115
|
+
size: "invisible"
|
|
1116
|
+
}),
|
|
1117
|
+
teardown
|
|
1118
|
+
},
|
|
1119
|
+
"recaptcha-v2": {
|
|
1120
|
+
scriptUrl: "https://www.google.com/recaptcha/api.js?render=explicit",
|
|
1121
|
+
globalName: "grecaptcha",
|
|
1122
|
+
label: "reCAPTCHA",
|
|
1123
|
+
invisibleRenderOptions: ({ siteKey, theme }) => ({
|
|
1124
|
+
sitekey: siteKey,
|
|
1125
|
+
// 'auto' is Turnstile vocabulary. hCaptcha and reCAPTCHA take light|dark
|
|
1126
|
+
// only and silently fall back to light on anything else, which reads badly
|
|
1127
|
+
// in a dark application.
|
|
1128
|
+
theme: theme === "auto" ? preferredTheme() : theme,
|
|
1129
|
+
size: "invisible"
|
|
1130
|
+
}),
|
|
1131
|
+
teardown
|
|
1132
|
+
}
|
|
1133
|
+
};
|
|
1134
|
+
}
|
|
1135
|
+
});
|
|
1136
|
+
|
|
936
1137
|
// ../../node_modules/.pnpm/qrcode-generator@2.0.4/node_modules/qrcode-generator/dist/qrcode.mjs
|
|
937
1138
|
var qrcode, QRMode, QRErrorCorrectionLevel, QRMaskPattern, QRUtil, QRMath, qrPolynomial, QRRSBlock, qrBitBuffer, qrNumber, qrAlphaNum, qr8BitByte, qrKanji, byteArrayOutputStream, base64EncodeOutputStream, base64DecodeInputStream, gifImage, createDataURL, qrcode_default, stringToBytes;
|
|
938
1139
|
var init_qrcode = __esm({
|
|
@@ -2653,11 +2854,11 @@ var init_model = __esm({
|
|
|
2653
2854
|
// src/components/organization/use-organization-roles.ts
|
|
2654
2855
|
function useOrganizationRoles(organizationId) {
|
|
2655
2856
|
const api = useAuthClient().organization;
|
|
2656
|
-
const apiRef =
|
|
2857
|
+
const apiRef = React50.useRef(api);
|
|
2657
2858
|
apiRef.current = api;
|
|
2658
|
-
const [dynamicRoles, setDynamicRoles] =
|
|
2659
|
-
const requestRef =
|
|
2660
|
-
|
|
2859
|
+
const [dynamicRoles, setDynamicRoles] = React50.useState([]);
|
|
2860
|
+
const requestRef = React50.useRef(0);
|
|
2861
|
+
React50.useEffect(() => {
|
|
2661
2862
|
const token = ++requestRef.current;
|
|
2662
2863
|
setDynamicRoles([]);
|
|
2663
2864
|
if (!organizationId) return;
|
|
@@ -2673,7 +2874,7 @@ function useOrganizationRoles(organizationId) {
|
|
|
2673
2874
|
requestRef.current += 1;
|
|
2674
2875
|
};
|
|
2675
2876
|
}, [organizationId]);
|
|
2676
|
-
const roles =
|
|
2877
|
+
const roles = React50.useMemo(() => {
|
|
2677
2878
|
const seen = /* @__PURE__ */ new Set();
|
|
2678
2879
|
const out = [];
|
|
2679
2880
|
for (const candidate of [...BUILTIN_ROLES, ...dynamicRoles.map((entry) => entry.role)]) {
|
|
@@ -2686,12 +2887,12 @@ function useOrganizationRoles(organizationId) {
|
|
|
2686
2887
|
}, [dynamicRoles]);
|
|
2687
2888
|
return { roles, dynamicRoles };
|
|
2688
2889
|
}
|
|
2689
|
-
var
|
|
2890
|
+
var React50, BUILTIN_ROLES;
|
|
2690
2891
|
var init_use_organization_roles = __esm({
|
|
2691
2892
|
"src/components/organization/use-organization-roles.ts"() {
|
|
2692
2893
|
"use strict";
|
|
2693
2894
|
"use client";
|
|
2694
|
-
|
|
2895
|
+
React50 = __toESM(require("react"), 1);
|
|
2695
2896
|
init_hooks();
|
|
2696
2897
|
BUILTIN_ROLES = ["owner", "admin", "member"];
|
|
2697
2898
|
}
|
|
@@ -2706,12 +2907,12 @@ function useOrganizationListResource({
|
|
|
2706
2907
|
inactiveData = null
|
|
2707
2908
|
}) {
|
|
2708
2909
|
const toServerError = useServerError();
|
|
2709
|
-
const requestFn =
|
|
2910
|
+
const requestFn = React52.useRef(request);
|
|
2710
2911
|
requestFn.current = request;
|
|
2711
|
-
const [data, setData] =
|
|
2712
|
-
const [error, setError] =
|
|
2713
|
-
const requestToken =
|
|
2714
|
-
const refresh =
|
|
2912
|
+
const [data, setData] = React52.useState(null);
|
|
2913
|
+
const [error, setError] = React52.useState(null);
|
|
2914
|
+
const requestToken = React52.useRef(0);
|
|
2915
|
+
const refresh = React52.useCallback(async () => {
|
|
2715
2916
|
const token = ++requestToken.current;
|
|
2716
2917
|
if (!enabled || !resourceKey) {
|
|
2717
2918
|
setData(inactiveData);
|
|
@@ -2731,7 +2932,7 @@ function useOrganizationListResource({
|
|
|
2731
2932
|
if (token === requestToken.current) setError(fallback);
|
|
2732
2933
|
}
|
|
2733
2934
|
}, [enabled, fallback, inactiveData, resourceKey, toServerError]);
|
|
2734
|
-
|
|
2935
|
+
React52.useEffect(() => {
|
|
2735
2936
|
setData(enabled && resourceKey ? null : inactiveData);
|
|
2736
2937
|
setError(null);
|
|
2737
2938
|
void refresh();
|
|
@@ -2741,12 +2942,12 @@ function useOrganizationListResource({
|
|
|
2741
2942
|
}, [enabled, inactiveData, refresh, resourceKey]);
|
|
2742
2943
|
return { data, isLoading: data === null && error === null, error, refresh };
|
|
2743
2944
|
}
|
|
2744
|
-
var
|
|
2945
|
+
var React52;
|
|
2745
2946
|
var init_use_organization_list_resource = __esm({
|
|
2746
2947
|
"src/components/organization/use-organization-list-resource.ts"() {
|
|
2747
2948
|
"use strict";
|
|
2748
2949
|
"use client";
|
|
2749
|
-
|
|
2950
|
+
React52 = __toESM(require("react"), 1);
|
|
2750
2951
|
init_i18n();
|
|
2751
2952
|
}
|
|
2752
2953
|
});
|
|
@@ -2754,7 +2955,7 @@ var init_use_organization_list_resource = __esm({
|
|
|
2754
2955
|
// src/components/organization/use-team-resources.ts
|
|
2755
2956
|
function useTeamsResource(organizationId) {
|
|
2756
2957
|
const api = useAuthClient().organization;
|
|
2757
|
-
const apiRef =
|
|
2958
|
+
const apiRef = React53.useRef(api);
|
|
2758
2959
|
apiRef.current = api;
|
|
2759
2960
|
const t = useT();
|
|
2760
2961
|
const resource = useOrganizationListResource({
|
|
@@ -2767,7 +2968,7 @@ function useTeamsResource(organizationId) {
|
|
|
2767
2968
|
}
|
|
2768
2969
|
function useTeamMembersResource(selectedTeamId) {
|
|
2769
2970
|
const api = useAuthClient().organization;
|
|
2770
|
-
const apiRef =
|
|
2971
|
+
const apiRef = React53.useRef(api);
|
|
2771
2972
|
apiRef.current = api;
|
|
2772
2973
|
const t = useT();
|
|
2773
2974
|
const resource = useOrganizationListResource({
|
|
@@ -2778,12 +2979,12 @@ function useTeamMembersResource(selectedTeamId) {
|
|
|
2778
2979
|
});
|
|
2779
2980
|
return { members: resource.data, error: resource.error, reload: resource.refresh };
|
|
2780
2981
|
}
|
|
2781
|
-
var
|
|
2982
|
+
var React53;
|
|
2782
2983
|
var init_use_team_resources = __esm({
|
|
2783
2984
|
"src/components/organization/use-team-resources.ts"() {
|
|
2784
2985
|
"use strict";
|
|
2785
2986
|
"use client";
|
|
2786
|
-
|
|
2987
|
+
React53 = __toESM(require("react"), 1);
|
|
2787
2988
|
init_hooks();
|
|
2788
2989
|
init_i18n();
|
|
2789
2990
|
init_use_organization_list_resource();
|
|
@@ -2800,7 +3001,7 @@ function TeamMembersPanel({
|
|
|
2800
3001
|
const t = useT();
|
|
2801
3002
|
const api = useAuthClient().organization;
|
|
2802
3003
|
const { pending, error: actionError, run } = useSubmitAction();
|
|
2803
|
-
const [userId, setUserId] =
|
|
3004
|
+
const [userId, setUserId] = React54.useState("");
|
|
2804
3005
|
const { members, error, reload } = useTeamMembersResource(team.id);
|
|
2805
3006
|
const assignedUserIds = new Set(members?.map((member) => member.userId));
|
|
2806
3007
|
const availableMembers = organization.members.filter((member) => !assignedUserIds.has(member.userId));
|
|
@@ -2866,12 +3067,12 @@ function TeamMembersPanel({
|
|
|
2866
3067
|
}) }) : error ? null : members === null ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "ba-skeleton", "aria-label": t("common.loading") }) : members.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { className: "ba-muted", children: t("organization.profile.teams.membersEmpty") }) : null
|
|
2867
3068
|
] });
|
|
2868
3069
|
}
|
|
2869
|
-
var
|
|
3070
|
+
var React54, import_jsx_runtime59;
|
|
2870
3071
|
var init_TeamMembersPanel = __esm({
|
|
2871
3072
|
"src/components/organization/TeamMembersPanel.tsx"() {
|
|
2872
3073
|
"use strict";
|
|
2873
3074
|
"use client";
|
|
2874
|
-
|
|
3075
|
+
React54 = __toESM(require("react"), 1);
|
|
2875
3076
|
init_hooks();
|
|
2876
3077
|
init_i18n();
|
|
2877
3078
|
init_FormError();
|
|
@@ -2896,11 +3097,11 @@ function TeamsSection({
|
|
|
2896
3097
|
const { teams, error: teamsError, reload } = useTeamsResource(organization.id);
|
|
2897
3098
|
const { dynamicRoles } = useOrganizationRoles(organization.id);
|
|
2898
3099
|
const capabilities = teamManagementCapabilities(membership, dynamicRoles);
|
|
2899
|
-
const [name, setName] =
|
|
2900
|
-
const [selectedTeamId, setSelectedTeamId] =
|
|
2901
|
-
const [editingTeamId, setEditingTeamId] =
|
|
2902
|
-
const [editingName, setEditingName] =
|
|
2903
|
-
|
|
3100
|
+
const [name, setName] = React55.useState("");
|
|
3101
|
+
const [selectedTeamId, setSelectedTeamId] = React55.useState(null);
|
|
3102
|
+
const [editingTeamId, setEditingTeamId] = React55.useState(null);
|
|
3103
|
+
const [editingName, setEditingName] = React55.useState("");
|
|
3104
|
+
React55.useEffect(() => {
|
|
2904
3105
|
setSelectedTeamId(null);
|
|
2905
3106
|
setEditingTeamId(null);
|
|
2906
3107
|
setEditingName("");
|
|
@@ -3002,12 +3203,12 @@ function TeamsSection({
|
|
|
3002
3203
|
)
|
|
3003
3204
|
] });
|
|
3004
3205
|
}
|
|
3005
|
-
var
|
|
3206
|
+
var React55, import_jsx_runtime60;
|
|
3006
3207
|
var init_TeamsSection = __esm({
|
|
3007
3208
|
"src/components/organization/TeamsSection.tsx"() {
|
|
3008
3209
|
"use strict";
|
|
3009
3210
|
"use client";
|
|
3010
|
-
|
|
3211
|
+
React55 = __toESM(require("react"), 1);
|
|
3011
3212
|
init_hooks();
|
|
3012
3213
|
init_i18n();
|
|
3013
3214
|
init_FormError();
|
|
@@ -3028,7 +3229,7 @@ __export(index_exports, {
|
|
|
3028
3229
|
AuthLoading: () => AuthLoading,
|
|
3029
3230
|
AuthOwlBadge: () => AuthOwlBadge,
|
|
3030
3231
|
AuthOwlBranding: () => AuthOwlBranding,
|
|
3031
|
-
AuthOwlError: () =>
|
|
3232
|
+
AuthOwlError: () => import_core8.AuthOwlError,
|
|
3032
3233
|
AuthOwlProvider: () => AuthOwlProvider,
|
|
3033
3234
|
BackupCodesManager: () => BackupCodesManager,
|
|
3034
3235
|
Bidi: () => Bidi,
|
|
@@ -3039,7 +3240,7 @@ __export(index_exports, {
|
|
|
3039
3240
|
EmailOtpForm: () => EmailOtpForm,
|
|
3040
3241
|
ForgotPassword: () => ForgotPassword,
|
|
3041
3242
|
GoogleOneTap: () => GoogleOneTap,
|
|
3042
|
-
InvalidKeyError: () =>
|
|
3243
|
+
InvalidKeyError: () => import_core8.InvalidKeyError,
|
|
3043
3244
|
InvitationPrompt: () => InvitationPrompt,
|
|
3044
3245
|
KNOWN_METHODS: () => KNOWN_METHODS,
|
|
3045
3246
|
MFAChallenge: () => MFAChallenge,
|
|
@@ -3053,7 +3254,7 @@ __export(index_exports, {
|
|
|
3053
3254
|
PasskeyManager: () => PasskeyManager,
|
|
3054
3255
|
PhoneOTP: () => PhoneOTP,
|
|
3055
3256
|
Protect: () => Protect,
|
|
3056
|
-
RateLimitedError: () =>
|
|
3257
|
+
RateLimitedError: () => import_core8.RateLimitedError,
|
|
3057
3258
|
ResetPassword: () => ResetPassword,
|
|
3058
3259
|
SignIn: () => SignIn,
|
|
3059
3260
|
SignOutButton: () => SignOutButton,
|
|
@@ -3067,11 +3268,11 @@ __export(index_exports, {
|
|
|
3067
3268
|
VerificationPending: () => VerificationPending,
|
|
3068
3269
|
VerifyEmail: () => VerifyEmail,
|
|
3069
3270
|
Waitlist: () => Waitlist,
|
|
3070
|
-
createMembershipHas: () =>
|
|
3271
|
+
createMembershipHas: () => import_core9.createMembershipHas,
|
|
3071
3272
|
emailAutocomplete: () => emailAutocomplete,
|
|
3072
|
-
membershipHas: () =>
|
|
3073
|
-
membershipHasPermission: () =>
|
|
3074
|
-
membershipHasTeam: () =>
|
|
3273
|
+
membershipHas: () => import_core9.membershipHas,
|
|
3274
|
+
membershipHasPermission: () => import_core9.membershipHasPermission,
|
|
3275
|
+
membershipHasTeam: () => import_core9.membershipHasTeam,
|
|
3075
3276
|
resolveSignInMethods: () => resolveSignInMethods,
|
|
3076
3277
|
useAccount: () => useAccount,
|
|
3077
3278
|
useAuth: () => useAuth,
|
|
@@ -3080,6 +3281,7 @@ __export(index_exports, {
|
|
|
3080
3281
|
useConsent: () => useConsent,
|
|
3081
3282
|
useEmailVerification: () => useEmailVerification,
|
|
3082
3283
|
useInvitationRecipientHint: () => useInvitationRecipientHint,
|
|
3284
|
+
useLastUsedSignInMethod: () => useLastUsedSignInMethod,
|
|
3083
3285
|
useLocale: () => useLocale,
|
|
3084
3286
|
useMFA: () => useMFA,
|
|
3085
3287
|
useOrganization: () => useOrganization,
|
|
@@ -3101,7 +3303,7 @@ init_brand();
|
|
|
3101
3303
|
init_hooks();
|
|
3102
3304
|
|
|
3103
3305
|
// src/project-capabilities.ts
|
|
3104
|
-
var
|
|
3306
|
+
var import_core4 = require("@authowl/core");
|
|
3105
3307
|
|
|
3106
3308
|
// src/signin-methods.ts
|
|
3107
3309
|
var KNOWN_METHODS = [
|
|
@@ -3133,7 +3335,7 @@ function resolveSignInMethods(config, pageHost) {
|
|
|
3133
3335
|
const methods = config?.enabledMethods ?? ["password"];
|
|
3134
3336
|
const social = config?.socialProviders ?? [];
|
|
3135
3337
|
const has = (m) => methods.includes(m);
|
|
3136
|
-
const capabilities = (0,
|
|
3338
|
+
const capabilities = (0, import_core4.resolveProjectCapabilities)(config);
|
|
3137
3339
|
const password = capabilities.passwordSignIn;
|
|
3138
3340
|
const username = capabilities.usernameSignIn;
|
|
3139
3341
|
const magicLink = capabilities.magicLinkSignIn;
|
|
@@ -3172,7 +3374,7 @@ function resolveSignInMethods(config, pageHost) {
|
|
|
3172
3374
|
}
|
|
3173
3375
|
|
|
3174
3376
|
// src/components/SignIn.tsx
|
|
3175
|
-
var
|
|
3377
|
+
var React20 = __toESM(require("react"), 1);
|
|
3176
3378
|
init_hooks();
|
|
3177
3379
|
init_i18n();
|
|
3178
3380
|
|
|
@@ -3238,15 +3440,15 @@ async function finishSignIn(opts) {
|
|
|
3238
3440
|
init_use_submit_action();
|
|
3239
3441
|
|
|
3240
3442
|
// src/components/passkey-autofill.ts
|
|
3241
|
-
var
|
|
3443
|
+
var React8 = __toESM(require("react"), 1);
|
|
3242
3444
|
init_hooks();
|
|
3243
3445
|
function usePasskeyAutofill(opts) {
|
|
3244
3446
|
const { signInPasskey } = useSignIn();
|
|
3245
3447
|
const { sessionStore } = useAuthClient();
|
|
3246
3448
|
const { enabled } = opts;
|
|
3247
|
-
const ref =
|
|
3449
|
+
const ref = React8.useRef({ ...opts, signInPasskey, sessionStore });
|
|
3248
3450
|
ref.current = { ...opts, signInPasskey, sessionStore };
|
|
3249
|
-
|
|
3451
|
+
React8.useEffect(() => {
|
|
3250
3452
|
if (!enabled || typeof window === "undefined") return;
|
|
3251
3453
|
const pkc = window.PublicKeyCredential;
|
|
3252
3454
|
if (!pkc?.isConditionalMediationAvailable) return;
|
|
@@ -3264,9 +3466,13 @@ function usePasskeyAutofill(opts) {
|
|
|
3264
3466
|
}, [enabled]);
|
|
3265
3467
|
}
|
|
3266
3468
|
|
|
3469
|
+
// src/components/SignIn.tsx
|
|
3470
|
+
init_last_used_method();
|
|
3471
|
+
|
|
3267
3472
|
// src/components/SocialButtons.tsx
|
|
3268
|
-
var
|
|
3473
|
+
var React9 = __toESM(require("react"), 1);
|
|
3269
3474
|
init_hooks();
|
|
3475
|
+
init_last_used_method();
|
|
3270
3476
|
init_i18n();
|
|
3271
3477
|
|
|
3272
3478
|
// src/components/social-icons.tsx
|
|
@@ -3345,9 +3551,10 @@ function SocialButtons({ providers, callbackURL }) {
|
|
|
3345
3551
|
const t = useT();
|
|
3346
3552
|
const toServerError = useServerError();
|
|
3347
3553
|
const { signInSocial } = useSignIn();
|
|
3348
|
-
const
|
|
3349
|
-
const [
|
|
3350
|
-
|
|
3554
|
+
const recordSignInMethod = useSignInMethodRecorder();
|
|
3555
|
+
const [pending, setPending] = React9.useState(null);
|
|
3556
|
+
const [error, setError] = React9.useState(null);
|
|
3557
|
+
React9.useEffect(() => {
|
|
3351
3558
|
if (typeof window === "undefined") return;
|
|
3352
3559
|
const url = new URL(window.location.href);
|
|
3353
3560
|
if (!url.searchParams.has("authowl_error")) return;
|
|
@@ -3377,6 +3584,8 @@ function SocialButtons({ providers, callbackURL }) {
|
|
|
3377
3584
|
if (res?.error) {
|
|
3378
3585
|
setError(toServerError(res.error, t("social.error.startFailed")));
|
|
3379
3586
|
setPending(null);
|
|
3587
|
+
} else {
|
|
3588
|
+
recordSignInMethod(`social:${provider}`, true);
|
|
3380
3589
|
}
|
|
3381
3590
|
} catch {
|
|
3382
3591
|
setError(t("social.error.startFailed"));
|
|
@@ -3440,100 +3649,16 @@ init_Spinner();
|
|
|
3440
3649
|
var React10 = __toESM(require("react"), 1);
|
|
3441
3650
|
init_hooks();
|
|
3442
3651
|
init_i18n();
|
|
3652
|
+
init_FormError();
|
|
3443
3653
|
|
|
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" });
|
|
3654
|
+
// src/components/captcha-provider-ids.ts
|
|
3655
|
+
var CAPTCHA_PROVIDER_IDS = ["turnstile", "hcaptcha", "recaptcha-v2"];
|
|
3656
|
+
function isSupportedCaptchaProvider(provider) {
|
|
3657
|
+
return CAPTCHA_PROVIDER_IDS.includes(provider);
|
|
3533
3658
|
}
|
|
3534
3659
|
|
|
3535
3660
|
// src/components/AuthChallenge.tsx
|
|
3536
|
-
var
|
|
3661
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
3537
3662
|
var AUTH_CHALLENGE_ACTIONS = {
|
|
3538
3663
|
signUp: "auth_signup",
|
|
3539
3664
|
signIn: "auth_signin",
|
|
@@ -3548,38 +3673,53 @@ var challengeError = {
|
|
|
3548
3673
|
code: "BOT_CHALLENGE_FAILED",
|
|
3549
3674
|
message: "Human verification failed."
|
|
3550
3675
|
};
|
|
3551
|
-
function
|
|
3676
|
+
function captchaTheme(root, fallback) {
|
|
3552
3677
|
const rendered = root?.dataset.authowlTheme;
|
|
3553
3678
|
if (rendered === "light" || rendered === "dark") return rendered;
|
|
3554
3679
|
if (fallback === "light" || fallback === "dark") return fallback;
|
|
3555
3680
|
return "auto";
|
|
3556
3681
|
}
|
|
3557
3682
|
function useAuthChallenge() {
|
|
3558
|
-
const { config, isLoading } = usePublicConfig();
|
|
3683
|
+
const { config, isLoading, retry } = usePublicConfig();
|
|
3559
3684
|
const t = useT();
|
|
3560
3685
|
const container = React10.useRef(null);
|
|
3561
3686
|
const active = React10.useRef(null);
|
|
3562
3687
|
const [status, setStatus] = React10.useState("idle");
|
|
3563
|
-
const
|
|
3688
|
+
const captcha = config?.captcha ?? null;
|
|
3689
|
+
const providerSupported = captcha ? isSupportedCaptchaProvider(captcha.provider) : false;
|
|
3690
|
+
const unavailableProvider = captcha && !providerSupported ? captcha.provider : null;
|
|
3691
|
+
const refetched = React10.useRef(null);
|
|
3692
|
+
const refetchIfConfigMayBeStale = React10.useCallback(() => {
|
|
3693
|
+
if (!config || refetched.current === config) return;
|
|
3694
|
+
refetched.current = config;
|
|
3695
|
+
retry();
|
|
3696
|
+
}, [config, retry]);
|
|
3564
3697
|
const removeActive = React10.useCallback((reason) => {
|
|
3565
3698
|
const current = active.current;
|
|
3566
3699
|
active.current = null;
|
|
3567
3700
|
if (!current) return;
|
|
3568
|
-
current.
|
|
3701
|
+
current.adapter.teardown(current.api, current.id);
|
|
3569
3702
|
if (reason) current.reject(reason);
|
|
3570
3703
|
}, []);
|
|
3571
3704
|
React10.useEffect(
|
|
3572
|
-
() => () => removeActive(new Error("
|
|
3705
|
+
() => () => removeActive(new Error("Captcha challenge was cancelled")),
|
|
3573
3706
|
[removeActive]
|
|
3574
3707
|
);
|
|
3575
3708
|
const tokenFor = React10.useCallback(
|
|
3576
3709
|
async (action) => {
|
|
3577
|
-
if (!
|
|
3710
|
+
if (!captcha) return null;
|
|
3711
|
+
if (!providerSupported) throw new Error(`Unsupported captcha provider: ${captcha.provider}`);
|
|
3578
3712
|
setStatus("checking");
|
|
3579
|
-
removeActive(new Error("
|
|
3713
|
+
removeActive(new Error("Captcha challenge was replaced"));
|
|
3580
3714
|
try {
|
|
3581
|
-
const
|
|
3582
|
-
|
|
3715
|
+
const [{ loadCaptcha: loadCaptcha2 }, { captchaAdapterFor: captchaAdapterFor2 }] = await Promise.all([
|
|
3716
|
+
Promise.resolve().then(() => (init_captcha_loader(), captcha_loader_exports)),
|
|
3717
|
+
Promise.resolve().then(() => (init_captcha_providers(), captcha_providers_exports))
|
|
3718
|
+
]);
|
|
3719
|
+
const adapter = captchaAdapterFor2(captcha.provider);
|
|
3720
|
+
if (!adapter) throw new Error(`Unsupported captcha provider: ${captcha.provider}`);
|
|
3721
|
+
const api = await loadCaptcha2(adapter);
|
|
3722
|
+
if (!container.current) throw new Error("Captcha container unavailable");
|
|
3583
3723
|
return await new Promise((resolve, reject) => {
|
|
3584
3724
|
let settled = false;
|
|
3585
3725
|
const finish = (outcome) => {
|
|
@@ -3587,27 +3727,29 @@ function useAuthChallenge() {
|
|
|
3587
3727
|
settled = true;
|
|
3588
3728
|
const current = active.current;
|
|
3589
3729
|
active.current = null;
|
|
3590
|
-
if (current) current.
|
|
3730
|
+
if (current) current.adapter.teardown(current.api, current.id);
|
|
3591
3731
|
if ("token" in outcome) resolve(outcome.token);
|
|
3592
3732
|
else reject(outcome.error);
|
|
3593
3733
|
};
|
|
3594
|
-
const fail = () => finish({ error: new Error("
|
|
3734
|
+
const fail = () => finish({ error: new Error("Captcha challenge failed") });
|
|
3595
3735
|
const root = container.current.closest(".authowl-root");
|
|
3736
|
+
const optionalFailureCallbacks = captcha.provider === "turnstile" ? {
|
|
3737
|
+
"timeout-callback": fail,
|
|
3738
|
+
"unsupported-callback": fail
|
|
3739
|
+
} : {};
|
|
3596
3740
|
const id = api.render(container.current, {
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
language: root?.dataset.authowlLocale ?? config?.locale,
|
|
3741
|
+
...adapter.invisibleRenderOptions({
|
|
3742
|
+
siteKey: captcha.siteKey,
|
|
3743
|
+
theme: captchaTheme(root, config?.branding?.theme),
|
|
3744
|
+
action,
|
|
3745
|
+
language: root?.dataset.authowlLocale ?? config?.locale
|
|
3746
|
+
}),
|
|
3604
3747
|
callback: (token) => finish({ token }),
|
|
3605
3748
|
"expired-callback": fail,
|
|
3606
3749
|
"error-callback": fail,
|
|
3607
|
-
|
|
3608
|
-
"unsupported-callback": fail
|
|
3750
|
+
...optionalFailureCallbacks
|
|
3609
3751
|
});
|
|
3610
|
-
active.current = { api, id, reject };
|
|
3752
|
+
active.current = { adapter, api, id, reject };
|
|
3611
3753
|
try {
|
|
3612
3754
|
api.execute(id);
|
|
3613
3755
|
} catch {
|
|
@@ -3618,7 +3760,7 @@ function useAuthChallenge() {
|
|
|
3618
3760
|
setStatus("idle");
|
|
3619
3761
|
}
|
|
3620
3762
|
},
|
|
3621
|
-
[config?.branding?.theme, config?.locale,
|
|
3763
|
+
[captcha, config?.branding?.theme, config?.locale, providerSupported, removeActive]
|
|
3622
3764
|
);
|
|
3623
3765
|
const run = React10.useCallback(
|
|
3624
3766
|
async (action, request) => {
|
|
@@ -3630,27 +3772,30 @@ function useAuthChallenge() {
|
|
|
3630
3772
|
}
|
|
3631
3773
|
try {
|
|
3632
3774
|
const token = await tokenFor(action);
|
|
3633
|
-
|
|
3775
|
+
const result = await request(token ? { authChallengeToken: token } : void 0);
|
|
3776
|
+
if (result?.error?.code === challengeError.code) refetchIfConfigMayBeStale();
|
|
3777
|
+
return result;
|
|
3634
3778
|
} catch {
|
|
3635
3779
|
setStatus("failed");
|
|
3780
|
+
refetchIfConfigMayBeStale();
|
|
3636
3781
|
return {
|
|
3637
3782
|
data: null,
|
|
3638
3783
|
error: challengeError
|
|
3639
3784
|
};
|
|
3640
3785
|
}
|
|
3641
3786
|
},
|
|
3642
|
-
[isLoading, tokenFor]
|
|
3787
|
+
[isLoading, refetchIfConfigMayBeStale, tokenFor]
|
|
3643
3788
|
);
|
|
3644
|
-
const control =
|
|
3645
|
-
/* @__PURE__ */ (0,
|
|
3646
|
-
/* @__PURE__ */ (0,
|
|
3789
|
+
const control = captcha ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "ba-auth-challenge", "data-testid": "auth-challenge", children: [
|
|
3790
|
+
providerSupported ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "ba-turnstile", ref: container }) : null,
|
|
3791
|
+
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
3792
|
] }) : null;
|
|
3648
3793
|
return { run, control, configPending: isLoading };
|
|
3649
3794
|
}
|
|
3650
3795
|
|
|
3651
3796
|
// src/components/ForgotPassword.tsx
|
|
3652
3797
|
init_FormError();
|
|
3653
|
-
var
|
|
3798
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
3654
3799
|
function ForgotPassword({ resetPasswordUrl, onBack }) {
|
|
3655
3800
|
const t = useT();
|
|
3656
3801
|
const { requestPasswordReset } = usePasswordReset();
|
|
@@ -3659,12 +3804,12 @@ function ForgotPassword({ resetPasswordUrl, onBack }) {
|
|
|
3659
3804
|
const [email, setEmail] = React11.useState("");
|
|
3660
3805
|
const [sent, setSent] = React11.useState(false);
|
|
3661
3806
|
if (sent) {
|
|
3662
|
-
return /* @__PURE__ */ (0,
|
|
3663
|
-
/* @__PURE__ */ (0,
|
|
3664
|
-
onBack && /* @__PURE__ */ (0,
|
|
3807
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ba-fields", "data-testid": "forgot-sent", children: [
|
|
3808
|
+
/* @__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 }) }) }),
|
|
3809
|
+
onBack && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "ba-link-button", onClick: onBack, children: t("forgotPassword.backToSignIn") })
|
|
3665
3810
|
] });
|
|
3666
3811
|
}
|
|
3667
|
-
return /* @__PURE__ */ (0,
|
|
3812
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
3668
3813
|
"form",
|
|
3669
3814
|
{
|
|
3670
3815
|
method: "post",
|
|
@@ -3678,9 +3823,9 @@ function ForgotPassword({ resetPasswordUrl, onBack }) {
|
|
|
3678
3823
|
});
|
|
3679
3824
|
},
|
|
3680
3825
|
children: [
|
|
3681
|
-
/* @__PURE__ */ (0,
|
|
3826
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "ba-label", children: [
|
|
3682
3827
|
t("common.emailLabel"),
|
|
3683
|
-
/* @__PURE__ */ (0,
|
|
3828
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3684
3829
|
"input",
|
|
3685
3830
|
{
|
|
3686
3831
|
className: "ba-input",
|
|
@@ -3693,18 +3838,18 @@ function ForgotPassword({ resetPasswordUrl, onBack }) {
|
|
|
3693
3838
|
)
|
|
3694
3839
|
] }),
|
|
3695
3840
|
authChallenge.control,
|
|
3696
|
-
/* @__PURE__ */ (0,
|
|
3697
|
-
/* @__PURE__ */ (0,
|
|
3841
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(FormError, { children: error }),
|
|
3842
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3698
3843
|
"button",
|
|
3699
3844
|
{
|
|
3700
3845
|
className: "ba-button",
|
|
3701
3846
|
type: "submit",
|
|
3702
3847
|
disabled: pending || authChallenge.configPending,
|
|
3703
3848
|
"aria-busy": pending || void 0,
|
|
3704
|
-
children: /* @__PURE__ */ (0,
|
|
3849
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Busy, { busy: pending, label: t("common.sending"), children: t("forgotPassword.submit") })
|
|
3705
3850
|
}
|
|
3706
3851
|
),
|
|
3707
|
-
onBack && /* @__PURE__ */ (0,
|
|
3852
|
+
onBack && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "ba-link-button", onClick: onBack, children: t("forgotPassword.backToSignIn") })
|
|
3708
3853
|
]
|
|
3709
3854
|
}
|
|
3710
3855
|
);
|
|
@@ -3714,7 +3859,7 @@ function ForgotPassword({ resetPasswordUrl, onBack }) {
|
|
|
3714
3859
|
init_i18n();
|
|
3715
3860
|
init_Spinner();
|
|
3716
3861
|
init_FormError();
|
|
3717
|
-
var
|
|
3862
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
3718
3863
|
function OtpCodeForm({
|
|
3719
3864
|
email,
|
|
3720
3865
|
code,
|
|
@@ -3725,7 +3870,7 @@ function OtpCodeForm({
|
|
|
3725
3870
|
error
|
|
3726
3871
|
}) {
|
|
3727
3872
|
const t = useT();
|
|
3728
|
-
return /* @__PURE__ */ (0,
|
|
3873
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
3729
3874
|
"form",
|
|
3730
3875
|
{
|
|
3731
3876
|
method: "post",
|
|
@@ -3736,9 +3881,9 @@ function OtpCodeForm({
|
|
|
3736
3881
|
onSubmit();
|
|
3737
3882
|
},
|
|
3738
3883
|
children: [
|
|
3739
|
-
/* @__PURE__ */ (0,
|
|
3740
|
-
richMessage(t("emailOtp.codeLabel"), { email: /* @__PURE__ */ (0,
|
|
3741
|
-
/* @__PURE__ */ (0,
|
|
3884
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("label", { className: "ba-label", children: [
|
|
3885
|
+
richMessage(t("emailOtp.codeLabel"), { email: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Bidi, { children: email }) }),
|
|
3886
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
3742
3887
|
"input",
|
|
3743
3888
|
{
|
|
3744
3889
|
className: "ba-input",
|
|
@@ -3751,9 +3896,9 @@ function OtpCodeForm({
|
|
|
3751
3896
|
}
|
|
3752
3897
|
)
|
|
3753
3898
|
] }),
|
|
3754
|
-
/* @__PURE__ */ (0,
|
|
3755
|
-
/* @__PURE__ */ (0,
|
|
3756
|
-
/* @__PURE__ */ (0,
|
|
3899
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(FormError, { children: error }),
|
|
3900
|
+
/* @__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") }) }),
|
|
3901
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "ba-link-button", onClick: onChangeEmail, children: t("emailOtp.changeEmail") })
|
|
3757
3902
|
]
|
|
3758
3903
|
}
|
|
3759
3904
|
);
|
|
@@ -3766,7 +3911,7 @@ init_i18n();
|
|
|
3766
3911
|
init_use_submit_action();
|
|
3767
3912
|
init_Spinner();
|
|
3768
3913
|
init_FormError();
|
|
3769
|
-
var
|
|
3914
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
3770
3915
|
function MFAChallenge({ onVerified, allowTrustDevice = true }) {
|
|
3771
3916
|
const t = useT();
|
|
3772
3917
|
const { verifyTotp, verifyBackupCode, sendOtp, verifyOtp } = useMFA();
|
|
@@ -3796,12 +3941,12 @@ function MFAChallenge({ onVerified, allowTrustDevice = true }) {
|
|
|
3796
3941
|
};
|
|
3797
3942
|
const hint = mode === "totp" ? t("mfa.challenge.totpHint") : mode === "backup" ? t("mfa.challenge.backupHint") : t("mfa.challenge.otpHint");
|
|
3798
3943
|
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,
|
|
3944
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("form", { method: "post", className: "ba-fields", "data-testid": "mfa-challenge", onSubmit: submit, children: [
|
|
3945
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h2", { className: "ba-title", children: t("mfa.challenge.title") }),
|
|
3946
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "ba-muted", children: hint }),
|
|
3947
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "ba-label", children: [
|
|
3803
3948
|
label2,
|
|
3804
|
-
/* @__PURE__ */ (0,
|
|
3949
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3805
3950
|
"input",
|
|
3806
3951
|
{
|
|
3807
3952
|
className: "ba-input",
|
|
@@ -3817,18 +3962,18 @@ function MFAChallenge({ onVerified, allowTrustDevice = true }) {
|
|
|
3817
3962
|
}
|
|
3818
3963
|
)
|
|
3819
3964
|
] }),
|
|
3820
|
-
mode !== "backup" && allowTrustDevice && /* @__PURE__ */ (0,
|
|
3821
|
-
/* @__PURE__ */ (0,
|
|
3822
|
-
/* @__PURE__ */ (0,
|
|
3823
|
-
/* @__PURE__ */ (0,
|
|
3965
|
+
mode !== "backup" && allowTrustDevice && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "ba-consent ba-consent-centered", children: [
|
|
3966
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "ba-checkbox-control", children: [
|
|
3967
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { className: "ba-checkbox", type: "checkbox", checked: trustDevice, onChange: (e) => setTrustDevice(e.target.checked) }),
|
|
3968
|
+
/* @__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
3969
|
] }),
|
|
3825
|
-
/* @__PURE__ */ (0,
|
|
3970
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: t("mfa.challenge.trustDevice", { days: 30 }) })
|
|
3826
3971
|
] }),
|
|
3827
|
-
/* @__PURE__ */ (0,
|
|
3828
|
-
/* @__PURE__ */ (0,
|
|
3829
|
-
mode !== "totp" && /* @__PURE__ */ (0,
|
|
3830
|
-
mode !== "backup" && /* @__PURE__ */ (0,
|
|
3831
|
-
/* @__PURE__ */ (0,
|
|
3972
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FormError, { children: error }),
|
|
3973
|
+
/* @__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") }) }),
|
|
3974
|
+
mode !== "totp" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "ba-link-button", onClick: () => switchMode("totp"), children: t("mfa.challenge.useTotp") }),
|
|
3975
|
+
mode !== "backup" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "ba-link-button", onClick: () => switchMode("backup"), children: t("mfa.challenge.useBackup") }),
|
|
3976
|
+
/* @__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
3977
|
] });
|
|
3833
3978
|
}
|
|
3834
3979
|
|
|
@@ -3853,7 +3998,7 @@ function shouldDiscardSetup(args) {
|
|
|
3853
3998
|
// src/components/QrCode.tsx
|
|
3854
3999
|
var React13 = __toESM(require("react"), 1);
|
|
3855
4000
|
init_i18n();
|
|
3856
|
-
var
|
|
4001
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
3857
4002
|
function QrCode({ value, size = 200 }) {
|
|
3858
4003
|
const t = useT();
|
|
3859
4004
|
const [path, setPath] = React13.useState(null);
|
|
@@ -3875,7 +4020,7 @@ function QrCode({ value, size = 200 }) {
|
|
|
3875
4020
|
if (!path) return null;
|
|
3876
4021
|
const margin = 4;
|
|
3877
4022
|
const dim = path.count + margin * 2;
|
|
3878
|
-
return /* @__PURE__ */ (0,
|
|
4023
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3879
4024
|
"svg",
|
|
3880
4025
|
{
|
|
3881
4026
|
width: size,
|
|
@@ -3886,8 +4031,8 @@ function QrCode({ value, size = 200 }) {
|
|
|
3886
4031
|
shapeRendering: "crispEdges",
|
|
3887
4032
|
className: "ba-qr",
|
|
3888
4033
|
children: [
|
|
3889
|
-
/* @__PURE__ */ (0,
|
|
3890
|
-
/* @__PURE__ */ (0,
|
|
4034
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("rect", { width: dim, height: dim, fill: "#ffffff" }),
|
|
4035
|
+
/* @__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
4036
|
]
|
|
3892
4037
|
}
|
|
3893
4038
|
);
|
|
@@ -3895,7 +4040,7 @@ function QrCode({ value, size = 200 }) {
|
|
|
3895
4040
|
|
|
3896
4041
|
// src/components/MFAEnrollment.tsx
|
|
3897
4042
|
init_FormError();
|
|
3898
|
-
var
|
|
4043
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3899
4044
|
function secretFromUri(uri) {
|
|
3900
4045
|
try {
|
|
3901
4046
|
return new URL(uri).searchParams.get("secret");
|
|
@@ -3929,22 +4074,22 @@ function MFAEnrollment({ onEnrolled, title }) {
|
|
|
3929
4074
|
}
|
|
3930
4075
|
}, [stale]);
|
|
3931
4076
|
if (done) {
|
|
3932
|
-
return /* @__PURE__ */ (0,
|
|
3933
|
-
/* @__PURE__ */ (0,
|
|
3934
|
-
/* @__PURE__ */ (0,
|
|
4077
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "ba-fields", "data-testid": "mfa-enroll-done", children: [
|
|
4078
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h2", { className: "ba-title", children: t("mfa.enroll.doneTitle") }),
|
|
4079
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "ba-muted", children: t("mfa.enroll.doneBody") })
|
|
3935
4080
|
] });
|
|
3936
4081
|
}
|
|
3937
4082
|
if (!activeSetup) {
|
|
3938
4083
|
if (!isLoaded) {
|
|
3939
|
-
return /* @__PURE__ */ (0,
|
|
4084
|
+
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
4085
|
}
|
|
3941
4086
|
if (user?.twoFactorEnabled) {
|
|
3942
|
-
return /* @__PURE__ */ (0,
|
|
3943
|
-
/* @__PURE__ */ (0,
|
|
3944
|
-
/* @__PURE__ */ (0,
|
|
4087
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "ba-fields", "data-testid": "mfa-enroll-active", children: [
|
|
4088
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h2", { className: "ba-title", children: t("mfa.enroll.activeTitle") }),
|
|
4089
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "ba-muted", children: t("mfa.enroll.activeBody") })
|
|
3945
4090
|
] });
|
|
3946
4091
|
}
|
|
3947
|
-
return /* @__PURE__ */ (0,
|
|
4092
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
3948
4093
|
"form",
|
|
3949
4094
|
{
|
|
3950
4095
|
method: "post",
|
|
@@ -3961,11 +4106,11 @@ function MFAEnrollment({ onEnrolled, title }) {
|
|
|
3961
4106
|
});
|
|
3962
4107
|
},
|
|
3963
4108
|
children: [
|
|
3964
|
-
title !== null && /* @__PURE__ */ (0,
|
|
3965
|
-
/* @__PURE__ */ (0,
|
|
3966
|
-
/* @__PURE__ */ (0,
|
|
4109
|
+
title !== null && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h2", { className: "ba-title", children: title ?? t("mfa.enroll.title") }),
|
|
4110
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "ba-muted", children: t("mfa.enroll.passwordHint") }),
|
|
4111
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "ba-label", children: [
|
|
3967
4112
|
t("common.passwordLabel"),
|
|
3968
|
-
/* @__PURE__ */ (0,
|
|
4113
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3969
4114
|
"input",
|
|
3970
4115
|
{
|
|
3971
4116
|
className: "ba-input",
|
|
@@ -3977,29 +4122,29 @@ function MFAEnrollment({ onEnrolled, title }) {
|
|
|
3977
4122
|
}
|
|
3978
4123
|
)
|
|
3979
4124
|
] }),
|
|
3980
|
-
/* @__PURE__ */ (0,
|
|
3981
|
-
/* @__PURE__ */ (0,
|
|
4125
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(FormError, { children: error }),
|
|
4126
|
+
/* @__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
4127
|
]
|
|
3983
4128
|
}
|
|
3984
4129
|
);
|
|
3985
4130
|
}
|
|
3986
4131
|
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,
|
|
4132
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "ba-fields", "data-testid": "mfa-enroll-verify", children: [
|
|
4133
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("h2", { className: "ba-title", children: t("mfa.enroll.scanQrTitle") }),
|
|
4134
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "ba-muted", children: t("mfa.enroll.scanQrHint") }),
|
|
4135
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(QrCode, { value: activeSetup.totpURI }),
|
|
4136
|
+
secret && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "ba-muted", children: richMessage(t("mfa.enroll.manualKey"), {
|
|
4137
|
+
secret: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("code", { className: "ba-code", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Bidi, { children: secret }) })
|
|
3993
4138
|
}) }),
|
|
3994
|
-
/* @__PURE__ */ (0,
|
|
3995
|
-
/* @__PURE__ */ (0,
|
|
3996
|
-
/* @__PURE__ */ (0,
|
|
4139
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { children: [
|
|
4140
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("p", { className: "ba-muted", children: [
|
|
4141
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("strong", { children: t("mfa.enroll.backupCodesWarningStrong") }),
|
|
3997
4142
|
" ",
|
|
3998
4143
|
t("mfa.enroll.backupCodesWarningRest")
|
|
3999
4144
|
] }),
|
|
4000
|
-
/* @__PURE__ */ (0,
|
|
4145
|
+
/* @__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
4146
|
] }),
|
|
4002
|
-
/* @__PURE__ */ (0,
|
|
4147
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
4003
4148
|
"form",
|
|
4004
4149
|
{
|
|
4005
4150
|
method: "post",
|
|
@@ -4017,9 +4162,9 @@ function MFAEnrollment({ onEnrolled, title }) {
|
|
|
4017
4162
|
});
|
|
4018
4163
|
},
|
|
4019
4164
|
children: [
|
|
4020
|
-
/* @__PURE__ */ (0,
|
|
4165
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("label", { className: "ba-label", children: [
|
|
4021
4166
|
t("mfa.enroll.codeLabel"),
|
|
4022
|
-
/* @__PURE__ */ (0,
|
|
4167
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
4023
4168
|
"input",
|
|
4024
4169
|
{
|
|
4025
4170
|
className: "ba-input",
|
|
@@ -4031,8 +4176,8 @@ function MFAEnrollment({ onEnrolled, title }) {
|
|
|
4031
4176
|
}
|
|
4032
4177
|
)
|
|
4033
4178
|
] }),
|
|
4034
|
-
/* @__PURE__ */ (0,
|
|
4035
|
-
/* @__PURE__ */ (0,
|
|
4179
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(FormError, { children: error }),
|
|
4180
|
+
/* @__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
4181
|
]
|
|
4037
4182
|
}
|
|
4038
4183
|
)
|
|
@@ -4040,7 +4185,7 @@ function MFAEnrollment({ onEnrolled, title }) {
|
|
|
4040
4185
|
}
|
|
4041
4186
|
|
|
4042
4187
|
// src/components/mfa-enrollment-step.tsx
|
|
4043
|
-
var
|
|
4188
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
4044
4189
|
function useConfirmedMfaPending(onUnknown = "pending") {
|
|
4045
4190
|
const client = useAuthClient();
|
|
4046
4191
|
const { needsMfaEnrollment } = useUser();
|
|
@@ -4070,32 +4215,32 @@ function useConfirmedMfaPending(onUnknown = "pending") {
|
|
|
4070
4215
|
function MfaEnrollmentStep({ title }) {
|
|
4071
4216
|
const t = useT();
|
|
4072
4217
|
const { refetch } = useSession();
|
|
4073
|
-
return /* @__PURE__ */ (0,
|
|
4074
|
-
/* @__PURE__ */ (0,
|
|
4075
|
-
/* @__PURE__ */ (0,
|
|
4076
|
-
/* @__PURE__ */ (0,
|
|
4218
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
4219
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h2", { className: "ba-title", children: title ?? t("mfaGate.title") }),
|
|
4220
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "ba-muted", children: t("mfaGate.body") }),
|
|
4221
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MFAEnrollment, { onEnrolled: () => refetch({ query: { disableCookieCache: true } }) })
|
|
4077
4222
|
] });
|
|
4078
4223
|
}
|
|
4079
4224
|
|
|
4080
4225
|
// src/components/AuthOwlBadge.tsx
|
|
4081
4226
|
init_hooks();
|
|
4082
4227
|
init_i18n();
|
|
4083
|
-
var
|
|
4228
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
4084
4229
|
function OwlMark() {
|
|
4085
|
-
return /* @__PURE__ */ (0,
|
|
4086
|
-
/* @__PURE__ */ (0,
|
|
4087
|
-
/* @__PURE__ */ (0,
|
|
4088
|
-
/* @__PURE__ */ (0,
|
|
4089
|
-
/* @__PURE__ */ (0,
|
|
4090
|
-
/* @__PURE__ */ (0,
|
|
4091
|
-
/* @__PURE__ */ (0,
|
|
4230
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { className: "ba-badge-mark", viewBox: "0 0 24 24", "aria-hidden": "true", focusable: "false", children: [
|
|
4231
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "12", cy: "12", r: "11", fill: "#F5B84C" }),
|
|
4232
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "8.4", cy: "10", r: "3", fill: "#fff" }),
|
|
4233
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "15.6", cy: "10", r: "3", fill: "#fff" }),
|
|
4234
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "8.4", cy: "10", r: "1.4", fill: "#1f1300" }),
|
|
4235
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "15.6", cy: "10", r: "1.4", fill: "#1f1300" }),
|
|
4236
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M12 13.1l1.5 2.1h-3z", fill: "#1f1300" })
|
|
4092
4237
|
] });
|
|
4093
4238
|
}
|
|
4094
4239
|
function AuthOwlBadge({ href = "https://authowl.dev", force } = {}) {
|
|
4095
4240
|
const t = useT();
|
|
4096
4241
|
const { config } = usePublicConfig();
|
|
4097
4242
|
if (!force && !config?.badge) return null;
|
|
4098
|
-
return /* @__PURE__ */ (0,
|
|
4243
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
4099
4244
|
"a",
|
|
4100
4245
|
{
|
|
4101
4246
|
className: "ba-badge",
|
|
@@ -4104,9 +4249,9 @@ function AuthOwlBadge({ href = "https://authowl.dev", force } = {}) {
|
|
|
4104
4249
|
rel: "noopener noreferrer",
|
|
4105
4250
|
"data-testid": "authowl-badge",
|
|
4106
4251
|
children: [
|
|
4107
|
-
/* @__PURE__ */ (0,
|
|
4108
|
-
/* @__PURE__ */ (0,
|
|
4109
|
-
brand: /* @__PURE__ */ (0,
|
|
4252
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(OwlMark, {}),
|
|
4253
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: richMessage(t("badge.securedBy"), {
|
|
4254
|
+
brand: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "ba-badge-brand", children: "AuthOwl" })
|
|
4110
4255
|
}) })
|
|
4111
4256
|
]
|
|
4112
4257
|
}
|
|
@@ -4117,8 +4262,8 @@ function AuthOwlBadge({ href = "https://authowl.dev", force } = {}) {
|
|
|
4117
4262
|
init_Spinner();
|
|
4118
4263
|
|
|
4119
4264
|
// src/components/PhoneOTP.tsx
|
|
4120
|
-
var
|
|
4121
|
-
var
|
|
4265
|
+
var React17 = __toESM(require("react"), 1);
|
|
4266
|
+
var import_core5 = require("@authowl/core");
|
|
4122
4267
|
init_hooks();
|
|
4123
4268
|
init_i18n();
|
|
4124
4269
|
|
|
@@ -4127,19 +4272,19 @@ init_i18n();
|
|
|
4127
4272
|
|
|
4128
4273
|
// src/components/ConsentDocLinks.tsx
|
|
4129
4274
|
init_i18n();
|
|
4130
|
-
var
|
|
4275
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
4131
4276
|
function ConsentDocLinks({ termsUrl, privacyUrl }) {
|
|
4132
4277
|
const t = useT();
|
|
4133
4278
|
if (!termsUrl && !privacyUrl) return null;
|
|
4134
|
-
return /* @__PURE__ */ (0,
|
|
4135
|
-
termsUrl && /* @__PURE__ */ (0,
|
|
4279
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
4280
|
+
termsUrl && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("a", { href: termsUrl, target: "_blank", rel: "noopener noreferrer", children: t("consent.termsOfService") }),
|
|
4136
4281
|
termsUrl && privacyUrl && t("consent.docJoiner"),
|
|
4137
|
-
privacyUrl && /* @__PURE__ */ (0,
|
|
4282
|
+
privacyUrl && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("a", { href: privacyUrl, target: "_blank", rel: "noopener noreferrer", children: t("consent.privacyPolicy") })
|
|
4138
4283
|
] });
|
|
4139
4284
|
}
|
|
4140
4285
|
|
|
4141
4286
|
// src/components/LegalConsentCheckbox.tsx
|
|
4142
|
-
var
|
|
4287
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
4143
4288
|
function LegalConsentCheckbox({
|
|
4144
4289
|
legal,
|
|
4145
4290
|
accepted,
|
|
@@ -4148,9 +4293,9 @@ function LegalConsentCheckbox({
|
|
|
4148
4293
|
}) {
|
|
4149
4294
|
const t = useT();
|
|
4150
4295
|
if (!legal.required) return null;
|
|
4151
|
-
return /* @__PURE__ */ (0,
|
|
4152
|
-
/* @__PURE__ */ (0,
|
|
4153
|
-
/* @__PURE__ */ (0,
|
|
4296
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { className: "ba-consent", "data-testid": testId, children: [
|
|
4297
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "ba-checkbox-control", children: [
|
|
4298
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4154
4299
|
"input",
|
|
4155
4300
|
{
|
|
4156
4301
|
className: "ba-checkbox",
|
|
@@ -4159,14 +4304,69 @@ function LegalConsentCheckbox({
|
|
|
4159
4304
|
onChange: (event) => onAcceptedChange(event.target.checked)
|
|
4160
4305
|
}
|
|
4161
4306
|
),
|
|
4162
|
-
/* @__PURE__ */ (0,
|
|
4307
|
+
/* @__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
4308
|
] }),
|
|
4164
|
-
/* @__PURE__ */ (0,
|
|
4165
|
-
links: /* @__PURE__ */ (0,
|
|
4309
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: richMessage(t("signUp.consentLabel"), {
|
|
4310
|
+
links: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ConsentDocLinks, { termsUrl: legal.termsUrl, privacyUrl: legal.privacyUrl })
|
|
4166
4311
|
}) })
|
|
4167
4312
|
] });
|
|
4168
4313
|
}
|
|
4169
4314
|
|
|
4315
|
+
// src/components/Turnstile.tsx
|
|
4316
|
+
var React16 = __toESM(require("react"), 1);
|
|
4317
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
4318
|
+
var LOCAL_TURNSTILE_TEST_TOKEN = "XXXX.DUMMY.TOKEN.XXXX";
|
|
4319
|
+
async function loadTurnstile() {
|
|
4320
|
+
const [{ loadCaptcha: loadCaptcha2 }, { CAPTCHA_ADAPTERS: CAPTCHA_ADAPTERS2 }] = await Promise.all([
|
|
4321
|
+
Promise.resolve().then(() => (init_captcha_loader(), captcha_loader_exports)),
|
|
4322
|
+
Promise.resolve().then(() => (init_captcha_providers(), captcha_providers_exports))
|
|
4323
|
+
]);
|
|
4324
|
+
const adapter = CAPTCHA_ADAPTERS2.turnstile;
|
|
4325
|
+
return { api: await loadCaptcha2(adapter), adapter };
|
|
4326
|
+
}
|
|
4327
|
+
function Turnstile({
|
|
4328
|
+
siteKey,
|
|
4329
|
+
theme,
|
|
4330
|
+
onToken,
|
|
4331
|
+
onUnavailable
|
|
4332
|
+
}) {
|
|
4333
|
+
const container = React16.useRef(null);
|
|
4334
|
+
const callbacks = React16.useRef({ onToken, onUnavailable });
|
|
4335
|
+
callbacks.current = { onToken, onUnavailable };
|
|
4336
|
+
React16.useEffect(() => {
|
|
4337
|
+
callbacks.current.onToken(null);
|
|
4338
|
+
if (!siteKey) {
|
|
4339
|
+
callbacks.current.onToken(LOCAL_TURNSTILE_TEST_TOKEN);
|
|
4340
|
+
return;
|
|
4341
|
+
}
|
|
4342
|
+
let active = true;
|
|
4343
|
+
let widget = null;
|
|
4344
|
+
void loadTurnstile().then(({ api, adapter }) => {
|
|
4345
|
+
if (!active || !container.current) return;
|
|
4346
|
+
const id = api.render(container.current, {
|
|
4347
|
+
sitekey: siteKey,
|
|
4348
|
+
theme: theme === "system" ? "auto" : theme,
|
|
4349
|
+
size: "flexible",
|
|
4350
|
+
callback: (token) => callbacks.current.onToken(token),
|
|
4351
|
+
"expired-callback": () => callbacks.current.onToken(null),
|
|
4352
|
+
"error-callback": () => {
|
|
4353
|
+
callbacks.current.onToken(null);
|
|
4354
|
+
callbacks.current.onUnavailable();
|
|
4355
|
+
}
|
|
4356
|
+
});
|
|
4357
|
+
widget = { api, adapter, id };
|
|
4358
|
+
}).catch(() => {
|
|
4359
|
+
if (active) callbacks.current.onUnavailable();
|
|
4360
|
+
});
|
|
4361
|
+
return () => {
|
|
4362
|
+
active = false;
|
|
4363
|
+
if (widget) widget.adapter.teardown(widget.api, widget.id);
|
|
4364
|
+
};
|
|
4365
|
+
}, [siteKey, theme]);
|
|
4366
|
+
if (!siteKey) return null;
|
|
4367
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "ba-turnstile", ref: container, "data-testid": "phoneotp-turnstile" });
|
|
4368
|
+
}
|
|
4369
|
+
|
|
4170
4370
|
// src/components/PhoneOTP.tsx
|
|
4171
4371
|
init_use_submit_action();
|
|
4172
4372
|
init_Spinner();
|
|
@@ -4183,20 +4383,20 @@ function PhoneOTP({
|
|
|
4183
4383
|
const { config, isLoading } = usePublicConfig();
|
|
4184
4384
|
const { preparePhoneOtp, startPhoneOtp, verifyPhoneOtp } = useSignIn();
|
|
4185
4385
|
const { pending, error, setError, run } = useSubmitAction();
|
|
4186
|
-
const [stage, setStage] =
|
|
4187
|
-
const [phoneNumber, setPhoneNumber] =
|
|
4188
|
-
const [code, setCode] =
|
|
4189
|
-
const [turnstileToken, setTurnstileToken] =
|
|
4190
|
-
const [guardState, setGuardState] =
|
|
4191
|
-
const [accepted, setAccepted] =
|
|
4192
|
-
const attempt =
|
|
4193
|
-
const guardRequest =
|
|
4386
|
+
const [stage, setStage] = React17.useState("phone");
|
|
4387
|
+
const [phoneNumber, setPhoneNumber] = React17.useState("");
|
|
4388
|
+
const [code, setCode] = React17.useState("");
|
|
4389
|
+
const [turnstileToken, setTurnstileToken] = React17.useState(null);
|
|
4390
|
+
const [guardState, setGuardState] = React17.useState({ status: "loading" });
|
|
4391
|
+
const [accepted, setAccepted] = React17.useState(false);
|
|
4392
|
+
const attempt = React17.useRef(null);
|
|
4393
|
+
const guardRequest = React17.useRef(0);
|
|
4194
4394
|
const legal = config?.legal;
|
|
4195
4395
|
const consentBlocked = Boolean(legal?.required && !accepted);
|
|
4196
4396
|
const guard = guardState.status === "ready" ? guardState.data : null;
|
|
4197
4397
|
const turnstileBlocked = guardState.status === "ready" && guardState.data.kind === "authowl_turnstile" && !turnstileToken;
|
|
4198
4398
|
const humanCheckError = t("phoneOtp.error.humanCheck");
|
|
4199
|
-
const loadGuard =
|
|
4399
|
+
const loadGuard = React17.useCallback(async () => {
|
|
4200
4400
|
const request = ++guardRequest.current;
|
|
4201
4401
|
setGuardState({ status: "loading" });
|
|
4202
4402
|
setError(null);
|
|
@@ -4215,7 +4415,7 @@ function PhoneOTP({
|
|
|
4215
4415
|
setError(humanCheckError);
|
|
4216
4416
|
}
|
|
4217
4417
|
}, [humanCheckError, preparePhoneOtp, setError]);
|
|
4218
|
-
|
|
4418
|
+
React17.useEffect(() => {
|
|
4219
4419
|
void loadGuard();
|
|
4220
4420
|
return () => {
|
|
4221
4421
|
guardRequest.current += 1;
|
|
@@ -4324,7 +4524,7 @@ function PhoneOTP({
|
|
|
4324
4524
|
return;
|
|
4325
4525
|
}
|
|
4326
4526
|
if (!attempt.current || attempt.current.phoneNumber !== phoneNumber) {
|
|
4327
|
-
attempt.current = { phoneNumber, idempotencyKey: (0,
|
|
4527
|
+
attempt.current = { phoneNumber, idempotencyKey: (0, import_core5.createIdempotencyKey)() };
|
|
4328
4528
|
}
|
|
4329
4529
|
const idempotencyKey = attempt.current.idempotencyKey;
|
|
4330
4530
|
void run(
|
|
@@ -4337,7 +4537,7 @@ function PhoneOTP({
|
|
|
4337
4537
|
const current = selected?.data ?? guard;
|
|
4338
4538
|
if (selected?.data) setGuardState({ status: "ready", data: selected.data });
|
|
4339
4539
|
if (current?.kind === "akedly_shield_v1_2") {
|
|
4340
|
-
const akedlyShield = await (0,
|
|
4540
|
+
const akedlyShield = await (0, import_core5.solvePhoneOtpChallenge)(current);
|
|
4341
4541
|
return startPhoneOtp({ phoneNumber, akedlyShield, idempotencyKey });
|
|
4342
4542
|
}
|
|
4343
4543
|
if (current?.kind === "authowl_turnstile" && turnstileToken) {
|
|
@@ -4422,7 +4622,7 @@ function PhoneOTP({
|
|
|
4422
4622
|
init_FormError();
|
|
4423
4623
|
|
|
4424
4624
|
// src/components/AuthOwlBranding.tsx
|
|
4425
|
-
var
|
|
4625
|
+
var React18 = __toESM(require("react"), 1);
|
|
4426
4626
|
init_hooks();
|
|
4427
4627
|
init_i18n();
|
|
4428
4628
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
@@ -4433,8 +4633,8 @@ function AuthOwlBranding({ href, showEnvironment = true } = {}) {
|
|
|
4433
4633
|
const appName = config?.branding?.appName?.trim() ?? "";
|
|
4434
4634
|
const showAppName = config?.branding?.showAppName !== false && appName.length > 0;
|
|
4435
4635
|
const alignment = config?.branding?.alignment ?? "left";
|
|
4436
|
-
const [logoFailed, setLogoFailed] =
|
|
4437
|
-
|
|
4636
|
+
const [logoFailed, setLogoFailed] = React18.useState(false);
|
|
4637
|
+
React18.useEffect(() => setLogoFailed(false), [logoUrl]);
|
|
4438
4638
|
if (!config) return null;
|
|
4439
4639
|
if (!logoUrl && !showAppName && (!showEnvironment || !config.environmentType)) return null;
|
|
4440
4640
|
const identity = /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "ba-branding-identity", children: [
|
|
@@ -4474,15 +4674,15 @@ function AuthOwlBranding({ href, showEnvironment = true } = {}) {
|
|
|
4474
4674
|
}
|
|
4475
4675
|
|
|
4476
4676
|
// src/components/InvitationBanner.tsx
|
|
4477
|
-
var
|
|
4478
|
-
var
|
|
4677
|
+
var React19 = __toESM(require("react"), 1);
|
|
4678
|
+
var import_core6 = require("@authowl/core");
|
|
4479
4679
|
init_i18n();
|
|
4480
4680
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
4481
4681
|
function InvitationBanner() {
|
|
4482
4682
|
const t = useT();
|
|
4483
|
-
const [pending, setPending] =
|
|
4484
|
-
|
|
4485
|
-
setPending((0,
|
|
4683
|
+
const [pending, setPending] = React19.useState(false);
|
|
4684
|
+
React19.useEffect(() => {
|
|
4685
|
+
setPending((0, import_core6.readInvitationClaim)() !== null);
|
|
4486
4686
|
}, []);
|
|
4487
4687
|
if (!pending) return null;
|
|
4488
4688
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "ba-muted", "data-testid": "authowl-invitation-banner", children: t("organization.invitationBanner") });
|
|
@@ -4529,18 +4729,27 @@ function SignIn({
|
|
|
4529
4729
|
const { config, isLoading, isError } = usePublicConfig();
|
|
4530
4730
|
const { pending, error, setError, run } = useSubmitAction();
|
|
4531
4731
|
const authChallenge = useAuthChallenge();
|
|
4532
|
-
const [email, setEmail] =
|
|
4533
|
-
const [username, setUsername] =
|
|
4534
|
-
const [password, setPassword] =
|
|
4535
|
-
const [credentialMode, setCredentialMode] =
|
|
4536
|
-
const [otp, setOtp] =
|
|
4537
|
-
const [view, setView] =
|
|
4732
|
+
const [email, setEmail] = React20.useState("");
|
|
4733
|
+
const [username, setUsername] = React20.useState("");
|
|
4734
|
+
const [password, setPassword] = React20.useState("");
|
|
4735
|
+
const [credentialMode, setCredentialMode] = React20.useState("email");
|
|
4736
|
+
const [otp, setOtp] = React20.useState("");
|
|
4737
|
+
const [view, setView] = React20.useState(
|
|
4538
4738
|
"sign-in"
|
|
4539
4739
|
);
|
|
4540
|
-
const [inFlight, setInFlight] =
|
|
4541
|
-
const [challenge, setChallenge] =
|
|
4740
|
+
const [inFlight, setInFlight] = React20.useState(null);
|
|
4741
|
+
const [challenge, setChallenge] = React20.useState(false);
|
|
4542
4742
|
const mfaEnrolment = useConfirmedMfaPending("clear");
|
|
4543
|
-
const emailRef =
|
|
4743
|
+
const emailRef = React20.useRef(null);
|
|
4744
|
+
const recordSignInMethod = useSignInMethodRecorder();
|
|
4745
|
+
const onPasskeySignedIn = React20.useCallback(() => {
|
|
4746
|
+
recordSignInMethod("passkey");
|
|
4747
|
+
onSignedIn?.();
|
|
4748
|
+
}, [onSignedIn, recordSignInMethod]);
|
|
4749
|
+
const onPhoneOtpSignedIn = React20.useCallback(() => {
|
|
4750
|
+
recordSignInMethod("phone-otp");
|
|
4751
|
+
onSignedIn?.();
|
|
4752
|
+
}, [onSignedIn, recordSignInMethod]);
|
|
4544
4753
|
const plan = resolveSignInMethods(
|
|
4545
4754
|
config,
|
|
4546
4755
|
typeof window === "undefined" ? void 0 : window.location.hostname
|
|
@@ -4548,7 +4757,7 @@ function SignIn({
|
|
|
4548
4757
|
usePasskeyAutofill({
|
|
4549
4758
|
enabled: credentialMode === "email" && plan.autofillHost !== null,
|
|
4550
4759
|
redirectTo,
|
|
4551
|
-
onSignedIn
|
|
4760
|
+
onSignedIn: onPasskeySignedIn
|
|
4552
4761
|
});
|
|
4553
4762
|
const badge = /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AuthOwlBadge, { force: showBadge });
|
|
4554
4763
|
const branding = showBranding ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AuthOwlBranding, {}) : null;
|
|
@@ -4600,7 +4809,10 @@ function SignIn({
|
|
|
4600
4809
|
error,
|
|
4601
4810
|
onSubmit: () => void run(() => signInEmailOtp({ email, otp }), {
|
|
4602
4811
|
failure: t("emailOtp.error.invalidCode"),
|
|
4603
|
-
onSuccess: () =>
|
|
4812
|
+
onSuccess: () => {
|
|
4813
|
+
recordSignInMethod("email-otp");
|
|
4814
|
+
finishSignIn({ sessionStore, redirectTo, onSignedIn });
|
|
4815
|
+
}
|
|
4604
4816
|
}),
|
|
4605
4817
|
onChangeEmail: () => {
|
|
4606
4818
|
setOtp("");
|
|
@@ -4628,7 +4840,7 @@ function SignIn({
|
|
|
4628
4840
|
PhoneOTP,
|
|
4629
4841
|
{
|
|
4630
4842
|
redirectTo,
|
|
4631
|
-
onSignedIn,
|
|
4843
|
+
onSignedIn: onPhoneOtpSignedIn,
|
|
4632
4844
|
onBack: () => setView("sign-in"),
|
|
4633
4845
|
onMfaPasswordRequired: () => {
|
|
4634
4846
|
setView("sign-in");
|
|
@@ -4656,6 +4868,7 @@ function SignIn({
|
|
|
4656
4868
|
failure: t("signIn.error.failed"),
|
|
4657
4869
|
onSuccess: (res) => {
|
|
4658
4870
|
const data = res.data;
|
|
4871
|
+
recordSignInMethod(credentialMode === "username" ? "username" : "password");
|
|
4659
4872
|
if (data && "twoFactorRedirect" in data && data.twoFactorRedirect) {
|
|
4660
4873
|
setChallenge(true);
|
|
4661
4874
|
} else {
|
|
@@ -4668,7 +4881,10 @@ function SignIn({
|
|
|
4668
4881
|
"magic",
|
|
4669
4882
|
() => void run(() => authChallenge.run(AUTH_CHALLENGE_ACTIONS.passwordless, (options) => signInMagicLink({ email, callbackURL: redirectTo }, options)), {
|
|
4670
4883
|
failure: t("magicLink.error.sendFailed"),
|
|
4671
|
-
onSuccess: () =>
|
|
4884
|
+
onSuccess: () => {
|
|
4885
|
+
recordSignInMethod("magic-link", true);
|
|
4886
|
+
setView("magic-sent");
|
|
4887
|
+
}
|
|
4672
4888
|
})
|
|
4673
4889
|
);
|
|
4674
4890
|
const doRequestOtp = () => start(
|
|
@@ -4685,6 +4901,7 @@ function SignIn({
|
|
|
4685
4901
|
{
|
|
4686
4902
|
failure: t("sso.error.startFailed"),
|
|
4687
4903
|
mapError: (error2) => error2.status === 404 ? t("sso.error.notFound") : null,
|
|
4904
|
+
onSuccess: () => recordSignInMethod("sso", true),
|
|
4688
4905
|
// SSO always redirects the browser to the IdP; keep the spinner up
|
|
4689
4906
|
// through that navigation instead of flashing back to idle.
|
|
4690
4907
|
keepPendingOnSuccess: true
|
|
@@ -4823,7 +5040,7 @@ function SignIn({
|
|
|
4823
5040
|
]
|
|
4824
5041
|
}
|
|
4825
5042
|
),
|
|
4826
|
-
plan.passkey && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PasskeyButton, { redirectTo, onSignedIn }),
|
|
5043
|
+
plan.passkey && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(PasskeyButton, { redirectTo, onSignedIn: onPasskeySignedIn }),
|
|
4827
5044
|
plan.phoneOtp && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4828
5045
|
"button",
|
|
4829
5046
|
{
|
|
@@ -4839,12 +5056,12 @@ function SignIn({
|
|
|
4839
5056
|
}
|
|
4840
5057
|
|
|
4841
5058
|
// src/components/SignUp.tsx
|
|
4842
|
-
var
|
|
5059
|
+
var React24 = __toESM(require("react"), 1);
|
|
4843
5060
|
init_hooks();
|
|
4844
5061
|
init_i18n();
|
|
4845
5062
|
|
|
4846
5063
|
// src/components/VerificationPending.tsx
|
|
4847
|
-
var
|
|
5064
|
+
var React21 = __toESM(require("react"), 1);
|
|
4848
5065
|
init_hooks();
|
|
4849
5066
|
init_i18n();
|
|
4850
5067
|
init_use_submit_action();
|
|
@@ -4864,9 +5081,9 @@ function VerificationPending({
|
|
|
4864
5081
|
} = useEmailVerification();
|
|
4865
5082
|
const { pending, error, run } = useSubmitAction();
|
|
4866
5083
|
const authChallenge = useAuthChallenge();
|
|
4867
|
-
const [resent, setResent] =
|
|
4868
|
-
const [code, setCode] =
|
|
4869
|
-
const [verified, setVerified] =
|
|
5084
|
+
const [resent, setResent] = React21.useState(false);
|
|
5085
|
+
const [code, setCode] = React21.useState("");
|
|
5086
|
+
const [verified, setVerified] = React21.useState(false);
|
|
4870
5087
|
if (verified) {
|
|
4871
5088
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { className: "ba-success", role: "status", "data-testid": "verify-code-success", children: t("verifyEmail.success") });
|
|
4872
5089
|
}
|
|
@@ -4969,7 +5186,7 @@ function VerificationPending({
|
|
|
4969
5186
|
}
|
|
4970
5187
|
|
|
4971
5188
|
// src/components/PasswordlessSignUp.tsx
|
|
4972
|
-
var
|
|
5189
|
+
var React22 = __toESM(require("react"), 1);
|
|
4973
5190
|
init_hooks();
|
|
4974
5191
|
init_i18n();
|
|
4975
5192
|
init_use_submit_action();
|
|
@@ -4981,9 +5198,9 @@ function PasswordlessSignUp({ onAuthenticated }) {
|
|
|
4981
5198
|
const { sendEmailOtp, signInEmailOtp } = useSignIn();
|
|
4982
5199
|
const { pending, error, setError, run } = useSubmitAction();
|
|
4983
5200
|
const authChallenge = useAuthChallenge();
|
|
4984
|
-
const [email, setEmail] =
|
|
4985
|
-
const [code, setCode] =
|
|
4986
|
-
const [codeSent, setCodeSent] =
|
|
5201
|
+
const [email, setEmail] = React22.useState("");
|
|
5202
|
+
const [code, setCode] = React22.useState("");
|
|
5203
|
+
const [codeSent, setCodeSent] = React22.useState(false);
|
|
4987
5204
|
if (codeSent) {
|
|
4988
5205
|
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "ba-fields", "data-testid": "signup-emailotp-code", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
4989
5206
|
OtpCodeForm,
|
|
@@ -5088,7 +5305,7 @@ init_Spinner();
|
|
|
5088
5305
|
init_FormError();
|
|
5089
5306
|
|
|
5090
5307
|
// src/components/Waitlist.tsx
|
|
5091
|
-
var
|
|
5308
|
+
var React23 = __toESM(require("react"), 1);
|
|
5092
5309
|
init_hooks();
|
|
5093
5310
|
init_i18n();
|
|
5094
5311
|
init_FormError();
|
|
@@ -5100,8 +5317,8 @@ function Waitlist({ onJoined, showBadge, showBranding = true } = {}) {
|
|
|
5100
5317
|
const { join } = useWaitlist();
|
|
5101
5318
|
const { pending, error, run } = useSubmitAction();
|
|
5102
5319
|
const authChallenge = useAuthChallenge();
|
|
5103
|
-
const [email, setEmail] =
|
|
5104
|
-
const [joined, setJoined] =
|
|
5320
|
+
const [email, setEmail] = React23.useState("");
|
|
5321
|
+
const [joined, setJoined] = React23.useState(false);
|
|
5105
5322
|
if (joined) {
|
|
5106
5323
|
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "ba-form", "data-testid": "waitlist-accepted", children: [
|
|
5107
5324
|
showBranding ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(AuthOwlBranding, {}) : null,
|
|
@@ -5185,24 +5402,24 @@ function SignUp({
|
|
|
5185
5402
|
const { signUp } = useSignUp();
|
|
5186
5403
|
const { config, isLoading, isError } = usePublicConfig();
|
|
5187
5404
|
const authChallenge = useAuthChallenge();
|
|
5188
|
-
const [email, setEmail] =
|
|
5189
|
-
const [password, setPassword] =
|
|
5190
|
-
const [name, setName] =
|
|
5191
|
-
const [firstName, setFirstName] =
|
|
5192
|
-
const [lastName, setLastName] =
|
|
5193
|
-
const [username, setUsername] =
|
|
5194
|
-
const [error, setError] =
|
|
5195
|
-
const [submitting, setSubmitting] =
|
|
5196
|
-
const [accepted, setAccepted] =
|
|
5405
|
+
const [email, setEmail] = React24.useState("");
|
|
5406
|
+
const [password, setPassword] = React24.useState("");
|
|
5407
|
+
const [name, setName] = React24.useState("");
|
|
5408
|
+
const [firstName, setFirstName] = React24.useState("");
|
|
5409
|
+
const [lastName, setLastName] = React24.useState("");
|
|
5410
|
+
const [username, setUsername] = React24.useState("");
|
|
5411
|
+
const [error, setError] = React24.useState(null);
|
|
5412
|
+
const [submitting, setSubmitting] = React24.useState(false);
|
|
5413
|
+
const [accepted, setAccepted] = React24.useState(false);
|
|
5197
5414
|
const legal = config?.legal;
|
|
5198
5415
|
const consentRequired = Boolean(legal?.required);
|
|
5199
5416
|
const consentBlocked = consentRequired && !accepted;
|
|
5200
|
-
const capabilities = (0,
|
|
5417
|
+
const capabilities = (0, import_core4.resolveProjectCapabilities)(config);
|
|
5201
5418
|
const passwordMinLength = capabilities.passwordMinLength;
|
|
5202
5419
|
const passwordMaxLength = capabilities.passwordMaxLength;
|
|
5203
5420
|
const passkeysEnabled = capabilities.passkeyAdd;
|
|
5204
|
-
const [pendingEmail, setPendingEmail] =
|
|
5205
|
-
const [completeWithPasskey, setCompleteWithPasskey] =
|
|
5421
|
+
const [pendingEmail, setPendingEmail] = React24.useState(null);
|
|
5422
|
+
const [completeWithPasskey, setCompleteWithPasskey] = React24.useState(false);
|
|
5206
5423
|
function finishSignUp() {
|
|
5207
5424
|
onSignedUp?.();
|
|
5208
5425
|
if (redirectTo) window.location.assign(redirectTo);
|
|
@@ -5489,7 +5706,7 @@ function MFARequiredGate({ children, title }) {
|
|
|
5489
5706
|
}
|
|
5490
5707
|
|
|
5491
5708
|
// src/components/BackupCodesManager.tsx
|
|
5492
|
-
var
|
|
5709
|
+
var React25 = __toESM(require("react"), 1);
|
|
5493
5710
|
init_hooks();
|
|
5494
5711
|
init_i18n();
|
|
5495
5712
|
init_use_submit_action();
|
|
@@ -5501,8 +5718,8 @@ function BackupCodesManager({ title }) {
|
|
|
5501
5718
|
const { user } = useUser();
|
|
5502
5719
|
const { regenerateBackupCodes } = useMFA();
|
|
5503
5720
|
const { pending, error, run } = useSubmitAction();
|
|
5504
|
-
const [password, setPassword] =
|
|
5505
|
-
const [codes, setCodes] =
|
|
5721
|
+
const [password, setPassword] = React25.useState("");
|
|
5722
|
+
const [codes, setCodes] = React25.useState(null);
|
|
5506
5723
|
if (!user?.twoFactorEnabled) return null;
|
|
5507
5724
|
const submit = (e) => {
|
|
5508
5725
|
e.preventDefault();
|
|
@@ -5546,7 +5763,7 @@ function BackupCodesManager({ title }) {
|
|
|
5546
5763
|
}
|
|
5547
5764
|
|
|
5548
5765
|
// src/components/MagicLinkForm.tsx
|
|
5549
|
-
var
|
|
5766
|
+
var React26 = __toESM(require("react"), 1);
|
|
5550
5767
|
init_hooks();
|
|
5551
5768
|
init_i18n();
|
|
5552
5769
|
init_use_submit_action();
|
|
@@ -5558,8 +5775,8 @@ function MagicLinkForm({ callbackURL, webauthnAutofill }) {
|
|
|
5558
5775
|
const { signInMagicLink } = useSignIn();
|
|
5559
5776
|
const { pending, error, run } = useSubmitAction();
|
|
5560
5777
|
const authChallenge = useAuthChallenge();
|
|
5561
|
-
const [email, setEmail] =
|
|
5562
|
-
const [sent, setSent] =
|
|
5778
|
+
const [email, setEmail] = React26.useState("");
|
|
5779
|
+
const [sent, setSent] = React26.useState(false);
|
|
5563
5780
|
if (sent) {
|
|
5564
5781
|
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "ba-muted", "data-testid": "magiclink-sent", children: t("magicLink.sent") });
|
|
5565
5782
|
}
|
|
@@ -5609,7 +5826,7 @@ function MagicLinkForm({ callbackURL, webauthnAutofill }) {
|
|
|
5609
5826
|
}
|
|
5610
5827
|
|
|
5611
5828
|
// src/components/EmailOtpForm.tsx
|
|
5612
|
-
var
|
|
5829
|
+
var React27 = __toESM(require("react"), 1);
|
|
5613
5830
|
init_hooks();
|
|
5614
5831
|
init_i18n();
|
|
5615
5832
|
init_use_submit_action();
|
|
@@ -5622,9 +5839,9 @@ function EmailOtpForm({ redirectTo, onSignedIn, webauthnAutofill }) {
|
|
|
5622
5839
|
const { sendEmailOtp, signInEmailOtp } = useSignIn();
|
|
5623
5840
|
const { pending, error, setError, run } = useSubmitAction();
|
|
5624
5841
|
const authChallenge = useAuthChallenge();
|
|
5625
|
-
const [email, setEmail] =
|
|
5626
|
-
const [otp, setOtp] =
|
|
5627
|
-
const [stage, setStage] =
|
|
5842
|
+
const [email, setEmail] = React27.useState("");
|
|
5843
|
+
const [otp, setOtp] = React27.useState("");
|
|
5844
|
+
const [stage, setStage] = React27.useState("email");
|
|
5628
5845
|
if (stage === "code") {
|
|
5629
5846
|
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
5630
5847
|
OtpCodeForm,
|
|
@@ -5698,7 +5915,7 @@ function EmailOtpForm({ redirectTo, onSignedIn, webauthnAutofill }) {
|
|
|
5698
5915
|
}
|
|
5699
5916
|
|
|
5700
5917
|
// src/components/ResetPassword.tsx
|
|
5701
|
-
var
|
|
5918
|
+
var React28 = __toESM(require("react"), 1);
|
|
5702
5919
|
init_hooks();
|
|
5703
5920
|
init_i18n();
|
|
5704
5921
|
init_use_submit_action();
|
|
@@ -5709,15 +5926,15 @@ function ResetPassword({ token: tokenProp, redirectTo, onReset }) {
|
|
|
5709
5926
|
const t = useT();
|
|
5710
5927
|
const { resetPassword } = usePasswordReset();
|
|
5711
5928
|
const { config } = usePublicConfig();
|
|
5712
|
-
const capabilities = (0,
|
|
5929
|
+
const capabilities = (0, import_core4.resolveProjectCapabilities)(config);
|
|
5713
5930
|
const { passwordMinLength, passwordMaxLength } = capabilities;
|
|
5714
5931
|
const { pending, error, setError, run } = useSubmitAction();
|
|
5715
|
-
const [token, setToken] =
|
|
5716
|
-
const [ready, setReady] =
|
|
5717
|
-
const [password, setPassword] =
|
|
5718
|
-
const [confirm, setConfirm] =
|
|
5719
|
-
const [done, setDone] =
|
|
5720
|
-
|
|
5932
|
+
const [token, setToken] = React28.useState(tokenProp ?? null);
|
|
5933
|
+
const [ready, setReady] = React28.useState(tokenProp != null);
|
|
5934
|
+
const [password, setPassword] = React28.useState("");
|
|
5935
|
+
const [confirm, setConfirm] = React28.useState("");
|
|
5936
|
+
const [done, setDone] = React28.useState(false);
|
|
5937
|
+
React28.useEffect(() => {
|
|
5721
5938
|
if (tokenProp != null) return;
|
|
5722
5939
|
const params = new URLSearchParams(window.location.search);
|
|
5723
5940
|
setToken(params.get("token"));
|
|
@@ -5804,7 +6021,7 @@ function ResetPassword({ token: tokenProp, redirectTo, onReset }) {
|
|
|
5804
6021
|
}
|
|
5805
6022
|
|
|
5806
6023
|
// src/components/VerifyEmail.tsx
|
|
5807
|
-
var
|
|
6024
|
+
var React29 = __toESM(require("react"), 1);
|
|
5808
6025
|
init_hooks();
|
|
5809
6026
|
init_i18n();
|
|
5810
6027
|
init_use_submit_action();
|
|
@@ -5816,11 +6033,11 @@ function VerifyEmail({ redirectTo, onVerified, callbackURL }) {
|
|
|
5816
6033
|
const { sendVerificationEmail } = useEmailVerification();
|
|
5817
6034
|
const { pending, error, run } = useSubmitAction();
|
|
5818
6035
|
const authChallenge = useAuthChallenge();
|
|
5819
|
-
const [ready, setReady] =
|
|
5820
|
-
const [failed, setFailed] =
|
|
5821
|
-
const [email, setEmail] =
|
|
5822
|
-
const [resent, setResent] =
|
|
5823
|
-
|
|
6036
|
+
const [ready, setReady] = React29.useState(false);
|
|
6037
|
+
const [failed, setFailed] = React29.useState(false);
|
|
6038
|
+
const [email, setEmail] = React29.useState("");
|
|
6039
|
+
const [resent, setResent] = React29.useState(false);
|
|
6040
|
+
React29.useEffect(() => {
|
|
5824
6041
|
const didFail = new URLSearchParams(window.location.search).has("error");
|
|
5825
6042
|
setFailed(didFail);
|
|
5826
6043
|
setReady(true);
|
|
@@ -5885,7 +6102,7 @@ function VerifyEmail({ redirectTo, onVerified, callbackURL }) {
|
|
|
5885
6102
|
}
|
|
5886
6103
|
|
|
5887
6104
|
// src/components/PasskeyManager.tsx
|
|
5888
|
-
var
|
|
6105
|
+
var React30 = __toESM(require("react"), 1);
|
|
5889
6106
|
init_hooks();
|
|
5890
6107
|
init_i18n();
|
|
5891
6108
|
init_use_submit_action();
|
|
@@ -5910,12 +6127,12 @@ function PasskeyManagerBody({
|
|
|
5910
6127
|
const t = useT();
|
|
5911
6128
|
const toServerError = useServerError();
|
|
5912
6129
|
const api = usePasskeys();
|
|
5913
|
-
const apiRef =
|
|
6130
|
+
const apiRef = React30.useRef(api);
|
|
5914
6131
|
apiRef.current = api;
|
|
5915
6132
|
const { pending, error, setError, run } = useSubmitAction();
|
|
5916
|
-
const [passkeys, setPasskeys] =
|
|
5917
|
-
const loadTokenRef =
|
|
5918
|
-
const load =
|
|
6133
|
+
const [passkeys, setPasskeys] = React30.useState(null);
|
|
6134
|
+
const loadTokenRef = React30.useRef(0);
|
|
6135
|
+
const load = React30.useCallback(async () => {
|
|
5919
6136
|
const token = ++loadTokenRef.current;
|
|
5920
6137
|
try {
|
|
5921
6138
|
const res = await apiRef.current.listPasskeys();
|
|
@@ -5931,7 +6148,7 @@ function PasskeyManagerBody({
|
|
|
5931
6148
|
setError(t("passkeys.error.loadFailed"));
|
|
5932
6149
|
}
|
|
5933
6150
|
}, [setError, toServerError, t]);
|
|
5934
|
-
|
|
6151
|
+
React30.useEffect(() => {
|
|
5935
6152
|
void load();
|
|
5936
6153
|
}, [load]);
|
|
5937
6154
|
function onRename(id, current) {
|
|
@@ -6002,7 +6219,7 @@ function PasskeyManagerBody({
|
|
|
6002
6219
|
}
|
|
6003
6220
|
|
|
6004
6221
|
// src/components/control.tsx
|
|
6005
|
-
var
|
|
6222
|
+
var import_core7 = require("@authowl/core");
|
|
6006
6223
|
init_hooks();
|
|
6007
6224
|
init_i18n();
|
|
6008
6225
|
init_Spinner();
|
|
@@ -6027,7 +6244,7 @@ function Protect({
|
|
|
6027
6244
|
const membership = useSession().data?.session?.membership ?? null;
|
|
6028
6245
|
if (!isLoaded) return null;
|
|
6029
6246
|
if (!isSignedIn || !user) return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_jsx_runtime39.Fragment, { children: fallback });
|
|
6030
|
-
if ((role !== void 0 || permission !== void 0 || teamId !== void 0) && !(0,
|
|
6247
|
+
if ((role !== void 0 || permission !== void 0 || teamId !== void 0) && !(0, import_core7.membershipHas)(membership, { role, permission, teamId })) {
|
|
6031
6248
|
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_jsx_runtime39.Fragment, { children: fallback });
|
|
6032
6249
|
}
|
|
6033
6250
|
if (condition && !condition(user)) return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_jsx_runtime39.Fragment, { children: fallback });
|
|
@@ -6051,7 +6268,7 @@ function AuthLoaded({ children }) {
|
|
|
6051
6268
|
init_Spinner();
|
|
6052
6269
|
|
|
6053
6270
|
// src/components/SignOutButton.tsx
|
|
6054
|
-
var
|
|
6271
|
+
var React31 = __toESM(require("react"), 1);
|
|
6055
6272
|
init_hooks();
|
|
6056
6273
|
init_i18n();
|
|
6057
6274
|
init_Spinner();
|
|
@@ -6059,7 +6276,7 @@ var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
|
6059
6276
|
function SignOutButton({ children, redirectTo, onSignedOut, className }) {
|
|
6060
6277
|
const t = useT();
|
|
6061
6278
|
const { signOut } = useSignOut();
|
|
6062
|
-
const [pending, setPending] =
|
|
6279
|
+
const [pending, setPending] = React31.useState(false);
|
|
6063
6280
|
const content = children ?? t("signOut.button");
|
|
6064
6281
|
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
6065
6282
|
"button",
|
|
@@ -6085,17 +6302,17 @@ function SignOutButton({ children, redirectTo, onSignedOut, className }) {
|
|
|
6085
6302
|
}
|
|
6086
6303
|
|
|
6087
6304
|
// src/components/UserButton.tsx
|
|
6088
|
-
var
|
|
6305
|
+
var React44 = __toESM(require("react"), 1);
|
|
6089
6306
|
init_hooks();
|
|
6090
6307
|
init_i18n();
|
|
6091
6308
|
|
|
6092
6309
|
// src/components/UserProfile.tsx
|
|
6093
|
-
var
|
|
6310
|
+
var React43 = __toESM(require("react"), 1);
|
|
6094
6311
|
init_hooks();
|
|
6095
6312
|
init_i18n();
|
|
6096
6313
|
|
|
6097
6314
|
// src/components/user-profile/EmailSection.tsx
|
|
6098
|
-
var
|
|
6315
|
+
var React32 = __toESM(require("react"), 1);
|
|
6099
6316
|
init_hooks();
|
|
6100
6317
|
init_i18n();
|
|
6101
6318
|
init_use_submit_action();
|
|
@@ -6107,9 +6324,9 @@ function EmailSection({ allowChange }) {
|
|
|
6107
6324
|
const account = useAccount();
|
|
6108
6325
|
const { user } = useUser();
|
|
6109
6326
|
const { pending, error, run } = useSubmitAction();
|
|
6110
|
-
const [newEmail, setNewEmail] =
|
|
6111
|
-
const [sent, setSent] =
|
|
6112
|
-
const titleId =
|
|
6327
|
+
const [newEmail, setNewEmail] = React32.useState("");
|
|
6328
|
+
const [sent, setSent] = React32.useState(false);
|
|
6329
|
+
const titleId = React32.useId();
|
|
6113
6330
|
if (!user?.email) {
|
|
6114
6331
|
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("section", { className: "ba-profile-section", "aria-labelledby": titleId, children: [
|
|
6115
6332
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("h2", { id: titleId, className: "ba-title", children: t("userProfile.email.title") }),
|
|
@@ -6174,7 +6391,7 @@ function EmailSection({ allowChange }) {
|
|
|
6174
6391
|
}
|
|
6175
6392
|
|
|
6176
6393
|
// src/components/user-profile/DeleteAccountSection.tsx
|
|
6177
|
-
var
|
|
6394
|
+
var React33 = __toESM(require("react"), 1);
|
|
6178
6395
|
init_hooks();
|
|
6179
6396
|
init_i18n();
|
|
6180
6397
|
init_use_submit_action();
|
|
@@ -6187,8 +6404,8 @@ function DeleteAccountSection({ onDeleted }) {
|
|
|
6187
6404
|
const session = useSession();
|
|
6188
6405
|
const { user } = useUser();
|
|
6189
6406
|
const { pending, error, run } = useSubmitAction();
|
|
6190
|
-
const [confirmation, setConfirmation] =
|
|
6191
|
-
const titleId =
|
|
6407
|
+
const [confirmation, setConfirmation] = React33.useState("");
|
|
6408
|
+
const titleId = React33.useId();
|
|
6192
6409
|
const identifier = user?.email ?? user?.phoneNumber ?? user?.id ?? "";
|
|
6193
6410
|
const confirmed = identifier.length > 0 && confirmation.trim().toLowerCase() === identifier.toLowerCase();
|
|
6194
6411
|
const submit = (event) => {
|
|
@@ -6246,7 +6463,7 @@ function DeleteAccountSection({ onDeleted }) {
|
|
|
6246
6463
|
}
|
|
6247
6464
|
|
|
6248
6465
|
// src/components/user-profile/MfaSection.tsx
|
|
6249
|
-
var
|
|
6466
|
+
var React34 = __toESM(require("react"), 1);
|
|
6250
6467
|
init_hooks();
|
|
6251
6468
|
init_i18n();
|
|
6252
6469
|
init_use_submit_action();
|
|
@@ -6260,10 +6477,10 @@ function MfaSection() {
|
|
|
6260
6477
|
const { config } = usePublicConfig();
|
|
6261
6478
|
const { disable } = useMFA();
|
|
6262
6479
|
const { pending, error, run } = useSubmitAction();
|
|
6263
|
-
const [password, setPassword] =
|
|
6264
|
-
const [showDisable, setShowDisable] =
|
|
6265
|
-
const titleId =
|
|
6266
|
-
const required = (0,
|
|
6480
|
+
const [password, setPassword] = React34.useState("");
|
|
6481
|
+
const [showDisable, setShowDisable] = React34.useState(false);
|
|
6482
|
+
const titleId = React34.useId();
|
|
6483
|
+
const required = (0, import_core4.resolveProjectCapabilities)(config).mfaRequired;
|
|
6267
6484
|
if (!user?.twoFactorEnabled) {
|
|
6268
6485
|
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("section", { className: "ba-profile-section", "aria-labelledby": titleId, children: [
|
|
6269
6486
|
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("header", { className: "ba-profile-section-header", children: [
|
|
@@ -6357,7 +6574,7 @@ function MfaSection() {
|
|
|
6357
6574
|
}
|
|
6358
6575
|
|
|
6359
6576
|
// src/components/user-profile/PasswordSection.tsx
|
|
6360
|
-
var
|
|
6577
|
+
var React35 = __toESM(require("react"), 1);
|
|
6361
6578
|
init_hooks();
|
|
6362
6579
|
init_i18n();
|
|
6363
6580
|
init_use_submit_action();
|
|
@@ -6368,13 +6585,13 @@ function PasswordSection() {
|
|
|
6368
6585
|
const t = useT();
|
|
6369
6586
|
const account = useAccount();
|
|
6370
6587
|
const { config } = usePublicConfig();
|
|
6371
|
-
const { passwordMinLength, passwordMaxLength } = (0,
|
|
6588
|
+
const { passwordMinLength, passwordMaxLength } = (0, import_core4.resolveProjectCapabilities)(config);
|
|
6372
6589
|
const { pending, error, setError, run } = useSubmitAction();
|
|
6373
|
-
const [currentPassword, setCurrentPassword] =
|
|
6374
|
-
const [newPassword, setNewPassword] =
|
|
6375
|
-
const [confirmPassword, setConfirmPassword] =
|
|
6376
|
-
const [saved, setSaved] =
|
|
6377
|
-
const titleId =
|
|
6590
|
+
const [currentPassword, setCurrentPassword] = React35.useState("");
|
|
6591
|
+
const [newPassword, setNewPassword] = React35.useState("");
|
|
6592
|
+
const [confirmPassword, setConfirmPassword] = React35.useState("");
|
|
6593
|
+
const [saved, setSaved] = React35.useState(false);
|
|
6594
|
+
const titleId = React35.useId();
|
|
6378
6595
|
const submit = (event) => {
|
|
6379
6596
|
event.preventDefault();
|
|
6380
6597
|
setSaved(false);
|
|
@@ -6443,12 +6660,12 @@ function PasswordSection() {
|
|
|
6443
6660
|
}
|
|
6444
6661
|
|
|
6445
6662
|
// src/components/user-profile/PasskeysSection.tsx
|
|
6446
|
-
var
|
|
6663
|
+
var React36 = __toESM(require("react"), 1);
|
|
6447
6664
|
init_i18n();
|
|
6448
6665
|
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
6449
6666
|
function PasskeysSection({ allowAdd }) {
|
|
6450
6667
|
const t = useT();
|
|
6451
|
-
const titleId =
|
|
6668
|
+
const titleId = React36.useId();
|
|
6452
6669
|
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("section", { className: "ba-profile-section", "aria-labelledby": titleId, children: [
|
|
6453
6670
|
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("header", { className: "ba-profile-section-header", children: [
|
|
6454
6671
|
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h2", { id: titleId, className: "ba-title", children: t("userProfile.passkeys.title") }),
|
|
@@ -6459,7 +6676,7 @@ function PasskeysSection({ allowAdd }) {
|
|
|
6459
6676
|
}
|
|
6460
6677
|
|
|
6461
6678
|
// src/components/user-profile/ProfileSection.tsx
|
|
6462
|
-
var
|
|
6679
|
+
var React37 = __toESM(require("react"), 1);
|
|
6463
6680
|
init_hooks();
|
|
6464
6681
|
init_i18n();
|
|
6465
6682
|
init_use_submit_action();
|
|
@@ -6476,15 +6693,15 @@ function ProfileSection({
|
|
|
6476
6693
|
const { user } = useUser();
|
|
6477
6694
|
const session = useSession();
|
|
6478
6695
|
const { pending, error, run } = useSubmitAction();
|
|
6479
|
-
const [name, setName] =
|
|
6480
|
-
const [firstName, setFirstName] =
|
|
6481
|
-
const [lastName, setLastName] =
|
|
6482
|
-
const [username, setUsername] =
|
|
6696
|
+
const [name, setName] = React37.useState(user?.name ?? "");
|
|
6697
|
+
const [firstName, setFirstName] = React37.useState(user?.firstName ?? "");
|
|
6698
|
+
const [lastName, setLastName] = React37.useState(user?.lastName ?? "");
|
|
6699
|
+
const [username, setUsername] = React37.useState(
|
|
6483
6700
|
user?.displayUsername ?? user?.username ?? ""
|
|
6484
6701
|
);
|
|
6485
|
-
const [image, setImage] =
|
|
6486
|
-
const [saved, setSaved] =
|
|
6487
|
-
const titleId =
|
|
6702
|
+
const [image, setImage] = React37.useState(user?.image ?? "");
|
|
6703
|
+
const [saved, setSaved] = React37.useState(false);
|
|
6704
|
+
const titleId = React37.useId();
|
|
6488
6705
|
const submit = (event) => {
|
|
6489
6706
|
event.preventDefault();
|
|
6490
6707
|
setSaved(false);
|
|
@@ -6594,14 +6811,14 @@ function ProfileSection({
|
|
|
6594
6811
|
}
|
|
6595
6812
|
|
|
6596
6813
|
// src/components/user-profile/RecoverySection.tsx
|
|
6597
|
-
var
|
|
6814
|
+
var React38 = __toESM(require("react"), 1);
|
|
6598
6815
|
init_hooks();
|
|
6599
6816
|
init_i18n();
|
|
6600
6817
|
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
6601
6818
|
function RecoverySection() {
|
|
6602
6819
|
const t = useT();
|
|
6603
6820
|
const { user } = useUser();
|
|
6604
|
-
const titleId =
|
|
6821
|
+
const titleId = React38.useId();
|
|
6605
6822
|
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("section", { className: "ba-profile-section", "aria-labelledby": titleId, children: [
|
|
6606
6823
|
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("header", { className: "ba-profile-section-header", children: [
|
|
6607
6824
|
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("h2", { id: titleId, className: "ba-title", children: t("userProfile.recovery.title") }),
|
|
@@ -6619,7 +6836,7 @@ function RecoverySection() {
|
|
|
6619
6836
|
}
|
|
6620
6837
|
|
|
6621
6838
|
// src/components/user-profile/SessionsSection.tsx
|
|
6622
|
-
var
|
|
6839
|
+
var React40 = __toESM(require("react"), 1);
|
|
6623
6840
|
init_hooks();
|
|
6624
6841
|
init_i18n();
|
|
6625
6842
|
init_use_submit_action();
|
|
@@ -6669,19 +6886,19 @@ function formatSessionTime(date, locale) {
|
|
|
6669
6886
|
}
|
|
6670
6887
|
|
|
6671
6888
|
// src/components/user-profile/use-account-resource.ts
|
|
6672
|
-
var
|
|
6889
|
+
var React39 = __toESM(require("react"), 1);
|
|
6673
6890
|
init_i18n();
|
|
6674
|
-
function useAccountResource(
|
|
6675
|
-
const loaderRef =
|
|
6676
|
-
loaderRef.current =
|
|
6677
|
-
const failureRef =
|
|
6891
|
+
function useAccountResource(loader, failure) {
|
|
6892
|
+
const loaderRef = React39.useRef(loader);
|
|
6893
|
+
loaderRef.current = loader;
|
|
6894
|
+
const failureRef = React39.useRef(failure);
|
|
6678
6895
|
failureRef.current = failure;
|
|
6679
6896
|
const toServerError = useServerError();
|
|
6680
|
-
const [data, setData] =
|
|
6681
|
-
const [error, setError] =
|
|
6682
|
-
const [loading, setLoading] =
|
|
6683
|
-
const requestRef =
|
|
6684
|
-
const load =
|
|
6897
|
+
const [data, setData] = React39.useState(null);
|
|
6898
|
+
const [error, setError] = React39.useState(null);
|
|
6899
|
+
const [loading, setLoading] = React39.useState(true);
|
|
6900
|
+
const requestRef = React39.useRef(0);
|
|
6901
|
+
const load = React39.useCallback(async () => {
|
|
6685
6902
|
const request = ++requestRef.current;
|
|
6686
6903
|
setLoading(true);
|
|
6687
6904
|
try {
|
|
@@ -6700,7 +6917,7 @@ function useAccountResource(loader2, failure) {
|
|
|
6700
6917
|
if (request === requestRef.current) setLoading(false);
|
|
6701
6918
|
}
|
|
6702
6919
|
}, [toServerError]);
|
|
6703
|
-
|
|
6920
|
+
React39.useEffect(() => {
|
|
6704
6921
|
void load();
|
|
6705
6922
|
return () => {
|
|
6706
6923
|
requestRef.current += 1;
|
|
@@ -6718,7 +6935,7 @@ function SessionsSection() {
|
|
|
6718
6935
|
const account = useAccount();
|
|
6719
6936
|
const sessionState = useSession();
|
|
6720
6937
|
const mutation = useSubmitAction();
|
|
6721
|
-
const titleId =
|
|
6938
|
+
const titleId = React40.useId();
|
|
6722
6939
|
const resource = useAccountResource(
|
|
6723
6940
|
() => account.listSessions(),
|
|
6724
6941
|
t("userProfile.sessions.loadError")
|
|
@@ -6789,7 +7006,7 @@ function SessionsSection() {
|
|
|
6789
7006
|
}
|
|
6790
7007
|
|
|
6791
7008
|
// src/components/user-profile/SocialSection.tsx
|
|
6792
|
-
var
|
|
7009
|
+
var React41 = __toESM(require("react"), 1);
|
|
6793
7010
|
init_hooks();
|
|
6794
7011
|
init_i18n();
|
|
6795
7012
|
init_use_submit_action();
|
|
@@ -6803,7 +7020,7 @@ function SocialSection() {
|
|
|
6803
7020
|
const account = useAccount();
|
|
6804
7021
|
const { config } = usePublicConfig();
|
|
6805
7022
|
const mutation = useSubmitAction();
|
|
6806
|
-
const titleId =
|
|
7023
|
+
const titleId = React41.useId();
|
|
6807
7024
|
const resource = useAccountResource(
|
|
6808
7025
|
() => account.listSocialAccounts(),
|
|
6809
7026
|
t("userProfile.social.loadError")
|
|
@@ -6875,7 +7092,7 @@ function SocialSection() {
|
|
|
6875
7092
|
}
|
|
6876
7093
|
|
|
6877
7094
|
// src/components/user-profile/UserProfileModal.tsx
|
|
6878
|
-
var
|
|
7095
|
+
var React42 = __toESM(require("react"), 1);
|
|
6879
7096
|
init_i18n();
|
|
6880
7097
|
init_ModalSurface();
|
|
6881
7098
|
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
@@ -6885,7 +7102,7 @@ function UserProfileModal({
|
|
|
6885
7102
|
branding
|
|
6886
7103
|
}) {
|
|
6887
7104
|
const t = useT();
|
|
6888
|
-
const titleId =
|
|
7105
|
+
const titleId = React42.useId();
|
|
6889
7106
|
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
6890
7107
|
ModalSurface,
|
|
6891
7108
|
{
|
|
@@ -6958,16 +7175,16 @@ function UserProfile(props = {}) {
|
|
|
6958
7175
|
const t = useT();
|
|
6959
7176
|
const { user, isLoaded, isSignedIn } = useUser();
|
|
6960
7177
|
const { config } = usePublicConfig();
|
|
6961
|
-
const [internalSection, setInternalSection] =
|
|
7178
|
+
const [internalSection, setInternalSection] = React43.useState(() => initialSection(defaultSection));
|
|
6962
7179
|
const active = section ?? internalSection;
|
|
6963
|
-
const capabilities = (0,
|
|
7180
|
+
const capabilities = (0, import_core4.resolveProjectCapabilities)(config);
|
|
6964
7181
|
const passwordEnabled = config !== null && capabilities.passwordSignIn;
|
|
6965
7182
|
const passkeysEnabled = capabilities.passkeySignIn || capabilities.passkeyAdd;
|
|
6966
7183
|
const mfaEnabled = capabilities.totp;
|
|
6967
7184
|
const recoveryEnabled = capabilities.backupCodes && user?.twoFactorEnabled === true;
|
|
6968
7185
|
const deletionEnabled = capabilities.accountDeletion;
|
|
6969
7186
|
const socialEnabled = (config?.socialProviders?.length ?? 0) > 0;
|
|
6970
|
-
const sections =
|
|
7187
|
+
const sections = React43.useMemo(
|
|
6971
7188
|
() => userProfileSectionsFor({
|
|
6972
7189
|
password: passwordEnabled,
|
|
6973
7190
|
passkeys: passkeysEnabled,
|
|
@@ -6978,7 +7195,7 @@ function UserProfile(props = {}) {
|
|
|
6978
7195
|
}),
|
|
6979
7196
|
[deletionEnabled, mfaEnabled, passkeysEnabled, passwordEnabled, recoveryEnabled, socialEnabled]
|
|
6980
7197
|
);
|
|
6981
|
-
|
|
7198
|
+
React43.useEffect(() => {
|
|
6982
7199
|
if (section || mode !== "page") return;
|
|
6983
7200
|
const onHashChange = () => {
|
|
6984
7201
|
const next = userProfileSectionFromHash(window.location.hash);
|
|
@@ -7077,10 +7294,10 @@ function UserButton() {
|
|
|
7077
7294
|
const t = useT();
|
|
7078
7295
|
const { user, isLoaded } = useUser();
|
|
7079
7296
|
const { signOut } = useSignOut();
|
|
7080
|
-
const [open, setOpen] =
|
|
7081
|
-
const [profileOpen, setProfileOpen] =
|
|
7082
|
-
const [failedImage, setFailedImage] =
|
|
7083
|
-
const triggerRef =
|
|
7297
|
+
const [open, setOpen] = React44.useState(false);
|
|
7298
|
+
const [profileOpen, setProfileOpen] = React44.useState(false);
|
|
7299
|
+
const [failedImage, setFailedImage] = React44.useState(null);
|
|
7300
|
+
const triggerRef = React44.useRef(null);
|
|
7084
7301
|
if (!isLoaded || !user) return null;
|
|
7085
7302
|
const identity = user.email ?? user.phoneNumber ?? user.name ?? "?";
|
|
7086
7303
|
const image = user.image ?? null;
|
|
@@ -7136,12 +7353,12 @@ function UserButton() {
|
|
|
7136
7353
|
}
|
|
7137
7354
|
|
|
7138
7355
|
// src/components/OrganizationSwitcher.tsx
|
|
7139
|
-
var
|
|
7356
|
+
var React57 = __toESM(require("react"), 1);
|
|
7140
7357
|
init_hooks();
|
|
7141
7358
|
init_i18n();
|
|
7142
7359
|
|
|
7143
7360
|
// src/components/CreateOrganization.tsx
|
|
7144
|
-
var
|
|
7361
|
+
var React45 = __toESM(require("react"), 1);
|
|
7145
7362
|
init_hooks();
|
|
7146
7363
|
init_i18n();
|
|
7147
7364
|
init_model();
|
|
@@ -7155,10 +7372,10 @@ function CreateOrganization({ onCreated, title } = {}) {
|
|
|
7155
7372
|
const { isLoaded, isSignedIn } = useUser();
|
|
7156
7373
|
const api = useAuthClient().organization;
|
|
7157
7374
|
const { pending, error, run } = useSubmitAction();
|
|
7158
|
-
const [name, setName] =
|
|
7159
|
-
const [slug, setSlug] =
|
|
7160
|
-
const [logo, setLogo] =
|
|
7161
|
-
const [slugTouched, setSlugTouched] =
|
|
7375
|
+
const [name, setName] = React45.useState("");
|
|
7376
|
+
const [slug, setSlug] = React45.useState("");
|
|
7377
|
+
const [logo, setLogo] = React45.useState("");
|
|
7378
|
+
const [slugTouched, setSlugTouched] = React45.useState(false);
|
|
7162
7379
|
if (configLoading || !isLoaded) {
|
|
7163
7380
|
return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "ba-skeleton", "aria-label": t("organization.loading") });
|
|
7164
7381
|
}
|
|
@@ -7258,7 +7475,7 @@ function CreateOrganization({ onCreated, title } = {}) {
|
|
|
7258
7475
|
}
|
|
7259
7476
|
|
|
7260
7477
|
// src/components/organization/OrganizationModal.tsx
|
|
7261
|
-
var
|
|
7478
|
+
var React46 = __toESM(require("react"), 1);
|
|
7262
7479
|
init_i18n();
|
|
7263
7480
|
init_ModalSurface();
|
|
7264
7481
|
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
@@ -7269,7 +7486,7 @@ function OrganizationModal({
|
|
|
7269
7486
|
children
|
|
7270
7487
|
}) {
|
|
7271
7488
|
const t = useT();
|
|
7272
|
-
const titleId =
|
|
7489
|
+
const titleId = React46.useId();
|
|
7273
7490
|
return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
|
|
7274
7491
|
ModalSurface,
|
|
7275
7492
|
{
|
|
@@ -7300,21 +7517,21 @@ function OrganizationModal({
|
|
|
7300
7517
|
}
|
|
7301
7518
|
|
|
7302
7519
|
// src/components/organization/use-organizations-resource.ts
|
|
7303
|
-
var
|
|
7520
|
+
var React47 = __toESM(require("react"), 1);
|
|
7304
7521
|
init_hooks();
|
|
7305
7522
|
init_i18n();
|
|
7306
7523
|
function useOrganizationsResource(enabled = true) {
|
|
7307
7524
|
const api = useAuthClient().organization;
|
|
7308
|
-
const apiRef =
|
|
7525
|
+
const apiRef = React47.useRef(api);
|
|
7309
7526
|
apiRef.current = api;
|
|
7310
7527
|
const { user, isLoaded, isSignedIn } = useUser();
|
|
7311
7528
|
const t = useT();
|
|
7312
7529
|
const toServerError = useServerError();
|
|
7313
|
-
const [organizations, setOrganizations] =
|
|
7314
|
-
const [error, setError] =
|
|
7315
|
-
const requestRef =
|
|
7530
|
+
const [organizations, setOrganizations] = React47.useState(null);
|
|
7531
|
+
const [error, setError] = React47.useState(null);
|
|
7532
|
+
const requestRef = React47.useRef(0);
|
|
7316
7533
|
const identity = user?.id ?? null;
|
|
7317
|
-
const refresh =
|
|
7534
|
+
const refresh = React47.useCallback(async () => {
|
|
7318
7535
|
const token = ++requestRef.current;
|
|
7319
7536
|
if (!enabled || !identity || !isSignedIn) {
|
|
7320
7537
|
setOrganizations([]);
|
|
@@ -7334,7 +7551,7 @@ function useOrganizationsResource(enabled = true) {
|
|
|
7334
7551
|
if (token === requestRef.current) setError(t("organization.error.load"));
|
|
7335
7552
|
}
|
|
7336
7553
|
}, [enabled, identity, isSignedIn, t, toServerError]);
|
|
7337
|
-
|
|
7554
|
+
React47.useEffect(() => {
|
|
7338
7555
|
setOrganizations(null);
|
|
7339
7556
|
setError(null);
|
|
7340
7557
|
if (!isLoaded) return;
|
|
@@ -7343,7 +7560,7 @@ function useOrganizationsResource(enabled = true) {
|
|
|
7343
7560
|
requestRef.current += 1;
|
|
7344
7561
|
};
|
|
7345
7562
|
}, [identity, isLoaded, refresh]);
|
|
7346
|
-
|
|
7563
|
+
React47.useEffect(
|
|
7347
7564
|
() => api.subscribe(() => void refresh()),
|
|
7348
7565
|
[api, refresh]
|
|
7349
7566
|
);
|
|
@@ -7356,12 +7573,12 @@ function useOrganizationsResource(enabled = true) {
|
|
|
7356
7573
|
}
|
|
7357
7574
|
|
|
7358
7575
|
// src/components/OrganizationProfile.tsx
|
|
7359
|
-
var
|
|
7576
|
+
var React56 = __toESM(require("react"), 1);
|
|
7360
7577
|
init_hooks();
|
|
7361
7578
|
init_i18n();
|
|
7362
7579
|
|
|
7363
7580
|
// src/components/organization/DangerSection.tsx
|
|
7364
|
-
var
|
|
7581
|
+
var React48 = __toESM(require("react"), 1);
|
|
7365
7582
|
init_hooks();
|
|
7366
7583
|
init_i18n();
|
|
7367
7584
|
init_use_submit_action();
|
|
@@ -7379,7 +7596,7 @@ function DangerSection({
|
|
|
7379
7596
|
const api = useAuthClient().organization;
|
|
7380
7597
|
const session = useSession();
|
|
7381
7598
|
const { pending, error, run } = useSubmitAction();
|
|
7382
|
-
const [confirmation, setConfirmation] =
|
|
7599
|
+
const [confirmation, setConfirmation] = React48.useState("");
|
|
7383
7600
|
const isOwner = hasOrganizationRole(membership, "owner");
|
|
7384
7601
|
const confirmed = confirmation.trim().toLowerCase() === organization.slug.toLowerCase();
|
|
7385
7602
|
const leave = () => {
|
|
@@ -7444,7 +7661,7 @@ function DangerSection({
|
|
|
7444
7661
|
}
|
|
7445
7662
|
|
|
7446
7663
|
// src/components/organization/GeneralSection.tsx
|
|
7447
|
-
var
|
|
7664
|
+
var React49 = __toESM(require("react"), 1);
|
|
7448
7665
|
init_hooks();
|
|
7449
7666
|
init_i18n();
|
|
7450
7667
|
init_use_submit_action();
|
|
@@ -7460,10 +7677,10 @@ function GeneralSection({
|
|
|
7460
7677
|
const t = useT();
|
|
7461
7678
|
const api = useAuthClient().organization;
|
|
7462
7679
|
const { pending, error, run } = useSubmitAction();
|
|
7463
|
-
const [name, setName] =
|
|
7464
|
-
const [slug, setSlug] =
|
|
7465
|
-
const [logo, setLogo] =
|
|
7466
|
-
|
|
7680
|
+
const [name, setName] = React49.useState(organization.name);
|
|
7681
|
+
const [slug, setSlug] = React49.useState(organization.slug);
|
|
7682
|
+
const [logo, setLogo] = React49.useState(organization.logo ?? "");
|
|
7683
|
+
React49.useEffect(() => {
|
|
7467
7684
|
setName(organization.name);
|
|
7468
7685
|
setSlug(organization.slug);
|
|
7469
7686
|
setLogo(organization.logo ?? "");
|
|
@@ -7540,7 +7757,7 @@ function GeneralSection({
|
|
|
7540
7757
|
}
|
|
7541
7758
|
|
|
7542
7759
|
// src/components/organization/InvitationsSection.tsx
|
|
7543
|
-
var
|
|
7760
|
+
var React51 = __toESM(require("react"), 1);
|
|
7544
7761
|
init_hooks();
|
|
7545
7762
|
init_i18n();
|
|
7546
7763
|
init_use_submit_action();
|
|
@@ -7571,8 +7788,8 @@ function InvitationsSection({
|
|
|
7571
7788
|
const api = useAuthClient().organization;
|
|
7572
7789
|
const { pending, error, run } = useSubmitAction();
|
|
7573
7790
|
const { roles } = useOrganizationRoles(organization.id);
|
|
7574
|
-
const [email, setEmail] =
|
|
7575
|
-
const [role, setRole] =
|
|
7791
|
+
const [email, setEmail] = React51.useState("");
|
|
7792
|
+
const [role, setRole] = React51.useState("member");
|
|
7576
7793
|
const invitations = organization.invitations.filter((invitation) => invitation.status === "pending");
|
|
7577
7794
|
const invite = (event) => {
|
|
7578
7795
|
event.preventDefault();
|
|
@@ -7713,7 +7930,7 @@ var SECTION_KEYS2 = {
|
|
|
7713
7930
|
invitations: "organization.profile.nav.invitations",
|
|
7714
7931
|
danger: "organization.profile.nav.danger"
|
|
7715
7932
|
};
|
|
7716
|
-
var TeamsSection2 =
|
|
7933
|
+
var TeamsSection2 = React56.lazy(() => Promise.resolve().then(() => (init_TeamsSection(), TeamsSection_exports)));
|
|
7717
7934
|
function OrganizationProfile({ organizationId, defaultSection = "general", onDeleted, onLeft } = {}) {
|
|
7718
7935
|
const t = useT();
|
|
7719
7936
|
const toServerError = useServerError();
|
|
@@ -7721,17 +7938,17 @@ function OrganizationProfile({ organizationId, defaultSection = "general", onDel
|
|
|
7721
7938
|
const { user, isLoaded, isSignedIn } = useUser();
|
|
7722
7939
|
const session = useSession();
|
|
7723
7940
|
const api = useAuthClient().organization;
|
|
7724
|
-
const apiRef =
|
|
7941
|
+
const apiRef = React56.useRef(api);
|
|
7725
7942
|
apiRef.current = api;
|
|
7726
7943
|
const activeOrganizationId = session.data?.session.activeOrganizationId ?? null;
|
|
7727
7944
|
const requestedId = organizationId ?? activeOrganizationId;
|
|
7728
7945
|
const enabled = config?.organizations === true && isSignedIn;
|
|
7729
|
-
const [organization, setOrganization] =
|
|
7730
|
-
const [error, setError] =
|
|
7731
|
-
const [wasRemoved, setWasRemoved] =
|
|
7732
|
-
const [section, setSection] =
|
|
7733
|
-
const requestRef =
|
|
7734
|
-
const load =
|
|
7946
|
+
const [organization, setOrganization] = React56.useState(null);
|
|
7947
|
+
const [error, setError] = React56.useState(null);
|
|
7948
|
+
const [wasRemoved, setWasRemoved] = React56.useState(false);
|
|
7949
|
+
const [section, setSection] = React56.useState(defaultSection);
|
|
7950
|
+
const requestRef = React56.useRef(0);
|
|
7951
|
+
const load = React56.useCallback(async () => {
|
|
7735
7952
|
const token = ++requestRef.current;
|
|
7736
7953
|
if (!enabled || !requestedId) {
|
|
7737
7954
|
setOrganization(null);
|
|
@@ -7751,7 +7968,7 @@ function OrganizationProfile({ organizationId, defaultSection = "general", onDel
|
|
|
7751
7968
|
if (token === requestRef.current) setError(t("organization.profile.loadError"));
|
|
7752
7969
|
}
|
|
7753
7970
|
}, [enabled, requestedId, t, toServerError]);
|
|
7754
|
-
|
|
7971
|
+
React56.useEffect(() => {
|
|
7755
7972
|
setOrganization(null);
|
|
7756
7973
|
setError(null);
|
|
7757
7974
|
setWasRemoved(false);
|
|
@@ -7805,7 +8022,7 @@ function OrganizationProfile({ organizationId, defaultSection = "general", onDel
|
|
|
7805
8022
|
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "ba-organization-profile-content", children: [
|
|
7806
8023
|
activeSection === "general" && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(GeneralSection, { organization, canManage, onChanged: load }),
|
|
7807
8024
|
activeSection === "members" && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(MembersSection, { organization, userId: user.id, canManage, onChanged: load }),
|
|
7808
|
-
activeSection === "teams" && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
8025
|
+
activeSection === "teams" && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(React56.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(TeamsSection2, { organization, membership }) }),
|
|
7809
8026
|
activeSection === "invitations" && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(InvitationsSection, { organization, onChanged: load }),
|
|
7810
8027
|
activeSection === "danger" && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
7811
8028
|
DangerSection,
|
|
@@ -7834,15 +8051,15 @@ function OrganizationSwitcher({ showPersonalWorkspace = true, onOrganizationChan
|
|
|
7834
8051
|
const enabled = config?.organizations === true && isSignedIn;
|
|
7835
8052
|
const { organizations, isLoading, error: loadError, refresh } = useOrganizationsResource(enabled);
|
|
7836
8053
|
const { pending, error, run } = useSubmitAction();
|
|
7837
|
-
const [open, setOpen] =
|
|
7838
|
-
const [dialog, setDialog] =
|
|
7839
|
-
const rootRef =
|
|
7840
|
-
const triggerRef =
|
|
7841
|
-
const menuRef =
|
|
7842
|
-
const menuId =
|
|
8054
|
+
const [open, setOpen] = React57.useState(false);
|
|
8055
|
+
const [dialog, setDialog] = React57.useState(null);
|
|
8056
|
+
const rootRef = React57.useRef(null);
|
|
8057
|
+
const triggerRef = React57.useRef(null);
|
|
8058
|
+
const menuRef = React57.useRef(null);
|
|
8059
|
+
const menuId = React57.useId();
|
|
7843
8060
|
const activeId = session.data?.session.activeOrganizationId ?? null;
|
|
7844
8061
|
const active = organizations?.find((organization) => organization.id === activeId) ?? null;
|
|
7845
|
-
|
|
8062
|
+
React57.useEffect(() => {
|
|
7846
8063
|
if (!open) return;
|
|
7847
8064
|
const onPointerDown = (event) => {
|
|
7848
8065
|
if (!rootRef.current?.contains(event.target)) setOpen(false);
|
|
@@ -7979,7 +8196,7 @@ function OrganizationSwitcher({ showPersonalWorkspace = true, onOrganizationChan
|
|
|
7979
8196
|
init_InvitationPrompt();
|
|
7980
8197
|
|
|
7981
8198
|
// src/components/OrganizationList.tsx
|
|
7982
|
-
var
|
|
8199
|
+
var React58 = __toESM(require("react"), 1);
|
|
7983
8200
|
init_hooks();
|
|
7984
8201
|
init_i18n();
|
|
7985
8202
|
init_use_submit_action();
|
|
@@ -7992,19 +8209,19 @@ function OrganizationList({ onOrganizationChange } = {}) {
|
|
|
7992
8209
|
const { user, isLoaded, isSignedIn } = useUser();
|
|
7993
8210
|
const session = useSession();
|
|
7994
8211
|
const api = useAuthClient().organization;
|
|
7995
|
-
const apiRef =
|
|
8212
|
+
const apiRef = React58.useRef(api);
|
|
7996
8213
|
apiRef.current = api;
|
|
7997
8214
|
const enabled = config?.organizations === true && isSignedIn;
|
|
7998
8215
|
const { organizations, isLoading, error: organizationError, refresh } = useOrganizationsResource(enabled);
|
|
7999
8216
|
const { pending, error, run } = useSubmitAction();
|
|
8000
|
-
const [invitations, setInvitations] =
|
|
8001
|
-
const [invitationError, setInvitationError] =
|
|
8002
|
-
const [dialog, setDialog] =
|
|
8003
|
-
const [profileId, setProfileId] =
|
|
8004
|
-
const dialogReturnFocusRef =
|
|
8005
|
-
const invitationRequestRef =
|
|
8217
|
+
const [invitations, setInvitations] = React58.useState(null);
|
|
8218
|
+
const [invitationError, setInvitationError] = React58.useState(null);
|
|
8219
|
+
const [dialog, setDialog] = React58.useState(null);
|
|
8220
|
+
const [profileId, setProfileId] = React58.useState(null);
|
|
8221
|
+
const dialogReturnFocusRef = React58.useRef(null);
|
|
8222
|
+
const invitationRequestRef = React58.useRef(0);
|
|
8006
8223
|
const activeId = session.data?.session.activeOrganizationId ?? null;
|
|
8007
|
-
const loadInvitations =
|
|
8224
|
+
const loadInvitations = React58.useCallback(async () => {
|
|
8008
8225
|
const token = ++invitationRequestRef.current;
|
|
8009
8226
|
if (!enabled) {
|
|
8010
8227
|
setInvitations([]);
|
|
@@ -8024,7 +8241,7 @@ function OrganizationList({ onOrganizationChange } = {}) {
|
|
|
8024
8241
|
if (token === invitationRequestRef.current) setInvitationError(t("organization.list.invitationsError"));
|
|
8025
8242
|
}
|
|
8026
8243
|
}, [enabled, t, toServerError]);
|
|
8027
|
-
|
|
8244
|
+
React58.useEffect(() => {
|
|
8028
8245
|
setInvitations(null);
|
|
8029
8246
|
setInvitationError(null);
|
|
8030
8247
|
if (!isLoaded) return;
|
|
@@ -8140,7 +8357,7 @@ function OrganizationList({ onOrganizationChange } = {}) {
|
|
|
8140
8357
|
}
|
|
8141
8358
|
|
|
8142
8359
|
// src/components/GoogleOneTap.tsx
|
|
8143
|
-
var
|
|
8360
|
+
var React59 = __toESM(require("react"), 1);
|
|
8144
8361
|
init_hooks();
|
|
8145
8362
|
|
|
8146
8363
|
// src/components/google-one-tap.ts
|
|
@@ -8290,6 +8507,14 @@ function normalizeDismissReason(reason) {
|
|
|
8290
8507
|
}
|
|
8291
8508
|
return "unknown";
|
|
8292
8509
|
}
|
|
8510
|
+
var warnedMissingNonce = /* @__PURE__ */ new Set();
|
|
8511
|
+
function warnOneTapWithoutNonce(clientId) {
|
|
8512
|
+
if (warnedMissingNonce.has(clientId)) return;
|
|
8513
|
+
warnedMissingNonce.add(clientId);
|
|
8514
|
+
console.warn(
|
|
8515
|
+
"[AuthOwl] <GoogleOneTap/> is running without a `nonce`. Google\u2019s ID token is then not bound to a value chosen for this prompt. Generate a fresh random value per prompt and pass it as `nonce`; AuthOwl forwards it to Google and verifies the match. The direct browser exchange does not keep separate one-time server state, so do not treat this prop by itself as replay protection. (This warning is dev-only.)"
|
|
8516
|
+
);
|
|
8517
|
+
}
|
|
8293
8518
|
function GoogleOneTap({
|
|
8294
8519
|
disabled = false,
|
|
8295
8520
|
nonce,
|
|
@@ -8309,11 +8534,16 @@ function GoogleOneTap({
|
|
|
8309
8534
|
const { config, isLoading: configLoading, isError: configError } = usePublicConfig();
|
|
8310
8535
|
const { user, isLoaded: sessionLoaded } = useUser();
|
|
8311
8536
|
const { signInSocial } = useSignIn();
|
|
8312
|
-
const callbacks =
|
|
8537
|
+
const callbacks = React59.useRef({ onSignedIn, onSkipped, onDismissed, onError });
|
|
8313
8538
|
callbacks.current = { onSignedIn, onSkipped, onDismissed, onError };
|
|
8314
8539
|
const googleEnabled = config?.socialProviders.includes("google") === true;
|
|
8315
8540
|
const clientId = config?.socialProviderClientIds?.google;
|
|
8316
|
-
|
|
8541
|
+
React59.useEffect(() => {
|
|
8542
|
+
if (process.env.NODE_ENV === "production") return;
|
|
8543
|
+
if (disabled || !googleEnabled || !clientId || nonce) return;
|
|
8544
|
+
warnOneTapWithoutNonce(clientId);
|
|
8545
|
+
}, [clientId, disabled, googleEnabled, nonce]);
|
|
8546
|
+
React59.useEffect(() => {
|
|
8317
8547
|
if (configLoading || !sessionLoaded) return;
|
|
8318
8548
|
if (disabled) {
|
|
8319
8549
|
callbacks.current.onSkipped?.("disabled");
|
|
@@ -8429,8 +8659,9 @@ function GoogleOneTap({
|
|
|
8429
8659
|
}
|
|
8430
8660
|
|
|
8431
8661
|
// src/index.ts
|
|
8432
|
-
var import_core7 = require("@authowl/core");
|
|
8433
8662
|
var import_core8 = require("@authowl/core");
|
|
8663
|
+
var import_core9 = require("@authowl/core");
|
|
8664
|
+
init_last_used_method();
|
|
8434
8665
|
// Annotate the CommonJS export names for ESM import in node:
|
|
8435
8666
|
0 && (module.exports = {
|
|
8436
8667
|
AuthLoaded,
|
|
@@ -8489,6 +8720,7 @@ var import_core8 = require("@authowl/core");
|
|
|
8489
8720
|
useConsent,
|
|
8490
8721
|
useEmailVerification,
|
|
8491
8722
|
useInvitationRecipientHint,
|
|
8723
|
+
useLastUsedSignInMethod,
|
|
8492
8724
|
useLocale,
|
|
8493
8725
|
useMFA,
|
|
8494
8726
|
useOrganization,
|