@ollaid/native-sso 2.7.1 → 2.7.3

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.d.ts CHANGED
@@ -40,8 +40,9 @@ export { mobilePasswordService } from './services/mobilePassword';
40
40
  export { profileChangeService } from './services/profileChange';
41
41
  export { profileMediaService } from './services/profileMedia';
42
42
  export { iamAccountService } from './services/iamAccount';
43
- export { setNativeAuthConfig, getNativeAuthConfig, setNativeStorage, getNativeStorage, ApiError, getAuthToken, getAuthUser, getAccountType, clearAuthToken, logout, getSsoSessionSnapshot, hasSsoSession, getDeviceId, getSessionUuid, STORAGE_KEYS, PROFILE_PROMPT_KEYS, getProfilePromptState, setProfilePromptState, markProfilePromptComplete, snoozeProfilePrompt, } from './services/api';
43
+ export { setNativeAuthConfig, getNativeAuthConfig, setNativeStorage, getNativeStorage, ApiError, getAuthToken, getAuthUser, getAccountType, clearAuthToken, clearNativeSsoStorage, repairNativeSsoStorage, logout, getSsoSessionSnapshot, hasSsoSession, getDeviceId, getSessionUuid, STORAGE_KEYS, PROFILE_PROMPT_KEYS, getProfilePromptState, setProfilePromptState, markProfilePromptComplete, snoozeProfilePrompt, } from './services/api';
44
44
  export type { NativeAuthConfig, NativeStorageAdapter, ApiErrorType, ProfilePromptState } from './services/api';
45
+ export type { NativeSsoStorageRepairResult } from './services/api';
45
46
  export type { SsoSessionSnapshot } from './services/api';
46
47
  export type { NativeAuthType, NativeAuthStatus, AccountType, RegistrationType, NativeCredentials, NativeEncryptRequest, NativeEncryptResponse, NativeConfigResponse, NativeInitResponse, NativeValidateResponse, NativeGrantAccessResponse, NativeResendOtpResponse, NativeExchangeResponse, NativeRefreshResponse, NativeUser, NativeAuthState, UserInfos, LinkPhoneRequest, LinkPhoneResponse, LinkEmailRequest, LinkEmailResponse, RefreshUserInfoSingleRequest, RefreshUserInfoSingleResponse, RefreshUserInfoBulkRequest, RefreshUserInfoBulkResponse, UpdateAvatarRequest, UpdateAvatarResponse, ResetAvatarRequest, ResetAvatarResponse, CheckTokenResponse, } from './types/native';
47
48
  export type { MobilePasswordState, MobilePasswordStatus, } from './types/mobile';
