react-keycloak-wrapper 0.0.1-beta.8 → 0.0.1-beta.9
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/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +109 -64
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +111 -65
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -42,6 +42,7 @@ type KeycloakUser = {
|
|
|
42
42
|
groups?: string[];
|
|
43
43
|
};
|
|
44
44
|
interface KeycloakContextValue {
|
|
45
|
+
configurationName?: string;
|
|
45
46
|
isLoading: boolean;
|
|
46
47
|
isAuthenticated: boolean;
|
|
47
48
|
userInfo: KeycloakUser | null;
|
|
@@ -76,11 +77,12 @@ declare function useKeycloak(): {
|
|
|
76
77
|
logout: (redirectUri: string) => Promise<void>;
|
|
77
78
|
isLoading: boolean;
|
|
78
79
|
isAuthenticated: boolean;
|
|
80
|
+
configurationName: string | undefined;
|
|
79
81
|
};
|
|
80
82
|
|
|
81
83
|
declare function useKeycloakUser<UserInfo = KeycloakUser>(): {
|
|
82
84
|
user: UserInfo | null;
|
|
83
|
-
|
|
85
|
+
isLoading: boolean;
|
|
84
86
|
};
|
|
85
87
|
|
|
86
88
|
declare function useKeycloakToken(): {
|
package/dist/index.d.ts
CHANGED
|
@@ -42,6 +42,7 @@ type KeycloakUser = {
|
|
|
42
42
|
groups?: string[];
|
|
43
43
|
};
|
|
44
44
|
interface KeycloakContextValue {
|
|
45
|
+
configurationName?: string;
|
|
45
46
|
isLoading: boolean;
|
|
46
47
|
isAuthenticated: boolean;
|
|
47
48
|
userInfo: KeycloakUser | null;
|
|
@@ -76,11 +77,12 @@ declare function useKeycloak(): {
|
|
|
76
77
|
logout: (redirectUri: string) => Promise<void>;
|
|
77
78
|
isLoading: boolean;
|
|
78
79
|
isAuthenticated: boolean;
|
|
80
|
+
configurationName: string | undefined;
|
|
79
81
|
};
|
|
80
82
|
|
|
81
83
|
declare function useKeycloakUser<UserInfo = KeycloakUser>(): {
|
|
82
84
|
user: UserInfo | null;
|
|
83
|
-
|
|
85
|
+
isLoading: boolean;
|
|
84
86
|
};
|
|
85
87
|
|
|
86
88
|
declare function useKeycloakToken(): {
|
package/dist/index.js
CHANGED
|
@@ -79,6 +79,11 @@ var ConfigurationStore = class {
|
|
|
79
79
|
}
|
|
80
80
|
};
|
|
81
81
|
|
|
82
|
+
// src/utils/constants.ts
|
|
83
|
+
function getSessionStoragePrefixCN(configurationName, suffix = "") {
|
|
84
|
+
return ["keycloak", configurationName ?? "default", suffix].filter(Boolean).join("_");
|
|
85
|
+
}
|
|
86
|
+
|
|
82
87
|
// src/provider/keycloak-context.ts
|
|
83
88
|
var import_react = require("react");
|
|
84
89
|
|
|
@@ -90,10 +95,16 @@ var initialKeycloakContextValue = {
|
|
|
90
95
|
sessionLost: false,
|
|
91
96
|
login: () => Promise.reject(new Error("Not implemented")),
|
|
92
97
|
logout: () => Promise.reject(new Error("Not implemented")),
|
|
93
|
-
userInfo: null
|
|
98
|
+
userInfo: null,
|
|
99
|
+
configurationName: void 0
|
|
94
100
|
};
|
|
95
101
|
function keycloakReducer(state, action) {
|
|
96
102
|
switch (action.type) {
|
|
103
|
+
case "SET_CONFIGURATION_NAME":
|
|
104
|
+
return {
|
|
105
|
+
...state,
|
|
106
|
+
configurationName: action.payload
|
|
107
|
+
};
|
|
97
108
|
case "SET_TOKEN":
|
|
98
109
|
return {
|
|
99
110
|
...state,
|
|
@@ -138,7 +149,6 @@ var KeycloakContext = (0, import_react.createContext)(
|
|
|
138
149
|
|
|
139
150
|
// src/provider/KeycloakProvider.tsx
|
|
140
151
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
141
|
-
var keycloak;
|
|
142
152
|
var logger = new Logger(false);
|
|
143
153
|
var KeycloakProvider = ({
|
|
144
154
|
configurationName = "default",
|
|
@@ -150,38 +160,15 @@ var KeycloakProvider = ({
|
|
|
150
160
|
SessionLostComponent
|
|
151
161
|
}) => {
|
|
152
162
|
logger.setEnabled(["wrapper", "both"].includes(logging ?? ""));
|
|
163
|
+
const keycloakRef = (0, import_react2.useRef)();
|
|
164
|
+
const timeoutRef = (0, import_react2.useRef)();
|
|
153
165
|
const [state, dispatch] = (0, import_react2.useReducer)(
|
|
154
166
|
keycloakReducer,
|
|
155
167
|
initialKeycloakContextValue
|
|
156
168
|
);
|
|
157
|
-
const
|
|
158
|
-
if (!
|
|
159
|
-
|
|
160
|
-
url: config.url,
|
|
161
|
-
realm: config.realm,
|
|
162
|
-
clientId: config.clientId,
|
|
163
|
-
oidcProvider: config.wellKnownUrlPrefix
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
if (keycloak && !keycloak.didInitialize) {
|
|
167
|
-
keycloak.init({
|
|
168
|
-
onLoad: "check-sso",
|
|
169
|
-
checkLoginIframe: false,
|
|
170
|
-
scope: config.scope,
|
|
171
|
-
enableLogging: ["keycloak", "both"].includes(logging ?? ""),
|
|
172
|
-
...ConfigurationStore.getConfiguration(
|
|
173
|
-
configurationName,
|
|
174
|
-
config.realm
|
|
175
|
-
)
|
|
176
|
-
}).catch((error) => {
|
|
177
|
-
logger.log("Failed to initialize Keycloak", { error });
|
|
178
|
-
dispatch({
|
|
179
|
-
type: "SET_ERROR",
|
|
180
|
-
payload: error || null
|
|
181
|
-
});
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
keycloak.onReady = (authenticated) => {
|
|
169
|
+
const watchKeycloakEvents = (0, import_react2.useCallback)(() => {
|
|
170
|
+
if (!keycloakRef.current) return;
|
|
171
|
+
keycloakRef.current.onReady = (authenticated) => {
|
|
185
172
|
logger.log("Keycloak is ready", { authenticated });
|
|
186
173
|
if (!authenticated) {
|
|
187
174
|
dispatch({
|
|
@@ -190,24 +177,24 @@ var KeycloakProvider = ({
|
|
|
190
177
|
});
|
|
191
178
|
}
|
|
192
179
|
};
|
|
193
|
-
|
|
180
|
+
keycloakRef.current.onAuthSuccess = () => {
|
|
194
181
|
logger.log("Authentication successful");
|
|
195
182
|
ConfigurationStore.setConfiguration(configurationName, config.realm, {
|
|
196
|
-
token:
|
|
197
|
-
refreshToken:
|
|
198
|
-
idToken:
|
|
183
|
+
token: keycloakRef.current?.token,
|
|
184
|
+
refreshToken: keycloakRef.current?.refreshToken,
|
|
185
|
+
idToken: keycloakRef.current?.idToken
|
|
199
186
|
});
|
|
200
187
|
dispatch({
|
|
201
188
|
type: "SET_TOKEN",
|
|
202
189
|
payload: {
|
|
203
190
|
isAuthenticated: true,
|
|
204
|
-
accessToken:
|
|
205
|
-
refreshToken:
|
|
206
|
-
idToken:
|
|
191
|
+
accessToken: keycloakRef.current?.token,
|
|
192
|
+
refreshToken: keycloakRef.current?.refreshToken,
|
|
193
|
+
idToken: keycloakRef.current?.idToken
|
|
207
194
|
}
|
|
208
195
|
});
|
|
209
196
|
logger.log("Loading user info");
|
|
210
|
-
|
|
197
|
+
keycloakRef.current?.loadUserInfo().then((userInfo) => {
|
|
211
198
|
logger.log("User info loaded", { userInfo });
|
|
212
199
|
dispatch({
|
|
213
200
|
type: "SET_USER_INFO",
|
|
@@ -219,14 +206,14 @@ var KeycloakProvider = ({
|
|
|
219
206
|
payload: false
|
|
220
207
|
});
|
|
221
208
|
});
|
|
222
|
-
setInterval(
|
|
209
|
+
timeoutRef.current = setInterval(
|
|
223
210
|
() => {
|
|
224
|
-
|
|
211
|
+
keycloakRef.current?.updateToken(config.refreshSecondsBeforeTokenExpires ?? 120).then((refreshed) => {
|
|
225
212
|
if (!refreshed) {
|
|
226
213
|
logger.log(
|
|
227
214
|
"Token is still valid, no need to refresh",
|
|
228
215
|
new Date(
|
|
229
|
-
(
|
|
216
|
+
(keycloakRef.current?.tokenParsed?.exp ?? 0) * 1e3
|
|
230
217
|
).toLocaleTimeString()
|
|
231
218
|
);
|
|
232
219
|
}
|
|
@@ -235,61 +222,111 @@ var KeycloakProvider = ({
|
|
|
235
222
|
(config.tokenRefreshIntervalInSeconds ?? 10) * 1e3
|
|
236
223
|
);
|
|
237
224
|
};
|
|
238
|
-
|
|
225
|
+
keycloakRef.current.onAuthLogout = () => {
|
|
239
226
|
logger.log("Session lost");
|
|
240
227
|
dispatch({
|
|
241
228
|
type: "SET_SESSION_LOST",
|
|
242
229
|
payload: true
|
|
243
230
|
});
|
|
244
231
|
};
|
|
245
|
-
|
|
232
|
+
keycloakRef.current.onAuthError = (error) => {
|
|
246
233
|
logger.log("Authentication error", { error });
|
|
247
234
|
dispatch({
|
|
248
235
|
type: "SET_ERROR",
|
|
249
236
|
payload: error || null
|
|
250
237
|
});
|
|
251
238
|
};
|
|
252
|
-
|
|
239
|
+
keycloakRef.current.onAuthRefreshError = () => {
|
|
253
240
|
logger.log("Token refresh error");
|
|
254
241
|
dispatch({
|
|
255
242
|
type: "SET_ERROR",
|
|
256
243
|
payload: new Error("Token refresh error") || null
|
|
257
244
|
});
|
|
258
245
|
};
|
|
259
|
-
|
|
260
|
-
logger.log("Token refresh successful",
|
|
246
|
+
keycloakRef.current.onAuthRefreshSuccess = () => {
|
|
247
|
+
logger.log("Token refresh successful", keycloakRef.current?.token);
|
|
261
248
|
ConfigurationStore.setConfiguration(configurationName, config.realm, {
|
|
262
|
-
token:
|
|
263
|
-
refreshToken:
|
|
264
|
-
idToken:
|
|
249
|
+
token: keycloakRef.current?.token,
|
|
250
|
+
refreshToken: keycloakRef.current?.refreshToken,
|
|
251
|
+
idToken: keycloakRef.current?.idToken
|
|
265
252
|
});
|
|
266
253
|
dispatch({
|
|
267
254
|
type: "SET_TOKEN",
|
|
268
255
|
payload: {
|
|
269
256
|
isAuthenticated: true,
|
|
270
|
-
accessToken:
|
|
271
|
-
refreshToken:
|
|
272
|
-
idToken:
|
|
257
|
+
accessToken: keycloakRef.current?.token,
|
|
258
|
+
refreshToken: keycloakRef.current?.refreshToken,
|
|
259
|
+
idToken: keycloakRef.current?.idToken
|
|
273
260
|
}
|
|
274
261
|
});
|
|
275
262
|
};
|
|
276
263
|
}, [
|
|
277
|
-
config.clientId,
|
|
278
264
|
config.realm,
|
|
279
265
|
config.refreshSecondsBeforeTokenExpires,
|
|
280
|
-
config.scope,
|
|
281
266
|
config.tokenRefreshIntervalInSeconds,
|
|
267
|
+
configurationName
|
|
268
|
+
]);
|
|
269
|
+
const initiateKeycloak = (0, import_react2.useCallback)(() => {
|
|
270
|
+
if (keycloakRef.current && !keycloakRef.current.didInitialize) {
|
|
271
|
+
keycloakRef.current.init({
|
|
272
|
+
onLoad: "check-sso",
|
|
273
|
+
checkLoginIframe: false,
|
|
274
|
+
scope: config.scope,
|
|
275
|
+
enableLogging: ["keycloak", "both"].includes(logging ?? ""),
|
|
276
|
+
...ConfigurationStore.getConfiguration(
|
|
277
|
+
configurationName,
|
|
278
|
+
config.realm
|
|
279
|
+
)
|
|
280
|
+
}).catch((error) => {
|
|
281
|
+
logger.log("Failed to initialize Keycloak", { error });
|
|
282
|
+
dispatch({
|
|
283
|
+
type: "SET_ERROR",
|
|
284
|
+
payload: error || null
|
|
285
|
+
});
|
|
286
|
+
dispatch({
|
|
287
|
+
type: "SET_LOADING",
|
|
288
|
+
payload: false
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
} else if (!keycloakRef.current) {
|
|
292
|
+
keycloakRef.current = new import_keycloak_js.default({
|
|
293
|
+
url: config.url,
|
|
294
|
+
realm: config.realm,
|
|
295
|
+
clientId: config.clientId,
|
|
296
|
+
oidcProvider: config.wellKnownUrlPrefix
|
|
297
|
+
});
|
|
298
|
+
watchKeycloakEvents();
|
|
299
|
+
dispatch({
|
|
300
|
+
type: "SET_CONFIGURATION_NAME",
|
|
301
|
+
payload: configurationName
|
|
302
|
+
});
|
|
303
|
+
return true;
|
|
304
|
+
}
|
|
305
|
+
}, [
|
|
306
|
+
config.clientId,
|
|
307
|
+
config.realm,
|
|
308
|
+
config.scope,
|
|
282
309
|
config.url,
|
|
283
310
|
config.wellKnownUrlPrefix,
|
|
284
311
|
configurationName,
|
|
285
|
-
logging
|
|
312
|
+
logging,
|
|
313
|
+
watchKeycloakEvents
|
|
286
314
|
]);
|
|
287
315
|
(0, import_react2.useLayoutEffect)(() => {
|
|
288
316
|
initiateKeycloak();
|
|
317
|
+
return () => {
|
|
318
|
+
if (keycloakRef.current?.didInitialize && keycloakRef.current.authenticated && timeoutRef.current !== void 0) {
|
|
319
|
+
logger.log("Cleaning up Keycloak refresh token");
|
|
320
|
+
clearInterval(timeoutRef.current);
|
|
321
|
+
timeoutRef.current = void 0;
|
|
322
|
+
}
|
|
323
|
+
};
|
|
289
324
|
}, [initiateKeycloak]);
|
|
290
325
|
(0, import_react2.useLayoutEffect)(() => {
|
|
291
326
|
if (!state.isLoading && state.isAuthenticated && config.redirectUri && window.location.href.startsWith(config.redirectUri)) {
|
|
292
|
-
const returnUrl = sessionStorage.getItem(
|
|
327
|
+
const returnUrl = sessionStorage.getItem(
|
|
328
|
+
getSessionStoragePrefixCN(configurationName, "return_url")
|
|
329
|
+
) || "/";
|
|
293
330
|
if (!window.location.href.endsWith(returnUrl)) {
|
|
294
331
|
logger.log("Redirecionando para a URL original ap\xF3s autentica\xE7\xE3o", {
|
|
295
332
|
returnUrl,
|
|
@@ -301,17 +338,24 @@ var KeycloakProvider = ({
|
|
|
301
338
|
window.location.origin + returnUrl
|
|
302
339
|
);
|
|
303
340
|
window.dispatchEvent(new PopStateEvent("popstate"));
|
|
304
|
-
sessionStorage.removeItem(
|
|
341
|
+
sessionStorage.removeItem(
|
|
342
|
+
getSessionStoragePrefixCN(configurationName, "return_url")
|
|
343
|
+
);
|
|
305
344
|
}
|
|
306
345
|
}
|
|
307
|
-
}, [
|
|
346
|
+
}, [
|
|
347
|
+
config.redirectUri,
|
|
348
|
+
configurationName,
|
|
349
|
+
state.isAuthenticated,
|
|
350
|
+
state.isLoading
|
|
351
|
+
]);
|
|
308
352
|
const handleLogin = (0, import_react2.useCallback)(
|
|
309
353
|
(redirectUri) => {
|
|
310
354
|
dispatch({
|
|
311
355
|
type: "SET_LOADING",
|
|
312
356
|
payload: true
|
|
313
357
|
});
|
|
314
|
-
return
|
|
358
|
+
return keycloakRef.current?.login({
|
|
315
359
|
redirectUri: redirectUri ?? config.redirectUri
|
|
316
360
|
}) ?? Promise.reject();
|
|
317
361
|
},
|
|
@@ -324,7 +368,7 @@ var KeycloakProvider = ({
|
|
|
324
368
|
payload: true
|
|
325
369
|
});
|
|
326
370
|
ConfigurationStore.clearConfiguration(configurationName, config.realm);
|
|
327
|
-
return
|
|
371
|
+
return keycloakRef.current?.logout({
|
|
328
372
|
redirectUri: redirectUriAfterLogout
|
|
329
373
|
}) ?? Promise.reject();
|
|
330
374
|
},
|
|
@@ -359,7 +403,8 @@ function useKeycloak() {
|
|
|
359
403
|
login: ctx.login,
|
|
360
404
|
logout: ctx.logout,
|
|
361
405
|
isLoading: ctx.isLoading,
|
|
362
|
-
isAuthenticated: ctx.isAuthenticated
|
|
406
|
+
isAuthenticated: ctx.isAuthenticated,
|
|
407
|
+
configurationName: ctx.configurationName
|
|
363
408
|
};
|
|
364
409
|
}
|
|
365
410
|
|
|
@@ -367,11 +412,11 @@ function useKeycloak() {
|
|
|
367
412
|
var KeycloakSecure = ({
|
|
368
413
|
children
|
|
369
414
|
}) => {
|
|
370
|
-
const { isAuthenticated, login, isLoading } = useKeycloak();
|
|
415
|
+
const { isAuthenticated, login, isLoading, configurationName } = useKeycloak();
|
|
371
416
|
if (isLoading) return null;
|
|
372
417
|
if (!isAuthenticated) {
|
|
373
418
|
sessionStorage.setItem(
|
|
374
|
-
"
|
|
419
|
+
getSessionStoragePrefixCN(configurationName, "return_url"),
|
|
375
420
|
window.location.pathname + window.location.search
|
|
376
421
|
);
|
|
377
422
|
login();
|
|
@@ -386,7 +431,7 @@ function useKeycloakUser() {
|
|
|
386
431
|
const ctx = (0, import_react4.useContext)(KeycloakContext);
|
|
387
432
|
return {
|
|
388
433
|
user: ctx?.userInfo,
|
|
389
|
-
|
|
434
|
+
isLoading: ctx?.isLoading
|
|
390
435
|
};
|
|
391
436
|
}
|
|
392
437
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/provider/KeycloakProvider.tsx","../src/components/Logger.ts","../src/store/ConfigurationStore.ts","../src/provider/keycloak-context.ts","../src/provider/keycloak-reducer.ts","../src/hooks/useKeycloak.ts","../src/components/KeycloakSecure.tsx","../src/hooks/useKeycloakUser.ts","../src/hooks/useKeycloakToken.ts"],"sourcesContent":["export * from \"./provider/KeycloakProvider\";\nexport * from \"./components/KeycloakSecure\";\n\nexport * from \"./hooks/useKeycloak\";\nexport * from \"./hooks/useKeycloakUser\";\nexport * from \"./hooks/useKeycloakToken\";\n\nexport * from \"./types\";\n","import Keycloak from \"keycloak-js\";\nimport React, {\n FC,\n ReactNode,\n useCallback,\n useLayoutEffect,\n useReducer,\n} from \"react\";\nimport Logger from \"../components/Logger\";\nimport ConfigurationStore from \"../store/ConfigurationStore\";\nimport { KeycloakConfig, KeycloakUser } from \"../types\";\nimport { KeycloakContext } from \"./keycloak-context\";\nimport {\n initialKeycloakContextValue,\n keycloakReducer,\n} from \"./keycloak-reducer\";\n\ninterface Props {\n configurationName?: string;\n logging?: \"wrapper\" | \"keycloak\" | \"both\";\n children: ReactNode;\n config: KeycloakConfig;\n LoadingComponent?: FC<{ opened: boolean }>;\n AuthenticatingErrorComponent?: FC<{\n error: Error | null;\n }>;\n SessionLostComponent?: FC;\n}\n\nlet keycloak: Keycloak | undefined;\nconst logger = new Logger(false);\nexport const KeycloakProvider: React.FC<Props> = ({\n configurationName = \"default\",\n logging,\n children,\n config,\n LoadingComponent,\n AuthenticatingErrorComponent,\n SessionLostComponent,\n}) => {\n logger.setEnabled([\"wrapper\", \"both\"].includes(logging ?? \"\"));\n\n const [state, dispatch] = useReducer(\n keycloakReducer,\n initialKeycloakContextValue,\n );\n\n const initiateKeycloak = useCallback(() => {\n if (!keycloak) {\n keycloak = new Keycloak({\n url: config.url,\n realm: config.realm,\n clientId: config.clientId,\n oidcProvider: config.wellKnownUrlPrefix,\n });\n }\n\n if (keycloak && !keycloak.didInitialize) {\n keycloak\n .init({\n onLoad: \"check-sso\",\n checkLoginIframe: false,\n scope: config.scope,\n enableLogging: [\"keycloak\", \"both\"].includes(logging ?? \"\"),\n ...ConfigurationStore.getConfiguration(\n configurationName,\n config.realm,\n ),\n })\n .catch((error) => {\n logger.log(\"Failed to initialize Keycloak\", { error });\n dispatch({\n type: \"SET_ERROR\",\n payload: error || null,\n });\n });\n }\n\n keycloak.onReady = (authenticated) => {\n logger.log(\"Keycloak is ready\", { authenticated });\n\n if (!authenticated) {\n dispatch({\n type: \"SET_LOADING\",\n payload: false,\n });\n }\n };\n\n keycloak.onAuthSuccess = () => {\n logger.log(\"Authentication successful\");\n\n ConfigurationStore.setConfiguration(configurationName, config.realm, {\n token: keycloak?.token,\n refreshToken: keycloak?.refreshToken,\n idToken: keycloak?.idToken,\n });\n\n dispatch({\n type: \"SET_TOKEN\",\n payload: {\n isAuthenticated: true,\n accessToken: keycloak?.token,\n refreshToken: keycloak?.refreshToken,\n idToken: keycloak?.idToken,\n },\n });\n\n logger.log(\"Loading user info\");\n keycloak\n ?.loadUserInfo()\n .then((userInfo) => {\n logger.log(\"User info loaded\", { userInfo });\n dispatch({\n type: \"SET_USER_INFO\",\n payload: userInfo as unknown as KeycloakUser,\n });\n })\n .finally(() => {\n dispatch({\n type: \"SET_LOADING\",\n payload: false,\n });\n });\n\n setInterval(\n () => {\n keycloak\n ?.updateToken(config.refreshSecondsBeforeTokenExpires ?? 120)\n .then((refreshed) => {\n if (!refreshed) {\n logger.log(\n \"Token is still valid, no need to refresh\",\n new Date(\n (keycloak?.tokenParsed?.exp ?? 0) * 1000,\n ).toLocaleTimeString(),\n );\n }\n });\n },\n (config.tokenRefreshIntervalInSeconds ?? 10) * 1000,\n );\n };\n\n keycloak.onAuthLogout = () => {\n logger.log(\"Session lost\");\n dispatch({\n type: \"SET_SESSION_LOST\",\n payload: true,\n });\n };\n\n keycloak.onAuthError = (error) => {\n logger.log(\"Authentication error\", { error });\n\n dispatch({\n type: \"SET_ERROR\",\n payload: error || null,\n });\n };\n\n keycloak.onAuthRefreshError = () => {\n logger.log(\"Token refresh error\");\n\n dispatch({\n type: \"SET_ERROR\",\n payload: new Error(\"Token refresh error\") || null,\n });\n };\n\n keycloak.onAuthRefreshSuccess = () => {\n logger.log(\"Token refresh successful\", keycloak?.token);\n\n ConfigurationStore.setConfiguration(configurationName, config.realm, {\n token: keycloak?.token,\n refreshToken: keycloak?.refreshToken,\n idToken: keycloak?.idToken,\n });\n\n dispatch({\n type: \"SET_TOKEN\",\n payload: {\n isAuthenticated: true,\n accessToken: keycloak?.token,\n refreshToken: keycloak?.refreshToken,\n idToken: keycloak?.idToken,\n },\n });\n };\n }, [\n config.clientId,\n config.realm,\n config.refreshSecondsBeforeTokenExpires,\n config.scope,\n config.tokenRefreshIntervalInSeconds,\n config.url,\n config.wellKnownUrlPrefix,\n configurationName,\n logging,\n ]);\n\n useLayoutEffect(() => {\n initiateKeycloak();\n }, [initiateKeycloak]);\n\n useLayoutEffect(() => {\n if (\n !state.isLoading &&\n state.isAuthenticated &&\n config.redirectUri &&\n window.location.href.startsWith(config.redirectUri)\n ) {\n const returnUrl = sessionStorage.getItem(\"keycloak_return_url\") || \"/\";\n if (!window.location.href.endsWith(returnUrl)) {\n logger.log(\"Redirecionando para a URL original após autenticação\", {\n returnUrl,\n origin: window.location.origin,\n });\n\n // Redireciona para a URL original\n window.history.replaceState(\n { keycloak_redirected: true },\n \"\",\n window.location.origin + returnUrl,\n );\n window.dispatchEvent(new PopStateEvent(\"popstate\"));\n sessionStorage.removeItem(\"keycloak_return_url\");\n }\n }\n }, [config.redirectUri, state.isAuthenticated, state.isLoading]);\n\n const handleLogin = useCallback(\n (redirectUri?: string) => {\n dispatch({\n type: \"SET_LOADING\",\n payload: true,\n });\n\n return (\n keycloak?.login({\n redirectUri: redirectUri ?? config.redirectUri,\n }) ?? Promise.reject()\n );\n },\n [config.redirectUri],\n );\n\n const handleLogout = useCallback(\n (redirectUriAfterLogout: string) => {\n dispatch({\n type: \"SET_LOADING\",\n payload: true,\n });\n\n ConfigurationStore.clearConfiguration(configurationName, config.realm);\n\n return (\n keycloak?.logout({\n redirectUri: redirectUriAfterLogout,\n }) ?? Promise.reject()\n );\n },\n [config.realm, configurationName],\n );\n\n // carregando > erro > sessão perdida > children\n\n const shouldRenderError =\n state?.error && !state.isLoading && AuthenticatingErrorComponent;\n\n const shouldRenderSessionLost =\n state.sessionLost &&\n !state.isLoading &&\n !state?.error &&\n SessionLostComponent;\n\n const shouldRenderChildren =\n !state.isLoading && !state.error && !state.sessionLost;\n\n return (\n <KeycloakContext.Provider\n value={{\n ...state,\n login: handleLogin,\n logout: handleLogout,\n }}\n >\n {shouldRenderChildren && children}\n\n {shouldRenderSessionLost && <SessionLostComponent />}\n\n {shouldRenderError && (\n <AuthenticatingErrorComponent error={state?.error} />\n )}\n\n {LoadingComponent && <LoadingComponent opened={state?.isLoading} />}\n </KeycloakContext.Provider>\n );\n};\n","export default class Logger {\n enabled: boolean = false;\n\n constructor(enabled: boolean = false) {\n this.enabled = enabled;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n log(...data: any[]) {\n if (this.enabled) {\n console.log(\"[react-keycloak-wrapper]\", ...data);\n }\n }\n\n setEnabled(enabled: boolean) {\n this.enabled = enabled;\n }\n}\n","type ConfigurationTokens = {\n idToken?: string;\n token?: string;\n refreshToken?: string;\n};\n\nfunction getConfigurationKey(name: string, realm: string) {\n return [\"keycloak\", realm, name].join(\".\");\n}\n\nexport default class ConfigurationStore {\n public static setConfiguration(\n name: string,\n realm: string,\n config: ConfigurationTokens,\n ): void {\n sessionStorage.setItem(\n getConfigurationKey(name, realm),\n JSON.stringify(config),\n );\n }\n\n public static getConfiguration(\n name: string,\n realm: string,\n ): ConfigurationTokens | object {\n const config = sessionStorage.getItem(getConfigurationKey(name, realm));\n return config ? (JSON.parse(config) as ConfigurationTokens) : {};\n }\n\n public static clearConfiguration(name: string, realm: string): void {\n sessionStorage.removeItem(getConfigurationKey(name, realm));\n }\n}\n","import { createContext } from \"react\";\nimport { KeycloakContextValue } from \"../types\";\nimport { initialKeycloakContextValue } from \"./keycloak-reducer\";\n\nexport const KeycloakContext = createContext<KeycloakContextValue>(\n initialKeycloakContextValue,\n);\n","import { KeycloakError } from \"keycloak-js\";\nimport { KeycloakContextValue, KeycloakUser } from \"../types\";\n\ntype GenericAction<T extends string, P = undefined> = { type: T; payload: P };\n\nexport type KeycloakAction =\n | GenericAction<\n \"SET_TOKEN\",\n {\n accessToken?: string;\n idToken?: string;\n refreshToken?: string;\n isAuthenticated?: boolean;\n }\n >\n | GenericAction<\"SET_LOADING\", boolean>\n | GenericAction<\"SET_ERROR\", Error | KeycloakError | null>\n | GenericAction<\"SET_SESSION_LOST\", boolean>\n | GenericAction<\"SET_USER_INFO\", KeycloakUser | null>;\n\nexport const initialKeycloakContextValue: KeycloakContextValue = {\n error: null,\n isAuthenticated: false,\n isLoading: true,\n sessionLost: false,\n login: () => Promise.reject(new Error(\"Not implemented\")),\n logout: () => Promise.reject(new Error(\"Not implemented\")),\n userInfo: null,\n};\n\nexport function keycloakReducer(\n state: KeycloakContextValue,\n action: KeycloakAction,\n): KeycloakContextValue {\n switch (action.type) {\n case \"SET_TOKEN\":\n return {\n ...state,\n accessToken: action.payload.accessToken,\n refreshToken: action.payload.refreshToken,\n idToken: action.payload.idToken,\n isAuthenticated:\n action.payload.isAuthenticated ?? state.isAuthenticated,\n };\n case \"SET_LOADING\":\n return {\n ...state,\n isLoading: action.payload,\n };\n case \"SET_ERROR\":\n return {\n ...state,\n error:\n !action.payload || action.payload instanceof Error\n ? action.payload\n : new Error(\n String(\n action.payload.error || action.payload.error_description,\n ),\n ),\n };\n case \"SET_SESSION_LOST\":\n return {\n ...state,\n sessionLost: action.payload,\n };\n case \"SET_USER_INFO\":\n return {\n ...state,\n userInfo: action.payload,\n };\n\n default:\n return state;\n }\n}\n","import { useContext } from \"react\";\nimport { KeycloakContext } from \"../provider/keycloak-context\";\n\nexport function useKeycloak() {\n const ctx = useContext(KeycloakContext);\n\n return {\n login: ctx.login,\n logout: ctx.logout,\n isLoading: ctx.isLoading,\n isAuthenticated: ctx.isAuthenticated,\n };\n}\n","import React from \"react\";\nimport { useKeycloak } from \"../hooks/useKeycloak\";\n\nexport const KeycloakSecure: React.FC<React.PropsWithChildren> = ({\n children,\n}) => {\n const { isAuthenticated, login, isLoading } = useKeycloak();\n\n if (isLoading) return null;\n\n if (!isAuthenticated) {\n // Salva a URL atual antes de redirecionar\n sessionStorage.setItem(\n \"keycloak_return_url\",\n window.location.pathname + window.location.search,\n );\n\n // Redireciona para o Keycloak com callback fixo\n login(); // Usa o redirectUri configurado (ex: /authorization)\n return null;\n }\n\n return children;\n};\n","import { useContext } from \"react\";\nimport { KeycloakContext } from \"../provider/keycloak-context\";\nimport { KeycloakUser } from \"../types\";\n\nexport function useKeycloakUser<UserInfo = KeycloakUser>() {\n const ctx = useContext(KeycloakContext);\n\n return {\n user: ctx?.userInfo as UserInfo | null,\n loading: ctx?.isLoading,\n };\n}\n","import { useContext } from \"react\";\nimport { KeycloakContext } from \"../provider/keycloak-context\";\n\nexport function useKeycloakToken() {\n const ctx = useContext(KeycloakContext);\n\n return {\n accessToken: ctx.accessToken,\n idToken: ctx.idToken,\n };\n}\n"],"mappings":"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","names":["import_react","Keycloak","import_react","import_react","import_react"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/provider/KeycloakProvider.tsx","../src/components/Logger.ts","../src/store/ConfigurationStore.ts","../src/utils/constants.ts","../src/provider/keycloak-context.ts","../src/provider/keycloak-reducer.ts","../src/hooks/useKeycloak.ts","../src/components/KeycloakSecure.tsx","../src/hooks/useKeycloakUser.ts","../src/hooks/useKeycloakToken.ts"],"sourcesContent":["export * from \"./provider/KeycloakProvider\";\nexport * from \"./components/KeycloakSecure\";\n\nexport * from \"./hooks/useKeycloak\";\nexport * from \"./hooks/useKeycloakUser\";\nexport * from \"./hooks/useKeycloakToken\";\n\nexport * from \"./types\";\n","import Keycloak from \"keycloak-js\";\nimport React, {\n FC,\n ReactNode,\n useCallback,\n useLayoutEffect,\n useReducer,\n useRef,\n} from \"react\";\nimport Logger from \"../components/Logger\";\nimport ConfigurationStore from \"../store/ConfigurationStore\";\nimport { KeycloakConfig, KeycloakUser } from \"../types\";\nimport { getSessionStoragePrefixCN } from \"../utils/constants\";\nimport { KeycloakContext } from \"./keycloak-context\";\nimport {\n initialKeycloakContextValue,\n keycloakReducer,\n} from \"./keycloak-reducer\";\n\ninterface Props {\n configurationName?: string;\n logging?: \"wrapper\" | \"keycloak\" | \"both\";\n children: ReactNode;\n config: KeycloakConfig;\n LoadingComponent?: FC<{ opened: boolean }>;\n AuthenticatingErrorComponent?: FC<{\n error: Error | null;\n }>;\n SessionLostComponent?: FC;\n}\n\nconst logger = new Logger(false);\nexport const KeycloakProvider: React.FC<Props> = ({\n configurationName = \"default\",\n logging,\n children,\n config,\n LoadingComponent,\n AuthenticatingErrorComponent,\n SessionLostComponent,\n}) => {\n logger.setEnabled([\"wrapper\", \"both\"].includes(logging ?? \"\"));\n\n const keycloakRef = useRef<Keycloak>();\n const timeoutRef = useRef<NodeJS.Timeout>();\n\n const [state, dispatch] = useReducer(\n keycloakReducer,\n initialKeycloakContextValue,\n );\n\n const watchKeycloakEvents = useCallback(() => {\n if (!keycloakRef.current) return;\n\n keycloakRef.current.onReady = (authenticated) => {\n logger.log(\"Keycloak is ready\", { authenticated });\n\n if (!authenticated) {\n dispatch({\n type: \"SET_LOADING\",\n payload: false,\n });\n }\n };\n\n keycloakRef.current.onAuthSuccess = () => {\n logger.log(\"Authentication successful\");\n\n ConfigurationStore.setConfiguration(configurationName, config.realm, {\n token: keycloakRef.current?.token,\n refreshToken: keycloakRef.current?.refreshToken,\n idToken: keycloakRef.current?.idToken,\n });\n\n dispatch({\n type: \"SET_TOKEN\",\n payload: {\n isAuthenticated: true,\n accessToken: keycloakRef.current?.token,\n refreshToken: keycloakRef.current?.refreshToken,\n idToken: keycloakRef.current?.idToken,\n },\n });\n\n logger.log(\"Loading user info\");\n keycloakRef.current\n ?.loadUserInfo()\n .then((userInfo) => {\n logger.log(\"User info loaded\", { userInfo });\n dispatch({\n type: \"SET_USER_INFO\",\n payload: userInfo as unknown as KeycloakUser,\n });\n })\n .finally(() => {\n dispatch({\n type: \"SET_LOADING\",\n payload: false,\n });\n });\n\n timeoutRef.current = setInterval(\n () => {\n keycloakRef.current\n ?.updateToken(config.refreshSecondsBeforeTokenExpires ?? 120)\n .then((refreshed) => {\n if (!refreshed) {\n logger.log(\n \"Token is still valid, no need to refresh\",\n new Date(\n (keycloakRef.current?.tokenParsed?.exp ?? 0) * 1000,\n ).toLocaleTimeString(),\n );\n }\n });\n },\n (config.tokenRefreshIntervalInSeconds ?? 10) * 1000,\n );\n };\n\n keycloakRef.current.onAuthLogout = () => {\n logger.log(\"Session lost\");\n dispatch({\n type: \"SET_SESSION_LOST\",\n payload: true,\n });\n };\n\n keycloakRef.current.onAuthError = (error) => {\n logger.log(\"Authentication error\", { error });\n\n dispatch({\n type: \"SET_ERROR\",\n payload: error || null,\n });\n };\n\n keycloakRef.current.onAuthRefreshError = () => {\n logger.log(\"Token refresh error\");\n\n dispatch({\n type: \"SET_ERROR\",\n payload: new Error(\"Token refresh error\") || null,\n });\n };\n\n keycloakRef.current.onAuthRefreshSuccess = () => {\n logger.log(\"Token refresh successful\", keycloakRef.current?.token);\n\n ConfigurationStore.setConfiguration(configurationName, config.realm, {\n token: keycloakRef.current?.token,\n refreshToken: keycloakRef.current?.refreshToken,\n idToken: keycloakRef.current?.idToken,\n });\n\n dispatch({\n type: \"SET_TOKEN\",\n payload: {\n isAuthenticated: true,\n accessToken: keycloakRef.current?.token,\n refreshToken: keycloakRef.current?.refreshToken,\n idToken: keycloakRef.current?.idToken,\n },\n });\n };\n }, [\n config.realm,\n config.refreshSecondsBeforeTokenExpires,\n config.tokenRefreshIntervalInSeconds,\n configurationName,\n ]);\n\n const initiateKeycloak = useCallback(() => {\n if (keycloakRef.current && !keycloakRef.current.didInitialize) {\n keycloakRef.current\n .init({\n onLoad: \"check-sso\",\n checkLoginIframe: false,\n scope: config.scope,\n enableLogging: [\"keycloak\", \"both\"].includes(logging ?? \"\"),\n ...ConfigurationStore.getConfiguration(\n configurationName,\n config.realm,\n ),\n })\n .catch((error) => {\n logger.log(\"Failed to initialize Keycloak\", { error });\n dispatch({\n type: \"SET_ERROR\",\n payload: error || null,\n });\n dispatch({\n type: \"SET_LOADING\",\n payload: false,\n });\n });\n } else if (!keycloakRef.current) {\n keycloakRef.current = new Keycloak({\n url: config.url,\n realm: config.realm,\n clientId: config.clientId,\n oidcProvider: config.wellKnownUrlPrefix,\n });\n\n watchKeycloakEvents();\n\n dispatch({\n type: \"SET_CONFIGURATION_NAME\",\n payload: configurationName,\n });\n\n return true;\n }\n }, [\n config.clientId,\n config.realm,\n config.scope,\n config.url,\n config.wellKnownUrlPrefix,\n configurationName,\n logging,\n watchKeycloakEvents,\n ]);\n\n useLayoutEffect(() => {\n initiateKeycloak();\n\n return () => {\n if (\n keycloakRef.current?.didInitialize &&\n keycloakRef.current.authenticated &&\n timeoutRef.current !== undefined\n ) {\n logger.log(\"Cleaning up Keycloak refresh token\");\n clearInterval(timeoutRef.current);\n timeoutRef.current = undefined;\n }\n };\n }, [initiateKeycloak]);\n\n useLayoutEffect(() => {\n if (\n !state.isLoading &&\n state.isAuthenticated &&\n config.redirectUri &&\n window.location.href.startsWith(config.redirectUri)\n ) {\n const returnUrl =\n sessionStorage.getItem(\n getSessionStoragePrefixCN(configurationName, \"return_url\"),\n ) || \"/\";\n if (!window.location.href.endsWith(returnUrl)) {\n logger.log(\"Redirecionando para a URL original após autenticação\", {\n returnUrl,\n origin: window.location.origin,\n });\n\n // Redireciona para a URL original\n window.history.replaceState(\n { keycloak_redirected: true },\n \"\",\n window.location.origin + returnUrl,\n );\n \n // Dispara um evento para que o ReactRouter detecte\n window.dispatchEvent(new PopStateEvent(\"popstate\"));\n sessionStorage.removeItem(\n getSessionStoragePrefixCN(configurationName, \"return_url\"),\n );\n }\n }\n }, [\n config.redirectUri,\n configurationName,\n state.isAuthenticated,\n state.isLoading,\n ]);\n\n const handleLogin = useCallback(\n (redirectUri?: string) => {\n dispatch({\n type: \"SET_LOADING\",\n payload: true,\n });\n\n return (\n keycloakRef.current?.login({\n redirectUri: redirectUri ?? config.redirectUri,\n }) ?? Promise.reject()\n );\n },\n [config.redirectUri],\n );\n\n const handleLogout = useCallback(\n (redirectUriAfterLogout: string) => {\n dispatch({\n type: \"SET_LOADING\",\n payload: true,\n });\n\n ConfigurationStore.clearConfiguration(configurationName, config.realm);\n\n return (\n keycloakRef.current?.logout({\n redirectUri: redirectUriAfterLogout,\n }) ?? Promise.reject()\n );\n },\n [config.realm, configurationName],\n );\n\n // carregando > erro > sessão perdida > children\n\n const shouldRenderError =\n state?.error && !state.isLoading && AuthenticatingErrorComponent;\n\n const shouldRenderSessionLost =\n state.sessionLost &&\n !state.isLoading &&\n !state?.error &&\n SessionLostComponent;\n\n const shouldRenderChildren =\n !state.isLoading && !state.error && !state.sessionLost;\n\n return (\n <KeycloakContext.Provider\n value={{\n ...state,\n login: handleLogin,\n logout: handleLogout,\n }}\n >\n {shouldRenderChildren && children}\n\n {shouldRenderSessionLost && <SessionLostComponent />}\n\n {shouldRenderError && (\n <AuthenticatingErrorComponent error={state?.error} />\n )}\n\n {LoadingComponent && <LoadingComponent opened={state?.isLoading} />}\n </KeycloakContext.Provider>\n );\n};\n","export default class Logger {\n enabled: boolean = false;\n\n constructor(enabled: boolean = false) {\n this.enabled = enabled;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n log(...data: any[]) {\n if (this.enabled) {\n console.log(\"[react-keycloak-wrapper]\", ...data);\n }\n }\n\n setEnabled(enabled: boolean) {\n this.enabled = enabled;\n }\n}\n","type ConfigurationTokens = {\n idToken?: string;\n token?: string;\n refreshToken?: string;\n};\n\nfunction getConfigurationKey(name: string, realm: string) {\n return [\"keycloak\", realm, name].join(\".\");\n}\n\nexport default class ConfigurationStore {\n public static setConfiguration(\n name: string,\n realm: string,\n config: ConfigurationTokens,\n ): void {\n sessionStorage.setItem(\n getConfigurationKey(name, realm),\n JSON.stringify(config),\n );\n }\n\n public static getConfiguration(\n name: string,\n realm: string,\n ): ConfigurationTokens | object {\n const config = sessionStorage.getItem(getConfigurationKey(name, realm));\n return config ? (JSON.parse(config) as ConfigurationTokens) : {};\n }\n\n public static clearConfiguration(name: string, realm: string): void {\n sessionStorage.removeItem(getConfigurationKey(name, realm));\n }\n}\n","export function getSessionStoragePrefixCN(\n configurationName?: string,\n suffix = \"\",\n) {\n return [\"keycloak\", configurationName ?? \"default\", suffix]\n .filter(Boolean)\n .join(\"_\");\n}\n","import { createContext } from \"react\";\nimport { KeycloakContextValue } from \"../types\";\nimport { initialKeycloakContextValue } from \"./keycloak-reducer\";\n\nexport const KeycloakContext = createContext<KeycloakContextValue>(\n initialKeycloakContextValue,\n);\n","import { KeycloakError } from \"keycloak-js\";\nimport { KeycloakContextValue, KeycloakUser } from \"../types\";\n\ntype GenericAction<T extends string, P = undefined> = { type: T; payload: P };\n\nexport type KeycloakAction =\n | GenericAction<\"SET_CONFIGURATION_NAME\", string>\n | GenericAction<\n \"SET_TOKEN\",\n {\n accessToken?: string;\n idToken?: string;\n refreshToken?: string;\n isAuthenticated?: boolean;\n }\n >\n | GenericAction<\"SET_LOADING\", boolean>\n | GenericAction<\"SET_ERROR\", Error | KeycloakError | null>\n | GenericAction<\"SET_SESSION_LOST\", boolean>\n | GenericAction<\"SET_USER_INFO\", KeycloakUser | null>;\n\nexport const initialKeycloakContextValue: KeycloakContextValue = {\n error: null,\n isAuthenticated: false,\n isLoading: true,\n sessionLost: false,\n login: () => Promise.reject(new Error(\"Not implemented\")),\n logout: () => Promise.reject(new Error(\"Not implemented\")),\n userInfo: null,\n configurationName: undefined,\n};\n\nexport function keycloakReducer(\n state: KeycloakContextValue,\n action: KeycloakAction,\n): KeycloakContextValue {\n switch (action.type) {\n case \"SET_CONFIGURATION_NAME\":\n return {\n ...state,\n configurationName: action.payload,\n };\n case \"SET_TOKEN\":\n return {\n ...state,\n accessToken: action.payload.accessToken,\n refreshToken: action.payload.refreshToken,\n idToken: action.payload.idToken,\n isAuthenticated:\n action.payload.isAuthenticated ?? state.isAuthenticated,\n };\n case \"SET_LOADING\":\n return {\n ...state,\n isLoading: action.payload,\n };\n case \"SET_ERROR\":\n return {\n ...state,\n error:\n !action.payload || action.payload instanceof Error\n ? action.payload\n : new Error(\n String(\n action.payload.error || action.payload.error_description,\n ),\n ),\n };\n case \"SET_SESSION_LOST\":\n return {\n ...state,\n sessionLost: action.payload,\n };\n case \"SET_USER_INFO\":\n return {\n ...state,\n userInfo: action.payload,\n };\n\n default:\n return state;\n }\n}\n","import { useContext } from \"react\";\nimport { KeycloakContext } from \"../provider/keycloak-context\";\n\nexport function useKeycloak() {\n const ctx = useContext(KeycloakContext);\n\n return {\n login: ctx.login,\n logout: ctx.logout,\n isLoading: ctx.isLoading,\n isAuthenticated: ctx.isAuthenticated,\n configurationName: ctx.configurationName,\n };\n}\n","import React from \"react\";\nimport { useKeycloak } from \"../hooks/useKeycloak\";\nimport { getSessionStoragePrefixCN } from \"../utils/constants\";\n\nexport const KeycloakSecure: React.FC<React.PropsWithChildren> = ({\n children,\n}) => {\n const { isAuthenticated, login, isLoading, configurationName } =\n useKeycloak();\n\n if (isLoading) return null;\n\n if (!isAuthenticated) {\n // Salva a URL atual antes de redirecionar\n sessionStorage.setItem(\n getSessionStoragePrefixCN(configurationName, \"return_url\"),\n window.location.pathname + window.location.search,\n );\n\n // Redireciona para o Keycloak com callback fixo\n login(); // Usa o redirectUri configurado (ex: /authorization)\n return null;\n }\n\n return children;\n};\n","import { useContext } from \"react\";\nimport { KeycloakContext } from \"../provider/keycloak-context\";\nimport { KeycloakUser } from \"../types\";\n\nexport function useKeycloakUser<UserInfo = KeycloakUser>() {\n const ctx = useContext(KeycloakContext);\n\n return {\n user: ctx?.userInfo as UserInfo | null,\n isLoading: ctx?.isLoading,\n };\n}\n","import { useContext } from \"react\";\nimport { KeycloakContext } from \"../provider/keycloak-context\";\n\nexport function useKeycloakToken() {\n const ctx = useContext(KeycloakContext);\n\n return {\n accessToken: ctx.accessToken,\n idToken: ctx.idToken,\n };\n}\n"],"mappings":"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","names":["import_react","Keycloak","import_react","import_react","import_react"]}
|
package/dist/index.mjs
CHANGED
|
@@ -3,7 +3,8 @@ import Keycloak from "keycloak-js";
|
|
|
3
3
|
import {
|
|
4
4
|
useCallback,
|
|
5
5
|
useLayoutEffect,
|
|
6
|
-
useReducer
|
|
6
|
+
useReducer,
|
|
7
|
+
useRef
|
|
7
8
|
} from "react";
|
|
8
9
|
|
|
9
10
|
// src/components/Logger.ts
|
|
@@ -43,6 +44,11 @@ var ConfigurationStore = class {
|
|
|
43
44
|
}
|
|
44
45
|
};
|
|
45
46
|
|
|
47
|
+
// src/utils/constants.ts
|
|
48
|
+
function getSessionStoragePrefixCN(configurationName, suffix = "") {
|
|
49
|
+
return ["keycloak", configurationName ?? "default", suffix].filter(Boolean).join("_");
|
|
50
|
+
}
|
|
51
|
+
|
|
46
52
|
// src/provider/keycloak-context.ts
|
|
47
53
|
import { createContext } from "react";
|
|
48
54
|
|
|
@@ -54,10 +60,16 @@ var initialKeycloakContextValue = {
|
|
|
54
60
|
sessionLost: false,
|
|
55
61
|
login: () => Promise.reject(new Error("Not implemented")),
|
|
56
62
|
logout: () => Promise.reject(new Error("Not implemented")),
|
|
57
|
-
userInfo: null
|
|
63
|
+
userInfo: null,
|
|
64
|
+
configurationName: void 0
|
|
58
65
|
};
|
|
59
66
|
function keycloakReducer(state, action) {
|
|
60
67
|
switch (action.type) {
|
|
68
|
+
case "SET_CONFIGURATION_NAME":
|
|
69
|
+
return {
|
|
70
|
+
...state,
|
|
71
|
+
configurationName: action.payload
|
|
72
|
+
};
|
|
61
73
|
case "SET_TOKEN":
|
|
62
74
|
return {
|
|
63
75
|
...state,
|
|
@@ -102,7 +114,6 @@ var KeycloakContext = createContext(
|
|
|
102
114
|
|
|
103
115
|
// src/provider/KeycloakProvider.tsx
|
|
104
116
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
105
|
-
var keycloak;
|
|
106
117
|
var logger = new Logger(false);
|
|
107
118
|
var KeycloakProvider = ({
|
|
108
119
|
configurationName = "default",
|
|
@@ -114,38 +125,15 @@ var KeycloakProvider = ({
|
|
|
114
125
|
SessionLostComponent
|
|
115
126
|
}) => {
|
|
116
127
|
logger.setEnabled(["wrapper", "both"].includes(logging ?? ""));
|
|
128
|
+
const keycloakRef = useRef();
|
|
129
|
+
const timeoutRef = useRef();
|
|
117
130
|
const [state, dispatch] = useReducer(
|
|
118
131
|
keycloakReducer,
|
|
119
132
|
initialKeycloakContextValue
|
|
120
133
|
);
|
|
121
|
-
const
|
|
122
|
-
if (!
|
|
123
|
-
|
|
124
|
-
url: config.url,
|
|
125
|
-
realm: config.realm,
|
|
126
|
-
clientId: config.clientId,
|
|
127
|
-
oidcProvider: config.wellKnownUrlPrefix
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
if (keycloak && !keycloak.didInitialize) {
|
|
131
|
-
keycloak.init({
|
|
132
|
-
onLoad: "check-sso",
|
|
133
|
-
checkLoginIframe: false,
|
|
134
|
-
scope: config.scope,
|
|
135
|
-
enableLogging: ["keycloak", "both"].includes(logging ?? ""),
|
|
136
|
-
...ConfigurationStore.getConfiguration(
|
|
137
|
-
configurationName,
|
|
138
|
-
config.realm
|
|
139
|
-
)
|
|
140
|
-
}).catch((error) => {
|
|
141
|
-
logger.log("Failed to initialize Keycloak", { error });
|
|
142
|
-
dispatch({
|
|
143
|
-
type: "SET_ERROR",
|
|
144
|
-
payload: error || null
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
keycloak.onReady = (authenticated) => {
|
|
134
|
+
const watchKeycloakEvents = useCallback(() => {
|
|
135
|
+
if (!keycloakRef.current) return;
|
|
136
|
+
keycloakRef.current.onReady = (authenticated) => {
|
|
149
137
|
logger.log("Keycloak is ready", { authenticated });
|
|
150
138
|
if (!authenticated) {
|
|
151
139
|
dispatch({
|
|
@@ -154,24 +142,24 @@ var KeycloakProvider = ({
|
|
|
154
142
|
});
|
|
155
143
|
}
|
|
156
144
|
};
|
|
157
|
-
|
|
145
|
+
keycloakRef.current.onAuthSuccess = () => {
|
|
158
146
|
logger.log("Authentication successful");
|
|
159
147
|
ConfigurationStore.setConfiguration(configurationName, config.realm, {
|
|
160
|
-
token:
|
|
161
|
-
refreshToken:
|
|
162
|
-
idToken:
|
|
148
|
+
token: keycloakRef.current?.token,
|
|
149
|
+
refreshToken: keycloakRef.current?.refreshToken,
|
|
150
|
+
idToken: keycloakRef.current?.idToken
|
|
163
151
|
});
|
|
164
152
|
dispatch({
|
|
165
153
|
type: "SET_TOKEN",
|
|
166
154
|
payload: {
|
|
167
155
|
isAuthenticated: true,
|
|
168
|
-
accessToken:
|
|
169
|
-
refreshToken:
|
|
170
|
-
idToken:
|
|
156
|
+
accessToken: keycloakRef.current?.token,
|
|
157
|
+
refreshToken: keycloakRef.current?.refreshToken,
|
|
158
|
+
idToken: keycloakRef.current?.idToken
|
|
171
159
|
}
|
|
172
160
|
});
|
|
173
161
|
logger.log("Loading user info");
|
|
174
|
-
|
|
162
|
+
keycloakRef.current?.loadUserInfo().then((userInfo) => {
|
|
175
163
|
logger.log("User info loaded", { userInfo });
|
|
176
164
|
dispatch({
|
|
177
165
|
type: "SET_USER_INFO",
|
|
@@ -183,14 +171,14 @@ var KeycloakProvider = ({
|
|
|
183
171
|
payload: false
|
|
184
172
|
});
|
|
185
173
|
});
|
|
186
|
-
setInterval(
|
|
174
|
+
timeoutRef.current = setInterval(
|
|
187
175
|
() => {
|
|
188
|
-
|
|
176
|
+
keycloakRef.current?.updateToken(config.refreshSecondsBeforeTokenExpires ?? 120).then((refreshed) => {
|
|
189
177
|
if (!refreshed) {
|
|
190
178
|
logger.log(
|
|
191
179
|
"Token is still valid, no need to refresh",
|
|
192
180
|
new Date(
|
|
193
|
-
(
|
|
181
|
+
(keycloakRef.current?.tokenParsed?.exp ?? 0) * 1e3
|
|
194
182
|
).toLocaleTimeString()
|
|
195
183
|
);
|
|
196
184
|
}
|
|
@@ -199,61 +187,111 @@ var KeycloakProvider = ({
|
|
|
199
187
|
(config.tokenRefreshIntervalInSeconds ?? 10) * 1e3
|
|
200
188
|
);
|
|
201
189
|
};
|
|
202
|
-
|
|
190
|
+
keycloakRef.current.onAuthLogout = () => {
|
|
203
191
|
logger.log("Session lost");
|
|
204
192
|
dispatch({
|
|
205
193
|
type: "SET_SESSION_LOST",
|
|
206
194
|
payload: true
|
|
207
195
|
});
|
|
208
196
|
};
|
|
209
|
-
|
|
197
|
+
keycloakRef.current.onAuthError = (error) => {
|
|
210
198
|
logger.log("Authentication error", { error });
|
|
211
199
|
dispatch({
|
|
212
200
|
type: "SET_ERROR",
|
|
213
201
|
payload: error || null
|
|
214
202
|
});
|
|
215
203
|
};
|
|
216
|
-
|
|
204
|
+
keycloakRef.current.onAuthRefreshError = () => {
|
|
217
205
|
logger.log("Token refresh error");
|
|
218
206
|
dispatch({
|
|
219
207
|
type: "SET_ERROR",
|
|
220
208
|
payload: new Error("Token refresh error") || null
|
|
221
209
|
});
|
|
222
210
|
};
|
|
223
|
-
|
|
224
|
-
logger.log("Token refresh successful",
|
|
211
|
+
keycloakRef.current.onAuthRefreshSuccess = () => {
|
|
212
|
+
logger.log("Token refresh successful", keycloakRef.current?.token);
|
|
225
213
|
ConfigurationStore.setConfiguration(configurationName, config.realm, {
|
|
226
|
-
token:
|
|
227
|
-
refreshToken:
|
|
228
|
-
idToken:
|
|
214
|
+
token: keycloakRef.current?.token,
|
|
215
|
+
refreshToken: keycloakRef.current?.refreshToken,
|
|
216
|
+
idToken: keycloakRef.current?.idToken
|
|
229
217
|
});
|
|
230
218
|
dispatch({
|
|
231
219
|
type: "SET_TOKEN",
|
|
232
220
|
payload: {
|
|
233
221
|
isAuthenticated: true,
|
|
234
|
-
accessToken:
|
|
235
|
-
refreshToken:
|
|
236
|
-
idToken:
|
|
222
|
+
accessToken: keycloakRef.current?.token,
|
|
223
|
+
refreshToken: keycloakRef.current?.refreshToken,
|
|
224
|
+
idToken: keycloakRef.current?.idToken
|
|
237
225
|
}
|
|
238
226
|
});
|
|
239
227
|
};
|
|
240
228
|
}, [
|
|
241
|
-
config.clientId,
|
|
242
229
|
config.realm,
|
|
243
230
|
config.refreshSecondsBeforeTokenExpires,
|
|
244
|
-
config.scope,
|
|
245
231
|
config.tokenRefreshIntervalInSeconds,
|
|
232
|
+
configurationName
|
|
233
|
+
]);
|
|
234
|
+
const initiateKeycloak = useCallback(() => {
|
|
235
|
+
if (keycloakRef.current && !keycloakRef.current.didInitialize) {
|
|
236
|
+
keycloakRef.current.init({
|
|
237
|
+
onLoad: "check-sso",
|
|
238
|
+
checkLoginIframe: false,
|
|
239
|
+
scope: config.scope,
|
|
240
|
+
enableLogging: ["keycloak", "both"].includes(logging ?? ""),
|
|
241
|
+
...ConfigurationStore.getConfiguration(
|
|
242
|
+
configurationName,
|
|
243
|
+
config.realm
|
|
244
|
+
)
|
|
245
|
+
}).catch((error) => {
|
|
246
|
+
logger.log("Failed to initialize Keycloak", { error });
|
|
247
|
+
dispatch({
|
|
248
|
+
type: "SET_ERROR",
|
|
249
|
+
payload: error || null
|
|
250
|
+
});
|
|
251
|
+
dispatch({
|
|
252
|
+
type: "SET_LOADING",
|
|
253
|
+
payload: false
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
} else if (!keycloakRef.current) {
|
|
257
|
+
keycloakRef.current = new Keycloak({
|
|
258
|
+
url: config.url,
|
|
259
|
+
realm: config.realm,
|
|
260
|
+
clientId: config.clientId,
|
|
261
|
+
oidcProvider: config.wellKnownUrlPrefix
|
|
262
|
+
});
|
|
263
|
+
watchKeycloakEvents();
|
|
264
|
+
dispatch({
|
|
265
|
+
type: "SET_CONFIGURATION_NAME",
|
|
266
|
+
payload: configurationName
|
|
267
|
+
});
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
}, [
|
|
271
|
+
config.clientId,
|
|
272
|
+
config.realm,
|
|
273
|
+
config.scope,
|
|
246
274
|
config.url,
|
|
247
275
|
config.wellKnownUrlPrefix,
|
|
248
276
|
configurationName,
|
|
249
|
-
logging
|
|
277
|
+
logging,
|
|
278
|
+
watchKeycloakEvents
|
|
250
279
|
]);
|
|
251
280
|
useLayoutEffect(() => {
|
|
252
281
|
initiateKeycloak();
|
|
282
|
+
return () => {
|
|
283
|
+
if (keycloakRef.current?.didInitialize && keycloakRef.current.authenticated && timeoutRef.current !== void 0) {
|
|
284
|
+
logger.log("Cleaning up Keycloak refresh token");
|
|
285
|
+
clearInterval(timeoutRef.current);
|
|
286
|
+
timeoutRef.current = void 0;
|
|
287
|
+
}
|
|
288
|
+
};
|
|
253
289
|
}, [initiateKeycloak]);
|
|
254
290
|
useLayoutEffect(() => {
|
|
255
291
|
if (!state.isLoading && state.isAuthenticated && config.redirectUri && window.location.href.startsWith(config.redirectUri)) {
|
|
256
|
-
const returnUrl = sessionStorage.getItem(
|
|
292
|
+
const returnUrl = sessionStorage.getItem(
|
|
293
|
+
getSessionStoragePrefixCN(configurationName, "return_url")
|
|
294
|
+
) || "/";
|
|
257
295
|
if (!window.location.href.endsWith(returnUrl)) {
|
|
258
296
|
logger.log("Redirecionando para a URL original ap\xF3s autentica\xE7\xE3o", {
|
|
259
297
|
returnUrl,
|
|
@@ -265,17 +303,24 @@ var KeycloakProvider = ({
|
|
|
265
303
|
window.location.origin + returnUrl
|
|
266
304
|
);
|
|
267
305
|
window.dispatchEvent(new PopStateEvent("popstate"));
|
|
268
|
-
sessionStorage.removeItem(
|
|
306
|
+
sessionStorage.removeItem(
|
|
307
|
+
getSessionStoragePrefixCN(configurationName, "return_url")
|
|
308
|
+
);
|
|
269
309
|
}
|
|
270
310
|
}
|
|
271
|
-
}, [
|
|
311
|
+
}, [
|
|
312
|
+
config.redirectUri,
|
|
313
|
+
configurationName,
|
|
314
|
+
state.isAuthenticated,
|
|
315
|
+
state.isLoading
|
|
316
|
+
]);
|
|
272
317
|
const handleLogin = useCallback(
|
|
273
318
|
(redirectUri) => {
|
|
274
319
|
dispatch({
|
|
275
320
|
type: "SET_LOADING",
|
|
276
321
|
payload: true
|
|
277
322
|
});
|
|
278
|
-
return
|
|
323
|
+
return keycloakRef.current?.login({
|
|
279
324
|
redirectUri: redirectUri ?? config.redirectUri
|
|
280
325
|
}) ?? Promise.reject();
|
|
281
326
|
},
|
|
@@ -288,7 +333,7 @@ var KeycloakProvider = ({
|
|
|
288
333
|
payload: true
|
|
289
334
|
});
|
|
290
335
|
ConfigurationStore.clearConfiguration(configurationName, config.realm);
|
|
291
|
-
return
|
|
336
|
+
return keycloakRef.current?.logout({
|
|
292
337
|
redirectUri: redirectUriAfterLogout
|
|
293
338
|
}) ?? Promise.reject();
|
|
294
339
|
},
|
|
@@ -323,7 +368,8 @@ function useKeycloak() {
|
|
|
323
368
|
login: ctx.login,
|
|
324
369
|
logout: ctx.logout,
|
|
325
370
|
isLoading: ctx.isLoading,
|
|
326
|
-
isAuthenticated: ctx.isAuthenticated
|
|
371
|
+
isAuthenticated: ctx.isAuthenticated,
|
|
372
|
+
configurationName: ctx.configurationName
|
|
327
373
|
};
|
|
328
374
|
}
|
|
329
375
|
|
|
@@ -331,11 +377,11 @@ function useKeycloak() {
|
|
|
331
377
|
var KeycloakSecure = ({
|
|
332
378
|
children
|
|
333
379
|
}) => {
|
|
334
|
-
const { isAuthenticated, login, isLoading } = useKeycloak();
|
|
380
|
+
const { isAuthenticated, login, isLoading, configurationName } = useKeycloak();
|
|
335
381
|
if (isLoading) return null;
|
|
336
382
|
if (!isAuthenticated) {
|
|
337
383
|
sessionStorage.setItem(
|
|
338
|
-
"
|
|
384
|
+
getSessionStoragePrefixCN(configurationName, "return_url"),
|
|
339
385
|
window.location.pathname + window.location.search
|
|
340
386
|
);
|
|
341
387
|
login();
|
|
@@ -350,7 +396,7 @@ function useKeycloakUser() {
|
|
|
350
396
|
const ctx = useContext2(KeycloakContext);
|
|
351
397
|
return {
|
|
352
398
|
user: ctx?.userInfo,
|
|
353
|
-
|
|
399
|
+
isLoading: ctx?.isLoading
|
|
354
400
|
};
|
|
355
401
|
}
|
|
356
402
|
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provider/KeycloakProvider.tsx","../src/components/Logger.ts","../src/store/ConfigurationStore.ts","../src/provider/keycloak-context.ts","../src/provider/keycloak-reducer.ts","../src/hooks/useKeycloak.ts","../src/components/KeycloakSecure.tsx","../src/hooks/useKeycloakUser.ts","../src/hooks/useKeycloakToken.ts"],"sourcesContent":["import Keycloak from \"keycloak-js\";\nimport React, {\n FC,\n ReactNode,\n useCallback,\n useLayoutEffect,\n useReducer,\n} from \"react\";\nimport Logger from \"../components/Logger\";\nimport ConfigurationStore from \"../store/ConfigurationStore\";\nimport { KeycloakConfig, KeycloakUser } from \"../types\";\nimport { KeycloakContext } from \"./keycloak-context\";\nimport {\n initialKeycloakContextValue,\n keycloakReducer,\n} from \"./keycloak-reducer\";\n\ninterface Props {\n configurationName?: string;\n logging?: \"wrapper\" | \"keycloak\" | \"both\";\n children: ReactNode;\n config: KeycloakConfig;\n LoadingComponent?: FC<{ opened: boolean }>;\n AuthenticatingErrorComponent?: FC<{\n error: Error | null;\n }>;\n SessionLostComponent?: FC;\n}\n\nlet keycloak: Keycloak | undefined;\nconst logger = new Logger(false);\nexport const KeycloakProvider: React.FC<Props> = ({\n configurationName = \"default\",\n logging,\n children,\n config,\n LoadingComponent,\n AuthenticatingErrorComponent,\n SessionLostComponent,\n}) => {\n logger.setEnabled([\"wrapper\", \"both\"].includes(logging ?? \"\"));\n\n const [state, dispatch] = useReducer(\n keycloakReducer,\n initialKeycloakContextValue,\n );\n\n const initiateKeycloak = useCallback(() => {\n if (!keycloak) {\n keycloak = new Keycloak({\n url: config.url,\n realm: config.realm,\n clientId: config.clientId,\n oidcProvider: config.wellKnownUrlPrefix,\n });\n }\n\n if (keycloak && !keycloak.didInitialize) {\n keycloak\n .init({\n onLoad: \"check-sso\",\n checkLoginIframe: false,\n scope: config.scope,\n enableLogging: [\"keycloak\", \"both\"].includes(logging ?? \"\"),\n ...ConfigurationStore.getConfiguration(\n configurationName,\n config.realm,\n ),\n })\n .catch((error) => {\n logger.log(\"Failed to initialize Keycloak\", { error });\n dispatch({\n type: \"SET_ERROR\",\n payload: error || null,\n });\n });\n }\n\n keycloak.onReady = (authenticated) => {\n logger.log(\"Keycloak is ready\", { authenticated });\n\n if (!authenticated) {\n dispatch({\n type: \"SET_LOADING\",\n payload: false,\n });\n }\n };\n\n keycloak.onAuthSuccess = () => {\n logger.log(\"Authentication successful\");\n\n ConfigurationStore.setConfiguration(configurationName, config.realm, {\n token: keycloak?.token,\n refreshToken: keycloak?.refreshToken,\n idToken: keycloak?.idToken,\n });\n\n dispatch({\n type: \"SET_TOKEN\",\n payload: {\n isAuthenticated: true,\n accessToken: keycloak?.token,\n refreshToken: keycloak?.refreshToken,\n idToken: keycloak?.idToken,\n },\n });\n\n logger.log(\"Loading user info\");\n keycloak\n ?.loadUserInfo()\n .then((userInfo) => {\n logger.log(\"User info loaded\", { userInfo });\n dispatch({\n type: \"SET_USER_INFO\",\n payload: userInfo as unknown as KeycloakUser,\n });\n })\n .finally(() => {\n dispatch({\n type: \"SET_LOADING\",\n payload: false,\n });\n });\n\n setInterval(\n () => {\n keycloak\n ?.updateToken(config.refreshSecondsBeforeTokenExpires ?? 120)\n .then((refreshed) => {\n if (!refreshed) {\n logger.log(\n \"Token is still valid, no need to refresh\",\n new Date(\n (keycloak?.tokenParsed?.exp ?? 0) * 1000,\n ).toLocaleTimeString(),\n );\n }\n });\n },\n (config.tokenRefreshIntervalInSeconds ?? 10) * 1000,\n );\n };\n\n keycloak.onAuthLogout = () => {\n logger.log(\"Session lost\");\n dispatch({\n type: \"SET_SESSION_LOST\",\n payload: true,\n });\n };\n\n keycloak.onAuthError = (error) => {\n logger.log(\"Authentication error\", { error });\n\n dispatch({\n type: \"SET_ERROR\",\n payload: error || null,\n });\n };\n\n keycloak.onAuthRefreshError = () => {\n logger.log(\"Token refresh error\");\n\n dispatch({\n type: \"SET_ERROR\",\n payload: new Error(\"Token refresh error\") || null,\n });\n };\n\n keycloak.onAuthRefreshSuccess = () => {\n logger.log(\"Token refresh successful\", keycloak?.token);\n\n ConfigurationStore.setConfiguration(configurationName, config.realm, {\n token: keycloak?.token,\n refreshToken: keycloak?.refreshToken,\n idToken: keycloak?.idToken,\n });\n\n dispatch({\n type: \"SET_TOKEN\",\n payload: {\n isAuthenticated: true,\n accessToken: keycloak?.token,\n refreshToken: keycloak?.refreshToken,\n idToken: keycloak?.idToken,\n },\n });\n };\n }, [\n config.clientId,\n config.realm,\n config.refreshSecondsBeforeTokenExpires,\n config.scope,\n config.tokenRefreshIntervalInSeconds,\n config.url,\n config.wellKnownUrlPrefix,\n configurationName,\n logging,\n ]);\n\n useLayoutEffect(() => {\n initiateKeycloak();\n }, [initiateKeycloak]);\n\n useLayoutEffect(() => {\n if (\n !state.isLoading &&\n state.isAuthenticated &&\n config.redirectUri &&\n window.location.href.startsWith(config.redirectUri)\n ) {\n const returnUrl = sessionStorage.getItem(\"keycloak_return_url\") || \"/\";\n if (!window.location.href.endsWith(returnUrl)) {\n logger.log(\"Redirecionando para a URL original após autenticação\", {\n returnUrl,\n origin: window.location.origin,\n });\n\n // Redireciona para a URL original\n window.history.replaceState(\n { keycloak_redirected: true },\n \"\",\n window.location.origin + returnUrl,\n );\n window.dispatchEvent(new PopStateEvent(\"popstate\"));\n sessionStorage.removeItem(\"keycloak_return_url\");\n }\n }\n }, [config.redirectUri, state.isAuthenticated, state.isLoading]);\n\n const handleLogin = useCallback(\n (redirectUri?: string) => {\n dispatch({\n type: \"SET_LOADING\",\n payload: true,\n });\n\n return (\n keycloak?.login({\n redirectUri: redirectUri ?? config.redirectUri,\n }) ?? Promise.reject()\n );\n },\n [config.redirectUri],\n );\n\n const handleLogout = useCallback(\n (redirectUriAfterLogout: string) => {\n dispatch({\n type: \"SET_LOADING\",\n payload: true,\n });\n\n ConfigurationStore.clearConfiguration(configurationName, config.realm);\n\n return (\n keycloak?.logout({\n redirectUri: redirectUriAfterLogout,\n }) ?? Promise.reject()\n );\n },\n [config.realm, configurationName],\n );\n\n // carregando > erro > sessão perdida > children\n\n const shouldRenderError =\n state?.error && !state.isLoading && AuthenticatingErrorComponent;\n\n const shouldRenderSessionLost =\n state.sessionLost &&\n !state.isLoading &&\n !state?.error &&\n SessionLostComponent;\n\n const shouldRenderChildren =\n !state.isLoading && !state.error && !state.sessionLost;\n\n return (\n <KeycloakContext.Provider\n value={{\n ...state,\n login: handleLogin,\n logout: handleLogout,\n }}\n >\n {shouldRenderChildren && children}\n\n {shouldRenderSessionLost && <SessionLostComponent />}\n\n {shouldRenderError && (\n <AuthenticatingErrorComponent error={state?.error} />\n )}\n\n {LoadingComponent && <LoadingComponent opened={state?.isLoading} />}\n </KeycloakContext.Provider>\n );\n};\n","export default class Logger {\n enabled: boolean = false;\n\n constructor(enabled: boolean = false) {\n this.enabled = enabled;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n log(...data: any[]) {\n if (this.enabled) {\n console.log(\"[react-keycloak-wrapper]\", ...data);\n }\n }\n\n setEnabled(enabled: boolean) {\n this.enabled = enabled;\n }\n}\n","type ConfigurationTokens = {\n idToken?: string;\n token?: string;\n refreshToken?: string;\n};\n\nfunction getConfigurationKey(name: string, realm: string) {\n return [\"keycloak\", realm, name].join(\".\");\n}\n\nexport default class ConfigurationStore {\n public static setConfiguration(\n name: string,\n realm: string,\n config: ConfigurationTokens,\n ): void {\n sessionStorage.setItem(\n getConfigurationKey(name, realm),\n JSON.stringify(config),\n );\n }\n\n public static getConfiguration(\n name: string,\n realm: string,\n ): ConfigurationTokens | object {\n const config = sessionStorage.getItem(getConfigurationKey(name, realm));\n return config ? (JSON.parse(config) as ConfigurationTokens) : {};\n }\n\n public static clearConfiguration(name: string, realm: string): void {\n sessionStorage.removeItem(getConfigurationKey(name, realm));\n }\n}\n","import { createContext } from \"react\";\nimport { KeycloakContextValue } from \"../types\";\nimport { initialKeycloakContextValue } from \"./keycloak-reducer\";\n\nexport const KeycloakContext = createContext<KeycloakContextValue>(\n initialKeycloakContextValue,\n);\n","import { KeycloakError } from \"keycloak-js\";\nimport { KeycloakContextValue, KeycloakUser } from \"../types\";\n\ntype GenericAction<T extends string, P = undefined> = { type: T; payload: P };\n\nexport type KeycloakAction =\n | GenericAction<\n \"SET_TOKEN\",\n {\n accessToken?: string;\n idToken?: string;\n refreshToken?: string;\n isAuthenticated?: boolean;\n }\n >\n | GenericAction<\"SET_LOADING\", boolean>\n | GenericAction<\"SET_ERROR\", Error | KeycloakError | null>\n | GenericAction<\"SET_SESSION_LOST\", boolean>\n | GenericAction<\"SET_USER_INFO\", KeycloakUser | null>;\n\nexport const initialKeycloakContextValue: KeycloakContextValue = {\n error: null,\n isAuthenticated: false,\n isLoading: true,\n sessionLost: false,\n login: () => Promise.reject(new Error(\"Not implemented\")),\n logout: () => Promise.reject(new Error(\"Not implemented\")),\n userInfo: null,\n};\n\nexport function keycloakReducer(\n state: KeycloakContextValue,\n action: KeycloakAction,\n): KeycloakContextValue {\n switch (action.type) {\n case \"SET_TOKEN\":\n return {\n ...state,\n accessToken: action.payload.accessToken,\n refreshToken: action.payload.refreshToken,\n idToken: action.payload.idToken,\n isAuthenticated:\n action.payload.isAuthenticated ?? state.isAuthenticated,\n };\n case \"SET_LOADING\":\n return {\n ...state,\n isLoading: action.payload,\n };\n case \"SET_ERROR\":\n return {\n ...state,\n error:\n !action.payload || action.payload instanceof Error\n ? action.payload\n : new Error(\n String(\n action.payload.error || action.payload.error_description,\n ),\n ),\n };\n case \"SET_SESSION_LOST\":\n return {\n ...state,\n sessionLost: action.payload,\n };\n case \"SET_USER_INFO\":\n return {\n ...state,\n userInfo: action.payload,\n };\n\n default:\n return state;\n }\n}\n","import { useContext } from \"react\";\nimport { KeycloakContext } from \"../provider/keycloak-context\";\n\nexport function useKeycloak() {\n const ctx = useContext(KeycloakContext);\n\n return {\n login: ctx.login,\n logout: ctx.logout,\n isLoading: ctx.isLoading,\n isAuthenticated: ctx.isAuthenticated,\n };\n}\n","import React from \"react\";\nimport { useKeycloak } from \"../hooks/useKeycloak\";\n\nexport const KeycloakSecure: React.FC<React.PropsWithChildren> = ({\n children,\n}) => {\n const { isAuthenticated, login, isLoading } = useKeycloak();\n\n if (isLoading) return null;\n\n if (!isAuthenticated) {\n // Salva a URL atual antes de redirecionar\n sessionStorage.setItem(\n \"keycloak_return_url\",\n window.location.pathname + window.location.search,\n );\n\n // Redireciona para o Keycloak com callback fixo\n login(); // Usa o redirectUri configurado (ex: /authorization)\n return null;\n }\n\n return children;\n};\n","import { useContext } from \"react\";\nimport { KeycloakContext } from \"../provider/keycloak-context\";\nimport { KeycloakUser } from \"../types\";\n\nexport function useKeycloakUser<UserInfo = KeycloakUser>() {\n const ctx = useContext(KeycloakContext);\n\n return {\n user: ctx?.userInfo as UserInfo | null,\n loading: ctx?.isLoading,\n };\n}\n","import { useContext } from \"react\";\nimport { KeycloakContext } from \"../provider/keycloak-context\";\n\nexport function useKeycloakToken() {\n const ctx = useContext(KeycloakContext);\n\n return {\n accessToken: ctx.accessToken,\n idToken: ctx.idToken,\n };\n}\n"],"mappings":"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","names":["useContext","useContext","useContext","useContext"]}
|
|
1
|
+
{"version":3,"sources":["../src/provider/KeycloakProvider.tsx","../src/components/Logger.ts","../src/store/ConfigurationStore.ts","../src/utils/constants.ts","../src/provider/keycloak-context.ts","../src/provider/keycloak-reducer.ts","../src/hooks/useKeycloak.ts","../src/components/KeycloakSecure.tsx","../src/hooks/useKeycloakUser.ts","../src/hooks/useKeycloakToken.ts"],"sourcesContent":["import Keycloak from \"keycloak-js\";\nimport React, {\n FC,\n ReactNode,\n useCallback,\n useLayoutEffect,\n useReducer,\n useRef,\n} from \"react\";\nimport Logger from \"../components/Logger\";\nimport ConfigurationStore from \"../store/ConfigurationStore\";\nimport { KeycloakConfig, KeycloakUser } from \"../types\";\nimport { getSessionStoragePrefixCN } from \"../utils/constants\";\nimport { KeycloakContext } from \"./keycloak-context\";\nimport {\n initialKeycloakContextValue,\n keycloakReducer,\n} from \"./keycloak-reducer\";\n\ninterface Props {\n configurationName?: string;\n logging?: \"wrapper\" | \"keycloak\" | \"both\";\n children: ReactNode;\n config: KeycloakConfig;\n LoadingComponent?: FC<{ opened: boolean }>;\n AuthenticatingErrorComponent?: FC<{\n error: Error | null;\n }>;\n SessionLostComponent?: FC;\n}\n\nconst logger = new Logger(false);\nexport const KeycloakProvider: React.FC<Props> = ({\n configurationName = \"default\",\n logging,\n children,\n config,\n LoadingComponent,\n AuthenticatingErrorComponent,\n SessionLostComponent,\n}) => {\n logger.setEnabled([\"wrapper\", \"both\"].includes(logging ?? \"\"));\n\n const keycloakRef = useRef<Keycloak>();\n const timeoutRef = useRef<NodeJS.Timeout>();\n\n const [state, dispatch] = useReducer(\n keycloakReducer,\n initialKeycloakContextValue,\n );\n\n const watchKeycloakEvents = useCallback(() => {\n if (!keycloakRef.current) return;\n\n keycloakRef.current.onReady = (authenticated) => {\n logger.log(\"Keycloak is ready\", { authenticated });\n\n if (!authenticated) {\n dispatch({\n type: \"SET_LOADING\",\n payload: false,\n });\n }\n };\n\n keycloakRef.current.onAuthSuccess = () => {\n logger.log(\"Authentication successful\");\n\n ConfigurationStore.setConfiguration(configurationName, config.realm, {\n token: keycloakRef.current?.token,\n refreshToken: keycloakRef.current?.refreshToken,\n idToken: keycloakRef.current?.idToken,\n });\n\n dispatch({\n type: \"SET_TOKEN\",\n payload: {\n isAuthenticated: true,\n accessToken: keycloakRef.current?.token,\n refreshToken: keycloakRef.current?.refreshToken,\n idToken: keycloakRef.current?.idToken,\n },\n });\n\n logger.log(\"Loading user info\");\n keycloakRef.current\n ?.loadUserInfo()\n .then((userInfo) => {\n logger.log(\"User info loaded\", { userInfo });\n dispatch({\n type: \"SET_USER_INFO\",\n payload: userInfo as unknown as KeycloakUser,\n });\n })\n .finally(() => {\n dispatch({\n type: \"SET_LOADING\",\n payload: false,\n });\n });\n\n timeoutRef.current = setInterval(\n () => {\n keycloakRef.current\n ?.updateToken(config.refreshSecondsBeforeTokenExpires ?? 120)\n .then((refreshed) => {\n if (!refreshed) {\n logger.log(\n \"Token is still valid, no need to refresh\",\n new Date(\n (keycloakRef.current?.tokenParsed?.exp ?? 0) * 1000,\n ).toLocaleTimeString(),\n );\n }\n });\n },\n (config.tokenRefreshIntervalInSeconds ?? 10) * 1000,\n );\n };\n\n keycloakRef.current.onAuthLogout = () => {\n logger.log(\"Session lost\");\n dispatch({\n type: \"SET_SESSION_LOST\",\n payload: true,\n });\n };\n\n keycloakRef.current.onAuthError = (error) => {\n logger.log(\"Authentication error\", { error });\n\n dispatch({\n type: \"SET_ERROR\",\n payload: error || null,\n });\n };\n\n keycloakRef.current.onAuthRefreshError = () => {\n logger.log(\"Token refresh error\");\n\n dispatch({\n type: \"SET_ERROR\",\n payload: new Error(\"Token refresh error\") || null,\n });\n };\n\n keycloakRef.current.onAuthRefreshSuccess = () => {\n logger.log(\"Token refresh successful\", keycloakRef.current?.token);\n\n ConfigurationStore.setConfiguration(configurationName, config.realm, {\n token: keycloakRef.current?.token,\n refreshToken: keycloakRef.current?.refreshToken,\n idToken: keycloakRef.current?.idToken,\n });\n\n dispatch({\n type: \"SET_TOKEN\",\n payload: {\n isAuthenticated: true,\n accessToken: keycloakRef.current?.token,\n refreshToken: keycloakRef.current?.refreshToken,\n idToken: keycloakRef.current?.idToken,\n },\n });\n };\n }, [\n config.realm,\n config.refreshSecondsBeforeTokenExpires,\n config.tokenRefreshIntervalInSeconds,\n configurationName,\n ]);\n\n const initiateKeycloak = useCallback(() => {\n if (keycloakRef.current && !keycloakRef.current.didInitialize) {\n keycloakRef.current\n .init({\n onLoad: \"check-sso\",\n checkLoginIframe: false,\n scope: config.scope,\n enableLogging: [\"keycloak\", \"both\"].includes(logging ?? \"\"),\n ...ConfigurationStore.getConfiguration(\n configurationName,\n config.realm,\n ),\n })\n .catch((error) => {\n logger.log(\"Failed to initialize Keycloak\", { error });\n dispatch({\n type: \"SET_ERROR\",\n payload: error || null,\n });\n dispatch({\n type: \"SET_LOADING\",\n payload: false,\n });\n });\n } else if (!keycloakRef.current) {\n keycloakRef.current = new Keycloak({\n url: config.url,\n realm: config.realm,\n clientId: config.clientId,\n oidcProvider: config.wellKnownUrlPrefix,\n });\n\n watchKeycloakEvents();\n\n dispatch({\n type: \"SET_CONFIGURATION_NAME\",\n payload: configurationName,\n });\n\n return true;\n }\n }, [\n config.clientId,\n config.realm,\n config.scope,\n config.url,\n config.wellKnownUrlPrefix,\n configurationName,\n logging,\n watchKeycloakEvents,\n ]);\n\n useLayoutEffect(() => {\n initiateKeycloak();\n\n return () => {\n if (\n keycloakRef.current?.didInitialize &&\n keycloakRef.current.authenticated &&\n timeoutRef.current !== undefined\n ) {\n logger.log(\"Cleaning up Keycloak refresh token\");\n clearInterval(timeoutRef.current);\n timeoutRef.current = undefined;\n }\n };\n }, [initiateKeycloak]);\n\n useLayoutEffect(() => {\n if (\n !state.isLoading &&\n state.isAuthenticated &&\n config.redirectUri &&\n window.location.href.startsWith(config.redirectUri)\n ) {\n const returnUrl =\n sessionStorage.getItem(\n getSessionStoragePrefixCN(configurationName, \"return_url\"),\n ) || \"/\";\n if (!window.location.href.endsWith(returnUrl)) {\n logger.log(\"Redirecionando para a URL original após autenticação\", {\n returnUrl,\n origin: window.location.origin,\n });\n\n // Redireciona para a URL original\n window.history.replaceState(\n { keycloak_redirected: true },\n \"\",\n window.location.origin + returnUrl,\n );\n \n // Dispara um evento para que o ReactRouter detecte\n window.dispatchEvent(new PopStateEvent(\"popstate\"));\n sessionStorage.removeItem(\n getSessionStoragePrefixCN(configurationName, \"return_url\"),\n );\n }\n }\n }, [\n config.redirectUri,\n configurationName,\n state.isAuthenticated,\n state.isLoading,\n ]);\n\n const handleLogin = useCallback(\n (redirectUri?: string) => {\n dispatch({\n type: \"SET_LOADING\",\n payload: true,\n });\n\n return (\n keycloakRef.current?.login({\n redirectUri: redirectUri ?? config.redirectUri,\n }) ?? Promise.reject()\n );\n },\n [config.redirectUri],\n );\n\n const handleLogout = useCallback(\n (redirectUriAfterLogout: string) => {\n dispatch({\n type: \"SET_LOADING\",\n payload: true,\n });\n\n ConfigurationStore.clearConfiguration(configurationName, config.realm);\n\n return (\n keycloakRef.current?.logout({\n redirectUri: redirectUriAfterLogout,\n }) ?? Promise.reject()\n );\n },\n [config.realm, configurationName],\n );\n\n // carregando > erro > sessão perdida > children\n\n const shouldRenderError =\n state?.error && !state.isLoading && AuthenticatingErrorComponent;\n\n const shouldRenderSessionLost =\n state.sessionLost &&\n !state.isLoading &&\n !state?.error &&\n SessionLostComponent;\n\n const shouldRenderChildren =\n !state.isLoading && !state.error && !state.sessionLost;\n\n return (\n <KeycloakContext.Provider\n value={{\n ...state,\n login: handleLogin,\n logout: handleLogout,\n }}\n >\n {shouldRenderChildren && children}\n\n {shouldRenderSessionLost && <SessionLostComponent />}\n\n {shouldRenderError && (\n <AuthenticatingErrorComponent error={state?.error} />\n )}\n\n {LoadingComponent && <LoadingComponent opened={state?.isLoading} />}\n </KeycloakContext.Provider>\n );\n};\n","export default class Logger {\n enabled: boolean = false;\n\n constructor(enabled: boolean = false) {\n this.enabled = enabled;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n log(...data: any[]) {\n if (this.enabled) {\n console.log(\"[react-keycloak-wrapper]\", ...data);\n }\n }\n\n setEnabled(enabled: boolean) {\n this.enabled = enabled;\n }\n}\n","type ConfigurationTokens = {\n idToken?: string;\n token?: string;\n refreshToken?: string;\n};\n\nfunction getConfigurationKey(name: string, realm: string) {\n return [\"keycloak\", realm, name].join(\".\");\n}\n\nexport default class ConfigurationStore {\n public static setConfiguration(\n name: string,\n realm: string,\n config: ConfigurationTokens,\n ): void {\n sessionStorage.setItem(\n getConfigurationKey(name, realm),\n JSON.stringify(config),\n );\n }\n\n public static getConfiguration(\n name: string,\n realm: string,\n ): ConfigurationTokens | object {\n const config = sessionStorage.getItem(getConfigurationKey(name, realm));\n return config ? (JSON.parse(config) as ConfigurationTokens) : {};\n }\n\n public static clearConfiguration(name: string, realm: string): void {\n sessionStorage.removeItem(getConfigurationKey(name, realm));\n }\n}\n","export function getSessionStoragePrefixCN(\n configurationName?: string,\n suffix = \"\",\n) {\n return [\"keycloak\", configurationName ?? \"default\", suffix]\n .filter(Boolean)\n .join(\"_\");\n}\n","import { createContext } from \"react\";\nimport { KeycloakContextValue } from \"../types\";\nimport { initialKeycloakContextValue } from \"./keycloak-reducer\";\n\nexport const KeycloakContext = createContext<KeycloakContextValue>(\n initialKeycloakContextValue,\n);\n","import { KeycloakError } from \"keycloak-js\";\nimport { KeycloakContextValue, KeycloakUser } from \"../types\";\n\ntype GenericAction<T extends string, P = undefined> = { type: T; payload: P };\n\nexport type KeycloakAction =\n | GenericAction<\"SET_CONFIGURATION_NAME\", string>\n | GenericAction<\n \"SET_TOKEN\",\n {\n accessToken?: string;\n idToken?: string;\n refreshToken?: string;\n isAuthenticated?: boolean;\n }\n >\n | GenericAction<\"SET_LOADING\", boolean>\n | GenericAction<\"SET_ERROR\", Error | KeycloakError | null>\n | GenericAction<\"SET_SESSION_LOST\", boolean>\n | GenericAction<\"SET_USER_INFO\", KeycloakUser | null>;\n\nexport const initialKeycloakContextValue: KeycloakContextValue = {\n error: null,\n isAuthenticated: false,\n isLoading: true,\n sessionLost: false,\n login: () => Promise.reject(new Error(\"Not implemented\")),\n logout: () => Promise.reject(new Error(\"Not implemented\")),\n userInfo: null,\n configurationName: undefined,\n};\n\nexport function keycloakReducer(\n state: KeycloakContextValue,\n action: KeycloakAction,\n): KeycloakContextValue {\n switch (action.type) {\n case \"SET_CONFIGURATION_NAME\":\n return {\n ...state,\n configurationName: action.payload,\n };\n case \"SET_TOKEN\":\n return {\n ...state,\n accessToken: action.payload.accessToken,\n refreshToken: action.payload.refreshToken,\n idToken: action.payload.idToken,\n isAuthenticated:\n action.payload.isAuthenticated ?? state.isAuthenticated,\n };\n case \"SET_LOADING\":\n return {\n ...state,\n isLoading: action.payload,\n };\n case \"SET_ERROR\":\n return {\n ...state,\n error:\n !action.payload || action.payload instanceof Error\n ? action.payload\n : new Error(\n String(\n action.payload.error || action.payload.error_description,\n ),\n ),\n };\n case \"SET_SESSION_LOST\":\n return {\n ...state,\n sessionLost: action.payload,\n };\n case \"SET_USER_INFO\":\n return {\n ...state,\n userInfo: action.payload,\n };\n\n default:\n return state;\n }\n}\n","import { useContext } from \"react\";\nimport { KeycloakContext } from \"../provider/keycloak-context\";\n\nexport function useKeycloak() {\n const ctx = useContext(KeycloakContext);\n\n return {\n login: ctx.login,\n logout: ctx.logout,\n isLoading: ctx.isLoading,\n isAuthenticated: ctx.isAuthenticated,\n configurationName: ctx.configurationName,\n };\n}\n","import React from \"react\";\nimport { useKeycloak } from \"../hooks/useKeycloak\";\nimport { getSessionStoragePrefixCN } from \"../utils/constants\";\n\nexport const KeycloakSecure: React.FC<React.PropsWithChildren> = ({\n children,\n}) => {\n const { isAuthenticated, login, isLoading, configurationName } =\n useKeycloak();\n\n if (isLoading) return null;\n\n if (!isAuthenticated) {\n // Salva a URL atual antes de redirecionar\n sessionStorage.setItem(\n getSessionStoragePrefixCN(configurationName, \"return_url\"),\n window.location.pathname + window.location.search,\n );\n\n // Redireciona para o Keycloak com callback fixo\n login(); // Usa o redirectUri configurado (ex: /authorization)\n return null;\n }\n\n return children;\n};\n","import { useContext } from \"react\";\nimport { KeycloakContext } from \"../provider/keycloak-context\";\nimport { KeycloakUser } from \"../types\";\n\nexport function useKeycloakUser<UserInfo = KeycloakUser>() {\n const ctx = useContext(KeycloakContext);\n\n return {\n user: ctx?.userInfo as UserInfo | null,\n isLoading: ctx?.isLoading,\n };\n}\n","import { useContext } from \"react\";\nimport { KeycloakContext } from \"../provider/keycloak-context\";\n\nexport function useKeycloakToken() {\n const ctx = useContext(KeycloakContext);\n\n return {\n accessToken: ctx.accessToken,\n idToken: ctx.idToken,\n };\n}\n"],"mappings":";AAAA,OAAO,cAAc;AACrB;AAAA,EAGE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACRP,IAAqB,SAArB,MAA4B;AAAA,EAG1B,YAAY,UAAmB,OAAO;AAFtC,mBAAmB;AAGjB,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA,EAGA,OAAO,MAAa;AAClB,QAAI,KAAK,SAAS;AAChB,cAAQ,IAAI,4BAA4B,GAAG,IAAI;AAAA,IACjD;AAAA,EACF;AAAA,EAEA,WAAW,SAAkB;AAC3B,SAAK,UAAU;AAAA,EACjB;AACF;;;ACXA,SAAS,oBAAoB,MAAc,OAAe;AACxD,SAAO,CAAC,YAAY,OAAO,IAAI,EAAE,KAAK,GAAG;AAC3C;AAEA,IAAqB,qBAArB,MAAwC;AAAA,EACtC,OAAc,iBACZ,MACA,OACA,QACM;AACN,mBAAe;AAAA,MACb,oBAAoB,MAAM,KAAK;AAAA,MAC/B,KAAK,UAAU,MAAM;AAAA,IACvB;AAAA,EACF;AAAA,EAEA,OAAc,iBACZ,MACA,OAC8B;AAC9B,UAAM,SAAS,eAAe,QAAQ,oBAAoB,MAAM,KAAK,CAAC;AACtE,WAAO,SAAU,KAAK,MAAM,MAAM,IAA4B,CAAC;AAAA,EACjE;AAAA,EAEA,OAAc,mBAAmB,MAAc,OAAqB;AAClE,mBAAe,WAAW,oBAAoB,MAAM,KAAK,CAAC;AAAA,EAC5D;AACF;;;ACjCO,SAAS,0BACd,mBACA,SAAS,IACT;AACA,SAAO,CAAC,YAAY,qBAAqB,WAAW,MAAM,EACvD,OAAO,OAAO,EACd,KAAK,GAAG;AACb;;;ACPA,SAAS,qBAAqB;;;ACqBvB,IAAM,8BAAoD;AAAA,EAC/D,OAAO;AAAA,EACP,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,aAAa;AAAA,EACb,OAAO,MAAM,QAAQ,OAAO,IAAI,MAAM,iBAAiB,CAAC;AAAA,EACxD,QAAQ,MAAM,QAAQ,OAAO,IAAI,MAAM,iBAAiB,CAAC;AAAA,EACzD,UAAU;AAAA,EACV,mBAAmB;AACrB;AAEO,SAAS,gBACd,OACA,QACsB;AACtB,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO;AAAA,QACL,GAAG;AAAA,QACH,mBAAmB,OAAO;AAAA,MAC5B;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,GAAG;AAAA,QACH,aAAa,OAAO,QAAQ;AAAA,QAC5B,cAAc,OAAO,QAAQ;AAAA,QAC7B,SAAS,OAAO,QAAQ;AAAA,QACxB,iBACE,OAAO,QAAQ,mBAAmB,MAAM;AAAA,MAC5C;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,OAAO;AAAA,MACpB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,GAAG;AAAA,QACH,OACE,CAAC,OAAO,WAAW,OAAO,mBAAmB,QACzC,OAAO,UACP,IAAI;AAAA,UACF;AAAA,YACE,OAAO,QAAQ,SAAS,OAAO,QAAQ;AAAA,UACzC;AAAA,QACF;AAAA,MACR;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,GAAG;AAAA,QACH,aAAa,OAAO;AAAA,MACtB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU,OAAO;AAAA,MACnB;AAAA,IAEF;AACE,aAAO;AAAA,EACX;AACF;;;AD9EO,IAAM,kBAAkB;AAAA,EAC7B;AACF;;;AJiUI,SAS8B,KAT9B;AAxSJ,IAAM,SAAS,IAAI,OAAO,KAAK;AACxB,IAAM,mBAAoC,CAAC;AAAA,EAChD,oBAAoB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,SAAO,WAAW,CAAC,WAAW,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC;AAE7D,QAAM,cAAc,OAAiB;AACrC,QAAM,aAAa,OAAuB;AAE1C,QAAM,CAAC,OAAO,QAAQ,IAAI;AAAA,IACxB;AAAA,IACA;AAAA,EACF;AAEA,QAAM,sBAAsB,YAAY,MAAM;AAC5C,QAAI,CAAC,YAAY,QAAS;AAE1B,gBAAY,QAAQ,UAAU,CAAC,kBAAkB;AAC/C,aAAO,IAAI,qBAAqB,EAAE,cAAc,CAAC;AAEjD,UAAI,CAAC,eAAe;AAClB,iBAAS;AAAA,UACP,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF;AAEA,gBAAY,QAAQ,gBAAgB,MAAM;AACxC,aAAO,IAAI,2BAA2B;AAEtC,yBAAmB,iBAAiB,mBAAmB,OAAO,OAAO;AAAA,QACnE,OAAO,YAAY,SAAS;AAAA,QAC5B,cAAc,YAAY,SAAS;AAAA,QACnC,SAAS,YAAY,SAAS;AAAA,MAChC,CAAC;AAED,eAAS;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,UACP,iBAAiB;AAAA,UACjB,aAAa,YAAY,SAAS;AAAA,UAClC,cAAc,YAAY,SAAS;AAAA,UACnC,SAAS,YAAY,SAAS;AAAA,QAChC;AAAA,MACF,CAAC;AAED,aAAO,IAAI,mBAAmB;AAC9B,kBAAY,SACR,aAAa,EACd,KAAK,CAAC,aAAa;AAClB,eAAO,IAAI,oBAAoB,EAAE,SAAS,CAAC;AAC3C,iBAAS;AAAA,UACP,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AAAA,MACH,CAAC,EACA,QAAQ,MAAM;AACb,iBAAS;AAAA,UACP,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AAAA,MACH,CAAC;AAEH,iBAAW,UAAU;AAAA,QACnB,MAAM;AACJ,sBAAY,SACR,YAAY,OAAO,oCAAoC,GAAG,EAC3D,KAAK,CAAC,cAAc;AACnB,gBAAI,CAAC,WAAW;AACd,qBAAO;AAAA,gBACL;AAAA,gBACA,IAAI;AAAA,mBACD,YAAY,SAAS,aAAa,OAAO,KAAK;AAAA,gBACjD,EAAE,mBAAmB;AAAA,cACvB;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACL;AAAA,SACC,OAAO,iCAAiC,MAAM;AAAA,MACjD;AAAA,IACF;AAEA,gBAAY,QAAQ,eAAe,MAAM;AACvC,aAAO,IAAI,cAAc;AACzB,eAAS;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAEA,gBAAY,QAAQ,cAAc,CAAC,UAAU;AAC3C,aAAO,IAAI,wBAAwB,EAAE,MAAM,CAAC;AAE5C,eAAS;AAAA,QACP,MAAM;AAAA,QACN,SAAS,SAAS;AAAA,MACpB,CAAC;AAAA,IACH;AAEA,gBAAY,QAAQ,qBAAqB,MAAM;AAC7C,aAAO,IAAI,qBAAqB;AAEhC,eAAS;AAAA,QACP,MAAM;AAAA,QACN,SAAS,IAAI,MAAM,qBAAqB,KAAK;AAAA,MAC/C,CAAC;AAAA,IACH;AAEA,gBAAY,QAAQ,uBAAuB,MAAM;AAC/C,aAAO,IAAI,4BAA4B,YAAY,SAAS,KAAK;AAEjE,yBAAmB,iBAAiB,mBAAmB,OAAO,OAAO;AAAA,QACnE,OAAO,YAAY,SAAS;AAAA,QAC5B,cAAc,YAAY,SAAS;AAAA,QACnC,SAAS,YAAY,SAAS;AAAA,MAChC,CAAC;AAED,eAAS;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,UACP,iBAAiB;AAAA,UACjB,aAAa,YAAY,SAAS;AAAA,UAClC,cAAc,YAAY,SAAS;AAAA,UACnC,SAAS,YAAY,SAAS;AAAA,QAChC;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,GAAG;AAAA,IACD,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP;AAAA,EACF,CAAC;AAED,QAAM,mBAAmB,YAAY,MAAM;AACzC,QAAI,YAAY,WAAW,CAAC,YAAY,QAAQ,eAAe;AAC7D,kBAAY,QACT,KAAK;AAAA,QACJ,QAAQ;AAAA,QACR,kBAAkB;AAAA,QAClB,OAAO,OAAO;AAAA,QACd,eAAe,CAAC,YAAY,MAAM,EAAE,SAAS,WAAW,EAAE;AAAA,QAC1D,GAAG,mBAAmB;AAAA,UACpB;AAAA,UACA,OAAO;AAAA,QACT;AAAA,MACF,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,eAAO,IAAI,iCAAiC,EAAE,MAAM,CAAC;AACrD,iBAAS;AAAA,UACP,MAAM;AAAA,UACN,SAAS,SAAS;AAAA,QACpB,CAAC;AACD,iBAAS;AAAA,UACP,MAAM;AAAA,UACN,SAAS;AAAA,QACX,CAAC;AAAA,MACH,CAAC;AAAA,IACL,WAAW,CAAC,YAAY,SAAS;AAC/B,kBAAY,UAAU,IAAI,SAAS;AAAA,QACjC,KAAK,OAAO;AAAA,QACZ,OAAO,OAAO;AAAA,QACd,UAAU,OAAO;AAAA,QACjB,cAAc,OAAO;AAAA,MACvB,CAAC;AAED,0BAAoB;AAEpB,eAAS;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,MACX,CAAC;AAED,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AAAA,IACD,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,kBAAgB,MAAM;AACpB,qBAAiB;AAEjB,WAAO,MAAM;AACX,UACE,YAAY,SAAS,iBACrB,YAAY,QAAQ,iBACpB,WAAW,YAAY,QACvB;AACA,eAAO,IAAI,oCAAoC;AAC/C,sBAAc,WAAW,OAAO;AAChC,mBAAW,UAAU;AAAA,MACvB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,gBAAgB,CAAC;AAErB,kBAAgB,MAAM;AACpB,QACE,CAAC,MAAM,aACP,MAAM,mBACN,OAAO,eACP,OAAO,SAAS,KAAK,WAAW,OAAO,WAAW,GAClD;AACA,YAAM,YACJ,eAAe;AAAA,QACb,0BAA0B,mBAAmB,YAAY;AAAA,MAC3D,KAAK;AACP,UAAI,CAAC,OAAO,SAAS,KAAK,SAAS,SAAS,GAAG;AAC7C,eAAO,IAAI,iEAAwD;AAAA,UACjE;AAAA,UACA,QAAQ,OAAO,SAAS;AAAA,QAC1B,CAAC;AAGD,eAAO,QAAQ;AAAA,UACb,EAAE,qBAAqB,KAAK;AAAA,UAC5B;AAAA,UACA,OAAO,SAAS,SAAS;AAAA,QAC3B;AAGA,eAAO,cAAc,IAAI,cAAc,UAAU,CAAC;AAClD,uBAAe;AAAA,UACb,0BAA0B,mBAAmB,YAAY;AAAA,QAC3D;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG;AAAA,IACD,OAAO;AAAA,IACP;AAAA,IACA,MAAM;AAAA,IACN,MAAM;AAAA,EACR,CAAC;AAED,QAAM,cAAc;AAAA,IAClB,CAAC,gBAAyB;AACxB,eAAS;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,MACX,CAAC;AAED,aACE,YAAY,SAAS,MAAM;AAAA,QACzB,aAAa,eAAe,OAAO;AAAA,MACrC,CAAC,KAAK,QAAQ,OAAO;AAAA,IAEzB;AAAA,IACA,CAAC,OAAO,WAAW;AAAA,EACrB;AAEA,QAAM,eAAe;AAAA,IACnB,CAAC,2BAAmC;AAClC,eAAS;AAAA,QACP,MAAM;AAAA,QACN,SAAS;AAAA,MACX,CAAC;AAED,yBAAmB,mBAAmB,mBAAmB,OAAO,KAAK;AAErE,aACE,YAAY,SAAS,OAAO;AAAA,QAC1B,aAAa;AAAA,MACf,CAAC,KAAK,QAAQ,OAAO;AAAA,IAEzB;AAAA,IACA,CAAC,OAAO,OAAO,iBAAiB;AAAA,EAClC;AAIA,QAAM,oBACJ,OAAO,SAAS,CAAC,MAAM,aAAa;AAEtC,QAAM,0BACJ,MAAM,eACN,CAAC,MAAM,aACP,CAAC,OAAO,SACR;AAEF,QAAM,uBACJ,CAAC,MAAM,aAAa,CAAC,MAAM,SAAS,CAAC,MAAM;AAE7C,SACE;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,QACH,OAAO;AAAA,QACP,QAAQ;AAAA,MACV;AAAA,MAEC;AAAA,gCAAwB;AAAA,QAExB,2BAA2B,oBAAC,wBAAqB;AAAA,QAEjD,qBACC,oBAAC,gCAA6B,OAAO,OAAO,OAAO;AAAA,QAGpD,oBAAoB,oBAAC,oBAAiB,QAAQ,OAAO,WAAW;AAAA;AAAA;AAAA,EACnE;AAEJ;;;AMzVA,SAAS,kBAAkB;AAGpB,SAAS,cAAc;AAC5B,QAAM,MAAM,WAAW,eAAe;AAEtC,SAAO;AAAA,IACL,OAAO,IAAI;AAAA,IACX,QAAQ,IAAI;AAAA,IACZ,WAAW,IAAI;AAAA,IACf,iBAAiB,IAAI;AAAA,IACrB,mBAAmB,IAAI;AAAA,EACzB;AACF;;;ACTO,IAAM,iBAAoD,CAAC;AAAA,EAChE;AACF,MAAM;AACJ,QAAM,EAAE,iBAAiB,OAAO,WAAW,kBAAkB,IAC3D,YAAY;AAEd,MAAI,UAAW,QAAO;AAEtB,MAAI,CAAC,iBAAiB;AAEpB,mBAAe;AAAA,MACb,0BAA0B,mBAAmB,YAAY;AAAA,MACzD,OAAO,SAAS,WAAW,OAAO,SAAS;AAAA,IAC7C;AAGA,UAAM;AACN,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;ACzBA,SAAS,cAAAA,mBAAkB;AAIpB,SAAS,kBAA2C;AACzD,QAAM,MAAMC,YAAW,eAAe;AAEtC,SAAO;AAAA,IACL,MAAM,KAAK;AAAA,IACX,WAAW,KAAK;AAAA,EAClB;AACF;;;ACXA,SAAS,cAAAC,mBAAkB;AAGpB,SAAS,mBAAmB;AACjC,QAAM,MAAMC,YAAW,eAAe;AAEtC,SAAO;AAAA,IACL,aAAa,IAAI;AAAA,IACjB,SAAS,IAAI;AAAA,EACf;AACF;","names":["useContext","useContext","useContext","useContext"]}
|