@ollaid/native-sso 1.0.3 → 1.0.6
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 +76 -0
- package/dist/components/AppsLogoSlider.d.ts +2 -1
- package/dist/components/NativeSSOPage.d.ts +4 -16
- package/dist/index.cjs +164 -79
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +164 -79
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -105,9 +105,79 @@ La page `/auth/sso` gère automatiquement :
|
|
|
105
105
|
| `logoUrl` | `string` | ❌ | URL du logo (remplace le slider) |
|
|
106
106
|
| `hideFooter` | `boolean` | ❌ | Masquer "Propulsé par iam.ollaid.com" |
|
|
107
107
|
| `onOnboardingComplete` | `(data: { image_url?: string; ccphone?: string; phone?: string }) => void` | ❌ | Callback après complétion de l'onboarding |
|
|
108
|
+
| `redirectAfterLogin` | `string` | ❌ | Route vers laquelle rediriger après connexion réussie (ex: `/client/dashboard`). Utilise `window.location.href`. Compatible avec ou sans react-router. |
|
|
109
|
+
| `redirectAfterLogout` | `string` | ❌ | Route vers laquelle rediriger après déconnexion (ex: `/auth/client`). Utilise `window.location.href`. |
|
|
108
110
|
|
|
109
111
|
> **Note :** Le mode `debug` est contrôlé **uniquement** par le backend via la variable d'environnement `IAM_DEBUG` dans le `.env` du SaaS. Il n'y a plus de prop `debug` à passer au composant. Le `DebugPanel` est **réactif** : il apparaît automatiquement après le chargement des credentials si `debug: true` est retourné par le backend.
|
|
110
112
|
|
|
113
|
+
### Redirections automatiques (optionnel)
|
|
114
|
+
|
|
115
|
+
> **Ces props sont entièrement optionnels.** Si vous ne les définissez pas,
|
|
116
|
+
> c'est votre backend SaaS qui gère la redirection après l'exchange — il connaît
|
|
117
|
+
> déjà le `accountType` et peut rediriger l'utilisateur vers la bonne page après
|
|
118
|
+
> avoir sauvegardé le token dans le localStorage.
|
|
119
|
+
|
|
120
|
+
Utilisez ces props uniquement si vous souhaitez que le **composant lui-même**
|
|
121
|
+
déclenche la redirection côté frontend :
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
<NativeSSOPage
|
|
125
|
+
saasApiUrl="https://votre-saas.com/api"
|
|
126
|
+
iamApiUrl="https://identityam.ollaid.com/api"
|
|
127
|
+
configPrefix="iam_client"
|
|
128
|
+
accountType="client"
|
|
129
|
+
redirectAfterLogin="/client/dashboard"
|
|
130
|
+
redirectAfterLogout="/auth/client"
|
|
131
|
+
/>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Sans ces props** (usage minimal, le SaaS gère la redirection) :
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
<NativeSSOPage
|
|
138
|
+
saasApiUrl="https://votre-saas.com/api"
|
|
139
|
+
iamApiUrl="https://identityam.ollaid.com/api"
|
|
140
|
+
configPrefix="iam_client"
|
|
141
|
+
accountType="client"
|
|
142
|
+
onLoginSuccess={(token, user) => { /* votre logique */ }}
|
|
143
|
+
/>
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Comportement :**
|
|
147
|
+
- Si `redirectAfterLogin` est défini → redirection via `window.location.href` après connexion
|
|
148
|
+
- Si `onLoginSuccess` est aussi défini → le callback est appelé **avant** la redirection
|
|
149
|
+
- Si **aucun** prop de redirection n'est défini → aucune redirection automatique, comportement inchangé
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Déconnexion externe (sans le composant)
|
|
154
|
+
|
|
155
|
+
Quand l'utilisateur se déconnecte **depuis votre SaaS** (ex : bouton logout dans le backoffice), le composant `NativeSSOPage` n'est pas impliqué. Vous devez donc nettoyer manuellement la session SSO pour éviter que le package considère l'utilisateur comme encore connecté.
|
|
156
|
+
|
|
157
|
+
### Utilisation
|
|
158
|
+
|
|
159
|
+
```tsx
|
|
160
|
+
import { clearAuthToken } from '@ollaid/native-sso';
|
|
161
|
+
|
|
162
|
+
const handleLogout = async () => {
|
|
163
|
+
await revokeBackendToken(); // votre logique SaaS (révocation Sanctum, etc.)
|
|
164
|
+
clearAuthToken(); // nettoie les 5 clés localStorage du package
|
|
165
|
+
navigate('/auth/login');
|
|
166
|
+
};
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Clés localStorage nettoyées par `clearAuthToken()`
|
|
170
|
+
|
|
171
|
+
| Clé | Description |
|
|
172
|
+
|-----|-------------|
|
|
173
|
+
| `auth_token` | Token Sanctum actif |
|
|
174
|
+
| `token` | Token legacy |
|
|
175
|
+
| `user` | Objet utilisateur (avec `iam_reference`, `alias_reference`) |
|
|
176
|
+
| `account_type` | Type de compte (`user` ou `client`) |
|
|
177
|
+
| `alias_reference` | Référence de l'alias de connexion |
|
|
178
|
+
|
|
179
|
+
> **Important :** Si vous ne nettoyez pas ces clés, l'utilisateur verra l'écran "Déconnexion" au lieu du formulaire de connexion en revenant sur la page SSO.
|
|
180
|
+
|
|
111
181
|
---
|
|
112
182
|
|
|
113
183
|
## Multi-Tenant (plusieurs applications sur le même backend)
|
|
@@ -136,6 +206,8 @@ Backend SaaS:
|
|
|
136
206
|
iamApiUrl="https://identityam.ollaid.com/api"
|
|
137
207
|
configPrefix="iam"
|
|
138
208
|
accountType="user"
|
|
209
|
+
redirectAfterLogin="/dashboard"
|
|
210
|
+
redirectAfterLogout="/auth/sso"
|
|
139
211
|
/>
|
|
140
212
|
|
|
141
213
|
{/* Page login espace vendeur */}
|
|
@@ -144,6 +216,8 @@ Backend SaaS:
|
|
|
144
216
|
iamApiUrl="https://identityam.ollaid.com/api"
|
|
145
217
|
configPrefix="iam_vendor"
|
|
146
218
|
accountType="client"
|
|
219
|
+
redirectAfterLogin="/vendor/dashboard"
|
|
220
|
+
redirectAfterLogout="/auth/vendor"
|
|
147
221
|
/>
|
|
148
222
|
|
|
149
223
|
{/* Page login admin — même backend, app IAM différente */}
|
|
@@ -152,6 +226,8 @@ Backend SaaS:
|
|
|
152
226
|
iamApiUrl="https://identityam.ollaid.com/api"
|
|
153
227
|
configPrefix="iam_admin"
|
|
154
228
|
accountType="user"
|
|
229
|
+
redirectAfterLogin="/admin/dashboard"
|
|
230
|
+
redirectAfterLogout="/auth/admin"
|
|
155
231
|
/>
|
|
156
232
|
```
|
|
157
233
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Apps Logo Slider for @ollaid/native-sso
|
|
3
|
+
* Matches Web SSO badge style: horizontal marquee, small icons, no app names
|
|
3
4
|
*/
|
|
4
5
|
interface AppsLogoSliderProps {
|
|
5
6
|
speed?: 'slow' | 'normal' | 'fast';
|
|
6
7
|
className?: string;
|
|
7
8
|
iamApiUrl?: string;
|
|
8
9
|
}
|
|
9
|
-
export declare function AppsLogoSlider({
|
|
10
|
+
export declare function AppsLogoSlider({ className, iamApiUrl: iamApiUrlProp }: AppsLogoSliderProps): import("react/jsx-runtime").JSX.Element | null;
|
|
10
11
|
export default AppsLogoSlider;
|
|
@@ -2,39 +2,27 @@
|
|
|
2
2
|
* NativeSSOPage — Page autonome complète pour @ollaid/native-sso
|
|
3
3
|
* Design aligné sur /sso/auth (fond primary, card blanche, ShieldCheck branding)
|
|
4
4
|
*
|
|
5
|
-
* @version
|
|
5
|
+
* @version 2.0.0
|
|
6
6
|
*/
|
|
7
7
|
import type { UserInfos } from '../types/native';
|
|
8
8
|
export interface NativeSSOPageProps {
|
|
9
|
-
/** URL du Backend SaaS */
|
|
10
9
|
saasApiUrl: string;
|
|
11
|
-
/** URL du Backend IAM */
|
|
12
10
|
iamApiUrl: string;
|
|
13
|
-
/** Callback après login/signup réussi — reçoit le token et l'utilisateur */
|
|
14
11
|
onLoginSuccess?: (token: string, user: UserInfos) => void;
|
|
15
|
-
/** Callback après logout */
|
|
16
12
|
onLogout?: () => void;
|
|
17
|
-
/** Callback quand l'utilisateur complète l'onboarding (photo/phone) */
|
|
18
13
|
onOnboardingComplete?: (data: {
|
|
19
14
|
image_url?: string;
|
|
20
15
|
ccphone?: string;
|
|
21
16
|
phone?: string;
|
|
22
17
|
}) => void;
|
|
23
|
-
/** Type de compte à persister dans localStorage (défaut: 'user') */
|
|
24
18
|
accountType?: 'user' | 'client';
|
|
25
|
-
/**
|
|
26
|
-
* Préfixe de configuration IAM côté backend (défaut: 'iam').
|
|
27
|
-
* Permet le multi-tenant : 'iam', 'iam_vendor', 'iam_client', 'iam_admin', etc.
|
|
28
|
-
*/
|
|
29
19
|
configPrefix?: string;
|
|
30
|
-
/** Titre personnalisé */
|
|
31
20
|
title?: string;
|
|
32
|
-
/** Description personnalisée */
|
|
33
21
|
description?: string;
|
|
34
|
-
/** Logo URL personnalisé */
|
|
35
22
|
logoUrl?: string;
|
|
36
|
-
/** Masquer le footer "Propulsé par" */
|
|
37
23
|
hideFooter?: boolean;
|
|
24
|
+
redirectAfterLogin?: string;
|
|
25
|
+
redirectAfterLogout?: string;
|
|
38
26
|
}
|
|
39
|
-
export declare function NativeSSOPage({ saasApiUrl, iamApiUrl, onLoginSuccess, onLogout, onOnboardingComplete, accountType, configPrefix, title, description, logoUrl, hideFooter, }: NativeSSOPageProps): import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
export declare function NativeSSOPage({ saasApiUrl, iamApiUrl, onLoginSuccess, onLogout, onOnboardingComplete, accountType, configPrefix, title, description, logoUrl, hideFooter, redirectAfterLogin, redirectAfterLogout, }: NativeSSOPageProps): import("react/jsx-runtime").JSX.Element;
|
|
40
28
|
export default NativeSSOPage;
|
package/dist/index.cjs
CHANGED
|
@@ -2954,12 +2954,9 @@ function PhoneInput({
|
|
|
2954
2954
|
] })
|
|
2955
2955
|
] });
|
|
2956
2956
|
}
|
|
2957
|
-
function AppsLogoSlider({
|
|
2958
|
-
const scrollRef = react.useRef(null);
|
|
2959
|
-
const [isPaused, setIsPaused] = react.useState(false);
|
|
2957
|
+
function AppsLogoSlider({ className = "", iamApiUrl: iamApiUrlProp }) {
|
|
2960
2958
|
const [applications, setApplications] = react.useState([]);
|
|
2961
2959
|
const [isLoading, setIsLoading] = react.useState(true);
|
|
2962
|
-
const speedMap = { slow: 50, normal: 30, fast: 15 };
|
|
2963
2960
|
react.useEffect(() => {
|
|
2964
2961
|
const resolvedIamApiUrl = iamApiUrlProp || getNativeAuthConfig().iamApiUrl;
|
|
2965
2962
|
if (!resolvedIamApiUrl) return;
|
|
@@ -2978,19 +2975,6 @@ function AppsLogoSlider({ speed = "normal", className = "", iamApiUrl: iamApiUrl
|
|
|
2978
2975
|
};
|
|
2979
2976
|
fetchApps();
|
|
2980
2977
|
}, [iamApiUrlProp]);
|
|
2981
|
-
react.useEffect(() => {
|
|
2982
|
-
const container = scrollRef.current;
|
|
2983
|
-
if (!container || applications.length === 0) return;
|
|
2984
|
-
let pos = 0;
|
|
2985
|
-
const id = setInterval(() => {
|
|
2986
|
-
if (!isPaused && container) {
|
|
2987
|
-
pos += 1;
|
|
2988
|
-
if (pos >= container.scrollWidth / 2) pos = 0;
|
|
2989
|
-
container.scrollLeft = pos;
|
|
2990
|
-
}
|
|
2991
|
-
}, speedMap[speed]);
|
|
2992
|
-
return () => clearInterval(id);
|
|
2993
|
-
}, [isPaused, speed, applications.length]);
|
|
2994
2978
|
const getLogoUrl = (logo) => {
|
|
2995
2979
|
if (!logo) return null;
|
|
2996
2980
|
if (logo.startsWith("http")) return logo;
|
|
@@ -2998,27 +2982,85 @@ function AppsLogoSlider({ speed = "normal", className = "", iamApiUrl: iamApiUrl
|
|
|
2998
2982
|
return `${resolvedUrl.replace("/api", "")}/storage/applications/${logo}`;
|
|
2999
2983
|
};
|
|
3000
2984
|
if (isLoading) {
|
|
3001
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: {
|
|
3002
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "3rem", height: "3rem", borderRadius: "0.75rem", backgroundColor: "#e5e7eb" } }),
|
|
3003
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "2.5rem", height: "0.75rem", borderRadius: "0.25rem", backgroundColor: "#e5e7eb" } })
|
|
3004
|
-
] }, i)) }) });
|
|
2985
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { width: "100%", height: "100%", display: "flex", alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", gap: "0.75rem", padding: "0 0.75rem" }, children: [1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "2rem", height: "2rem", borderRadius: "0.5rem", backgroundColor: "#e5e7eb", flexShrink: 0 } }, i)) }) });
|
|
3005
2986
|
}
|
|
3006
2987
|
if (applications.length === 0) return null;
|
|
3007
|
-
const displayApps = [...applications, ...applications];
|
|
3008
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
2988
|
+
const displayApps = [...applications, ...applications, ...applications];
|
|
2989
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3009
2990
|
"div",
|
|
3010
2991
|
{
|
|
3011
2992
|
className,
|
|
3012
|
-
style: { position: "relative", overflow: "hidden" },
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
2993
|
+
style: { position: "relative", width: "100%", height: "100%", overflow: "hidden" },
|
|
2994
|
+
children: [
|
|
2995
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
2996
|
+
position: "absolute",
|
|
2997
|
+
left: 0,
|
|
2998
|
+
top: 0,
|
|
2999
|
+
bottom: 0,
|
|
3000
|
+
width: "1.5rem",
|
|
3001
|
+
background: "linear-gradient(to right, #ffffff, transparent)",
|
|
3002
|
+
zIndex: 10,
|
|
3003
|
+
pointerEvents: "none"
|
|
3004
|
+
} }),
|
|
3005
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
3006
|
+
display: "flex",
|
|
3007
|
+
animation: "ollaid-marquee 20s linear infinite",
|
|
3008
|
+
height: "100%",
|
|
3009
|
+
alignItems: "center"
|
|
3010
|
+
}, children: displayApps.map((app, index) => {
|
|
3011
|
+
var _a, _b;
|
|
3012
|
+
const logoUrl = getLogoUrl(app.logo);
|
|
3013
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3014
|
+
"div",
|
|
3015
|
+
{
|
|
3016
|
+
style: { flexShrink: 0, padding: "0 0.75rem", display: "flex", alignItems: "center", height: "100%" },
|
|
3017
|
+
children: [
|
|
3018
|
+
logoUrl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3019
|
+
"img",
|
|
3020
|
+
{
|
|
3021
|
+
src: logoUrl,
|
|
3022
|
+
alt: app.name,
|
|
3023
|
+
style: { width: "2rem", height: "2rem", objectFit: "contain" },
|
|
3024
|
+
onError: (e) => {
|
|
3025
|
+
const target = e.currentTarget;
|
|
3026
|
+
target.style.display = "none";
|
|
3027
|
+
if (target.nextElementSibling) {
|
|
3028
|
+
target.nextElementSibling.style.display = "flex";
|
|
3029
|
+
}
|
|
3030
|
+
}
|
|
3031
|
+
}
|
|
3032
|
+
) : null,
|
|
3033
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3034
|
+
"div",
|
|
3035
|
+
{
|
|
3036
|
+
style: {
|
|
3037
|
+
width: "2rem",
|
|
3038
|
+
height: "2rem",
|
|
3039
|
+
borderRadius: "0.5rem",
|
|
3040
|
+
backgroundColor: "#f3f4f6",
|
|
3041
|
+
alignItems: "center",
|
|
3042
|
+
justifyContent: "center",
|
|
3043
|
+
display: logoUrl ? "none" : "flex"
|
|
3044
|
+
},
|
|
3045
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: "0.75rem", fontWeight: 700, color: "#6b7280" }, children: ((_b = (_a = app.name) == null ? void 0 : _a.charAt(0)) == null ? void 0 : _b.toUpperCase()) || "A" })
|
|
3046
|
+
}
|
|
3047
|
+
)
|
|
3048
|
+
]
|
|
3049
|
+
},
|
|
3050
|
+
`${app.id}-${index}`
|
|
3051
|
+
);
|
|
3052
|
+
}) }),
|
|
3053
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
3054
|
+
position: "absolute",
|
|
3055
|
+
right: 0,
|
|
3056
|
+
top: 0,
|
|
3057
|
+
bottom: 0,
|
|
3058
|
+
width: "1.5rem",
|
|
3059
|
+
background: "linear-gradient(to left, #ffffff, transparent)",
|
|
3060
|
+
zIndex: 10,
|
|
3061
|
+
pointerEvents: "none"
|
|
3062
|
+
} })
|
|
3063
|
+
]
|
|
3022
3064
|
}
|
|
3023
3065
|
);
|
|
3024
3066
|
}
|
|
@@ -4101,8 +4143,10 @@ function DebugPanel({ saasApiUrl, iamApiUrl }) {
|
|
|
4101
4143
|
] })
|
|
4102
4144
|
] });
|
|
4103
4145
|
}
|
|
4146
|
+
const ollaidLogo = "data:image/png;base64,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";
|
|
4104
4147
|
const COLORS = {
|
|
4105
4148
|
primary: "#002147",
|
|
4149
|
+
primaryForeground: "#ffffff",
|
|
4106
4150
|
accent: "#e8430a",
|
|
4107
4151
|
card: "#ffffff",
|
|
4108
4152
|
cardForeground: "#1a2332",
|
|
@@ -4131,13 +4175,49 @@ const LIGHT_VARS = {
|
|
|
4131
4175
|
"--input": "40 15% 88%",
|
|
4132
4176
|
"--ring": "209 100% 13%"
|
|
4133
4177
|
};
|
|
4134
|
-
const ShieldCheckIcon = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { width:
|
|
4178
|
+
const ShieldCheckIcon = ({ size = 24, color = COLORS.accent }) => /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
4135
4179
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" }),
|
|
4136
4180
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "m9 12 2 2 4-4" })
|
|
4137
4181
|
] });
|
|
4138
4182
|
function needsOnboarding(user) {
|
|
4139
4183
|
return !user.image_url || !user.phone;
|
|
4140
4184
|
}
|
|
4185
|
+
const GRADIENT_STYLE_ID = "ollaid-sso-gradient-anim";
|
|
4186
|
+
function injectGradientAnimation() {
|
|
4187
|
+
if (document.getElementById(GRADIENT_STYLE_ID)) return;
|
|
4188
|
+
const style = document.createElement("style");
|
|
4189
|
+
style.id = GRADIENT_STYLE_ID;
|
|
4190
|
+
style.textContent = `
|
|
4191
|
+
@keyframes ollaid-border-gradient {
|
|
4192
|
+
0% { background-position: 0% 50%; }
|
|
4193
|
+
50% { background-position: 100% 50%; }
|
|
4194
|
+
100% { background-position: 0% 50%; }
|
|
4195
|
+
}
|
|
4196
|
+
@keyframes ollaid-marquee {
|
|
4197
|
+
0% { transform: translateX(0); }
|
|
4198
|
+
100% { transform: translateX(-50%); }
|
|
4199
|
+
}
|
|
4200
|
+
`;
|
|
4201
|
+
document.head.appendChild(style);
|
|
4202
|
+
}
|
|
4203
|
+
const TopBranding = ({ subtitle }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "center", marginBottom: "1.5rem" }, children: [
|
|
4204
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "0.5rem", marginBottom: "0.5rem" }, children: [
|
|
4205
|
+
/* @__PURE__ */ jsxRuntime.jsx(ShieldCheckIcon, { size: 28, color: COLORS.accent }),
|
|
4206
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "1.25rem", fontWeight: 700, color: COLORS.primaryForeground }, children: [
|
|
4207
|
+
"iam.",
|
|
4208
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: COLORS.accent }, children: "ollaid" }),
|
|
4209
|
+
".com"
|
|
4210
|
+
] })
|
|
4211
|
+
] }),
|
|
4212
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "1rem", fontWeight: 600, color: "rgba(255,255,255,0.85)" }, children: subtitle })
|
|
4213
|
+
] });
|
|
4214
|
+
const Footer = ({ hideFooter }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: "1.5rem", textAlign: "center" }, children: [
|
|
4215
|
+
/* @__PURE__ */ jsxRuntime.jsx("img", { src: ollaidLogo, alt: "Ollaid", style: { height: "28px", margin: "0 auto 0.5rem" } }),
|
|
4216
|
+
!hideFooter && /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { fontSize: "0.75rem", color: "rgba(255,255,255,0.5)" }, children: [
|
|
4217
|
+
"© 2026 iam.ollaid.com propulsé par ",
|
|
4218
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 500 }, children: "ollaid" })
|
|
4219
|
+
] })
|
|
4220
|
+
] });
|
|
4141
4221
|
function NativeSSOPage({
|
|
4142
4222
|
saasApiUrl,
|
|
4143
4223
|
iamApiUrl,
|
|
@@ -4146,10 +4226,12 @@ function NativeSSOPage({
|
|
|
4146
4226
|
onOnboardingComplete,
|
|
4147
4227
|
accountType = "user",
|
|
4148
4228
|
configPrefix = "iam",
|
|
4149
|
-
title = "Un compte
|
|
4229
|
+
title = "Un compte pour toutes vos applications",
|
|
4150
4230
|
description = "Connectez-vous avec votre compte Ollaid pour accéder à toutes les applications partenaires.",
|
|
4151
4231
|
logoUrl,
|
|
4152
|
-
hideFooter = false
|
|
4232
|
+
hideFooter = false,
|
|
4233
|
+
redirectAfterLogin,
|
|
4234
|
+
redirectAfterLogout
|
|
4153
4235
|
}) {
|
|
4154
4236
|
const [modal, setModal] = react.useState("none");
|
|
4155
4237
|
const [showOnboarding, setShowOnboarding] = react.useState(false);
|
|
@@ -4165,6 +4247,7 @@ function NativeSSOPage({
|
|
|
4165
4247
|
});
|
|
4166
4248
|
const { isDebug: resolvedDebug } = useNativeAuth({ saasApiUrl, iamApiUrl, configPrefix, autoLoadCredentials: true });
|
|
4167
4249
|
react.useEffect(() => {
|
|
4250
|
+
injectGradientAnimation();
|
|
4168
4251
|
const root = document.documentElement;
|
|
4169
4252
|
const originalValues = {};
|
|
4170
4253
|
Object.keys(LIGHT_VARS).forEach((key) => {
|
|
@@ -4218,8 +4301,9 @@ function NativeSSOPage({
|
|
|
4218
4301
|
} else {
|
|
4219
4302
|
setSession({ token, user: userObj });
|
|
4220
4303
|
onLoginSuccess == null ? void 0 : onLoginSuccess(token, user);
|
|
4304
|
+
if (redirectAfterLogin) window.location.href = redirectAfterLogin;
|
|
4221
4305
|
}
|
|
4222
|
-
}, [onLoginSuccess]);
|
|
4306
|
+
}, [onLoginSuccess, redirectAfterLogin]);
|
|
4223
4307
|
const handleOnboardingComplete = react.useCallback((data) => {
|
|
4224
4308
|
if (!pendingSession) return;
|
|
4225
4309
|
const updatedUser = { ...pendingSession.user, ...data };
|
|
@@ -4229,14 +4313,16 @@ function NativeSSOPage({
|
|
|
4229
4313
|
setPendingSession(null);
|
|
4230
4314
|
onOnboardingComplete == null ? void 0 : onOnboardingComplete(data);
|
|
4231
4315
|
onLoginSuccess == null ? void 0 : onLoginSuccess(pendingSession.token, updatedUser);
|
|
4232
|
-
|
|
4316
|
+
if (redirectAfterLogin) window.location.href = redirectAfterLogin;
|
|
4317
|
+
}, [pendingSession, onLoginSuccess, onOnboardingComplete, redirectAfterLogin]);
|
|
4233
4318
|
const handleOnboardingSkip = react.useCallback(() => {
|
|
4234
4319
|
if (!pendingSession) return;
|
|
4235
4320
|
setShowOnboarding(false);
|
|
4236
4321
|
setSession(pendingSession);
|
|
4237
4322
|
setPendingSession(null);
|
|
4238
4323
|
onLoginSuccess == null ? void 0 : onLoginSuccess(pendingSession.token, pendingSession.user);
|
|
4239
|
-
|
|
4324
|
+
if (redirectAfterLogin) window.location.href = redirectAfterLogin;
|
|
4325
|
+
}, [pendingSession, onLoginSuccess, redirectAfterLogin]);
|
|
4240
4326
|
const handleLogout = react.useCallback(() => {
|
|
4241
4327
|
localStorage.removeItem(STORAGE.AUTH_TOKEN);
|
|
4242
4328
|
localStorage.removeItem(STORAGE.TOKEN);
|
|
@@ -4245,7 +4331,8 @@ function NativeSSOPage({
|
|
|
4245
4331
|
localStorage.removeItem(STORAGE.ALIAS_REFERENCE);
|
|
4246
4332
|
setSession(null);
|
|
4247
4333
|
onLogout == null ? void 0 : onLogout();
|
|
4248
|
-
|
|
4334
|
+
if (redirectAfterLogout) window.location.href = redirectAfterLogout;
|
|
4335
|
+
}, [onLogout, redirectAfterLogout]);
|
|
4249
4336
|
const containerStyle = {
|
|
4250
4337
|
minHeight: "100vh",
|
|
4251
4338
|
backgroundColor: COLORS.primary,
|
|
@@ -4253,7 +4340,7 @@ function NativeSSOPage({
|
|
|
4253
4340
|
flexDirection: "column",
|
|
4254
4341
|
alignItems: "center",
|
|
4255
4342
|
justifyContent: "center",
|
|
4256
|
-
padding: "1rem"
|
|
4343
|
+
padding: "1.5rem 1rem"
|
|
4257
4344
|
};
|
|
4258
4345
|
const cardStyle = {
|
|
4259
4346
|
width: "100%",
|
|
@@ -4264,25 +4351,40 @@ function NativeSSOPage({
|
|
|
4264
4351
|
boxShadow: COLORS.shadow,
|
|
4265
4352
|
overflow: "hidden"
|
|
4266
4353
|
};
|
|
4267
|
-
const
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4354
|
+
const SliderBadge = () => /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: "100%", maxWidth: "28rem", marginBottom: "1.5rem" }, children: logoUrl ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoUrl, alt: "Logo", style: { height: "3rem", margin: "0 auto" } }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "1rem" }, children: [
|
|
4355
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
4356
|
+
width: "3rem",
|
|
4357
|
+
height: "3rem",
|
|
4358
|
+
borderRadius: "50%",
|
|
4359
|
+
backgroundColor: "#ffffff",
|
|
4360
|
+
display: "flex",
|
|
4361
|
+
alignItems: "center",
|
|
4362
|
+
justifyContent: "center",
|
|
4363
|
+
flexShrink: 0,
|
|
4364
|
+
boxShadow: "0 2px 8px rgba(0,0,0,0.15)",
|
|
4365
|
+
border: `1px solid ${COLORS.border}`
|
|
4366
|
+
}, children: /* @__PURE__ */ jsxRuntime.jsx(ShieldCheckIcon, { size: 22, color: COLORS.accent }) }),
|
|
4367
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
4368
|
+
flex: 1,
|
|
4369
|
+
minWidth: 0,
|
|
4370
|
+
position: "relative",
|
|
4371
|
+
borderRadius: "9999px",
|
|
4372
|
+
padding: "2px",
|
|
4373
|
+
background: `linear-gradient(90deg, ${COLORS.primary}, ${COLORS.accent}, ${COLORS.primary})`,
|
|
4374
|
+
backgroundSize: "200% 100%",
|
|
4375
|
+
animation: "ollaid-border-gradient 3s ease infinite"
|
|
4376
|
+
}, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
|
|
4377
|
+
backgroundColor: "#ffffff",
|
|
4378
|
+
borderRadius: "9999px",
|
|
4379
|
+
height: "3rem",
|
|
4380
|
+
overflow: "hidden"
|
|
4381
|
+
}, children: /* @__PURE__ */ jsxRuntime.jsx(AppsLogoSlider, { iamApiUrl, speed: "normal" }) }) })
|
|
4280
4382
|
] }) });
|
|
4281
4383
|
if (session) {
|
|
4282
4384
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle, children: [
|
|
4283
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4385
|
+
/* @__PURE__ */ jsxRuntime.jsx(TopBranding, { subtitle: title }),
|
|
4386
|
+
/* @__PURE__ */ jsxRuntime.jsx(SliderBadge, {}),
|
|
4284
4387
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: cardStyle, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "2rem 1.5rem 1.5rem" }, children: [
|
|
4285
|
-
/* @__PURE__ */ jsxRuntime.jsx(BrandingHeader, {}),
|
|
4286
4388
|
/* @__PURE__ */ jsxRuntime.jsxs("h2", { style: { fontSize: "1.25rem", fontWeight: 600, textAlign: "center", color: COLORS.cardForeground }, children: [
|
|
4287
4389
|
"Bienvenue, ",
|
|
4288
4390
|
session.user.name
|
|
@@ -4290,20 +4392,13 @@ function NativeSSOPage({
|
|
|
4290
4392
|
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.875rem", color: COLORS.muted, textAlign: "center", marginTop: "0.25rem" }, children: "Vous êtes connecté à votre compte Ollaid SSO" }),
|
|
4291
4393
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: "1.5rem" }, children: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: handleLogout, style: { width: "100%" }, children: "Déconnexion" }) })
|
|
4292
4394
|
] }) }),
|
|
4293
|
-
|
|
4294
|
-
"Géré par",
|
|
4295
|
-
" ",
|
|
4296
|
-
/* @__PURE__ */ jsxRuntime.jsx("a", { href: "https://iam.ollaid.com", target: "_blank", rel: "noopener noreferrer", style: { color: COLORS.accent, textDecoration: "none" }, children: "iam.ollaid.com" }),
|
|
4297
|
-
" ",
|
|
4298
|
-
"— Identity Access Manager"
|
|
4299
|
-
] })
|
|
4395
|
+
/* @__PURE__ */ jsxRuntime.jsx(Footer, { hideFooter })
|
|
4300
4396
|
] });
|
|
4301
4397
|
}
|
|
4302
4398
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle, children: [
|
|
4303
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4399
|
+
/* @__PURE__ */ jsxRuntime.jsx(TopBranding, { subtitle: title }),
|
|
4400
|
+
/* @__PURE__ */ jsxRuntime.jsx(SliderBadge, {}),
|
|
4304
4401
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: cardStyle, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "2rem 1.5rem 1.5rem" }, children: [
|
|
4305
|
-
/* @__PURE__ */ jsxRuntime.jsx(BrandingHeader, {}),
|
|
4306
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: { fontSize: "1.25rem", fontWeight: 600, textAlign: "center", color: COLORS.cardForeground, marginBottom: "0.5rem" }, children: title }),
|
|
4307
4402
|
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.875rem", color: COLORS.muted, textAlign: "center", marginBottom: "1.5rem" }, children: description }),
|
|
4308
4403
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
|
|
4309
4404
|
/* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: openLogin, style: { width: "100%", height: "2.75rem" }, children: "Connexion" }),
|
|
@@ -4312,24 +4407,13 @@ function NativeSSOPage({
|
|
|
4312
4407
|
{
|
|
4313
4408
|
variant: "outline",
|
|
4314
4409
|
onClick: openSignup,
|
|
4315
|
-
style: {
|
|
4316
|
-
width: "100%",
|
|
4317
|
-
height: "2.75rem",
|
|
4318
|
-
borderColor: COLORS.cardForeground,
|
|
4319
|
-
color: COLORS.cardForeground
|
|
4320
|
-
},
|
|
4410
|
+
style: { width: "100%", height: "2.75rem", borderColor: COLORS.cardForeground, color: COLORS.cardForeground },
|
|
4321
4411
|
children: "Inscription"
|
|
4322
4412
|
}
|
|
4323
4413
|
)
|
|
4324
4414
|
] })
|
|
4325
4415
|
] }) }),
|
|
4326
|
-
|
|
4327
|
-
"Géré par",
|
|
4328
|
-
" ",
|
|
4329
|
-
/* @__PURE__ */ jsxRuntime.jsx("a", { href: "https://iam.ollaid.com", target: "_blank", rel: "noopener noreferrer", style: { color: COLORS.accent, textDecoration: "none" }, children: "iam.ollaid.com" }),
|
|
4330
|
-
" ",
|
|
4331
|
-
"— Identity Access Manager"
|
|
4332
|
-
] }),
|
|
4416
|
+
/* @__PURE__ */ jsxRuntime.jsx(Footer, { hideFooter }),
|
|
4333
4417
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4334
4418
|
LoginModal,
|
|
4335
4419
|
{
|
|
@@ -4548,6 +4632,7 @@ exports.OnboardingModal = OnboardingModal;
|
|
|
4548
4632
|
exports.PasswordRecoveryModal = PasswordRecoveryModal;
|
|
4549
4633
|
exports.PhoneInput = PhoneInput;
|
|
4550
4634
|
exports.SignupModal = SignupModal;
|
|
4635
|
+
exports.clearAuthToken = clearAuthToken;
|
|
4551
4636
|
exports.getAccountType = getAccountType;
|
|
4552
4637
|
exports.getAuthToken = getAuthToken;
|
|
4553
4638
|
exports.getAuthUser = getAuthUser;
|