@shane_donnelly/dsi-internal-react-utils 0.1.3 → 0.1.4
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 -55
- package/dist/keycloak/core/types.d.ts +22 -6
- package/dist/keycloak/index.d.ts +2 -4
- package/dist/keycloak/index.js +2 -3
- package/dist/keycloak/react/KeycloakProvider/index.js +5 -2
- package/dist/keycloak/react/hooks/{useAuth.d.ts → useKeycloakAuth.d.ts} +18 -4
- package/dist/keycloak/react/hooks/useKeycloakAuth.js +10 -0
- package/dist/main.d.ts +2 -2
- package/dist/main.js +2 -3
- package/package.json +1 -1
- package/dist/ProtectedRoute-_48urWWd.js +0 -55
- package/dist/keycloak/react/ProtectedRoute/index.d.ts +0 -69
- package/dist/keycloak/react/ProtectedRoute/index.js +0 -2
- package/dist/keycloak/react/hooks/useAuth.js +0 -10
- package/dist/style.css +0 -2
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ import '@shane_donnelly/dsi-internal-react-utils/style.css'
|
|
|
26
26
|
|
|
27
27
|
### Keycloak
|
|
28
28
|
|
|
29
|
-
Wrapper de simplification pour `keycloak-js`.
|
|
29
|
+
Wrapper de simplification pour `keycloak-js`. `KeycloakProvider` singleton à la racine, `useKeycloakAuth` pour accéder à l'état d'auth et déclencher login / logout depuis n'importe quel composant.
|
|
30
30
|
|
|
31
31
|
[Documentation complète du module Keycloak](docs/keycloak.md)
|
|
32
32
|
|
|
@@ -39,6 +39,7 @@ Wrapper de simplification pour `keycloak-js`. Gère l'authentification automatiq
|
|
|
39
39
|
import React from 'react';
|
|
40
40
|
import ReactDOM from 'react-dom/client';
|
|
41
41
|
import { BrowserRouter } from 'react-router-dom';
|
|
42
|
+
import '@shane_donnelly/dsi-internal-react-utils/style.css';
|
|
42
43
|
import App from './App';
|
|
43
44
|
|
|
44
45
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
@@ -53,10 +54,9 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
|
53
54
|
```tsx
|
|
54
55
|
// App.tsx
|
|
55
56
|
import { Routes, Route } from 'react-router-dom';
|
|
56
|
-
import { KeycloakProvider
|
|
57
|
+
import { KeycloakProvider } from '@shane_donnelly/dsi-internal-react-utils';
|
|
57
58
|
import PublicPage from './pages/PublicPage';
|
|
58
59
|
import Dashboard from './pages/Dashboard';
|
|
59
|
-
import Profile from './pages/Profile';
|
|
60
60
|
|
|
61
61
|
const keycloakConfig = {
|
|
62
62
|
url: 'https://keycloak.example.com',
|
|
@@ -68,26 +68,8 @@ export default function App() {
|
|
|
68
68
|
return (
|
|
69
69
|
<KeycloakProvider config={keycloakConfig} idpHint="oidc" refreshInterval={300}>
|
|
70
70
|
<Routes>
|
|
71
|
-
{/* Route publique — accessible sans authentification */}
|
|
72
71
|
<Route path="/" element={<PublicPage />} />
|
|
73
|
-
|
|
74
|
-
{/* Routes protégées — redirection automatique vers l'IDP */}
|
|
75
|
-
<Route
|
|
76
|
-
path="/dashboard"
|
|
77
|
-
element={
|
|
78
|
-
<ProtectedRoute>
|
|
79
|
-
<Dashboard />
|
|
80
|
-
</ProtectedRoute>
|
|
81
|
-
}
|
|
82
|
-
/>
|
|
83
|
-
<Route
|
|
84
|
-
path="/profile"
|
|
85
|
-
element={
|
|
86
|
-
<ProtectedRoute fallback={<p>Chargement du profil...</p>}>
|
|
87
|
-
<Profile />
|
|
88
|
-
</ProtectedRoute>
|
|
89
|
-
}
|
|
90
|
-
/>
|
|
72
|
+
<Route path="/dashboard" element={<Dashboard />} />
|
|
91
73
|
</Routes>
|
|
92
74
|
</KeycloakProvider>
|
|
93
75
|
);
|
|
@@ -96,51 +78,43 @@ export default function App() {
|
|
|
96
78
|
|
|
97
79
|
```tsx
|
|
98
80
|
// pages/Dashboard.tsx
|
|
99
|
-
import {
|
|
81
|
+
import { useEffect } from 'react';
|
|
82
|
+
import { useNavigate } from 'react-router-dom';
|
|
83
|
+
import { useKeycloakAuth } from '@shane_donnelly/dsi-internal-react-utils';
|
|
100
84
|
|
|
101
85
|
export default function Dashboard() {
|
|
102
|
-
const { user,
|
|
86
|
+
const { isAuthenticated, status, user, login, logout } = useKeycloakAuth();
|
|
87
|
+
const navigate = useNavigate();
|
|
88
|
+
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
if (status === 'unauthenticated') {
|
|
91
|
+
login({ idpHint: 'oidc' });
|
|
92
|
+
}
|
|
93
|
+
}, [status, login]);
|
|
94
|
+
|
|
95
|
+
if (status === 'loading' || status === 'unauthenticated') return <p>Chargement...</p>;
|
|
96
|
+
if (status === 'error') return <p>Erreur d'authentification.</p>;
|
|
103
97
|
|
|
104
98
|
return (
|
|
105
99
|
<div>
|
|
106
100
|
<h1>Bienvenue {user?.name}</h1>
|
|
107
101
|
<p>Email : {user?.email}</p>
|
|
108
|
-
|
|
102
|
+
{/* Déconnexion avec redirection KC vers l'accueil */}
|
|
103
|
+
<button onClick={() => logout({ redirectUri: window.location.origin })}>
|
|
104
|
+
Se déconnecter
|
|
105
|
+
</button>
|
|
109
106
|
</div>
|
|
110
107
|
);
|
|
111
108
|
}
|
|
112
109
|
```
|
|
113
110
|
|
|
114
|
-
### Mode plug & play (sans Provider)
|
|
115
|
-
|
|
116
|
-
Pour un usage rapide sans `KeycloakProvider`, passez `config` directement à `ProtectedRoute` :
|
|
117
|
-
|
|
118
|
-
```tsx
|
|
119
|
-
import { ProtectedRoute } from '@shane_donnelly/dsi-internal-react-utils';
|
|
120
|
-
|
|
121
|
-
function App() {
|
|
122
|
-
return (
|
|
123
|
-
<ProtectedRoute
|
|
124
|
-
config={{
|
|
125
|
-
url: 'https://keycloak.example.com',
|
|
126
|
-
realm: 'my-realm',
|
|
127
|
-
clientId: 'my-frontend',
|
|
128
|
-
}}
|
|
129
|
-
idpHint="oidc"
|
|
130
|
-
>
|
|
131
|
-
<Dashboard />
|
|
132
|
-
</ProtectedRoute>
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
```
|
|
136
|
-
|
|
137
111
|
### Utiliser le token pour les appels API
|
|
138
112
|
|
|
139
113
|
```tsx
|
|
140
|
-
import {
|
|
114
|
+
import { useKeycloakAuth } from '@shane_donnelly/dsi-internal-react-utils';
|
|
141
115
|
|
|
142
116
|
function useAuthFetch() {
|
|
143
|
-
const { token } =
|
|
117
|
+
const { token } = useKeycloakAuth();
|
|
144
118
|
|
|
145
119
|
return (url: string, options?: RequestInit) =>
|
|
146
120
|
fetch(url, {
|
|
@@ -156,10 +130,10 @@ function useAuthFetch() {
|
|
|
156
130
|
### Accéder à l'instance keycloak-js (usage avancé)
|
|
157
131
|
|
|
158
132
|
```tsx
|
|
159
|
-
import {
|
|
133
|
+
import { useKeycloakAuth } from '@shane_donnelly/dsi-internal-react-utils';
|
|
160
134
|
|
|
161
135
|
function AdvancedComponent() {
|
|
162
|
-
const { keycloak } =
|
|
136
|
+
const { keycloak } = useKeycloakAuth();
|
|
163
137
|
|
|
164
138
|
// Accès direct à l'instance keycloak-js pour des cas spécifiques
|
|
165
139
|
console.log(keycloak?.tokenParsed);
|
|
@@ -171,10 +145,10 @@ function AdvancedComponent() {
|
|
|
171
145
|
Deux fonctions sont disponibles pour manipuler l'instance Keycloak en dehors de React (intercepteurs HTTP, services, etc.) :
|
|
172
146
|
|
|
173
147
|
```tsx
|
|
174
|
-
import {
|
|
148
|
+
import { useKeycloakAuth, logoutKeycloak, refreshTokenKeycloak } from '@shane_donnelly/dsi-internal-react-utils';
|
|
175
149
|
|
|
176
|
-
// Récupérer l'instance keycloak via
|
|
177
|
-
const { keycloak } =
|
|
150
|
+
// Récupérer l'instance keycloak via useKeycloakAuth()
|
|
151
|
+
const { keycloak } = useKeycloakAuth();
|
|
178
152
|
|
|
179
153
|
// Rafraîchir le token (minValidity en secondes, défaut: 30)
|
|
180
154
|
const refreshed = await refreshTokenKeycloak(keycloak!, 60);
|
|
@@ -20,9 +20,25 @@ export type KeycloakAuthOptions = {
|
|
|
20
20
|
refreshInterval?: number;
|
|
21
21
|
/** Validité minimale du token en secondes avant rafraîchissement (défaut: 30) */
|
|
22
22
|
minTokenValidity?: number;
|
|
23
|
-
/** Comportement en cas d'erreur
|
|
23
|
+
/** Comportement en cas d'erreur de refresh token: 'login' pour rediriger, 'logout' pour déconnecter, ou un handler custom */
|
|
24
24
|
onAuthError?: 'login' | 'logout' | ((error: unknown) => void);
|
|
25
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* Options pour déclencher le login Keycloak.
|
|
28
|
+
*/
|
|
29
|
+
export type LoginOptions = {
|
|
30
|
+
/** Identity provider hint, override le `idpHint` du `KeycloakProvider` */
|
|
31
|
+
idpHint?: string;
|
|
32
|
+
/** URI vers laquelle Keycloak redirige après le login */
|
|
33
|
+
redirectUri?: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Options pour déclencher le logout.
|
|
37
|
+
*/
|
|
38
|
+
export type LogoutOptions = {
|
|
39
|
+
/** URI de redirection après déconnexion (défaut: `window.location.origin`) */
|
|
40
|
+
redirectUri?: string;
|
|
41
|
+
};
|
|
26
42
|
/**
|
|
27
43
|
* État de l'authentification.
|
|
28
44
|
* - `loading` : vérification en cours
|
|
@@ -45,7 +61,7 @@ export type AuthUser = {
|
|
|
45
61
|
[key: string]: unknown;
|
|
46
62
|
};
|
|
47
63
|
/**
|
|
48
|
-
* Valeur du contexte d'authentification exposée par `KeycloakProvider` et `
|
|
64
|
+
* Valeur du contexte d'authentification exposée par `KeycloakProvider` et `useKeycloakAuth`.
|
|
49
65
|
*/
|
|
50
66
|
export type AuthContextValue = {
|
|
51
67
|
/** État actuel de l'authentification */
|
|
@@ -58,10 +74,10 @@ export type AuthContextValue = {
|
|
|
58
74
|
isAuthenticated: boolean;
|
|
59
75
|
/** Instance keycloak-js sous-jacente (pour usage avancé) */
|
|
60
76
|
keycloak: Keycloak | null;
|
|
61
|
-
/** Déclencher une redirection
|
|
62
|
-
login: (
|
|
63
|
-
/** Déclencher
|
|
64
|
-
logout: (
|
|
77
|
+
/** Déclencher une redirection vers le login Keycloak */
|
|
78
|
+
login: (options?: LoginOptions) => Promise<void>;
|
|
79
|
+
/** Déclencher le logout. Redirige vers `redirectUri` après déconnexion (défaut: `window.location.origin`). */
|
|
80
|
+
logout: (options?: LogoutOptions) => Promise<void>;
|
|
65
81
|
/** Rafraîchir manuellement le token. Retourne true si réussi. */
|
|
66
82
|
refreshToken: () => Promise<boolean>;
|
|
67
83
|
};
|
package/dist/keycloak/index.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
export { KeycloakProvider } from './react/KeycloakProvider';
|
|
2
2
|
export type { KeycloakProviderProps } from './react/KeycloakProvider';
|
|
3
|
-
export {
|
|
4
|
-
export type { ProtectedRouteProps } from './react/ProtectedRoute';
|
|
5
|
-
export { useAuth } from './react/hooks/useAuth';
|
|
3
|
+
export { useKeycloakAuth } from './react/hooks/useKeycloakAuth';
|
|
6
4
|
export { logoutKeycloak, refreshTokenKeycloak } from './core/client';
|
|
7
|
-
export type { KeycloakConfig, KeycloakAuthOptions, AuthStatus, AuthUser, AuthContextValue, } from './core/types';
|
|
5
|
+
export type { KeycloakConfig, KeycloakAuthOptions, AuthStatus, AuthUser, AuthContextValue, LoginOptions, LogoutOptions, } from './core/types';
|
package/dist/keycloak/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { logoutKeycloak as e, refreshTokenKeycloak as t } from "./core/client.js";
|
|
2
2
|
import { KeycloakProvider as n } from "./react/KeycloakProvider/index.js";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
export { n as KeycloakProvider, i as ProtectedRoute, e as logoutKeycloak, t as refreshTokenKeycloak, r as useAuth };
|
|
3
|
+
import { useKeycloakAuth as r } from "./react/hooks/useKeycloakAuth.js";
|
|
4
|
+
export { n as KeycloakProvider, e as logoutKeycloak, t as refreshTokenKeycloak, r as useKeycloakAuth };
|
|
@@ -47,10 +47,13 @@ function u({ config: r, children: u, idpHint: d, refreshInterval: f = 300, minTo
|
|
|
47
47
|
]);
|
|
48
48
|
let E = i(async (e) => {
|
|
49
49
|
let t = x.current;
|
|
50
|
-
t && await t.login({
|
|
50
|
+
t && await t.login({
|
|
51
|
+
idpHint: e?.idpHint ?? d,
|
|
52
|
+
redirectUri: e?.redirectUri
|
|
53
|
+
});
|
|
51
54
|
}, [d]), D = i(async (e) => {
|
|
52
55
|
let t = x.current;
|
|
53
|
-
t && await t.logout({ redirectUri: e ?? window.location.origin });
|
|
56
|
+
t && await t.logout({ redirectUri: e?.redirectUri ?? window.location.origin });
|
|
54
57
|
}, []), O = {
|
|
55
58
|
status: h,
|
|
56
59
|
token: _,
|
|
@@ -5,14 +5,14 @@ import { AuthContextValue } from '../../core/types';
|
|
|
5
5
|
* Donne accès à l'état d'authentification, au token, aux infos utilisateur,
|
|
6
6
|
* et aux actions (login, logout, refreshToken).
|
|
7
7
|
*
|
|
8
|
-
* Doit être utilisé à l'intérieur d'un `KeycloakProvider
|
|
8
|
+
* Doit être utilisé à l'intérieur d'un `KeycloakProvider`.
|
|
9
9
|
*
|
|
10
10
|
* @returns Objet d'authentification complet
|
|
11
11
|
*
|
|
12
12
|
* @example
|
|
13
13
|
* ```tsx
|
|
14
14
|
* function UserProfile() {
|
|
15
|
-
* const { user, token, isAuthenticated, logout } =
|
|
15
|
+
* const { user, token, isAuthenticated, logout } = useKeycloakAuth();
|
|
16
16
|
*
|
|
17
17
|
* if (!isAuthenticated) return null;
|
|
18
18
|
*
|
|
@@ -25,10 +25,24 @@ import { AuthContextValue } from '../../core/types';
|
|
|
25
25
|
* }
|
|
26
26
|
* ```
|
|
27
27
|
*
|
|
28
|
+
* @example Déconnexion avec navigation React Router
|
|
29
|
+
* ```tsx
|
|
30
|
+
* function LogoutButton() {
|
|
31
|
+
* const { logout } = useKeycloakAuth();
|
|
32
|
+
* const navigate = useNavigate();
|
|
33
|
+
*
|
|
34
|
+
* return (
|
|
35
|
+
* <button onClick={() => logout({ onSuccess: () => navigate('/') })}>
|
|
36
|
+
* Se déconnecter
|
|
37
|
+
* </button>
|
|
38
|
+
* );
|
|
39
|
+
* }
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
28
42
|
* @example Utiliser le token pour des appels API
|
|
29
43
|
* ```tsx
|
|
30
44
|
* function useFetchWithAuth(url: string) {
|
|
31
|
-
* const { token } =
|
|
45
|
+
* const { token } = useKeycloakAuth();
|
|
32
46
|
*
|
|
33
47
|
* return fetch(url, {
|
|
34
48
|
* headers: { Authorization: `Bearer ${token}` },
|
|
@@ -36,4 +50,4 @@ import { AuthContextValue } from '../../core/types';
|
|
|
36
50
|
* }
|
|
37
51
|
* ```
|
|
38
52
|
*/
|
|
39
|
-
export declare function
|
|
53
|
+
export declare function useKeycloakAuth(): AuthContextValue;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { KeycloakAuthContext as e } from "../KeycloakProvider/index.js";
|
|
2
|
+
import { useContext as t } from "react";
|
|
3
|
+
//#region lib/keycloak/react/hooks/useKeycloakAuth.ts
|
|
4
|
+
function n() {
|
|
5
|
+
let n = t(e);
|
|
6
|
+
if (!n) throw Error("[dsi-keycloak] useKeycloakAuth() must be used within a <KeycloakProvider>.");
|
|
7
|
+
return n;
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { n as useKeycloakAuth };
|
package/dist/main.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { KeycloakProvider,
|
|
2
|
-
export type { KeycloakProviderProps,
|
|
1
|
+
export { KeycloakProvider, useKeycloakAuth, logoutKeycloak, refreshTokenKeycloak, } from './keycloak';
|
|
2
|
+
export type { KeycloakProviderProps, KeycloakConfig, KeycloakAuthOptions, AuthStatus, AuthUser, AuthContextValue, LoginOptions, LogoutOptions, } from './keycloak';
|
package/dist/main.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { logoutKeycloak as e, refreshTokenKeycloak as t } from "./keycloak/core/client.js";
|
|
2
2
|
import { KeycloakProvider as n } from "./keycloak/react/KeycloakProvider/index.js";
|
|
3
|
-
import {
|
|
4
|
-
import { t as i } from "./ProtectedRoute-_48urWWd.js";
|
|
3
|
+
import { useKeycloakAuth as r } from "./keycloak/react/hooks/useKeycloakAuth.js";
|
|
5
4
|
import "./keycloak/index.js";
|
|
6
|
-
export { n as KeycloakProvider,
|
|
5
|
+
export { n as KeycloakProvider, e as logoutKeycloak, t as refreshTokenKeycloak, r as useKeycloakAuth };
|
package/package.json
CHANGED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { KeycloakProvider as e } from "./keycloak/react/KeycloakProvider/index.js";
|
|
2
|
-
import { useAuth as t } from "./keycloak/react/hooks/useAuth.js";
|
|
3
|
-
import { useEffect as n, useRef as r } from "react";
|
|
4
|
-
import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
5
|
-
var s = {
|
|
6
|
-
loadingContainer: "_loadingContainer_1th3z_1",
|
|
7
|
-
spinner: "_spinner_1th3z_11",
|
|
8
|
-
spin: "_spin_1th3z_11",
|
|
9
|
-
errorContainer: "_errorContainer_1th3z_26",
|
|
10
|
-
errorMessage: "_errorMessage_1th3z_36"
|
|
11
|
-
};
|
|
12
|
-
//#endregion
|
|
13
|
-
//#region lib/keycloak/react/ProtectedRoute/index.tsx
|
|
14
|
-
function c() {
|
|
15
|
-
return /* @__PURE__ */ o("div", {
|
|
16
|
-
className: s.loadingContainer,
|
|
17
|
-
children: [/* @__PURE__ */ a("div", { className: s.spinner }), /* @__PURE__ */ a("p", { children: "Authentication in progress..." })]
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
function l() {
|
|
21
|
-
return /* @__PURE__ */ a("div", {
|
|
22
|
-
className: s.errorContainer,
|
|
23
|
-
children: /* @__PURE__ */ a("p", {
|
|
24
|
-
className: s.errorMessage,
|
|
25
|
-
children: "Authentication error. Please try again later."
|
|
26
|
-
})
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
function u({ children: e, fallback: o, errorFallback: s }) {
|
|
30
|
-
let { status: u, login: d } = t(), f = r(!1);
|
|
31
|
-
return n(() => {
|
|
32
|
-
u === "unauthenticated" && !f.current && (f.current = !0, d().catch((e) => {
|
|
33
|
-
console.error("[dsi-keycloak] Login redirect failed:", e);
|
|
34
|
-
}));
|
|
35
|
-
}, [u, d]), u === "loading" || u === "unauthenticated" ? /* @__PURE__ */ a(i, { children: o ?? /* @__PURE__ */ a(c, {}) }) : u === "error" ? /* @__PURE__ */ a(i, { children: s ?? /* @__PURE__ */ a(l, {}) }) : /* @__PURE__ */ a(i, { children: e });
|
|
36
|
-
}
|
|
37
|
-
function d(e) {
|
|
38
|
-
return "config" in e && e.config != null;
|
|
39
|
-
}
|
|
40
|
-
function f(t) {
|
|
41
|
-
if (d(t)) {
|
|
42
|
-
let { config: n, idpHint: r, refreshInterval: i, minTokenValidity: o, onAuthError: s, ...c } = t;
|
|
43
|
-
return /* @__PURE__ */ a(e, {
|
|
44
|
-
config: n,
|
|
45
|
-
idpHint: r,
|
|
46
|
-
refreshInterval: i,
|
|
47
|
-
minTokenValidity: o,
|
|
48
|
-
onAuthError: s,
|
|
49
|
-
children: /* @__PURE__ */ a(u, { ...c })
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
return /* @__PURE__ */ a(u, { ...t });
|
|
53
|
-
}
|
|
54
|
-
//#endregion
|
|
55
|
-
export { f as t };
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
2
|
-
import { KeycloakConfig, KeycloakAuthOptions } from '../../core/types';
|
|
3
|
-
/**
|
|
4
|
-
* Props de base du composant `ProtectedRoute`.
|
|
5
|
-
*/
|
|
6
|
-
interface BaseProtectedRouteProps {
|
|
7
|
-
/** Contenu protégé, affiché une fois authentifié */
|
|
8
|
-
children: ReactNode;
|
|
9
|
-
/** Composant affiché pendant le chargement / la redirection (défaut: spinner) */
|
|
10
|
-
fallback?: ReactNode;
|
|
11
|
-
/** Composant affiché en cas d'erreur d'authentification (défaut: message d'erreur) */
|
|
12
|
-
errorFallback?: ReactNode;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Props pour le mode standalone (sans `KeycloakProvider` parent).
|
|
16
|
-
* Inclut la configuration Keycloak et les options d'authentification.
|
|
17
|
-
*/
|
|
18
|
-
interface StandaloneProtectedRouteProps extends BaseProtectedRouteProps, KeycloakAuthOptions {
|
|
19
|
-
/** Configuration du serveur Keycloak */
|
|
20
|
-
config: KeycloakConfig;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Props pour le mode contexte (à l'intérieur d'un `KeycloakProvider`).
|
|
24
|
-
*/
|
|
25
|
-
type ContextProtectedRouteProps = BaseProtectedRouteProps;
|
|
26
|
-
/**
|
|
27
|
-
* Union des props acceptées par `ProtectedRoute`.
|
|
28
|
-
*/
|
|
29
|
-
export type ProtectedRouteProps = StandaloneProtectedRouteProps | ContextProtectedRouteProps;
|
|
30
|
-
/**
|
|
31
|
-
* Composant de protection de route / zone authentifiée.
|
|
32
|
-
*
|
|
33
|
-
* Fonctionne en deux modes :
|
|
34
|
-
*
|
|
35
|
-
* **Mode standalone** (plug & play) : fournir `config` et les options directement.
|
|
36
|
-
* Crée automatiquement un `KeycloakProvider` interne.
|
|
37
|
-
*
|
|
38
|
-
* **Mode contexte** : utiliser à l'intérieur d'un `KeycloakProvider` parent.
|
|
39
|
-
* Ne nécessite que `children` et optionnellement `fallback` / `errorFallback`.
|
|
40
|
-
*
|
|
41
|
-
* Dans les deux cas, le composant :
|
|
42
|
-
* - Vérifie l'état d'authentification via `check-sso`
|
|
43
|
-
* - Redirige vers le login Keycloak (via l'IDP configuré) si non authentifié
|
|
44
|
-
* - Affiche un fallback pendant le chargement
|
|
45
|
-
* - Rend les enfants une fois authentifié
|
|
46
|
-
*
|
|
47
|
-
* Basé sur `keycloak-js`.
|
|
48
|
-
*
|
|
49
|
-
* @example Mode standalone (plug & play)
|
|
50
|
-
* ```tsx
|
|
51
|
-
* <ProtectedRoute
|
|
52
|
-
* config={{ url: 'https://keycloak.example.com', realm: 'my-realm', clientId: 'my-client' }}
|
|
53
|
-
* idpHint="oidc"
|
|
54
|
-
* >
|
|
55
|
-
* <Dashboard />
|
|
56
|
-
* </ProtectedRoute>
|
|
57
|
-
* ```
|
|
58
|
-
*
|
|
59
|
-
* @example Mode contexte (avec KeycloakProvider parent)
|
|
60
|
-
* ```tsx
|
|
61
|
-
* <KeycloakProvider config={...} idpHint="oidc">
|
|
62
|
-
* <ProtectedRoute>
|
|
63
|
-
* <Dashboard />
|
|
64
|
-
* </ProtectedRoute>
|
|
65
|
-
* </KeycloakProvider>
|
|
66
|
-
* ```
|
|
67
|
-
*/
|
|
68
|
-
export declare function ProtectedRoute(props: ProtectedRouteProps): import("react/jsx-runtime").JSX.Element;
|
|
69
|
-
export {};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { KeycloakAuthContext as e } from "../KeycloakProvider/index.js";
|
|
2
|
-
import { useContext as t } from "react";
|
|
3
|
-
//#region lib/keycloak/react/hooks/useAuth.ts
|
|
4
|
-
function n() {
|
|
5
|
-
let n = t(e);
|
|
6
|
-
if (!n) throw Error("[dsi-keycloak] useAuth() must be used within a <KeycloakProvider> or a <ProtectedRoute config={...}>.");
|
|
7
|
-
return n;
|
|
8
|
-
}
|
|
9
|
-
//#endregion
|
|
10
|
-
export { n as useAuth };
|
package/dist/style.css
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
._loadingContainer_1th3z_1{flex-direction:column;justify-content:center;align-items:center;gap:1rem;min-height:100vh;font-family:system-ui,-apple-system,sans-serif;display:flex}._spinner_1th3z_11{border:3px solid #e5e7eb;border-top-color:#3b82f6;border-radius:50%;width:40px;height:40px;animation:1s linear infinite _spin_1th3z_11}@keyframes _spin_1th3z_11{to{transform:rotate(360deg)}}._errorContainer_1th3z_26{flex-direction:column;justify-content:center;align-items:center;gap:1rem;min-height:100vh;font-family:system-ui,-apple-system,sans-serif;display:flex}._errorMessage_1th3z_36{color:#dc2626;text-align:center;background:#fef2f2;border-radius:12px;max-width:400px;padding:1.5rem}
|
|
2
|
-
/*$vite$:1*/
|