@ollaid/native-sso 1.0.2 → 1.0.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/README.md +204 -1
- package/dist/components/AppsLogoSlider.d.ts +2 -1
- package/dist/components/NativeSSOPage.d.ts +6 -1
- package/dist/hooks/useNativeAuth.d.ts +7 -0
- package/dist/index.cjs +37 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +37 -27
- package/dist/index.js.map +1 -1
- package/dist/services/api.d.ts +8 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -452,7 +452,8 @@ let config = {
|
|
|
452
452
|
saasApiUrl: "",
|
|
453
453
|
iamApiUrl: "",
|
|
454
454
|
timeout: 3e4,
|
|
455
|
-
debug: false
|
|
455
|
+
debug: false,
|
|
456
|
+
configPrefix: "iam"
|
|
456
457
|
};
|
|
457
458
|
const setNativeAuthConfig = (newConfig) => {
|
|
458
459
|
config = { ...config, ...newConfig };
|
|
@@ -572,7 +573,7 @@ async function fetchWithTimeout(url, options, timeout) {
|
|
|
572
573
|
throw new ApiError("Erreur inattendue", "unknown");
|
|
573
574
|
}
|
|
574
575
|
}
|
|
575
|
-
function getHeaders(token) {
|
|
576
|
+
function getHeaders(token, includeConfigPrefix = false) {
|
|
576
577
|
const headers = {
|
|
577
578
|
"Content-Type": "application/json",
|
|
578
579
|
"Accept": "application/json"
|
|
@@ -581,6 +582,9 @@ function getHeaders(token) {
|
|
|
581
582
|
if (deviceId) {
|
|
582
583
|
headers["X-Device-Id"] = deviceId;
|
|
583
584
|
}
|
|
585
|
+
if (includeConfigPrefix && config.configPrefix) {
|
|
586
|
+
headers["X-IAM-Config-Prefix"] = config.configPrefix;
|
|
587
|
+
}
|
|
584
588
|
if (token) {
|
|
585
589
|
headers["Authorization"] = `Bearer ${token}`;
|
|
586
590
|
}
|
|
@@ -628,7 +632,7 @@ const nativeAuthService = {
|
|
|
628
632
|
}
|
|
629
633
|
const response = await fetchWithTimeout(
|
|
630
634
|
`${config2.saasApiUrl}/native/config`,
|
|
631
|
-
{ method: "GET", headers: getHeaders() },
|
|
635
|
+
{ method: "GET", headers: getHeaders(void 0, true) },
|
|
632
636
|
config2.timeout || 3e4
|
|
633
637
|
);
|
|
634
638
|
if (!response.success || !response.encrypted_credentials || !response.app_key) {
|
|
@@ -803,7 +807,7 @@ const nativeAuthService = {
|
|
|
803
807
|
`${config2.saasApiUrl}/native/exchange`,
|
|
804
808
|
{
|
|
805
809
|
method: "POST",
|
|
806
|
-
headers: getHeaders(),
|
|
810
|
+
headers: getHeaders(void 0, true),
|
|
807
811
|
body: JSON.stringify({ callback_token: callbackToken })
|
|
808
812
|
},
|
|
809
813
|
config2.timeout || 3e4
|
|
@@ -832,7 +836,7 @@ const nativeAuthService = {
|
|
|
832
836
|
`${cfg.saasApiUrl}/native/check-token`,
|
|
833
837
|
{
|
|
834
838
|
method: "POST",
|
|
835
|
-
headers: getHeaders(token)
|
|
839
|
+
headers: getHeaders(token, true)
|
|
836
840
|
},
|
|
837
841
|
1e4
|
|
838
842
|
);
|
|
@@ -854,7 +858,7 @@ const nativeAuthService = {
|
|
|
854
858
|
`${config2.saasApiUrl}/native/logout`,
|
|
855
859
|
{
|
|
856
860
|
method: "POST",
|
|
857
|
-
headers: getHeaders(token)
|
|
861
|
+
headers: getHeaders(token, true)
|
|
858
862
|
},
|
|
859
863
|
config2.timeout || 3e4
|
|
860
864
|
);
|
|
@@ -1639,15 +1643,15 @@ function getErrorMessage$1(err, context) {
|
|
|
1639
1643
|
return { message: `Erreur lors de ${context}`, type: "unknown" };
|
|
1640
1644
|
}
|
|
1641
1645
|
function useNativeAuth(options) {
|
|
1642
|
-
const { saasApiUrl, iamApiUrl, autoLoadCredentials = true, defaultAccountType = "user" } = options;
|
|
1646
|
+
const { saasApiUrl, iamApiUrl, autoLoadCredentials = true, defaultAccountType = "user", configPrefix = "iam" } = options;
|
|
1643
1647
|
const configuredRef = useRef(false);
|
|
1644
|
-
const
|
|
1648
|
+
const [isDebug, setIsDebug] = useState(isDebugMode());
|
|
1645
1649
|
useEffect(() => {
|
|
1646
1650
|
if (!configuredRef.current) {
|
|
1647
|
-
setNativeAuthConfig({ saasApiUrl, iamApiUrl });
|
|
1651
|
+
setNativeAuthConfig({ saasApiUrl, iamApiUrl, configPrefix });
|
|
1648
1652
|
configuredRef.current = true;
|
|
1649
1653
|
}
|
|
1650
|
-
}, [saasApiUrl, iamApiUrl]);
|
|
1654
|
+
}, [saasApiUrl, iamApiUrl, configPrefix]);
|
|
1651
1655
|
const [state, setState] = useState({
|
|
1652
1656
|
credentialsLoaded: false,
|
|
1653
1657
|
processToken: null,
|
|
@@ -1665,7 +1669,7 @@ function useNativeAuth(options) {
|
|
|
1665
1669
|
});
|
|
1666
1670
|
const [accountType, setAccountType] = useState("email");
|
|
1667
1671
|
const handleTokenInvalid = useCallback(() => {
|
|
1668
|
-
if (
|
|
1672
|
+
if (isDebug) console.log("🔐 [HealthCheck] Token invalide — déconnexion locale");
|
|
1669
1673
|
clearSession();
|
|
1670
1674
|
setState({
|
|
1671
1675
|
credentialsLoaded: false,
|
|
@@ -1682,7 +1686,7 @@ function useNativeAuth(options) {
|
|
|
1682
1686
|
otpMethod: null,
|
|
1683
1687
|
otpSentTo: null
|
|
1684
1688
|
});
|
|
1685
|
-
}, [
|
|
1689
|
+
}, [isDebug]);
|
|
1686
1690
|
const handleUserUpdated = useCallback((userInfos) => {
|
|
1687
1691
|
const storedRaw = localStorage.getItem(STORAGE.USER);
|
|
1688
1692
|
if (storedRaw) {
|
|
@@ -1700,7 +1704,7 @@ function useNativeAuth(options) {
|
|
|
1700
1704
|
saasApiUrl,
|
|
1701
1705
|
onTokenInvalid: handleTokenInvalid,
|
|
1702
1706
|
onUserUpdated: handleUserUpdated,
|
|
1703
|
-
debug
|
|
1707
|
+
debug: isDebug
|
|
1704
1708
|
});
|
|
1705
1709
|
useEffect(() => {
|
|
1706
1710
|
const storedToken = localStorage.getItem(STORAGE.AUTH_TOKEN) || localStorage.getItem(STORAGE.TOKEN);
|
|
@@ -1723,23 +1727,25 @@ function useNativeAuth(options) {
|
|
|
1723
1727
|
if (state.status === "completed" || !state.credentialsLoaded) return;
|
|
1724
1728
|
const ttl = nativeAuthService.getCredentialsTtl();
|
|
1725
1729
|
const refreshInterval = Math.max((ttl - 30) * 1e3, 3e4);
|
|
1726
|
-
if (
|
|
1730
|
+
if (isDebug) {
|
|
1727
1731
|
console.log(`🔄 [Native] Auto-refresh credentials every ${refreshInterval / 1e3}s (TTL: ${ttl}s)`);
|
|
1728
1732
|
}
|
|
1729
1733
|
const timer = setInterval(async () => {
|
|
1730
1734
|
try {
|
|
1731
1735
|
await nativeAuthService.loadCredentials();
|
|
1732
|
-
|
|
1736
|
+
setIsDebug(isDebugMode());
|
|
1737
|
+
if (isDebugMode()) console.log("✅ [Native] Credentials auto-refreshed");
|
|
1733
1738
|
} catch (err) {
|
|
1734
|
-
if (
|
|
1739
|
+
if (isDebugMode()) console.warn("⚠️ [Native] Auto-refresh failed:", err);
|
|
1735
1740
|
}
|
|
1736
1741
|
}, refreshInterval);
|
|
1737
1742
|
return () => clearInterval(timer);
|
|
1738
|
-
}, [state.status, state.credentialsLoaded,
|
|
1743
|
+
}, [state.status, state.credentialsLoaded, isDebug]);
|
|
1739
1744
|
const loadCredentials = useCallback(async () => {
|
|
1740
1745
|
setState((prev) => ({ ...prev, loading: true, error: null }));
|
|
1741
1746
|
try {
|
|
1742
1747
|
await nativeAuthService.loadCredentials();
|
|
1748
|
+
setIsDebug(isDebugMode());
|
|
1743
1749
|
setState((prev) => ({ ...prev, credentialsLoaded: true, loading: false }));
|
|
1744
1750
|
return { success: true };
|
|
1745
1751
|
} catch (err) {
|
|
@@ -2227,6 +2233,8 @@ function useNativeAuth(options) {
|
|
|
2227
2233
|
error: state.error,
|
|
2228
2234
|
errorType: state.errorType,
|
|
2229
2235
|
isAuthenticated: state.status === "completed" && state.user !== null,
|
|
2236
|
+
/** Debug réactif — mis à jour après loadCredentials */
|
|
2237
|
+
isDebug,
|
|
2230
2238
|
accountType,
|
|
2231
2239
|
isPhoneOnly: accountType === "phone-only",
|
|
2232
2240
|
otpMethod: state.otpMethod,
|
|
@@ -2944,17 +2952,18 @@ function PhoneInput({
|
|
|
2944
2952
|
] })
|
|
2945
2953
|
] });
|
|
2946
2954
|
}
|
|
2947
|
-
function AppsLogoSlider({ speed = "normal", className = "" }) {
|
|
2955
|
+
function AppsLogoSlider({ speed = "normal", className = "", iamApiUrl: iamApiUrlProp }) {
|
|
2948
2956
|
const scrollRef = useRef(null);
|
|
2949
2957
|
const [isPaused, setIsPaused] = useState(false);
|
|
2950
2958
|
const [applications, setApplications] = useState([]);
|
|
2951
2959
|
const [isLoading, setIsLoading] = useState(true);
|
|
2952
2960
|
const speedMap = { slow: 50, normal: 30, fast: 15 };
|
|
2953
2961
|
useEffect(() => {
|
|
2962
|
+
const resolvedIamApiUrl = iamApiUrlProp || getNativeAuthConfig().iamApiUrl;
|
|
2963
|
+
if (!resolvedIamApiUrl) return;
|
|
2954
2964
|
const fetchApps = async () => {
|
|
2955
2965
|
try {
|
|
2956
|
-
const
|
|
2957
|
-
const iamBaseUrl = config2.iamApiUrl.replace("/api", "");
|
|
2966
|
+
const iamBaseUrl = resolvedIamApiUrl.replace("/api", "");
|
|
2958
2967
|
const response = await fetch(`${iamBaseUrl}/api/public/applications`, { headers: { "Accept": "application/json" } });
|
|
2959
2968
|
if (response.ok) {
|
|
2960
2969
|
const data = await response.json();
|
|
@@ -2966,7 +2975,7 @@ function AppsLogoSlider({ speed = "normal", className = "" }) {
|
|
|
2966
2975
|
}
|
|
2967
2976
|
};
|
|
2968
2977
|
fetchApps();
|
|
2969
|
-
}, []);
|
|
2978
|
+
}, [iamApiUrlProp]);
|
|
2970
2979
|
useEffect(() => {
|
|
2971
2980
|
const container = scrollRef.current;
|
|
2972
2981
|
if (!container || applications.length === 0) return;
|
|
@@ -2983,8 +2992,8 @@ function AppsLogoSlider({ speed = "normal", className = "" }) {
|
|
|
2983
2992
|
const getLogoUrl = (logo) => {
|
|
2984
2993
|
if (!logo) return null;
|
|
2985
2994
|
if (logo.startsWith("http")) return logo;
|
|
2986
|
-
const
|
|
2987
|
-
return `${
|
|
2995
|
+
const resolvedUrl = iamApiUrlProp || getNativeAuthConfig().iamApiUrl;
|
|
2996
|
+
return `${resolvedUrl.replace("/api", "")}/storage/applications/${logo}`;
|
|
2988
2997
|
};
|
|
2989
2998
|
if (isLoading) {
|
|
2990
2999
|
return /* @__PURE__ */ jsx("div", { className, style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: "1rem", padding: "0.5rem 0" }, children: [1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ jsxs("div", { style: { flexShrink: 0, display: "flex", flexDirection: "column", alignItems: "center", gap: "0.5rem" }, children: [
|
|
@@ -3579,7 +3588,7 @@ function SignupModal({ open, onOpenChange, onSwitchToLogin, onSignupSuccess, saa
|
|
|
3579
3588
|
/* @__PURE__ */ jsx(DialogTitle, { children: "Ouvrez un compte Ollaid" }),
|
|
3580
3589
|
/* @__PURE__ */ jsx(DialogDescription, { children: "Un compte unique qui vous donne accès à toutes les applications" })
|
|
3581
3590
|
] }),
|
|
3582
|
-
/* @__PURE__ */ jsx(AppsLogoSlider, {}),
|
|
3591
|
+
/* @__PURE__ */ jsx(AppsLogoSlider, { iamApiUrl }),
|
|
3583
3592
|
/* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem", fontSize: "0.875rem", color: C$1.gray500, margin: "1rem 0" }, children: ["Un seul compte pour toutes les applications", "Plus besoin de multiples mots de passe", "Connexion simplifiée et sécurisée"].map((text) => /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.75rem" }, children: [
|
|
3584
3593
|
/* @__PURE__ */ jsx(IconCheckCircle2, { style: { width: "1.25rem", height: "1.25rem", color: C$1.green, flexShrink: 0 } }),
|
|
3585
3594
|
text
|
|
@@ -4134,6 +4143,7 @@ function NativeSSOPage({
|
|
|
4134
4143
|
onLogout,
|
|
4135
4144
|
onOnboardingComplete,
|
|
4136
4145
|
accountType = "user",
|
|
4146
|
+
configPrefix = "iam",
|
|
4137
4147
|
title = "Un compte, plusieurs accès",
|
|
4138
4148
|
description = "Connectez-vous avec votre compte Ollaid pour accéder à toutes les applications partenaires.",
|
|
4139
4149
|
logoUrl,
|
|
@@ -4151,7 +4161,7 @@ function NativeSSOPage({
|
|
|
4151
4161
|
}
|
|
4152
4162
|
return null;
|
|
4153
4163
|
});
|
|
4154
|
-
const resolvedDebug =
|
|
4164
|
+
const { isDebug: resolvedDebug } = useNativeAuth({ saasApiUrl, iamApiUrl, configPrefix, autoLoadCredentials: true });
|
|
4155
4165
|
useEffect(() => {
|
|
4156
4166
|
const root = document.documentElement;
|
|
4157
4167
|
const originalValues = {};
|
|
@@ -4268,7 +4278,7 @@ function NativeSSOPage({
|
|
|
4268
4278
|
] }) });
|
|
4269
4279
|
if (session) {
|
|
4270
4280
|
return /* @__PURE__ */ jsxs("div", { style: containerStyle, children: [
|
|
4271
|
-
/* @__PURE__ */ jsx("div", { style: { width: "100%", maxWidth: "28rem", marginBottom: "1.5rem" }, children: /* @__PURE__ */ jsx(AppsLogoSlider, {}) }),
|
|
4281
|
+
/* @__PURE__ */ jsx("div", { style: { width: "100%", maxWidth: "28rem", marginBottom: "1.5rem" }, children: /* @__PURE__ */ jsx(AppsLogoSlider, { iamApiUrl }) }),
|
|
4272
4282
|
/* @__PURE__ */ jsx("div", { style: cardStyle, children: /* @__PURE__ */ jsxs("div", { style: { padding: "2rem 1.5rem 1.5rem" }, children: [
|
|
4273
4283
|
/* @__PURE__ */ jsx(BrandingHeader, {}),
|
|
4274
4284
|
/* @__PURE__ */ jsxs("h2", { style: { fontSize: "1.25rem", fontWeight: 600, textAlign: "center", color: COLORS.cardForeground }, children: [
|
|
@@ -4288,7 +4298,7 @@ function NativeSSOPage({
|
|
|
4288
4298
|
] });
|
|
4289
4299
|
}
|
|
4290
4300
|
return /* @__PURE__ */ jsxs("div", { style: containerStyle, children: [
|
|
4291
|
-
/* @__PURE__ */ jsx("div", { style: { width: "100%", maxWidth: "28rem", marginBottom: "1.5rem" }, children: logoUrl ? /* @__PURE__ */ jsx("img", { src: logoUrl, alt: "Logo", style: { height: "3rem", margin: "0 auto" } }) : /* @__PURE__ */ jsx(AppsLogoSlider, {}) }),
|
|
4301
|
+
/* @__PURE__ */ jsx("div", { style: { width: "100%", maxWidth: "28rem", marginBottom: "1.5rem" }, children: logoUrl ? /* @__PURE__ */ jsx("img", { src: logoUrl, alt: "Logo", style: { height: "3rem", margin: "0 auto" } }) : /* @__PURE__ */ jsx(AppsLogoSlider, { iamApiUrl }) }),
|
|
4292
4302
|
/* @__PURE__ */ jsx("div", { style: cardStyle, children: /* @__PURE__ */ jsxs("div", { style: { padding: "2rem 1.5rem 1.5rem" }, children: [
|
|
4293
4303
|
/* @__PURE__ */ jsx(BrandingHeader, {}),
|
|
4294
4304
|
/* @__PURE__ */ jsx("h2", { style: { fontSize: "1.25rem", fontWeight: 600, textAlign: "center", color: COLORS.cardForeground, marginBottom: "0.5rem" }, children: title }),
|