@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.cjs +211 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +211 -51
- package/dist/index.js.map +1 -1
- package/dist/services/api.d.ts +22 -0
- package/package.json +1 -1
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(
|
|
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(
|
|
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
|
|
7128
|
-
|
|
7129
|
-
|
|
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
|
-
|
|
7133
|
-
|
|
7161
|
+
const normalizedValue = normalizeStorageValue(value);
|
|
7162
|
+
if (!normalizedValue.startsWith(STORAGE_ENCRYPTION_PREFIX)) {
|
|
7163
|
+
return normalizedValue;
|
|
7134
7164
|
}
|
|
7135
|
-
const
|
|
7136
|
-
|
|
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.
|
|
7158
|
-
base.
|
|
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,
|
|
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
|
|
9754
|
+
if (result.success) {
|
|
9670
9755
|
const token = getAuthToken() || "";
|
|
9671
|
-
|
|
9672
|
-
|
|
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
|
-
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
|
|
9699
|
-
|
|
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
|
-
|
|
13444
|
-
|
|
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
|
-
|
|
13491
|
-
|
|
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
|
-
|
|
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,
|