@shane_donnelly/dsi-internal-react-utils 0.1.0 → 0.1.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 +52 -2
- package/dist/{ProtectedRoute-Bl0cCdQ2.js → ProtectedRoute-_48urWWd.js} +1 -1
- package/dist/keycloak/core/client.d.ts +38 -0
- package/dist/keycloak/core/client.js +11 -1
- package/dist/keycloak/index.d.ts +1 -0
- package/dist/keycloak/index.js +5 -4
- package/dist/keycloak/react/ProtectedRoute/index.js +1 -1
- package/dist/main.d.ts +1 -1
- package/dist/main.js +5 -4
- package/dist/{assets/ProtectedRoute.css → style.css} +1 -0
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -8,10 +8,16 @@ Librairie de composants et utilitaires React pour les projets front-end de la DS
|
|
|
8
8
|
npm install @shane_donnelly/dsi-internal-react-utils keycloak-js
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
### Styles
|
|
12
|
+
|
|
13
|
+
L'import du CSS est obligatoire pour charger les styles des composants :
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import '@shane_donnelly/dsi-internal-react-utils/style.css'
|
|
17
|
+
```
|
|
18
|
+
|
|
11
19
|
### Prérequis
|
|
12
20
|
|
|
13
|
-
- React >= 19
|
|
14
|
-
- keycloak-js >= 25
|
|
15
21
|
- Un serveur Keycloak configuré avec un realm, un client, et au moins un Identity Provider
|
|
16
22
|
|
|
17
23
|
> **Recommandé** : utiliser [react-router](https://reactrouter.com/) pour éviter de perdre l'état de la page lors des redirections d'authentification.
|
|
@@ -159,3 +165,47 @@ function AdvancedComponent() {
|
|
|
159
165
|
console.log(keycloak?.tokenParsed);
|
|
160
166
|
}
|
|
161
167
|
```
|
|
168
|
+
|
|
169
|
+
### Fonctions utilitaires standalone
|
|
170
|
+
|
|
171
|
+
Deux fonctions sont disponibles pour manipuler l'instance Keycloak en dehors de React (intercepteurs HTTP, services, etc.) :
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
import { useAuth, logoutKeycloak, refreshTokenKeycloak } from '@shane_donnelly/dsi-internal-react-utils';
|
|
175
|
+
|
|
176
|
+
// Récupérer l'instance keycloak via useAuth()
|
|
177
|
+
const { keycloak } = useAuth();
|
|
178
|
+
|
|
179
|
+
// Rafraîchir le token (minValidity en secondes, défaut: 30)
|
|
180
|
+
const refreshed = await refreshTokenKeycloak(keycloak!, 60);
|
|
181
|
+
const freshToken = keycloak!.token;
|
|
182
|
+
|
|
183
|
+
// Déconnecter l'utilisateur (redirectUri optionnel, défaut: window.location.origin)
|
|
184
|
+
await logoutKeycloak(keycloak!);
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Exemple dans un intercepteur Axios :
|
|
188
|
+
|
|
189
|
+
```ts
|
|
190
|
+
import axios from 'axios';
|
|
191
|
+
import { logoutKeycloak, refreshTokenKeycloak } from '@shane_donnelly/dsi-internal-react-utils';
|
|
192
|
+
import type Keycloak from 'keycloak-js';
|
|
193
|
+
|
|
194
|
+
function setupInterceptors(keycloak: Keycloak) {
|
|
195
|
+
axios.interceptors.request.use(async (config) => {
|
|
196
|
+
await refreshTokenKeycloak(keycloak, 60);
|
|
197
|
+
config.headers.Authorization = `Bearer ${keycloak.token}`;
|
|
198
|
+
return config;
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
axios.interceptors.response.use(
|
|
202
|
+
(response) => response,
|
|
203
|
+
async (error) => {
|
|
204
|
+
if (error.response?.status === 401) {
|
|
205
|
+
await logoutKeycloak(keycloak);
|
|
206
|
+
}
|
|
207
|
+
return Promise.reject(error);
|
|
208
|
+
},
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
```
|
|
@@ -2,7 +2,7 @@ import { KeycloakProvider as e } from "./keycloak/react/KeycloakProvider/index.j
|
|
|
2
2
|
import { useAuth as t } from "./keycloak/react/hooks/useAuth.js";
|
|
3
3
|
import { useEffect as n, useRef as r } from "react";
|
|
4
4
|
import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
5
|
-
|
|
5
|
+
var s = {
|
|
6
6
|
loadingContainer: "_loadingContainer_1th3z_1",
|
|
7
7
|
spinner: "_spinner_1th3z_11",
|
|
8
8
|
spin: "_spin_1th3z_11",
|
|
@@ -20,3 +20,41 @@ export declare function initKeycloak(keycloak: Keycloak): Promise<boolean>;
|
|
|
20
20
|
* @returns Informations utilisateur ou `null`
|
|
21
21
|
*/
|
|
22
22
|
export declare function parseUser(keycloak: Keycloak): AuthUser | null;
|
|
23
|
+
/**
|
|
24
|
+
* Déconnecte l'utilisateur via l'instance Keycloak.
|
|
25
|
+
*
|
|
26
|
+
* Utilisable en dehors de React (ex: intercepteur HTTP, service, guard).
|
|
27
|
+
*
|
|
28
|
+
* @param keycloak - Instance Keycloak (récupérable via `useAuth().keycloak`)
|
|
29
|
+
* @param redirectUri - URL de redirection après déconnexion (défaut: `window.location.origin`)
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```ts
|
|
33
|
+
* import { logoutKeycloak } from '@shane_donnelly/dsi-internal-react-utils';
|
|
34
|
+
*
|
|
35
|
+
* // dans un intercepteur axios
|
|
36
|
+
* if (response.status === 401) {
|
|
37
|
+
* await logoutKeycloak(keycloakInstance);
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export declare function logoutKeycloak(keycloak: Keycloak, redirectUri?: string): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Rafraîchit le token d'accès via l'instance Keycloak.
|
|
44
|
+
*
|
|
45
|
+
* Utilisable en dehors de React (ex: intercepteur HTTP, service).
|
|
46
|
+
*
|
|
47
|
+
* @param keycloak - Instance Keycloak (récupérable via `useAuth().keycloak`)
|
|
48
|
+
* @param minValidity - Durée minimale de validité restante en secondes (défaut: 30)
|
|
49
|
+
* @returns `true` si le token a été rafraîchi, `false` sinon
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* import { refreshTokenKeycloak } from '@shane_donnelly/dsi-internal-react-utils';
|
|
54
|
+
*
|
|
55
|
+
* // avant un appel API
|
|
56
|
+
* await refreshTokenKeycloak(keycloakInstance, 60);
|
|
57
|
+
* const token = keycloakInstance.token;
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare function refreshTokenKeycloak(keycloak: Keycloak, minValidity?: number): Promise<boolean>;
|
|
@@ -21,5 +21,15 @@ async function n(e) {
|
|
|
21
21
|
function r(e) {
|
|
22
22
|
return e.tokenParsed ? e.tokenParsed : null;
|
|
23
23
|
}
|
|
24
|
+
async function i(e, t) {
|
|
25
|
+
await e.logout({ redirectUri: t ?? window.location.origin });
|
|
26
|
+
}
|
|
27
|
+
async function a(e, t = 30) {
|
|
28
|
+
try {
|
|
29
|
+
return await e.updateToken(t);
|
|
30
|
+
} catch (e) {
|
|
31
|
+
return console.warn("[dsi-keycloak] Token refresh failed:", e), !1;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
24
34
|
//#endregion
|
|
25
|
-
export { t as createKeycloakInstance, n as initKeycloak, r as parseUser };
|
|
35
|
+
export { t as createKeycloakInstance, n as initKeycloak, i as logoutKeycloak, r as parseUser, a as refreshTokenKeycloak };
|
package/dist/keycloak/index.d.ts
CHANGED
|
@@ -3,4 +3,5 @@ export type { KeycloakProviderProps } from './react/KeycloakProvider';
|
|
|
3
3
|
export { ProtectedRoute } from './react/ProtectedRoute';
|
|
4
4
|
export type { ProtectedRouteProps } from './react/ProtectedRoute';
|
|
5
5
|
export { useAuth } from './react/hooks/useAuth';
|
|
6
|
+
export { logoutKeycloak, refreshTokenKeycloak } from './core/client';
|
|
6
7
|
export type { KeycloakConfig, KeycloakAuthOptions, AuthStatus, AuthUser, AuthContextValue, } from './core/types';
|
package/dist/keycloak/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { logoutKeycloak as e, refreshTokenKeycloak as t } from "./core/client.js";
|
|
2
|
+
import { KeycloakProvider as n } from "./react/KeycloakProvider/index.js";
|
|
3
|
+
import { useAuth as r } from "./react/hooks/useAuth.js";
|
|
4
|
+
import { t as i } from "../ProtectedRoute-_48urWWd.js";
|
|
5
|
+
export { n as KeycloakProvider, i as ProtectedRoute, e as logoutKeycloak, t as refreshTokenKeycloak, r as useAuth };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as e } from "../../../ProtectedRoute-
|
|
1
|
+
import { t as e } from "../../../ProtectedRoute-_48urWWd.js";
|
|
2
2
|
export { e as ProtectedRoute };
|
package/dist/main.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { KeycloakProvider, ProtectedRoute, useAuth, } from './keycloak';
|
|
1
|
+
export { KeycloakProvider, ProtectedRoute, useAuth, logoutKeycloak, refreshTokenKeycloak, } from './keycloak';
|
|
2
2
|
export type { KeycloakProviderProps, ProtectedRouteProps, KeycloakConfig, KeycloakAuthOptions, AuthStatus, AuthUser, AuthContextValue, } from './keycloak';
|
package/dist/main.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { logoutKeycloak as e, refreshTokenKeycloak as t } from "./keycloak/core/client.js";
|
|
2
|
+
import { KeycloakProvider as n } from "./keycloak/react/KeycloakProvider/index.js";
|
|
3
|
+
import { useAuth as r } from "./keycloak/react/hooks/useAuth.js";
|
|
4
|
+
import { t as i } from "./ProtectedRoute-_48urWWd.js";
|
|
4
5
|
import "./keycloak/index.js";
|
|
5
|
-
export {
|
|
6
|
+
export { n as KeycloakProvider, i as ProtectedRoute, e as logoutKeycloak, t as refreshTokenKeycloak, r as useAuth };
|
|
@@ -1 +1,2 @@
|
|
|
1
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*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shane_donnelly/dsi-internal-react-utils",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite",
|
|
@@ -33,12 +33,16 @@
|
|
|
33
33
|
},
|
|
34
34
|
"main": "dist/main.js",
|
|
35
35
|
"types": "dist/main.d.ts",
|
|
36
|
+
"exports": {
|
|
37
|
+
".": {
|
|
38
|
+
"import": "./dist/main.js",
|
|
39
|
+
"types": "./dist/main.d.ts"
|
|
40
|
+
},
|
|
41
|
+
"./style.css": "./dist/style.css"
|
|
42
|
+
},
|
|
36
43
|
"files": [
|
|
37
44
|
"dist"
|
|
38
45
|
],
|
|
39
|
-
"sideEffects": [
|
|
40
|
-
"**/*.css"
|
|
41
|
-
],
|
|
42
46
|
"peerDependencies": {
|
|
43
47
|
"react": "^19.2.4",
|
|
44
48
|
"react-dom": "^19.2.4",
|