@ollaid/native-sso 2.7.0 → 2.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +183 -89
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +183 -89
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -291,17 +291,18 @@ function OTPInput({
|
|
|
291
291
|
disabled = false,
|
|
292
292
|
autoFocus = true
|
|
293
293
|
}) {
|
|
294
|
+
const safeLength = Number.isFinite(length) ? Math.max(1, Math.min(12, Math.trunc(length))) : 6;
|
|
294
295
|
const inputRefs = react.useRef([]);
|
|
295
296
|
const [activeIndex, setActiveIndex] = react.useState(0);
|
|
296
297
|
react.useEffect(() => {
|
|
297
|
-
inputRefs.current = inputRefs.current.slice(0,
|
|
298
|
-
}, [
|
|
298
|
+
inputRefs.current = inputRefs.current.slice(0, safeLength);
|
|
299
|
+
}, [safeLength]);
|
|
299
300
|
react.useEffect(() => {
|
|
300
301
|
if (autoFocus && inputRefs.current[0]) inputRefs.current[0].focus();
|
|
301
302
|
}, [autoFocus]);
|
|
302
303
|
react.useEffect(() => {
|
|
303
|
-
if (value.length ===
|
|
304
|
-
}, [value,
|
|
304
|
+
if (value.length === safeLength && onComplete) onComplete(value);
|
|
305
|
+
}, [value, safeLength, onComplete]);
|
|
305
306
|
const handleChange = (index, char) => {
|
|
306
307
|
var _a;
|
|
307
308
|
if (disabled) return;
|
|
@@ -309,8 +310,8 @@ function OTPInput({
|
|
|
309
310
|
if (!digit) return;
|
|
310
311
|
const newValue = value.split("");
|
|
311
312
|
newValue[index] = digit;
|
|
312
|
-
onChange(newValue.join("").slice(0,
|
|
313
|
-
if (index <
|
|
313
|
+
onChange(newValue.join("").slice(0, safeLength));
|
|
314
|
+
if (index < safeLength - 1) {
|
|
314
315
|
(_a = inputRefs.current[index + 1]) == null ? void 0 : _a.focus();
|
|
315
316
|
setActiveIndex(index + 1);
|
|
316
317
|
}
|
|
@@ -333,7 +334,7 @@ function OTPInput({
|
|
|
333
334
|
} else if (e.key === "ArrowLeft" && index > 0) {
|
|
334
335
|
(_b = inputRefs.current[index - 1]) == null ? void 0 : _b.focus();
|
|
335
336
|
setActiveIndex(index - 1);
|
|
336
|
-
} else if (e.key === "ArrowRight" && index <
|
|
337
|
+
} else if (e.key === "ArrowRight" && index < safeLength - 1) {
|
|
337
338
|
(_c = inputRefs.current[index + 1]) == null ? void 0 : _c.focus();
|
|
338
339
|
setActiveIndex(index + 1);
|
|
339
340
|
}
|
|
@@ -344,14 +345,14 @@ function OTPInput({
|
|
|
344
345
|
e.preventDefault();
|
|
345
346
|
const pasted = e.clipboardData.getData("text").replace(/[^0-9]/g, "");
|
|
346
347
|
if (pasted) {
|
|
347
|
-
const newValue = pasted.slice(0,
|
|
348
|
+
const newValue = pasted.slice(0, safeLength);
|
|
348
349
|
onChange(newValue);
|
|
349
|
-
const focusIndex = Math.min(newValue.length,
|
|
350
|
+
const focusIndex = Math.min(newValue.length, safeLength - 1);
|
|
350
351
|
(_a = inputRefs.current[focusIndex]) == null ? void 0 : _a.focus();
|
|
351
352
|
setActiveIndex(focusIndex);
|
|
352
353
|
}
|
|
353
354
|
};
|
|
354
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "0.5rem" }, children: Array.from({ length }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
355
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "0.5rem" }, children: Array.from({ length: safeLength }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
355
356
|
"input",
|
|
356
357
|
{
|
|
357
358
|
ref: (el) => inputRefs.current[index] = el,
|
|
@@ -7557,8 +7558,12 @@ function getHeaders(token, includeConfigPrefix = false) {
|
|
|
7557
7558
|
let credentials = null;
|
|
7558
7559
|
let credentialsLoadedAt = 0;
|
|
7559
7560
|
let credentialsTtl = 300;
|
|
7561
|
+
let refreshInFlight = null;
|
|
7562
|
+
let lastSuccessfulRefreshAt = 0;
|
|
7563
|
+
let lastSuccessfulRefreshResponse = null;
|
|
7560
7564
|
const DEFAULT_TTL = 300;
|
|
7561
7565
|
const REFRESH_MARGIN = 30;
|
|
7566
|
+
const REFRESH_COOLDOWN_MS = 60 * 1e3;
|
|
7562
7567
|
const nativeAuthService = {
|
|
7563
7568
|
hasCredentials() {
|
|
7564
7569
|
return credentials !== null;
|
|
@@ -7857,6 +7862,16 @@ const nativeAuthService = {
|
|
|
7857
7862
|
}
|
|
7858
7863
|
},
|
|
7859
7864
|
async refresh() {
|
|
7865
|
+
const now = Date.now();
|
|
7866
|
+
if (refreshInFlight) {
|
|
7867
|
+
return refreshInFlight;
|
|
7868
|
+
}
|
|
7869
|
+
if ((lastSuccessfulRefreshResponse == null ? void 0 : lastSuccessfulRefreshResponse.success) && lastSuccessfulRefreshAt && now - lastSuccessfulRefreshAt < REFRESH_COOLDOWN_MS) {
|
|
7870
|
+
if (isDebugMode()) {
|
|
7871
|
+
console.log("🔄 [SaaS] POST /native/refresh — cooldown actif, réponse réutilisée");
|
|
7872
|
+
}
|
|
7873
|
+
return lastSuccessfulRefreshResponse;
|
|
7874
|
+
}
|
|
7860
7875
|
const cfg = getNativeAuthConfig();
|
|
7861
7876
|
if (!cfg.saasApiUrl) {
|
|
7862
7877
|
throw new ApiError("saasApiUrl non configurée", "unknown");
|
|
@@ -7869,51 +7884,62 @@ const nativeAuthService = {
|
|
|
7869
7884
|
if (isDebugMode()) {
|
|
7870
7885
|
console.log("📤 [SaaS] POST /native/refresh");
|
|
7871
7886
|
}
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7887
|
+
refreshInFlight = (async () => {
|
|
7888
|
+
try {
|
|
7889
|
+
let response;
|
|
7890
|
+
try {
|
|
7891
|
+
response = await fetchWithTimeout(
|
|
7892
|
+
`${cfg.saasApiUrl}/native/refresh`,
|
|
7893
|
+
{
|
|
7894
|
+
method: "POST",
|
|
7895
|
+
headers: getHeaders(void 0, true),
|
|
7896
|
+
body: JSON.stringify({ refresh_token: refreshToken })
|
|
7897
|
+
},
|
|
7898
|
+
cfg.timeout || 3e4
|
|
7899
|
+
);
|
|
7900
|
+
} catch (err) {
|
|
7901
|
+
if (err instanceof ApiError) {
|
|
7902
|
+
if (err.statusCode === 401) {
|
|
7903
|
+
response = {
|
|
7904
|
+
success: false,
|
|
7905
|
+
error_type: err.errorType || "invalid_refresh",
|
|
7906
|
+
message: err.message
|
|
7907
|
+
};
|
|
7908
|
+
} else if (err.statusCode === 404) {
|
|
7909
|
+
response = {
|
|
7910
|
+
success: false,
|
|
7911
|
+
error_type: "not_supported",
|
|
7912
|
+
message: "Endpoint refresh non disponible sur ce SaaS"
|
|
7913
|
+
};
|
|
7914
|
+
} else {
|
|
7915
|
+
throw err;
|
|
7916
|
+
}
|
|
7917
|
+
} else {
|
|
7918
|
+
throw err;
|
|
7919
|
+
}
|
|
7891
7920
|
}
|
|
7892
|
-
if (
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7921
|
+
if (response.success) {
|
|
7922
|
+
if (response.token) {
|
|
7923
|
+
setAuthToken(response.token);
|
|
7924
|
+
}
|
|
7925
|
+
const storage = getNativeStorage();
|
|
7926
|
+
if (response.expires_at) storage.setItem(STORAGE.TOKEN_EXPIRES_AT, response.expires_at);
|
|
7927
|
+
if (response.refresh_token) storage.setItem(STORAGE.REFRESH_TOKEN, response.refresh_token);
|
|
7928
|
+
if (response.refresh_expires_at) storage.setItem(STORAGE.REFRESH_EXPIRES_AT, response.refresh_expires_at);
|
|
7929
|
+
if (response.app_access_token_ref) storage.setItem(STORAGE.APP_ACCESS_TOKEN_REF, response.app_access_token_ref);
|
|
7930
|
+
if (response.alias_reference) storage.setItem(STORAGE.ALIAS_REFERENCE, response.alias_reference);
|
|
7931
|
+
if (response.user) {
|
|
7932
|
+
setAuthUser(response.user);
|
|
7933
|
+
}
|
|
7934
|
+
lastSuccessfulRefreshAt = Date.now();
|
|
7935
|
+
lastSuccessfulRefreshResponse = response;
|
|
7898
7936
|
}
|
|
7937
|
+
return response;
|
|
7938
|
+
} finally {
|
|
7939
|
+
refreshInFlight = null;
|
|
7899
7940
|
}
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
if (response.success) {
|
|
7903
|
-
if (response.token) {
|
|
7904
|
-
setAuthToken(response.token);
|
|
7905
|
-
}
|
|
7906
|
-
const storage = getNativeStorage();
|
|
7907
|
-
if (response.expires_at) storage.setItem(STORAGE.TOKEN_EXPIRES_AT, response.expires_at);
|
|
7908
|
-
if (response.refresh_token) storage.setItem(STORAGE.REFRESH_TOKEN, response.refresh_token);
|
|
7909
|
-
if (response.refresh_expires_at) storage.setItem(STORAGE.REFRESH_EXPIRES_AT, response.refresh_expires_at);
|
|
7910
|
-
if (response.app_access_token_ref) storage.setItem(STORAGE.APP_ACCESS_TOKEN_REF, response.app_access_token_ref);
|
|
7911
|
-
if (response.alias_reference) storage.setItem(STORAGE.ALIAS_REFERENCE, response.alias_reference);
|
|
7912
|
-
if (response.user) {
|
|
7913
|
-
setAuthUser(response.user);
|
|
7914
|
-
}
|
|
7915
|
-
}
|
|
7916
|
-
return response;
|
|
7941
|
+
})();
|
|
7942
|
+
return refreshInFlight;
|
|
7917
7943
|
},
|
|
7918
7944
|
async logout(token) {
|
|
7919
7945
|
const config2 = getNativeAuthConfig();
|
|
@@ -7962,11 +7988,17 @@ const nativeAuthService = {
|
|
|
7962
7988
|
clearAuthToken();
|
|
7963
7989
|
credentials = null;
|
|
7964
7990
|
credentialsLoadedAt = 0;
|
|
7991
|
+
refreshInFlight = null;
|
|
7992
|
+
lastSuccessfulRefreshAt = 0;
|
|
7993
|
+
lastSuccessfulRefreshResponse = null;
|
|
7965
7994
|
return { success: true };
|
|
7966
7995
|
},
|
|
7967
7996
|
clearCredentials() {
|
|
7968
7997
|
credentials = null;
|
|
7969
7998
|
credentialsLoadedAt = 0;
|
|
7999
|
+
refreshInFlight = null;
|
|
8000
|
+
lastSuccessfulRefreshAt = 0;
|
|
8001
|
+
lastSuccessfulRefreshResponse = null;
|
|
7970
8002
|
},
|
|
7971
8003
|
// ============================================
|
|
7972
8004
|
// High-level methods
|
|
@@ -9585,6 +9617,8 @@ function LoginModal({
|
|
|
9585
9617
|
const [loginSuccess, setLoginSuccess] = react.useState(false);
|
|
9586
9618
|
const [loginData, setLoginData] = react.useState(null);
|
|
9587
9619
|
const [showPasswordRecovery, setShowPasswordRecovery] = react.useState(false);
|
|
9620
|
+
const [passwordSubmitting, setPasswordSubmitting] = react.useState(false);
|
|
9621
|
+
const successCallbackTimerRef = react.useRef(null);
|
|
9588
9622
|
const CCPHONE = "+221";
|
|
9589
9623
|
const isSubmitting = authLoading || loading;
|
|
9590
9624
|
const error = localError || authError;
|
|
@@ -9602,15 +9636,11 @@ function LoginModal({
|
|
|
9602
9636
|
setResendCooldown(60);
|
|
9603
9637
|
}
|
|
9604
9638
|
}, [status, step]);
|
|
9605
|
-
react.useEffect(() => {
|
|
9606
|
-
if (loginSuccess && loginData) {
|
|
9607
|
-
const timer = setTimeout(() => {
|
|
9608
|
-
onLoginSuccess == null ? void 0 : onLoginSuccess(loginData.token, loginData.user);
|
|
9609
|
-
}, 1e3);
|
|
9610
|
-
return () => clearTimeout(timer);
|
|
9611
|
-
}
|
|
9612
|
-
}, [loginSuccess, loginData, onLoginSuccess]);
|
|
9613
9639
|
const resetState = react.useCallback(() => {
|
|
9640
|
+
if (successCallbackTimerRef.current) {
|
|
9641
|
+
clearTimeout(successCallbackTimerRef.current);
|
|
9642
|
+
successCallbackTimerRef.current = null;
|
|
9643
|
+
}
|
|
9614
9644
|
setStep("choice");
|
|
9615
9645
|
setEmail("");
|
|
9616
9646
|
setPassword("");
|
|
@@ -9624,6 +9654,7 @@ function LoginModal({
|
|
|
9624
9654
|
setLoginSuccess(false);
|
|
9625
9655
|
setLoginData(null);
|
|
9626
9656
|
setResendCooldown(0);
|
|
9657
|
+
setPasswordSubmitting(false);
|
|
9627
9658
|
resetAuth();
|
|
9628
9659
|
}, [resetAuth]);
|
|
9629
9660
|
react.useEffect(() => {
|
|
@@ -9636,12 +9667,34 @@ function LoginModal({
|
|
|
9636
9667
|
}
|
|
9637
9668
|
}, [open, initialPhone]);
|
|
9638
9669
|
const finalizeLogin = (result) => {
|
|
9639
|
-
if (result.success
|
|
9670
|
+
if (result.success) {
|
|
9640
9671
|
const token = getAuthToken() || "";
|
|
9641
|
-
|
|
9642
|
-
|
|
9672
|
+
const resolvedUser = result.user || user;
|
|
9673
|
+
if (resolvedUser) {
|
|
9674
|
+
setLoginData({ token, user: resolvedUser });
|
|
9675
|
+
setLoginSuccess(true);
|
|
9676
|
+
}
|
|
9643
9677
|
}
|
|
9644
9678
|
};
|
|
9679
|
+
react.useEffect(() => {
|
|
9680
|
+
if (!loginSuccess || !loginData || !onLoginSuccess) return;
|
|
9681
|
+
if (successCallbackTimerRef.current) {
|
|
9682
|
+
clearTimeout(successCallbackTimerRef.current);
|
|
9683
|
+
}
|
|
9684
|
+
successCallbackTimerRef.current = setTimeout(() => {
|
|
9685
|
+
try {
|
|
9686
|
+
onLoginSuccess(loginData.token, loginData.user);
|
|
9687
|
+
} catch (callbackError) {
|
|
9688
|
+
console.error("Erreur dans onLoginSuccess", callbackError);
|
|
9689
|
+
}
|
|
9690
|
+
}, 900);
|
|
9691
|
+
return () => {
|
|
9692
|
+
if (successCallbackTimerRef.current) {
|
|
9693
|
+
clearTimeout(successCallbackTimerRef.current);
|
|
9694
|
+
successCallbackTimerRef.current = null;
|
|
9695
|
+
}
|
|
9696
|
+
};
|
|
9697
|
+
}, [loginSuccess, loginData, onLoginSuccess]);
|
|
9645
9698
|
const handleEmailCheck = async () => {
|
|
9646
9699
|
setLocalError(null);
|
|
9647
9700
|
clearError();
|
|
@@ -9658,18 +9711,24 @@ function LoginModal({
|
|
|
9658
9711
|
};
|
|
9659
9712
|
const handleEmailPasswordSubmit = async (e) => {
|
|
9660
9713
|
e.preventDefault();
|
|
9714
|
+
if (passwordSubmitting || isSubmitting) return;
|
|
9715
|
+
setPasswordSubmitting(true);
|
|
9661
9716
|
setLocalError(null);
|
|
9662
9717
|
clearError();
|
|
9663
|
-
|
|
9664
|
-
|
|
9665
|
-
|
|
9666
|
-
|
|
9667
|
-
|
|
9668
|
-
|
|
9669
|
-
|
|
9718
|
+
try {
|
|
9719
|
+
if (!password) {
|
|
9720
|
+
setLocalError("Le mot de passe est requis");
|
|
9721
|
+
return;
|
|
9722
|
+
}
|
|
9723
|
+
if (password.length < 8) {
|
|
9724
|
+
setLocalError("Le mot de passe doit contenir au moins 8 caractères");
|
|
9725
|
+
return;
|
|
9726
|
+
}
|
|
9727
|
+
const result = await submitPassword(password);
|
|
9728
|
+
finalizeLogin(result);
|
|
9729
|
+
} finally {
|
|
9730
|
+
setPasswordSubmitting(false);
|
|
9670
9731
|
}
|
|
9671
|
-
const result = await submitPassword(password);
|
|
9672
|
-
finalizeLogin(result);
|
|
9673
9732
|
};
|
|
9674
9733
|
const handleEmailOtpVerify = async () => {
|
|
9675
9734
|
setLocalError(null);
|
|
@@ -9933,7 +9992,7 @@ function LoginModal({
|
|
|
9933
9992
|
placeholder: "••••••••",
|
|
9934
9993
|
value: password,
|
|
9935
9994
|
onChange: (e) => setPassword(e.target.value),
|
|
9936
|
-
disabled: isSubmitting,
|
|
9995
|
+
disabled: isSubmitting || passwordSubmitting,
|
|
9937
9996
|
style: { paddingRight: "2.5rem" }
|
|
9938
9997
|
}
|
|
9939
9998
|
),
|
|
@@ -9949,7 +10008,7 @@ function LoginModal({
|
|
|
9949
10008
|
] })
|
|
9950
10009
|
] })
|
|
9951
10010
|
] }) }),
|
|
9952
|
-
/* @__PURE__ */ jsxRuntime.jsx(DialogFooter, { children: /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", disabled: isSubmitting || !password, style: { width: "100%" }, children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
10011
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogFooter, { children: /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", disabled: isSubmitting || passwordSubmitting || !password, style: { width: "100%" }, children: isSubmitting ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
|
|
9953
10012
|
/* @__PURE__ */ jsxRuntime.jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
|
|
9954
10013
|
"Connexion..."
|
|
9955
10014
|
] }) : "Se connecter" }) })
|
|
@@ -13205,6 +13264,8 @@ function NativeSSOPage({
|
|
|
13205
13264
|
const [showOnboarding, setShowOnboarding] = react.useState(false);
|
|
13206
13265
|
const [pendingSession, setPendingSession] = react.useState(null);
|
|
13207
13266
|
const [debugOnboardingState, setDebugOnboardingState] = react.useState(null);
|
|
13267
|
+
const [redirectingTarget, setRedirectingTarget] = react.useState(null);
|
|
13268
|
+
const [redirectingReason, setRedirectingReason] = react.useState(null);
|
|
13208
13269
|
const [session, setSession] = react.useState(() => {
|
|
13209
13270
|
try {
|
|
13210
13271
|
const storage2 = getNativeStorage();
|
|
@@ -13227,6 +13288,17 @@ function NativeSSOPage({
|
|
|
13227
13288
|
react.useEffect(() => {
|
|
13228
13289
|
sessionRef.current = session;
|
|
13229
13290
|
}, [session]);
|
|
13291
|
+
react.useEffect(() => {
|
|
13292
|
+
if (!redirectingTarget) return;
|
|
13293
|
+
const timer = window.setTimeout(() => {
|
|
13294
|
+
const redirected = safeRedirect(redirectingTarget);
|
|
13295
|
+
if (!redirected) {
|
|
13296
|
+
setRedirectingTarget(null);
|
|
13297
|
+
setRedirectingReason(null);
|
|
13298
|
+
}
|
|
13299
|
+
}, 200);
|
|
13300
|
+
return () => window.clearTimeout(timer);
|
|
13301
|
+
}, [redirectingTarget]);
|
|
13230
13302
|
const clearOnboardingTimers = react.useCallback(() => {
|
|
13231
13303
|
if (onboardingPromptTimerRef.current) {
|
|
13232
13304
|
clearTimeout(onboardingPromptTimerRef.current);
|
|
@@ -13394,6 +13466,12 @@ function NativeSSOPage({
|
|
|
13394
13466
|
setLoginInitialPhone(phone);
|
|
13395
13467
|
setTimeout(() => setModal("login"), 150);
|
|
13396
13468
|
}, []);
|
|
13469
|
+
const beginRedirect = react.useCallback((target, reason = "login") => {
|
|
13470
|
+
if (!target) return false;
|
|
13471
|
+
setRedirectingReason(reason);
|
|
13472
|
+
setRedirectingTarget(target);
|
|
13473
|
+
return true;
|
|
13474
|
+
}, []);
|
|
13397
13475
|
const handleLoginSuccess = react.useCallback((token, user) => {
|
|
13398
13476
|
const userObj = {
|
|
13399
13477
|
reference: "",
|
|
@@ -13410,10 +13488,14 @@ function NativeSSOPage({
|
|
|
13410
13488
|
void refreshSessionProfile(true);
|
|
13411
13489
|
if (!needsOnboarding(userObj)) {
|
|
13412
13490
|
markProfilePromptComplete();
|
|
13413
|
-
|
|
13414
|
-
|
|
13491
|
+
try {
|
|
13492
|
+
onLoginSuccess == null ? void 0 : onLoginSuccess(token, user);
|
|
13493
|
+
} catch (callbackError) {
|
|
13494
|
+
console.error("Erreur dans le callback onLoginSuccess du wrapper SSO", callbackError);
|
|
13495
|
+
}
|
|
13496
|
+
beginRedirect(redirectAfterLogin, "login");
|
|
13415
13497
|
}
|
|
13416
|
-
}, [onLoginSuccess, redirectAfterLogin, persistSessionUser, syncProfilePrompt, refreshSessionProfile, accountType]);
|
|
13498
|
+
}, [onLoginSuccess, redirectAfterLogin, persistSessionUser, syncProfilePrompt, refreshSessionProfile, accountType, beginRedirect]);
|
|
13417
13499
|
const handleOnboardingComplete = react.useCallback((data) => {
|
|
13418
13500
|
const activeSession = debugOnboardingState || pendingSession;
|
|
13419
13501
|
if (!activeSession) return;
|
|
@@ -13457,11 +13539,15 @@ function NativeSSOPage({
|
|
|
13457
13539
|
if (!debugOnboardingState) {
|
|
13458
13540
|
persistSessionUser(activeSession.token, activeSession.user);
|
|
13459
13541
|
snoozeProfilePrompt(PROFILE_PROMPT_SNOOZE_MS / (60 * 60 * 1e3));
|
|
13460
|
-
|
|
13461
|
-
|
|
13542
|
+
try {
|
|
13543
|
+
onLoginSuccess == null ? void 0 : onLoginSuccess(activeSession.token, activeSession.user);
|
|
13544
|
+
} catch (callbackError) {
|
|
13545
|
+
console.error("Erreur dans le callback onLoginSuccess du wrapper SSO", callbackError);
|
|
13546
|
+
}
|
|
13547
|
+
beginRedirect(redirectAfterLogin, "login");
|
|
13462
13548
|
return;
|
|
13463
13549
|
}
|
|
13464
|
-
}, [pendingSession, debugOnboardingState, onLoginSuccess, redirectAfterLogin, persistSessionUser]);
|
|
13550
|
+
}, [pendingSession, debugOnboardingState, onLoginSuccess, redirectAfterLogin, persistSessionUser, beginRedirect]);
|
|
13465
13551
|
const handleOnboardingDismiss = react.useCallback(() => {
|
|
13466
13552
|
setShowOnboarding(false);
|
|
13467
13553
|
setPendingSession(null);
|
|
@@ -13474,8 +13560,8 @@ function NativeSSOPage({
|
|
|
13474
13560
|
setDebugOnboardingState(null);
|
|
13475
13561
|
clearOnboardingTimers();
|
|
13476
13562
|
onLogout == null ? void 0 : onLogout();
|
|
13477
|
-
|
|
13478
|
-
}, [onLogout, redirectAfterLogout, clearOnboardingTimers]);
|
|
13563
|
+
beginRedirect(redirectAfterLogout, "logout");
|
|
13564
|
+
}, [onLogout, redirectAfterLogout, clearOnboardingTimers, beginRedirect]);
|
|
13479
13565
|
const openDebugLogin = react.useCallback(() => {
|
|
13480
13566
|
clearOnboardingTimers();
|
|
13481
13567
|
setShowOnboarding(false);
|
|
@@ -13490,6 +13576,10 @@ function NativeSSOPage({
|
|
|
13490
13576
|
setDebugOnboardingState(null);
|
|
13491
13577
|
setModal("signup");
|
|
13492
13578
|
}, [clearOnboardingTimers]);
|
|
13579
|
+
react.useEffect(() => {
|
|
13580
|
+
if (!(session == null ? void 0 : session.token) || !redirectAfterLogin || redirectingTarget) return;
|
|
13581
|
+
beginRedirect(redirectAfterLogin, "already-authenticated");
|
|
13582
|
+
}, [session == null ? void 0 : session.token, redirectAfterLogin, redirectingTarget, beginRedirect]);
|
|
13493
13583
|
const openDebugOnboarding = react.useCallback((preset = "current") => {
|
|
13494
13584
|
if (!session) return;
|
|
13495
13585
|
clearOnboardingTimers();
|
|
@@ -13612,14 +13702,18 @@ function NativeSSOPage({
|
|
|
13612
13702
|
overflow: "hidden"
|
|
13613
13703
|
}, children: /* @__PURE__ */ jsxRuntime.jsx(AppsLogoSlider, { iamApiUrl, speed: "normal" }) }) })
|
|
13614
13704
|
] }) });
|
|
13705
|
+
if (redirectingTarget) {
|
|
13706
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle, children: [
|
|
13707
|
+
/* @__PURE__ */ jsxRuntime.jsx(TopBranding, { subtitle: title }),
|
|
13708
|
+
/* @__PURE__ */ jsxRuntime.jsx(SliderBadge, {}),
|
|
13709
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: cardStyle, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "2rem 1.5rem 1.5rem", textAlign: "center" }, children: [
|
|
13710
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: { fontSize: "1.25rem", fontWeight: 600, color: COLORS.cardForeground }, children: redirectingReason === "logout" ? "Déconnexion réussie" : redirectingReason === "already-authenticated" ? "Session déjà valide" : "Connexion réussie" }),
|
|
13711
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.875rem", color: COLORS.muted, marginTop: "0.5rem" }, children: "Redirection en cours..." })
|
|
13712
|
+
] }) }),
|
|
13713
|
+
/* @__PURE__ */ jsxRuntime.jsx(Footer, { hideFooter })
|
|
13714
|
+
] });
|
|
13715
|
+
}
|
|
13615
13716
|
if (session) {
|
|
13616
|
-
if (redirectAfterLogin) {
|
|
13617
|
-
safeRedirect(redirectAfterLogin);
|
|
13618
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle, children: [
|
|
13619
|
-
/* @__PURE__ */ jsxRuntime.jsx(TopBranding, { subtitle: title }),
|
|
13620
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { color: "rgba(255,255,255,0.7)", fontSize: "0.875rem" }, children: "Redirection en cours..." })
|
|
13621
|
-
] });
|
|
13622
|
-
}
|
|
13623
13717
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle, children: [
|
|
13624
13718
|
/* @__PURE__ */ jsxRuntime.jsx(TopBranding, { subtitle: title }),
|
|
13625
13719
|
/* @__PURE__ */ jsxRuntime.jsx(SliderBadge, {}),
|