package/dist/index.js CHANGED
@@ -7106,6 +7106,27 @@ function isRawStorageKey(key) {
7106
7106
  function getLegacyStorageKey(key) {
7107
7107
  return LEGACY_STORAGE_KEYS[key] || null;
7108
7108
  }
7109
+ function normalizeStorageValue(value) {
7110
+ if (typeof value === "string") return value;
7111
+ if (value === null || value === void 0) return "";
7112
+ if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
7113
+ return String(value);
7114
+ }
7115
+ try {
7116
+ const serialized = JSON.stringify(value);
7117
+ return serialized ?? "";
7118
+ } catch {
7119
+ return String(value);
7120
+ }
7121
+ }
7122
+ function safeJSONStringify(value) {
7123
+ try {
7124
+ const serialized = JSON.stringify(value);
7125
+ return serialized ?? "null";
7126
+ } catch {
7127
+ return "null";
7128
+ }
7129
+ }
7109
7130
  function migrateLegacyValue(base, key, legacyKey, rawValue) {
7110
7131
  base.setItem(key, encryptStorageValue(rawValue));
7111
7132
  base.removeItem(legacyKey);
@@ -7114,31 +7135,44 @@ function migrateLegacyValue(base, key, legacyKey, rawValue) {
7114
7135
  function getStorageEncryptionSecret() {
7115
7136
  var _a;
7116
7137
  const storage = rawStorageAdapter;
7117
- let seed = storage.getItem("native_sso_storage_seed");
7138
+ let seed = storage.getItem(STORAGE_SEED_KEY);
7118
7139
  if (!seed) {
7119
7140
  seed = `seed_${Date.now()}_${Math.random().toString(36).substring(2, 15)}_${Math.random().toString(36).substring(2, 15)}`;
7120
- storage.setItem("native_sso_storage_seed", seed);
7141
+ storage.setItem(STORAGE_SEED_KEY, seed);
7121
7142
  }
7122
7143
  const origin = typeof window !== "undefined" && ((_a = window.location) == null ? void 0 : _a.origin) ? window.location.origin : "unknown-origin";
7123
7144
  const prefix = config.configPrefix || "iam";
7124
7145
  return `${STORAGE_ENCRYPTION_SECRET_PREFIX}::${origin}::${prefix}::${seed}`;
7125
7146
  }
7126
7147
  function encryptStorageValue(value) {
7127
- const secret = getStorageEncryptionSecret();
7128
- const ciphertext = cryptoJsExports.AES.encrypt(value, secret).toString();
7129
- return `${STORAGE_ENCRYPTION_PREFIX}${ciphertext}`;
7148
+ const normalizedValue = normalizeStorageValue(value);
7149
+ try {
7150
+ const secret = getStorageEncryptionSecret();
7151
+ const ciphertext = cryptoJsExports.AES.encrypt(normalizedValue, secret).toString();
7152
+ return `${STORAGE_ENCRYPTION_PREFIX}${ciphertext}`;
7153
+ } catch (error) {
7154
+ if (isDebugMode()) {
7155
+ console.warn("⚠️ [native-sso] Encryption storage fallback to plain value", error);
7156
+ }
7157
+ return normalizedValue;
7158
+ }
7130
7159
  }
7131
7160
  function decryptStorageValue(value) {
7132
- if (!value.startsWith(STORAGE_ENCRYPTION_PREFIX)) {
7133
- return value;
7161
+ const normalizedValue = normalizeStorageValue(value);
7162
+ if (!normalizedValue.startsWith(STORAGE_ENCRYPTION_PREFIX)) {
7163
+ return normalizedValue;
7134
7164
  }
7135
- const secret = getStorageEncryptionSecret();
7136
- const ciphertext = value.slice(STORAGE_ENCRYPTION_PREFIX.length);
7165
+ const ciphertext = normalizedValue.slice(STORAGE_ENCRYPTION_PREFIX.length);
7166
+ if (!ciphertext) return null;
7137
7167
  try {
7168
+ const secret = getStorageEncryptionSecret();
7138
7169
  const bytes = cryptoJsExports.AES.decrypt(ciphertext, secret);
7139
7170
  const plaintext = bytes.toString(cryptoJsExports.enc.Utf8);
7140
7171
  return plaintext || null;
7141
- } catch {
7172
+ } catch (error) {
7173
+ if (isDebugMode()) {
7174
+ console.warn("⚠️ [native-sso] Failed to decrypt storage value, clearing corrupted entry", error);
7175
+ }
7142
7176
  return null;
7143
7177
  }
7144
7178
  }
@@ -7154,8 +7188,9 @@ function createEncryptedStorageAdapter(base) {
7154
7188
  if (decrypted !== null) {
7155
7189
  return decrypted;
7156
7190
  }
7157
- if (rawValue.length > 0) {
7158
- base.setItem(key, encryptStorageValue(rawValue));
7191
+ if (normalizeStorageValue(rawValue).startsWith(STORAGE_ENCRYPTION_PREFIX)) {
7192
+ base.removeItem(key);
7193
+ return null;
7159
7194
  }
7160
7195
  return rawValue;
7161
7196
  }
@@ -7176,7 +7211,7 @@ function createEncryptedStorageAdapter(base) {
7176
7211
  },
7177
7212
  setItem: (key, value) => {
7178
7213
  if (isRawStorageKey(key)) {
7179
- base.setItem(key, value);
7214
+ base.setItem(key, normalizeStorageValue(value));
7180
7215
  return;
7181
7216
  }
7182
7217
  base.setItem(key, encryptStorageValue(value));
@@ -7228,6 +7263,7 @@ const getIamApiBaseUrl = () => {
7228
7263
  };
7229
7264
  const DEVICE_ID_KEY = "sso_device_id";
7230
7265
  const SESSION_UUID_KEY = "sso_session_uuid";
7266
+ const STORAGE_SEED_KEY = "native_sso_storage_seed";
7231
7267
  function generateUuid() {
7232
7268
  const globalCrypto = typeof globalThis !== "undefined" ? globalThis.crypto : void 0;
7233
7269
  if (globalCrypto && typeof globalCrypto.randomUUID === "function") {
@@ -7335,8 +7371,26 @@ const PROFILE_STORAGE = {
7335
7371
  IMAGE_LAST_CHECK: "sso_image_last_check",
7336
7372
  IMAGE_RECHECK_AT: "sso_image_recheck_at"
7337
7373
  };
7374
+ const ALL_SESSION_STORAGE_KEYS = [
7375
+ STORAGE.AUTH_TOKEN,
7376
+ STORAGE.TOKEN,
7377
+ STORAGE.USER,
7378
+ STORAGE.ACCOUNT_TYPE,
7379
+ STORAGE.ALIAS_REFERENCE,
7380
+ STORAGE.APP_ACCESS_TOKEN_REF,
7381
+ STORAGE.REFRESH_TOKEN,
7382
+ STORAGE.TOKEN_EXPIRES_AT,
7383
+ STORAGE.REFRESH_EXPIRES_AT,
7384
+ PROFILE_STORAGE.IMAGE_LAST_STATUS,
7385
+ PROFILE_STORAGE.IMAGE_LAST_CHECK,
7386
+ PROFILE_STORAGE.IMAGE_RECHECK_AT,
7387
+ DEVICE_ID_KEY,
7388
+ SESSION_UUID_KEY,
7389
+ STORAGE_SEED_KEY
7390
+ ];
7338
7391
  const setAuthToken = (token) => {
7339
7392
  const storage = getNativeStorage();
7393
+ if (typeof token !== "string" || token.length === 0) return;
7340
7394
  storage.setItem(STORAGE.AUTH_TOKEN, token);
7341
7395
  };
7342
7396
  const getAuthToken = () => {
@@ -7355,13 +7409,45 @@ const clearAuthToken = () => {
7355
7409
  storage.removeItem(STORAGE.TOKEN_EXPIRES_AT);
7356
7410
  storage.removeItem(STORAGE.REFRESH_EXPIRES_AT);
7357
7411
  };
7412
+ const clearNativeSsoStorage = (options) => {
7413
+ const storage = getNativeStorage();
7414
+ const preserveDeviceIdentity = (options == null ? void 0 : options.preserveDeviceIdentity) === true;
7415
+ ALL_SESSION_STORAGE_KEYS.forEach((key) => {
7416
+ if (preserveDeviceIdentity && (key === DEVICE_ID_KEY || key === SESSION_UUID_KEY || key === STORAGE_SEED_KEY)) {
7417
+ return;
7418
+ }
7419
+ storage.removeItem(key);
7420
+ });
7421
+ };
7422
+ const repairNativeSsoStorage = () => {
7423
+ const storage = getNativeStorage();
7424
+ const authToken = getAuthToken();
7425
+ const userRaw = storage.getItem(STORAGE.USER);
7426
+ if (userRaw && !authToken) {
7427
+ clearNativeSsoStorage();
7428
+ return { cleaned: true, reason: "incomplete_session" };
7429
+ }
7430
+ if (authToken && !userRaw) {
7431
+ clearNativeSsoStorage();
7432
+ return { cleaned: true, reason: "incomplete_session" };
7433
+ }
7434
+ if (userRaw) {
7435
+ try {
7436
+ JSON.parse(userRaw);
7437
+ } catch {
7438
+ clearNativeSsoStorage();
7439
+ return { cleaned: true, reason: "invalid_user_json" };
7440
+ }
7441
+ }
7442
+ return { cleaned: false, reason: null };
7443
+ };
7358
7444
  const logout = async () => {
7359
7445
  const { nativeAuthService: nativeAuthService2 } = await Promise.resolve().then(() => nativeAuth);
7360
7446
  const token = getAuthToken();
7361
7447
  return nativeAuthService2.logout(token || void 0);
7362
7448
  };
7363
7449
  const setAuthUser = (user) => {
7364
- getNativeStorage().setItem(STORAGE.USER, JSON.stringify(user));
7450
+ getNativeStorage().setItem(STORAGE.USER, safeJSONStringify(user));
7365
7451
  };
7366
7452
  const getAuthUser = () => {
7367
7453
  const user = getNativeStorage().getItem(STORAGE.USER);
@@ -9615,6 +9701,8 @@ function LoginModal({
9615
9701
  const [loginSuccess, setLoginSuccess] = useState(false);
9616
9702
  const [loginData, setLoginData] = useState(null);
9617
9703
  const [showPasswordRecovery, setShowPasswordRecovery] = useState(false);
9704
+ const [passwordSubmitting, setPasswordSubmitting] = useState(false);
9705
+ const successCallbackTimerRef = useRef(null);
9618
9706
  const CCPHONE = "+221";
9619
9707
  const isSubmitting = authLoading || loading;
9620
9708
  const error = localError || authError;
@@ -9632,15 +9720,11 @@ function LoginModal({
9632
9720
  setResendCooldown(60);
9633
9721
  }
9634
9722
  }, [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
9723
  const resetState = useCallback(() => {
9724
+ if (successCallbackTimerRef.current) {
9725
+ clearTimeout(successCallbackTimerRef.current);
9726
+ successCallbackTimerRef.current = null;
9727
+ }
9644
9728
  setStep("choice");
9645
9729
  setEmail("");
9646
9730
  setPassword("");
@@ -9654,6 +9738,7 @@ function LoginModal({
9654
9738
  setLoginSuccess(false);
9655
9739
  setLoginData(null);
9656
9740
  setResendCooldown(0);
9741
+ setPasswordSubmitting(false);
9657
9742
  resetAuth();
9658
9743
  }, [resetAuth]);
9659
9744
  useEffect(() => {
@@ -9666,12 +9751,34 @@ function LoginModal({
9666
9751
  }
9667
9752
  }, [open, initialPhone]);
9668
9753
  const finalizeLogin = (result) => {
9669
- if (result.success && result.user) {
9754
+ if (result.success) {
9670
9755
  const token = getAuthToken() || "";
9671
- setLoginData({ token, user: result.user });
9672
- setLoginSuccess(true);
9756
+ const resolvedUser = result.user || user;
9757
+ if (resolvedUser) {
9758
+ setLoginData({ token, user: resolvedUser });
9759
+ setLoginSuccess(true);
9760
+ }
9673
9761
  }
9674
9762
  };
9763
+ useEffect(() => {
9764
+ if (!loginSuccess || !loginData || !onLoginSuccess) return;
9765
+ if (successCallbackTimerRef.current) {
9766
+ clearTimeout(successCallbackTimerRef.current);
9767
+ }
9768
+ successCallbackTimerRef.current = setTimeout(() => {
9769
+ try {
9770
+ onLoginSuccess(loginData.token, loginData.user);
9771
+ } catch (callbackError) {
9772
+ console.error("Erreur dans onLoginSuccess", callbackError);
9773
+ }
9774
+ }, 900);
9775
+ return () => {
9776
+ if (successCallbackTimerRef.current) {
9777
+ clearTimeout(successCallbackTimerRef.current);
9778
+ successCallbackTimerRef.current = null;
9779
+ }
9780
+ };
9781
+ }, [loginSuccess, loginData, onLoginSuccess]);
9675
9782
  const handleEmailCheck = async () => {
9676
9783
  setLocalError(null);
9677
9784
  clearError();
@@ -9688,18 +9795,24 @@ function LoginModal({
9688
9795
  };
9689
9796
  const handleEmailPasswordSubmit = async (e) => {
9690
9797
  e.preventDefault();
9798
+ if (passwordSubmitting || isSubmitting) return;
9799
+ setPasswordSubmitting(true);
9691
9800
  setLocalError(null);
9692
9801
  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;
9802
+ try {
9803
+ if (!password) {
9804
+ setLocalError("Le mot de passe est requis");
9805
+ return;
9806
+ }
9807
+ if (password.length < 8) {
9808
+ setLocalError("Le mot de passe doit contenir au moins 8 caractères");
9809
+ return;
9810
+ }
9811
+ const result = await submitPassword(password);
9812
+ finalizeLogin(result);
9813
+ } finally {
9814
+ setPasswordSubmitting(false);
9700
9815
  }
9701
- const result = await submitPassword(password);
9702
- finalizeLogin(result);
9703
9816
  };
9704
9817
  const handleEmailOtpVerify = async () => {
9705
9818
  setLocalError(null);
@@ -9963,7 +10076,7 @@ function LoginModal({
9963
10076
  placeholder: "••••••••",
9964
10077
  value: password,
9965
10078
  onChange: (e) => setPassword(e.target.value),
9966
- disabled: isSubmitting,
10079
+ disabled: isSubmitting || passwordSubmitting,
9967
10080
  style: { paddingRight: "2.5rem" }
9968
10081
  }
9969
10082
  ),
@@ -9979,7 +10092,7 @@ function LoginModal({
9979
10092
  ] })
9980
10093
  ] })
9981
10094
  ] }) }),
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: [
10095
+ /* @__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
10096
  /* @__PURE__ */ jsx(IconLoader2, { style: { width: "1rem", height: "1rem" } }),
9984
10097
  "Connexion..."
9985
10098
  ] }) : "Se connecter" }) })
@@ -13235,6 +13348,8 @@ function NativeSSOPage({
13235
13348
  const [showOnboarding, setShowOnboarding] = useState(false);
13236
13349
  const [pendingSession, setPendingSession] = useState(null);
13237
13350
  const [debugOnboardingState, setDebugOnboardingState] = useState(null);
13351
+ const [redirectingTarget, setRedirectingTarget] = useState(null);
13352
+ const [redirectingReason, setRedirectingReason] = useState(null);
13238
13353
  const [session, setSession] = useState(() => {
13239
13354
  try {
13240
13355
  const storage2 = getNativeStorage();
@@ -13257,6 +13372,27 @@ function NativeSSOPage({
13257
13372
  useEffect(() => {
13258
13373
  sessionRef.current = session;
13259
13374
  }, [session]);
13375
+ useEffect(() => {
13376
+ const repairResult = repairNativeSsoStorage();
13377
+ if (repairResult.cleaned) {
13378
+ setSession(null);
13379
+ const isDev = Boolean(false);
13380
+ if (isDev) {
13381
+ console.warn("🔧 [NativeSSOPage] Storage SSO réparé", repairResult.reason);
13382
+ }
13383
+ }
13384
+ }, []);
13385
+ useEffect(() => {
13386
+ if (!redirectingTarget) return;
13387
+ const timer = window.setTimeout(() => {
13388
+ const redirected = safeRedirect(redirectingTarget);
13389
+ if (!redirected) {
13390
+ setRedirectingTarget(null);
13391
+ setRedirectingReason(null);
13392
+ }
13393
+ }, 200);
13394
+ return () => window.clearTimeout(timer);
13395
+ }, [redirectingTarget]);
13260
13396
  const clearOnboardingTimers = useCallback(() => {
13261
13397
  if (onboardingPromptTimerRef.current) {
13262
13398
  clearTimeout(onboardingPromptTimerRef.current);
@@ -13424,6 +13560,12 @@ function NativeSSOPage({
13424
13560
  setLoginInitialPhone(phone);
13425
13561
  setTimeout(() => setModal("login"), 150);
13426
13562
  }, []);
13563
+ const beginRedirect = useCallback((target, reason = "login") => {
13564
+ if (!target) return false;
13565
+ setRedirectingReason(reason);
13566
+ setRedirectingTarget(target);
13567
+ return true;
13568
+ }, []);
13427
13569
  const handleLoginSuccess = useCallback((token, user) => {
13428
13570
  const userObj = {
13429
13571
  reference: "",
@@ -13440,10 +13582,14 @@ function NativeSSOPage({
13440
13582
  void refreshSessionProfile(true);
13441
13583
  if (!needsOnboarding(userObj)) {
13442
13584
  markProfilePromptComplete();
13443
- onLoginSuccess == null ? void 0 : onLoginSuccess(token, user);
13444
- safeRedirect(redirectAfterLogin);
13585
+ try {
13586
+ onLoginSuccess == null ? void 0 : onLoginSuccess(token, user);
13587
+ } catch (callbackError) {
13588
+ console.error("Erreur dans le callback onLoginSuccess du wrapper SSO", callbackError);
13589
+ }
13590
+ beginRedirect(redirectAfterLogin, "login");
13445
13591
  }
13446
- }, [onLoginSuccess, redirectAfterLogin, persistSessionUser, syncProfilePrompt, refreshSessionProfile, accountType]);
13592
+ }, [onLoginSuccess, redirectAfterLogin, persistSessionUser, syncProfilePrompt, refreshSessionProfile, accountType, beginRedirect]);
13447
13593
  const handleOnboardingComplete = useCallback((data) => {
13448
13594
  const activeSession = debugOnboardingState || pendingSession;
13449
13595
  if (!activeSession) return;
@@ -13487,11 +13633,15 @@ function NativeSSOPage({
13487
13633
  if (!debugOnboardingState) {
13488
13634
  persistSessionUser(activeSession.token, activeSession.user);
13489
13635
  snoozeProfilePrompt(PROFILE_PROMPT_SNOOZE_MS / (60 * 60 * 1e3));
13490
- onLoginSuccess == null ? void 0 : onLoginSuccess(activeSession.token, activeSession.user);
13491
- safeRedirect(redirectAfterLogin);
13636
+ try {
13637
+ onLoginSuccess == null ? void 0 : onLoginSuccess(activeSession.token, activeSession.user);
13638
+ } catch (callbackError) {
13639
+ console.error("Erreur dans le callback onLoginSuccess du wrapper SSO", callbackError);
13640
+ }
13641
+ beginRedirect(redirectAfterLogin, "login");
13492
13642
  return;
13493
13643
  }
13494
- }, [pendingSession, debugOnboardingState, onLoginSuccess, redirectAfterLogin, persistSessionUser]);
13644
+ }, [pendingSession, debugOnboardingState, onLoginSuccess, redirectAfterLogin, persistSessionUser, beginRedirect]);
13495
13645
  const handleOnboardingDismiss = useCallback(() => {
13496
13646
  setShowOnboarding(false);
13497
13647
  setPendingSession(null);
@@ -13504,8 +13654,8 @@ function NativeSSOPage({
13504
13654
  setDebugOnboardingState(null);
13505
13655
  clearOnboardingTimers();
13506
13656
  onLogout == null ? void 0 : onLogout();
13507
- safeRedirect(redirectAfterLogout);
13508
- }, [onLogout, redirectAfterLogout, clearOnboardingTimers]);
13657
+ beginRedirect(redirectAfterLogout, "logout");
13658
+ }, [onLogout, redirectAfterLogout, clearOnboardingTimers, beginRedirect]);
13509
13659
  const openDebugLogin = useCallback(() => {
13510
13660
  clearOnboardingTimers();
13511
13661
  setShowOnboarding(false);
@@ -13520,6 +13670,10 @@ function NativeSSOPage({
13520
13670
  setDebugOnboardingState(null);
13521
13671
  setModal("signup");
13522
13672
  }, [clearOnboardingTimers]);
13673
+ useEffect(() => {
13674
+ if (!(session == null ? void 0 : session.token) || !redirectAfterLogin || redirectingTarget) return;
13675
+ beginRedirect(redirectAfterLogin, "already-authenticated");
13676
+ }, [session == null ? void 0 : session.token, redirectAfterLogin, redirectingTarget, beginRedirect]);
13523
13677
  const openDebugOnboarding = useCallback((preset = "current") => {
13524
13678
  if (!session) return;
13525
13679
  clearOnboardingTimers();
@@ -13642,14 +13796,18 @@ function NativeSSOPage({
13642
13796
  overflow: "hidden"
13643
13797
  }, children: /* @__PURE__ */ jsx(AppsLogoSlider, { iamApiUrl, speed: "normal" }) }) })
13644
13798
  ] }) });
13799
+ if (redirectingTarget) {
13800
+ return /* @__PURE__ */ jsxs("div", { style: containerStyle, children: [
13801
+ /* @__PURE__ */ jsx(TopBranding, { subtitle: title }),
13802
+ /* @__PURE__ */ jsx(SliderBadge, {}),
13803
+ /* @__PURE__ */ jsx("div", { style: cardStyle, children: /* @__PURE__ */ jsxs("div", { style: { padding: "2rem 1.5rem 1.5rem", textAlign: "center" }, children: [
13804
+ /* @__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" }),
13805
+ /* @__PURE__ */ jsx("p", { style: { fontSize: "0.875rem", color: COLORS.muted, marginTop: "0.5rem" }, children: "Redirection en cours..." })
13806
+ ] }) }),
13807
+ /* @__PURE__ */ jsx(Footer, { hideFooter })
13808
+ ] });
13809
+ }
13645
13810
  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
13811
  return /* @__PURE__ */ jsxs("div", { style: containerStyle, children: [
13654
13812
  /* @__PURE__ */ jsx(TopBranding, { subtitle: title }),
13655
13813
  /* @__PURE__ */ jsx(SliderBadge, {}),
@@ -13972,6 +14130,7 @@ export {
13972
14130
  STORAGE as STORAGE_KEYS,
13973
14131
  SignupModal,
13974
14132
  clearAuthToken,
14133
+ clearNativeSsoStorage,
13975
14134
  getAccountType,
13976
14135
  getAuthToken,
13977
14136
  getAuthUser,
@@ -13992,6 +14151,7 @@ export {
13992
14151
  nativeAuthService,
13993
14152
  profileChangeService,
13994
14153
  profileMediaService,
14154
+ repairNativeSsoStorage,
13995
14155
  searchCountries,
13996
14156
  setNativeAuthConfig,
13997
14157
  setNativeStorage,