@ollaid/native-sso 1.0.0 → 1.0.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
@@ -479,7 +479,8 @@ const STORAGE = {
479
479
  AUTH_TOKEN: "auth_token",
480
480
  TOKEN: "token",
481
481
  USER: "user",
482
- ACCOUNT_TYPE: "account_type"
482
+ ACCOUNT_TYPE: "account_type",
483
+ ALIAS_REFERENCE: "alias_reference"
483
484
  };
484
485
  const setAuthToken = (token) => {
485
486
  if (typeof localStorage !== "undefined") {
@@ -497,6 +498,7 @@ const clearAuthToken = () => {
497
498
  localStorage.removeItem(STORAGE.TOKEN);
498
499
  localStorage.removeItem(STORAGE.USER);
499
500
  localStorage.removeItem(STORAGE.ACCOUNT_TYPE);
501
+ localStorage.removeItem(STORAGE.ALIAS_REFERENCE);
500
502
  }
501
503
  };
502
504
  const setAuthUser = (user) => {
@@ -585,6 +587,10 @@ function getHeaders(token) {
585
587
  return headers;
586
588
  }
587
589
  let credentials = null;
590
+ let credentialsLoadedAt = 0;
591
+ let credentialsTtl = 300;
592
+ const DEFAULT_TTL = 300;
593
+ const REFRESH_MARGIN = 30;
588
594
  const nativeAuthService = {
589
595
  hasCredentials() {
590
596
  return credentials !== null;
@@ -592,6 +598,26 @@ const nativeAuthService = {
592
598
  getCredentials() {
593
599
  return credentials ? { ...credentials } : null;
594
600
  },
601
+ getCredentialsTtl() {
602
+ return credentialsTtl;
603
+ },
604
+ getCredentialsAge() {
605
+ if (!credentialsLoadedAt) return Infinity;
606
+ return (Date.now() - credentialsLoadedAt) / 1e3;
607
+ },
608
+ areCredentialsExpiringSoon() {
609
+ if (!credentials || !credentialsLoadedAt) return true;
610
+ const age = this.getCredentialsAge();
611
+ return age >= credentialsTtl - REFRESH_MARGIN;
612
+ },
613
+ async ensureFreshCredentials() {
614
+ if (!credentials || this.areCredentialsExpiringSoon()) {
615
+ if (isDebugMode()) {
616
+ console.log("🔄 [Native] Credentials expirés ou proches — auto-refresh");
617
+ }
618
+ await this.loadCredentials();
619
+ }
620
+ },
595
621
  async loadCredentials() {
596
622
  const config2 = getNativeAuthConfig();
597
623
  if (!config2.saasApiUrl) {
@@ -612,6 +638,8 @@ const nativeAuthService = {
612
638
  appKey: response.app_key,
613
639
  encryptedCredentials: response.encrypted_credentials
614
640
  };
641
+ credentialsLoadedAt = Date.now();
642
+ credentialsTtl = response.credentials_ttl || DEFAULT_TTL;
615
643
  if (typeof response.debug === "boolean") {
616
644
  const currentConfig = getNativeAuthConfig();
617
645
  if (currentConfig.debug !== true) {
@@ -619,11 +647,12 @@ const nativeAuthService = {
619
647
  }
620
648
  }
621
649
  if (isDebugMode()) {
622
- console.log("✅ [SaaS] Credentials chargés (debug:", response.debug ?? "non défini", ")");
650
+ console.log("✅ [SaaS] Credentials chargés (ttl:", credentialsTtl, "s, debug:", response.debug ?? "non défini", ")");
623
651
  }
624
652
  return credentials;
625
653
  },
626
654
  async encrypt(type, data) {
655
+ await this.ensureFreshCredentials();
627
656
  if (!credentials) {
628
657
  throw new ApiError("Credentials non chargés. Appelez loadCredentials() d'abord.", "auth");
629
658
  }
@@ -831,15 +860,18 @@ const nativeAuthService = {
831
860
  );
832
861
  clearAuthToken();
833
862
  credentials = null;
863
+ credentialsLoadedAt = 0;
834
864
  return response;
835
865
  } catch {
836
866
  clearAuthToken();
837
867
  credentials = null;
868
+ credentialsLoadedAt = 0;
838
869
  return { success: true };
839
870
  }
840
871
  },
841
872
  clearCredentials() {
842
873
  credentials = null;
874
+ credentialsLoadedAt = 0;
843
875
  },
844
876
  // ============================================
845
877
  // High-level methods
@@ -1022,14 +1054,14 @@ function getErrorMessage$2(err, context) {
1022
1054
  return { message: `Erreur lors de ${context}`, type: "unknown" };
1023
1055
  }
1024
1056
  function useMobilePassword(options) {
1025
- const { saasApiUrl, iamApiUrl, autoLoadCredentials = true, debug = false } = options;
1057
+ const { saasApiUrl, iamApiUrl, autoLoadCredentials = true } = options;
1026
1058
  const configuredRef = useRef(false);
1027
1059
  useEffect(() => {
1028
1060
  if (!configuredRef.current) {
1029
- setNativeAuthConfig({ saasApiUrl, iamApiUrl, debug });
1061
+ setNativeAuthConfig({ saasApiUrl, iamApiUrl });
1030
1062
  configuredRef.current = true;
1031
1063
  }
1032
- }, [saasApiUrl, iamApiUrl, debug]);
1064
+ }, [saasApiUrl, iamApiUrl]);
1033
1065
  const [state, setState] = useState({
1034
1066
  credentialsLoaded: false,
1035
1067
  processToken: null,
@@ -1265,7 +1297,7 @@ const backBtnStyle$2 = {
1265
1297
  color: C$3.gray700,
1266
1298
  zIndex: 10
1267
1299
  };
1268
- function PasswordRecoveryModal({ open, onOpenChange, onSuccess, saasApiUrl, iamApiUrl, debug = false }) {
1300
+ function PasswordRecoveryModal({ open, onOpenChange, onSuccess, saasApiUrl, iamApiUrl }) {
1269
1301
  const {
1270
1302
  status,
1271
1303
  loading: pwLoading,
@@ -1280,7 +1312,7 @@ function PasswordRecoveryModal({ open, onOpenChange, onSuccess, saasApiUrl, iamA
1280
1312
  resendOtp,
1281
1313
  reset: resetHook,
1282
1314
  clearError
1283
- } = useMobilePassword({ saasApiUrl, iamApiUrl, debug });
1315
+ } = useMobilePassword({ saasApiUrl, iamApiUrl });
1284
1316
  const [step, setStep] = useState("email");
1285
1317
  const [email, setEmail] = useState("");
1286
1318
  const [otp, setOtp] = useState("");
@@ -1567,11 +1599,22 @@ function useTokenHealthCheck(options) {
1567
1599
  }, [enabled, saasApiUrl, performCheck, debug]);
1568
1600
  }
1569
1601
  function saveSession(exchangeResult, accountType) {
1602
+ var _a, _b;
1570
1603
  const sanctumToken = exchangeResult.auth_token || exchangeResult.token;
1571
1604
  localStorage.setItem(STORAGE.AUTH_TOKEN, sanctumToken);
1572
1605
  localStorage.setItem(STORAGE.TOKEN, sanctumToken);
1573
- const userToStore = exchangeResult.user_infos ? { ...exchangeResult.user, ...exchangeResult.user_infos } : exchangeResult.user;
1574
- const acctType = accountType === "phone-only" ? "client" : "user";
1606
+ const baseUser = exchangeResult.user_infos ? { ...exchangeResult.user, ...exchangeResult.user_infos } : exchangeResult.user;
1607
+ const aliasRef = ((_a = exchangeResult.user) == null ? void 0 : _a.alias_reference) || exchangeResult.alias_reference || "";
1608
+ const iamRef = ((_b = exchangeResult.user) == null ? void 0 : _b.reference) || "";
1609
+ const userToStore = {
1610
+ ...baseUser,
1611
+ iam_reference: iamRef,
1612
+ alias_reference: aliasRef
1613
+ };
1614
+ if (aliasRef) {
1615
+ localStorage.setItem(STORAGE.ALIAS_REFERENCE, aliasRef);
1616
+ }
1617
+ const acctType = typeof accountType === "string" ? accountType : "user";
1575
1618
  localStorage.setItem(STORAGE.USER, JSON.stringify(userToStore));
1576
1619
  localStorage.setItem(STORAGE.ACCOUNT_TYPE, acctType);
1577
1620
  return { token: sanctumToken, user: userToStore };
@@ -1581,6 +1624,7 @@ function clearSession() {
1581
1624
  localStorage.removeItem(STORAGE.TOKEN);
1582
1625
  localStorage.removeItem(STORAGE.USER);
1583
1626
  localStorage.removeItem(STORAGE.ACCOUNT_TYPE);
1627
+ localStorage.removeItem(STORAGE.ALIAS_REFERENCE);
1584
1628
  }
1585
1629
  function getErrorMessage$1(err, context) {
1586
1630
  if (err instanceof Error) {
@@ -1595,14 +1639,15 @@ function getErrorMessage$1(err, context) {
1595
1639
  return { message: `Erreur lors de ${context}`, type: "unknown" };
1596
1640
  }
1597
1641
  function useNativeAuth(options) {
1598
- const { saasApiUrl, iamApiUrl, autoLoadCredentials = true, debug = false } = options;
1642
+ const { saasApiUrl, iamApiUrl, autoLoadCredentials = true, defaultAccountType = "user" } = options;
1599
1643
  const configuredRef = useRef(false);
1644
+ const debug = isDebugMode();
1600
1645
  useEffect(() => {
1601
1646
  if (!configuredRef.current) {
1602
- setNativeAuthConfig({ saasApiUrl, iamApiUrl, debug });
1647
+ setNativeAuthConfig({ saasApiUrl, iamApiUrl });
1603
1648
  configuredRef.current = true;
1604
1649
  }
1605
- }, [saasApiUrl, iamApiUrl, debug]);
1650
+ }, [saasApiUrl, iamApiUrl]);
1606
1651
  const [state, setState] = useState({
1607
1652
  credentialsLoaded: false,
1608
1653
  processToken: null,
@@ -1674,6 +1719,23 @@ function useNativeAuth(options) {
1674
1719
  loadCredentials();
1675
1720
  }
1676
1721
  }, [autoLoadCredentials, state.credentialsLoaded, state.user]);
1722
+ useEffect(() => {
1723
+ if (state.status === "completed" || !state.credentialsLoaded) return;
1724
+ const ttl = nativeAuthService.getCredentialsTtl();
1725
+ const refreshInterval = Math.max((ttl - 30) * 1e3, 3e4);
1726
+ if (debug) {
1727
+ console.log(`🔄 [Native] Auto-refresh credentials every ${refreshInterval / 1e3}s (TTL: ${ttl}s)`);
1728
+ }
1729
+ const timer = setInterval(async () => {
1730
+ try {
1731
+ await nativeAuthService.loadCredentials();
1732
+ if (debug) console.log("✅ [Native] Credentials auto-refreshed");
1733
+ } catch (err) {
1734
+ if (debug) console.warn("⚠️ [Native] Auto-refresh failed:", err);
1735
+ }
1736
+ }, refreshInterval);
1737
+ return () => clearInterval(timer);
1738
+ }, [state.status, state.credentialsLoaded, debug]);
1677
1739
  const loadCredentials = useCallback(async () => {
1678
1740
  setState((prev) => ({ ...prev, loading: true, error: null }));
1679
1741
  try {
@@ -1901,7 +1963,7 @@ function useNativeAuth(options) {
1901
1963
  if (response.success && response.callback_token) {
1902
1964
  const exchangeResult = await nativeAuthService.exchange(response.callback_token);
1903
1965
  if (exchangeResult.success) {
1904
- const { user: savedUser } = saveSession(exchangeResult, accountType);
1966
+ const { user: savedUser } = saveSession(exchangeResult, defaultAccountType);
1905
1967
  setState((prev) => ({
1906
1968
  ...prev,
1907
1969
  status: "completed",
@@ -1962,7 +2024,7 @@ function useNativeAuth(options) {
1962
2024
  if (response.success && response.callback_token) {
1963
2025
  const exchangeResult = await nativeAuthService.exchange(response.callback_token);
1964
2026
  if (exchangeResult.success) {
1965
- const { user: savedUser } = saveSession(exchangeResult, accountType);
2027
+ const { user: savedUser } = saveSession(exchangeResult, defaultAccountType);
1966
2028
  setState((prev) => ({
1967
2029
  ...prev,
1968
2030
  status: "completed",
@@ -2023,7 +2085,7 @@ function useNativeAuth(options) {
2023
2085
  if (response.success && response.callback_token) {
2024
2086
  const exchangeResult = await nativeAuthService.exchange(response.callback_token);
2025
2087
  if (exchangeResult.success) {
2026
- const { user: savedUser } = saveSession(exchangeResult, accountType);
2088
+ const { user: savedUser } = saveSession(exchangeResult, defaultAccountType);
2027
2089
  setState((prev) => ({
2028
2090
  ...prev,
2029
2091
  status: "completed",
@@ -2057,7 +2119,7 @@ function useNativeAuth(options) {
2057
2119
  if (response.success && response.callback_token) {
2058
2120
  const exchangeResult = await nativeAuthService.exchange(response.callback_token);
2059
2121
  if (exchangeResult.success) {
2060
- const { user: savedUser } = saveSession(exchangeResult, accountType);
2122
+ const { user: savedUser } = saveSession(exchangeResult, defaultAccountType);
2061
2123
  setState((prev) => ({
2062
2124
  ...prev,
2063
2125
  status: "completed",
@@ -2102,14 +2164,14 @@ function useNativeAuth(options) {
2102
2164
  }
2103
2165
  }, [state.processToken]);
2104
2166
  const setSession = useCallback((data) => {
2105
- const { user: savedUser } = saveSession(data, accountType);
2167
+ const { user: savedUser } = saveSession(data, defaultAccountType);
2106
2168
  setState((prev) => ({
2107
2169
  ...prev,
2108
2170
  user: savedUser,
2109
2171
  status: "completed",
2110
2172
  processToken: null
2111
2173
  }));
2112
- }, [accountType]);
2174
+ }, [defaultAccountType]);
2113
2175
  const logout = useCallback(async () => {
2114
2176
  const token = localStorage.getItem(STORAGE.AUTH_TOKEN) || localStorage.getItem(STORAGE.TOKEN);
2115
2177
  try {
@@ -2269,7 +2331,7 @@ function LoginModal({
2269
2331
  iamApiUrl,
2270
2332
  loading,
2271
2333
  showSwitchToSignup = true,
2272
- debug = false
2334
+ defaultAccountType
2273
2335
  }) {
2274
2336
  const {
2275
2337
  status,
@@ -2288,7 +2350,7 @@ function LoginModal({
2288
2350
  setSession,
2289
2351
  reset: resetAuth,
2290
2352
  clearError
2291
- } = useNativeAuth({ saasApiUrl, iamApiUrl, debug });
2353
+ } = useNativeAuth({ saasApiUrl, iamApiUrl, defaultAccountType });
2292
2354
  const [step, setStep] = useState("choice");
2293
2355
  const [email, setEmail] = useState("");
2294
2356
  const [password, setPassword] = useState("");
@@ -2797,8 +2859,7 @@ function LoginModal({
2797
2859
  onOpenChange: setShowPasswordRecovery,
2798
2860
  onSuccess: () => setShowPasswordRecovery(false),
2799
2861
  saasApiUrl,
2800
- iamApiUrl,
2801
- debug
2862
+ iamApiUrl
2802
2863
  }
2803
2864
  )
2804
2865
  ] });
@@ -3056,8 +3117,7 @@ function useMobileRegistration(options) {
3056
3117
  if (options && !configuredRef.current) {
3057
3118
  setNativeAuthConfig({
3058
3119
  saasApiUrl: options.saasApiUrl,
3059
- iamApiUrl: options.iamApiUrl,
3060
- debug: options.debug
3120
+ iamApiUrl: options.iamApiUrl
3061
3121
  });
3062
3122
  configuredRef.current = true;
3063
3123
  }
@@ -3356,7 +3416,7 @@ function SuccessOrbit() {
3356
3416
  })
3357
3417
  ] });
3358
3418
  }
3359
- function SignupModal({ open, onOpenChange, onSwitchToLogin, onSignupSuccess, saasApiUrl, iamApiUrl, debug = false }) {
3419
+ function SignupModal({ open, onOpenChange, onSwitchToLogin, onSignupSuccess, saasApiUrl, iamApiUrl, defaultAccountType }) {
3360
3420
  const {
3361
3421
  status,
3362
3422
  formData,
@@ -3372,7 +3432,7 @@ function SignupModal({ open, onOpenChange, onSwitchToLogin, onSignupSuccess, saa
3372
3432
  resendOtp,
3373
3433
  reset: resetReg,
3374
3434
  clearError
3375
- } = useMobileRegistration({ saasApiUrl, iamApiUrl, debug });
3435
+ } = useMobileRegistration({ saasApiUrl, iamApiUrl });
3376
3436
  const [step, setStep] = useState("intro");
3377
3437
  const [otpCode, setOtpCode] = useState("");
3378
3438
  const [password, setPassword] = useState("");
@@ -4073,7 +4133,7 @@ function NativeSSOPage({
4073
4133
  onLoginSuccess,
4074
4134
  onLogout,
4075
4135
  onOnboardingComplete,
4076
- debug,
4136
+ accountType = "user",
4077
4137
  title = "Un compte, plusieurs accès",
4078
4138
  description = "Connectez-vous avec votre compte Ollaid pour accéder à toutes les applications partenaires.",
4079
4139
  logoUrl,
@@ -4091,7 +4151,7 @@ function NativeSSOPage({
4091
4151
  }
4092
4152
  return null;
4093
4153
  });
4094
- const resolvedDebug = debug !== void 0 ? debug : isDebugMode();
4154
+ const resolvedDebug = isDebugMode();
4095
4155
  useEffect(() => {
4096
4156
  const root = document.documentElement;
4097
4157
  const originalValues = {};
@@ -4170,6 +4230,7 @@ function NativeSSOPage({
4170
4230
  localStorage.removeItem(STORAGE.TOKEN);
4171
4231
  localStorage.removeItem(STORAGE.USER);
4172
4232
  localStorage.removeItem(STORAGE.ACCOUNT_TYPE);
4233
+ localStorage.removeItem(STORAGE.ALIAS_REFERENCE);
4173
4234
  setSession(null);
4174
4235
  onLogout == null ? void 0 : onLogout();
4175
4236
  }, [onLogout]);
@@ -4268,7 +4329,7 @@ function NativeSSOPage({
4268
4329
  onLoginSuccess: handleLoginSuccess,
4269
4330
  saasApiUrl,
4270
4331
  iamApiUrl,
4271
- debug: resolvedDebug
4332
+ defaultAccountType: accountType
4272
4333
  }
4273
4334
  ),
4274
4335
  /* @__PURE__ */ jsx(
@@ -4282,7 +4343,7 @@ function NativeSSOPage({
4282
4343
  onSignupSuccess: handleLoginSuccess,
4283
4344
  saasApiUrl,
4284
4345
  iamApiUrl,
4285
- debug: resolvedDebug
4346
+ defaultAccountType: accountType
4286
4347
  }
4287
4348
  ),
4288
4349
  pendingSession && /* @__PURE__ */ jsx(