@ollaid/native-sso 2.7.1 → 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.js CHANGED
@@ -9615,6 +9615,8 @@ function LoginModal({
9615
9615
  const [loginSuccess, setLoginSuccess] = useState(false);
9616
9616
  const [loginData, setLoginData] = useState(null);
9617
9617
  const [showPasswordRecovery, setShowPasswordRecovery] = useState(false);
9618
+ const [passwordSubmitting, setPasswordSubmitting] = useState(false);
9619
+ const successCallbackTimerRef = useRef(null);
9618
9620
  const CCPHONE = "+221";
9619
9621
  const isSubmitting = authLoading || loading;
9620
9622
  const error = localError || authError;
@@ -9632,15 +9634,11 @@ function LoginModal({
9632
9634
  setResendCooldown(60);
9633
9635
  }
9634
9636
  }, [status, step]);
9635
- useEffect(() => {
9636
- if (loginSuccess && loginData) {
9637
- const timer = setTimeout(() => {
9638
- onLoginSuccess == null ? void 0 : onLoginSuccess(loginData.token, loginData.user);
9639
- }, 1e3);
9640
- return () => clearTimeout(timer);
9641
- }
9642
- }, [loginSuccess, loginData, onLoginSuccess]);
9643
9637
  const resetState = useCallback(() => {
9638
+ if (successCallbackTimerRef.current) {
9639
+ clearTimeout(successCallbackTimerRef.current);
9640
+ successCallbackTimerRef.current = null;
9641
+ }
9644
9642
  setStep("choice");
9645
9643
  setEmail("");
9646
9644
  setPassword("");
@@ -9654,6 +9652,7 @@ function LoginModal({
9654
9652
  setLoginSuccess(false);
9655
9653
  setLoginData(null);
9656
9654
  setResendCooldown(0);
9655
+ setPasswordSubmitting(false);
9657
9656
  resetAuth();
9658
9657
  }, [resetAuth]);
9659
9658
  useEffect(() => {
@@ -9666,12 +9665,34 @@ function LoginModal({
9666
9665
  }
9667
9666
  }, [open, initialPhone]);
9668
9667
  const finalizeLogin = (result) => {
9669
- if (result.success && result.user) {
9668
+ if (result.success) {
9670
9669
  const token = getAuthToken() || "";
9671
- setLoginData({ token, user: result.user });
9672
- setLoginSuccess(true);
9670
+ const resolvedUser = result.user || user;
9671
+ if (resolvedUser) {
9672
+ setLoginData({ token, user: resolvedUser });
9673
+ setLoginSuccess(true);
9674
+ }
9673
9675
  }
9674
9676
  };
9677
+ useEffect(() => {
9678
+ if (!loginSuccess || !loginData || !onLoginSuccess) return;
9679
+ if (successCallbackTimerRef.current) {
9680
+ clearTimeout(successCallbackTimerRef.current);
9681
+ }
9682
+ successCallbackTimerRef.current = setTimeout(() => {
9683
+ try {
9684
+ onLoginSuccess(loginData.token, loginData.user);
9685
+ } catch (callbackError) {
9686
+ console.error("Erreur dans onLoginSuccess", callbackError);
9687
+ }
9688
+ }, 900);
9689
+ return () => {
9690
+ if (successCallbackTimerRef.current) {
9691
+ clearTimeout(successCallbackTimerRef.current);
9692
+ successCallbackTimerRef.current = null;
9693
+ }
9694
+ };
9695
+ }, [loginSuccess, loginData, onLoginSuccess]);
9675
9696
  const handleEmailCheck = async () => {
9676
9697
  setLocalError(null);
9677
9698
  clearError();
@@ -9688,18 +9709,24 @@ function LoginModal({
9688
9709
  };
9689
9710
  const handleEmailPasswordSubmit = async (e) => {
9690
9711
  e.preventDefault();
9712
+ if (passwordSubmitting || isSubmitting) return;
9713
+ setPasswordSubmitting(true);
9691
9714
  setLocalError(null);
9692
9715
  clearError();
9693
- if (!password) {
9694
- setLocalError("Le mot de passe est requis");
9695
- return;
9696
- }
9697
- if (password.length < 8) {
9698
- setLocalError("Le mot de passe doit contenir au moins 8 caractères");
9699
- return;
9716
+ try {
9717
+ if (!password) {
9718
+ setLocalError("Le mot de passe est requis");
9719
+ return;
9720
+ }
9721
+ if (password.length < 8) {
9722
+ setLocalError("Le mot de passe doit contenir au moins 8 caractères");
9723
+ return;
9724
+ }
9725
+ const result = await submitPassword(password);
9726
+ finalizeLogin(result);
9727
+ } finally {
9728
+ setPasswordSubmitting(false);
9700
9729
  }
9701
- const result = await submitPassword(password);
9702
- finalizeLogin(result);
9703
9730
  };
9704
9731
  const handleEmailOtpVerify = async () => {
9705
9732
  setLocalError(null);
@@ -9963,7 +9990,7 @@ function LoginModal({
9963
9990
  placeholder: "••••••••",
9964
9991
  value: password,
9965
9992
  onChange: (e) => setPassword(e.target.value),
9966
- disabled: isSubmitting,
9993
+ disabled: isSubmitting || passwordSubmitting,
9967
9994
  style: { paddingRight: "2.5rem" }
9968
9995
  }
9969
9996
  ),
@@ -9979,7 +10006,7 @@ function LoginModal({
9979
10006
  ] })
9980
10007
  ] })
9981
10008
  ] }) }),
