@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/README.md +29 -8
- package/dist/components/LoginModal.d.ts +3 -2
- package/dist/components/NativeSSOPage.d.ts +3 -3
- package/dist/components/PasswordRecoveryModal.d.ts +1 -2
- package/dist/components/SignupModal.d.ts +3 -2
- package/dist/hooks/useMobilePassword.d.ts +0 -1
- package/dist/hooks/useMobileRegistration.d.ts +0 -1
- package/dist/hooks/useNativeAuth.d.ts +66 -6
- package/dist/index.cjs +91 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +91 -30
- package/dist/index.js.map +1 -1
- package/dist/services/api.d.ts +1 -0
- package/dist/services/nativeAuth.d.ts +4 -0
- package/dist/types/native.d.ts +5 -0
- package/package.json +1 -1
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
|
|
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
|
|
1061
|
+
setNativeAuthConfig({ saasApiUrl, iamApiUrl });
|
|
1030
1062
|
configuredRef.current = true;
|
|
1031
1063
|
}
|
|
1032
|
-
}, [saasApiUrl, iamApiUrl
|
|
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
|
|
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
|
|
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
|
|
1574
|
-
const
|
|
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,
|
|
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
|
|
1647
|
+
setNativeAuthConfig({ saasApiUrl, iamApiUrl });
|
|
1603
1648
|
configuredRef.current = true;
|
|
1604
1649
|
}
|
|
1605
|
-
}, [saasApiUrl, iamApiUrl
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
}, [
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
4346
|
+
defaultAccountType: accountType
|
|
4286
4347
|
}
|
|
4287
4348
|
),
|
|
4288
4349
|
pendingSession && /* @__PURE__ */ jsx(
|