9982
- /* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsx(Button, { type: "submit", disabled: isSubmitting || !password, style: { width: "100%" }, children: isSubmitting ? /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
10009
+ /* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsx(Button, { type: "submit", disabled: isSubmitting || passwordSubmitting || !password, style: { width: "100%" }, children: isSubmitting ? /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
9983
10010
  /* @__PURE__ */ jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
9984
10011
  "Connexion..."
9985
10012
  ] }) : "Se connecter" }) })
@@ -13235,6 +13262,8 @@ function NativeSSOPage({
13235
13262
  const [showOnboarding, setShowOnboarding] = useState(false);
13236
13263
  const [pendingSession, setPendingSession] = useState(null);
13237
13264
  const [debugOnboardingState, setDebugOnboardingState] = useState(null);
13265
+ const [redirectingTarget, setRedirectingTarget] = useState(null);
13266
+ const [redirectingReason, setRedirectingReason] = useState(null);
13238
13267
  const [session, setSession] = useState(() => {
13239
13268
  try {
13240
13269
  const storage2 = getNativeStorage();
@@ -13257,6 +13286,17 @@ function NativeSSOPage({
13257
13286
  useEffect(() => {
13258
13287
  sessionRef.current = session;
13259
13288
  }, [session]);
13289
+ useEffect(() => {
13290
+ if (!redirectingTarget) return;
13291
+ const timer = window.setTimeout(() => {
13292
+ const redirected = safeRedirect(redirectingTarget);
13293
+ if (!redirected) {
13294
+ setRedirectingTarget(null);
13295
+ setRedirectingReason(null);
13296
+ }
13297
+ }, 200);
13298
+ return () => window.clearTimeout(timer);
13299
+ }, [redirectingTarget]);
13260
13300
  const clearOnboardingTimers = useCallback(() => {
13261
13301
  if (onboardingPromptTimerRef.current) {
13262
13302
  clearTimeout(onboardingPromptTimerRef.current);
@@ -13424,6 +13464,12 @@ function NativeSSOPage({
13424
13464
  setLoginInitialPhone(phone);
13425
13465
  setTimeout(() => setModal("login"), 150);
13426
13466
  }, []);
13467
+ const beginRedirect = useCallback((target, reason = "login") => {
13468
+ if (!target) return false;
13469
+ setRedirectingReason(reason);
13470
+ setRedirectingTarget(target);
13471
+ return true;
13472
+ }, []);
13427
13473
  const handleLoginSuccess = useCallback((token, user) => {
13428
13474
  const userObj = {
13429
13475
  reference: "",
@@ -13440,10 +13486,14 @@ function NativeSSOPage({
13440
13486
  void refreshSessionProfile(true);
13441
13487
  if (!needsOnboarding(userObj)) {
13442
13488
  markProfilePromptComplete();
13443
- onLoginSuccess == null ? void 0 : onLoginSuccess(token, user);
13444
- safeRedirect(redirectAfterLogin);
13489
+ try {
13490
+ onLoginSuccess == null ? void 0 : onLoginSuccess(token, user);
13491
+ } catch (callbackError) {
13492
+ console.error("Erreur dans le callback onLoginSuccess du wrapper SSO", callbackError);
13493
+ }
13494
+ beginRedirect(redirectAfterLogin, "login");
13445
13495
  }
13446
- }, [onLoginSuccess, redirectAfterLogin, persistSessionUser, syncProfilePrompt, refreshSessionProfile, accountType]);
13496
+ }, [onLoginSuccess, redirectAfterLogin, persistSessionUser, syncProfilePrompt, refreshSessionProfile, accountType, beginRedirect]);
13447
13497
  const handleOnboardingComplete = useCallback((data) => {
13448
13498
  const activeSession = debugOnboardingState || pendingSession;
13449
13499
  if (!activeSession) return;
@@ -13487,11 +13537,15 @@ function NativeSSOPage({
13487
13537
  if (!debugOnboardingState) {
13488
13538
  persistSessionUser(activeSession.token, activeSession.user);
13489
13539
  snoozeProfilePrompt(PROFILE_PROMPT_SNOOZE_MS / (60 * 60 * 1e3));
13490
- onLoginSuccess == null ? void 0 : onLoginSuccess(activeSession.token, activeSession.user);
13491
- safeRedirect(redirectAfterLogin);
13540
+ try {
13541
+ onLoginSuccess == null ? void 0 : onLoginSuccess(activeSession.token, activeSession.user);
13542
+ } catch (callbackError) {
13543
+ console.error("Erreur dans le callback onLoginSuccess du wrapper SSO", callbackError);
13544
+ }
13545
+ beginRedirect(redirectAfterLogin, "login");
13492
13546
  return;
13493
13547
  }
13494
- }, [pendingSession, debugOnboardingState, onLoginSuccess, redirectAfterLogin, persistSessionUser]);
13548
+ }, [pendingSession, debugOnboardingState, onLoginSuccess, redirectAfterLogin, persistSessionUser, beginRedirect]);
13495
13549
  const handleOnboardingDismiss = useCallback(() => {
13496
13550
  setShowOnboarding(false);
13497
13551
  setPendingSession(null);
@@ -13504,8 +13558,8 @@ function NativeSSOPage({
13504
13558
  setDebugOnboardingState(null);
13505
13559
  clearOnboardingTimers();
13506
13560
  onLogout == null ? void 0 : onLogout();
13507
- safeRedirect(redirectAfterLogout);
13508
- }, [onLogout, redirectAfterLogout, clearOnboardingTimers]);
13561
+ beginRedirect(redirectAfterLogout, "logout");
13562
+ }, [onLogout, redirectAfterLogout, clearOnboardingTimers, beginRedirect]);
13509
13563
  const openDebugLogin = useCallback(() => {
13510
13564
  clearOnboardingTimers();
13511
13565
  setShowOnboarding(false);
@@ -13520,6 +13574,10 @@ function NativeSSOPage({
13520
13574
  setDebugOnboardingState(null);
13521
13575
  setModal("signup");
13522
13576
  }, [clearOnboardingTimers]);
13577
+ useEffect(() => {
13578
+ if (!(session == null ? void 0 : session.token) || !redirectAfterLogin || redirectingTarget) return;
13579
+ beginRedirect(redirectAfterLogin, "already-authenticated");
13580
+ }, [session == null ? void 0 : session.token, redirectAfterLogin, redirectingTarget, beginRedirect]);
13523
13581
  const openDebugOnboarding = useCallback((preset = "current") => {
13524
13582
  if (!session) return;
13525
13583
  clearOnboardingTimers();
@@ -13642,14 +13700,18 @@ function NativeSSOPage({
13642
13700
  overflow: "hidden"
13643
13701
  }, children: /* @__PURE__ */ jsx(AppsLogoSlider, { iamApiUrl, speed: "normal" }) }) })
13644
13702
  ] }) });
13703
+ if (redirectingTarget) {
13704
+ return /* @__PURE__ */ jsxs("div", { style: containerStyle, children: [
13705
+ /* @__PURE__ */ jsx(TopBranding, { subtitle: title }),
13706
+ /* @__PURE__ */ jsx(SliderBadge, {}),
13707
+ /* @__PURE__ */ jsx("div", { style: cardStyle, children: /* @__PURE__ */ jsxs("div", { style: { padding: "2rem 1.5rem 1.5rem", textAlign: "center" }, children: [
13708
+ /* @__PURE__ */ 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" }),
13709
+ /* @__PURE__ */ jsx("p", { style: { fontSize: "0.875rem", color: COLORS.muted, marginTop: "0.5rem" }, children: "Redirection en cours..." })
13710
+ ] }) }),
13711
+ /* @__PURE__ */ jsx(Footer, { hideFooter })
13712
+ ] });
13713
+ }
13645
13714
  if (session) {
13646
- if (redirectAfterLogin) {
13647
- safeRedirect(redirectAfterLogin);
13648
- return /* @__PURE__ */ jsxs("div", { style: containerStyle, children: [
13649
- /* @__PURE__ */ jsx(TopBranding, { subtitle: title }),
13650
- /* @__PURE__ */ jsx("p", { style: { color: "rgba(255,255,255,0.7)", fontSize: "0.875rem" }, children: "Redirection en cours..." })
13651
- ] });
13652
- }
13653
13715
  return /* @__PURE__ */ jsxs("div", { style: containerStyle, children: [
13654
13716
  /* @__PURE__ */ jsx(TopBranding, { subtitle: title }),
13655
13717
  /* @__PURE__ */ jsx(SliderBadge, {}),