@pubflow/react 0.2.0 → 0.3.1
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.cjs +276 -238
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +276 -239
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -209,64 +209,36 @@ const PubflowContext = React.createContext({
|
|
|
209
209
|
defaultInstance: 'default'
|
|
210
210
|
});
|
|
211
211
|
/**
|
|
212
|
-
* Pubflow
|
|
212
|
+
* Pubflow Provider Component
|
|
213
213
|
*/
|
|
214
|
-
function PubflowProvider({ children, config, instances, defaultInstance = 'default',
|
|
215
|
-
const [isInitialized, setIsInitialized] = React.useState(false);
|
|
214
|
+
function PubflowProvider({ children, config, instances, defaultInstance = 'default', enableDebugTools = false, showSessionAlerts = false, persistentCache = { enabled: false }, theme = {}, loginRedirectPath = '/login', publicPaths = [] }) {
|
|
216
215
|
const [contextValue, setContextValue] = React.useState({
|
|
217
216
|
instances: {},
|
|
218
217
|
defaultInstance
|
|
219
218
|
});
|
|
220
|
-
//
|
|
221
|
-
React.useEffect(() => {
|
|
222
|
-
if (enableDebugTools) {
|
|
223
|
-
console.log('Pubflow debug tools enabled');
|
|
224
|
-
// Add debug utilities to window object
|
|
225
|
-
if (typeof window !== 'undefined') {
|
|
226
|
-
window.pubflowDebug = {
|
|
227
|
-
getInstances: () => contextValue.instances,
|
|
228
|
-
getDefaultInstance: () => contextValue.defaultInstance,
|
|
229
|
-
clearStorage: async () => {
|
|
230
|
-
const storage = new BrowserStorageAdapter();
|
|
231
|
-
await storage.removeItem('pubflow_session_id');
|
|
232
|
-
await storage.removeItem('pubflow_user_data');
|
|
233
|
-
console.log('Pubflow storage cleared');
|
|
234
|
-
},
|
|
235
|
-
loginRedirectPath,
|
|
236
|
-
publicPaths,
|
|
237
|
-
theme
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
}, [enableDebugTools, contextValue, loginRedirectPath, publicPaths, theme]);
|
|
242
|
-
// Handle session expiration
|
|
219
|
+
// Session handlers
|
|
243
220
|
const handleSessionExpired = React.useCallback(() => {
|
|
244
|
-
if (showSessionAlerts) {
|
|
245
|
-
|
|
246
|
-
}
|
|
247
|
-
if (onSessionExpired) {
|
|
248
|
-
onSessionExpired();
|
|
221
|
+
if (showSessionAlerts && typeof window !== 'undefined') {
|
|
222
|
+
console.warn('Session expired');
|
|
249
223
|
}
|
|
250
|
-
}, [
|
|
251
|
-
// Handle session refresh
|
|
224
|
+
}, [showSessionAlerts]);
|
|
252
225
|
const handleSessionRefreshed = React.useCallback(() => {
|
|
253
|
-
if (showSessionAlerts) {
|
|
254
|
-
|
|
255
|
-
}
|
|
256
|
-
if (onSessionRefreshed) {
|
|
257
|
-
onSessionRefreshed();
|
|
226
|
+
if (showSessionAlerts && typeof window !== 'undefined') {
|
|
227
|
+
console.log('Session refreshed');
|
|
258
228
|
}
|
|
259
|
-
}, [
|
|
229
|
+
}, [showSessionAlerts]);
|
|
230
|
+
// Initialize instances
|
|
260
231
|
React.useEffect(() => {
|
|
232
|
+
let isMounted = true;
|
|
261
233
|
const initialize = async () => {
|
|
262
234
|
var _a, _b;
|
|
263
235
|
try {
|
|
264
|
-
// Initialize instances
|
|
265
236
|
const instancesMap = {};
|
|
266
237
|
if (instances && instances.length > 0) {
|
|
267
238
|
// Initialize multiple instances
|
|
268
239
|
for (const instanceConfig of instances) {
|
|
269
|
-
|
|
240
|
+
if (!isMounted)
|
|
241
|
+
return;
|
|
270
242
|
const fullConfig = core.initConfig({
|
|
271
243
|
...instanceConfig,
|
|
272
244
|
sessionConfig: {
|
|
@@ -275,36 +247,24 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
275
247
|
onSessionRefreshed: handleSessionRefreshed
|
|
276
248
|
}
|
|
277
249
|
}, instanceConfig.id);
|
|
278
|
-
// Create storage adapter
|
|
279
250
|
const storage = new BrowserStorageAdapter({
|
|
280
251
|
prefix: (_a = fullConfig.storageConfig) === null || _a === void 0 ? void 0 : _a.prefix
|
|
281
252
|
});
|
|
282
|
-
// Create API client
|
|
283
253
|
const apiClient = new core.ApiClient(fullConfig, storage);
|
|
284
|
-
// Create auth service
|
|
285
254
|
const authService = new core.AuthService(apiClient, storage, fullConfig);
|
|
286
|
-
// Get current user
|
|
255
|
+
// Get current user (non-blocking)
|
|
287
256
|
let user = null;
|
|
288
257
|
let isAuthenticated = false;
|
|
289
|
-
try {
|
|
290
|
-
user = await authService.getCurrentUser();
|
|
291
|
-
isAuthenticated = !!user;
|
|
292
|
-
}
|
|
293
|
-
catch (error) {
|
|
294
|
-
console.error(`Error getting current user for instance ${instanceConfig.id}:`, error);
|
|
295
|
-
}
|
|
296
|
-
// Create instance
|
|
297
258
|
instancesMap[instanceConfig.id] = {
|
|
298
259
|
config: fullConfig,
|
|
299
260
|
apiClient,
|
|
300
261
|
authService,
|
|
301
262
|
user,
|
|
302
263
|
isAuthenticated,
|
|
303
|
-
isLoading:
|
|
264
|
+
isLoading: true,
|
|
304
265
|
login: async (credentials) => {
|
|
305
266
|
const result = await authService.login(credentials);
|
|
306
|
-
if (result.success && result.user) {
|
|
307
|
-
// Update instance
|
|
267
|
+
if (result.success && result.user && isMounted) {
|
|
308
268
|
setContextValue(prev => ({
|
|
309
269
|
...prev,
|
|
310
270
|
instances: {
|
|
@@ -312,7 +272,8 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
312
272
|
[instanceConfig.id]: {
|
|
313
273
|
...prev.instances[instanceConfig.id],
|
|
314
274
|
user: result.user,
|
|
315
|
-
isAuthenticated: true
|
|
275
|
+
isAuthenticated: true,
|
|
276
|
+
isLoading: false
|
|
316
277
|
}
|
|
317
278
|
}
|
|
318
279
|
}));
|
|
@@ -321,41 +282,74 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
321
282
|
},
|
|
322
283
|
logout: async () => {
|
|
323
284
|
await authService.logout();
|
|
324
|
-
|
|
285
|
+
if (isMounted) {
|
|
286
|
+
setContextValue(prev => ({
|
|
287
|
+
...prev,
|
|
288
|
+
instances: {
|
|
289
|
+
...prev.instances,
|
|
290
|
+
[instanceConfig.id]: {
|
|
291
|
+
...prev.instances[instanceConfig.id],
|
|
292
|
+
user: null,
|
|
293
|
+
isAuthenticated: false,
|
|
294
|
+
isLoading: false
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}));
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
validateSession: async () => {
|
|
301
|
+
const result = await authService.validateSession();
|
|
302
|
+
if (isMounted) {
|
|
303
|
+
setContextValue(prev => ({
|
|
304
|
+
...prev,
|
|
305
|
+
instances: {
|
|
306
|
+
...prev.instances,
|
|
307
|
+
[instanceConfig.id]: {
|
|
308
|
+
...prev.instances[instanceConfig.id],
|
|
309
|
+
user: result.user || null,
|
|
310
|
+
isAuthenticated: result.isValid,
|
|
311
|
+
isLoading: false
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}));
|
|
315
|
+
}
|
|
316
|
+
return result;
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
// Load user asynchronously
|
|
320
|
+
authService.getCurrentUser().then(currentUser => {
|
|
321
|
+
if (isMounted) {
|
|
325
322
|
setContextValue(prev => ({
|
|
326
323
|
...prev,
|
|
327
324
|
instances: {
|
|
328
325
|
...prev.instances,
|
|
329
326
|
[instanceConfig.id]: {
|
|
330
327
|
...prev.instances[instanceConfig.id],
|
|
331
|
-
user:
|
|
332
|
-
isAuthenticated:
|
|
328
|
+
user: currentUser,
|
|
329
|
+
isAuthenticated: !!currentUser,
|
|
330
|
+
isLoading: false
|
|
333
331
|
}
|
|
334
332
|
}
|
|
335
333
|
}));
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
// Update instance
|
|
334
|
+
}
|
|
335
|
+
}).catch(() => {
|
|
336
|
+
if (isMounted) {
|
|
340
337
|
setContextValue(prev => ({
|
|
341
338
|
...prev,
|
|
342
339
|
instances: {
|
|
343
340
|
...prev.instances,
|
|
344
341
|
[instanceConfig.id]: {
|
|
345
342
|
...prev.instances[instanceConfig.id],
|
|
346
|
-
|
|
347
|
-
isAuthenticated: result.isValid
|
|
343
|
+
isLoading: false
|
|
348
344
|
}
|
|
349
345
|
}
|
|
350
346
|
}));
|
|
351
|
-
return result;
|
|
352
347
|
}
|
|
353
|
-
};
|
|
348
|
+
});
|
|
354
349
|
}
|
|
355
350
|
}
|
|
356
351
|
else if (config) {
|
|
357
|
-
//
|
|
358
|
-
// Initialize configuration
|
|
352
|
+
// Single instance mode (simplified)
|
|
359
353
|
const fullConfig = core.initConfig({
|
|
360
354
|
...config,
|
|
361
355
|
sessionConfig: {
|
|
@@ -363,37 +357,22 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
363
357
|
onSessionExpired: handleSessionExpired,
|
|
364
358
|
onSessionRefreshed: handleSessionRefreshed
|
|
365
359
|
}
|
|
366
|
-
}, defaultInstance);
|
|
367
|
-
// Create storage adapter
|
|
360
|
+
}, config.id || defaultInstance);
|
|
368
361
|
const storage = new BrowserStorageAdapter({
|
|
369
362
|
prefix: (_b = fullConfig.storageConfig) === null || _b === void 0 ? void 0 : _b.prefix
|
|
370
363
|
});
|
|
371
|
-
// Create API client
|
|
372
364
|
const apiClient = new core.ApiClient(fullConfig, storage);
|
|
373
|
-
// Create auth service
|
|
374
365
|
const authService = new core.AuthService(apiClient, storage, fullConfig);
|
|
375
|
-
// Get current user
|
|
376
|
-
let user = null;
|
|
377
|
-
let isAuthenticated = false;
|
|
378
|
-
try {
|
|
379
|
-
user = await authService.getCurrentUser();
|
|
380
|
-
isAuthenticated = !!user;
|
|
381
|
-
}
|
|
382
|
-
catch (error) {
|
|
383
|
-
console.error('Error getting current user:', error);
|
|
384
|
-
}
|
|
385
|
-
// Create instance
|
|
386
366
|
instancesMap[defaultInstance] = {
|
|
387
367
|
config: fullConfig,
|
|
388
368
|
apiClient,
|
|
389
369
|
authService,
|
|
390
|
-
user,
|
|
391
|
-
isAuthenticated,
|
|
392
|
-
isLoading:
|
|
370
|
+
user: null,
|
|
371
|
+
isAuthenticated: false,
|
|
372
|
+
isLoading: true,
|
|
393
373
|
login: async (credentials) => {
|
|
394
374
|
const result = await authService.login(credentials);
|
|
395
|
-
if (result.success && result.user) {
|
|
396
|
-
// Update instance
|
|
375
|
+
if (result.success && result.user && isMounted) {
|
|
397
376
|
setContextValue(prev => ({
|
|
398
377
|
...prev,
|
|
399
378
|
instances: {
|
|
@@ -401,7 +380,8 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
401
380
|
[defaultInstance]: {
|
|
402
381
|
...prev.instances[defaultInstance],
|
|
403
382
|
user: result.user,
|
|
404
|
-
isAuthenticated: true
|
|
383
|
+
isAuthenticated: true,
|
|
384
|
+
isLoading: false
|
|
405
385
|
}
|
|
406
386
|
}
|
|
407
387
|
}));
|
|
@@ -410,61 +390,107 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
410
390
|
},
|
|
411
391
|
logout: async () => {
|
|
412
392
|
await authService.logout();
|
|
413
|
-
|
|
393
|
+
if (isMounted) {
|
|
394
|
+
setContextValue(prev => ({
|
|
395
|
+
...prev,
|
|
396
|
+
instances: {
|
|
397
|
+
...prev.instances,
|
|
398
|
+
[defaultInstance]: {
|
|
399
|
+
...prev.instances[defaultInstance],
|
|
400
|
+
user: null,
|
|
401
|
+
isAuthenticated: false,
|
|
402
|
+
isLoading: false
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}));
|
|
406
|
+
}
|
|
407
|
+
},
|
|
408
|
+
validateSession: async () => {
|
|
409
|
+
const result = await authService.validateSession();
|
|
410
|
+
if (isMounted) {
|
|
411
|
+
setContextValue(prev => ({
|
|
412
|
+
...prev,
|
|
413
|
+
instances: {
|
|
414
|
+
...prev.instances,
|
|
415
|
+
[defaultInstance]: {
|
|
416
|
+
...prev.instances[defaultInstance],
|
|
417
|
+
user: result.user || null,
|
|
418
|
+
isAuthenticated: result.isValid,
|
|
419
|
+
isLoading: false
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}));
|
|
423
|
+
}
|
|
424
|
+
return result;
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
// Load user asynchronously
|
|
428
|
+
authService.getCurrentUser().then(currentUser => {
|
|
429
|
+
if (isMounted) {
|
|
414
430
|
setContextValue(prev => ({
|
|
415
431
|
...prev,
|
|
416
432
|
instances: {
|
|
417
433
|
...prev.instances,
|
|
418
434
|
[defaultInstance]: {
|
|
419
435
|
...prev.instances[defaultInstance],
|
|
420
|
-
user:
|
|
421
|
-
isAuthenticated:
|
|
436
|
+
user: currentUser,
|
|
437
|
+
isAuthenticated: !!currentUser,
|
|
438
|
+
isLoading: false
|
|
422
439
|
}
|
|
423
440
|
}
|
|
424
441
|
}));
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
// Update instance
|
|
442
|
+
}
|
|
443
|
+
}).catch(() => {
|
|
444
|
+
if (isMounted) {
|
|
429
445
|
setContextValue(prev => ({
|
|
430
446
|
...prev,
|
|
431
447
|
instances: {
|
|
432
448
|
...prev.instances,
|
|
433
449
|
[defaultInstance]: {
|
|
434
450
|
...prev.instances[defaultInstance],
|
|
435
|
-
|
|
436
|
-
isAuthenticated: result.isValid
|
|
451
|
+
isLoading: false
|
|
437
452
|
}
|
|
438
453
|
}
|
|
439
454
|
}));
|
|
440
|
-
return result;
|
|
441
455
|
}
|
|
442
|
-
};
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
if (isMounted) {
|
|
459
|
+
setContextValue({
|
|
460
|
+
instances: instancesMap,
|
|
461
|
+
defaultInstance
|
|
462
|
+
});
|
|
443
463
|
}
|
|
444
|
-
// Set context value
|
|
445
|
-
setContextValue({
|
|
446
|
-
instances: instancesMap,
|
|
447
|
-
defaultInstance
|
|
448
|
-
});
|
|
449
|
-
// Set initialized
|
|
450
|
-
setIsInitialized(true);
|
|
451
464
|
}
|
|
452
465
|
catch (error) {
|
|
453
466
|
console.error('Error initializing Pubflow:', error);
|
|
454
467
|
}
|
|
455
468
|
};
|
|
456
469
|
initialize();
|
|
470
|
+
return () => {
|
|
471
|
+
isMounted = false;
|
|
472
|
+
};
|
|
457
473
|
}, [config, instances, defaultInstance, handleSessionExpired, handleSessionRefreshed]);
|
|
458
|
-
//
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
474
|
+
// Debug tools (simplified)
|
|
475
|
+
React.useEffect(() => {
|
|
476
|
+
if (enableDebugTools && typeof window !== 'undefined') {
|
|
477
|
+
window.pubflowDebug = {
|
|
478
|
+
getInstances: () => contextValue.instances,
|
|
479
|
+
getDefaultInstance: () => contextValue.defaultInstance
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
}, [enableDebugTools]);
|
|
483
|
+
// SWR configuration
|
|
484
|
+
const swrConfig = {
|
|
485
|
+
revalidateOnFocus: false,
|
|
486
|
+
revalidateOnReconnect: true,
|
|
487
|
+
...(persistentCache.enabled && {
|
|
488
|
+
provider: () => new Map(),
|
|
489
|
+
isOnline: () => true,
|
|
490
|
+
isVisible: () => true
|
|
491
|
+
})
|
|
492
|
+
};
|
|
493
|
+
return (jsxRuntime.jsx(PubflowContext.Provider, { value: contextValue, children: jsxRuntime.jsx(useSWR.SWRConfig, { value: swrConfig, children: children }) }));
|
|
468
494
|
}
|
|
469
495
|
|
|
470
496
|
/**
|
|
@@ -480,7 +506,6 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
480
506
|
*/
|
|
481
507
|
function useAuth(instanceId) {
|
|
482
508
|
const context = React.useContext(PubflowContext);
|
|
483
|
-
const [isLoading, setIsLoading] = React.useState(false);
|
|
484
509
|
if (!context) {
|
|
485
510
|
throw new Error('useAuth must be used within a PubflowProvider');
|
|
486
511
|
}
|
|
@@ -489,68 +514,14 @@ function useAuth(instanceId) {
|
|
|
489
514
|
if (!pubflowInstance) {
|
|
490
515
|
throw new Error(`Pubflow instance '${instance}' not found`);
|
|
491
516
|
}
|
|
492
|
-
// Wrap login to handle loading state
|
|
493
|
-
const login = React.useCallback(async (credentials) => {
|
|
494
|
-
setIsLoading(true);
|
|
495
|
-
try {
|
|
496
|
-
return await pubflowInstance.login(credentials);
|
|
497
|
-
}
|
|
498
|
-
finally {
|
|
499
|
-
setIsLoading(false);
|
|
500
|
-
}
|
|
501
|
-
}, [pubflowInstance]);
|
|
502
|
-
// Wrap logout to handle loading state
|
|
503
|
-
const logout = React.useCallback(async () => {
|
|
504
|
-
setIsLoading(true);
|
|
505
|
-
try {
|
|
506
|
-
await pubflowInstance.logout();
|
|
507
|
-
}
|
|
508
|
-
finally {
|
|
509
|
-
setIsLoading(false);
|
|
510
|
-
}
|
|
511
|
-
}, [pubflowInstance]);
|
|
512
|
-
// Wrap validateSession to handle loading state
|
|
513
|
-
const validateSession = React.useCallback(async () => {
|
|
514
|
-
setIsLoading(true);
|
|
515
|
-
try {
|
|
516
|
-
return await pubflowInstance.validateSession();
|
|
517
|
-
}
|
|
518
|
-
finally {
|
|
519
|
-
setIsLoading(false);
|
|
520
|
-
}
|
|
521
|
-
}, [pubflowInstance]);
|
|
522
|
-
// Add refreshUser function to manually refresh user data
|
|
523
|
-
const refreshUser = React.useCallback(async () => {
|
|
524
|
-
setIsLoading(true);
|
|
525
|
-
try {
|
|
526
|
-
const result = await pubflowInstance.validateSession();
|
|
527
|
-
return result.user || null;
|
|
528
|
-
}
|
|
529
|
-
finally {
|
|
530
|
-
setIsLoading(false);
|
|
531
|
-
}
|
|
532
|
-
}, [pubflowInstance]);
|
|
533
|
-
// Validate session on mount
|
|
534
|
-
React.useEffect(() => {
|
|
535
|
-
const validate = async () => {
|
|
536
|
-
try {
|
|
537
|
-
await validateSession();
|
|
538
|
-
}
|
|
539
|
-
catch (error) {
|
|
540
|
-
console.error('Error validating session:', error);
|
|
541
|
-
}
|
|
542
|
-
};
|
|
543
|
-
validate();
|
|
544
|
-
}, [validateSession]);
|
|
545
517
|
return {
|
|
546
518
|
// Ensure user is never undefined
|
|
547
519
|
user: pubflowInstance.user || null,
|
|
548
520
|
isAuthenticated: pubflowInstance.isAuthenticated,
|
|
549
|
-
isLoading,
|
|
550
|
-
login,
|
|
551
|
-
logout,
|
|
552
|
-
validateSession
|
|
553
|
-
refreshUser
|
|
521
|
+
isLoading: pubflowInstance.isLoading,
|
|
522
|
+
login: pubflowInstance.login,
|
|
523
|
+
logout: pubflowInstance.logout,
|
|
524
|
+
validateSession: pubflowInstance.validateSession
|
|
554
525
|
};
|
|
555
526
|
}
|
|
556
527
|
|
|
@@ -9560,6 +9531,131 @@ function createStyles(theme) {
|
|
|
9560
9531
|
};
|
|
9561
9532
|
}
|
|
9562
9533
|
|
|
9534
|
+
/**
|
|
9535
|
+
* Authentication Guard Hook for React
|
|
9536
|
+
*
|
|
9537
|
+
* Framework-agnostic hook for handling authentication validation and redirects
|
|
9538
|
+
*/
|
|
9539
|
+
/**
|
|
9540
|
+
* Hook for handling authentication validation and redirects
|
|
9541
|
+
*
|
|
9542
|
+
* This hook is framework-agnostic and requires the user to provide
|
|
9543
|
+
* their own redirect function (e.g., Next.js router, React Router, etc.)
|
|
9544
|
+
*
|
|
9545
|
+
* @param options Hook options
|
|
9546
|
+
* @returns Authentication guard result
|
|
9547
|
+
*/
|
|
9548
|
+
function useAuthGuard({ validateOnMount = true, allowedTypes = ['authenticated'], instanceId, onRedirect, onSessionExpired, loginRedirectPath = '/login', accessDeniedPath = '/access-denied', enableLogging = false } = {}) {
|
|
9549
|
+
const { user, isAuthenticated, isLoading, validateSession } = useAuth(instanceId);
|
|
9550
|
+
// Check if user is authorized based on user type
|
|
9551
|
+
const isAuthorized = React.useCallback(() => {
|
|
9552
|
+
if (!isAuthenticated || !user) {
|
|
9553
|
+
return false;
|
|
9554
|
+
}
|
|
9555
|
+
// If allowedTypes includes 'authenticated', any authenticated user is allowed
|
|
9556
|
+
if (allowedTypes.includes('authenticated')) {
|
|
9557
|
+
return true;
|
|
9558
|
+
}
|
|
9559
|
+
// Check specific user types
|
|
9560
|
+
const userType = user.userType || user.user_type || '';
|
|
9561
|
+
return allowedTypes.some(type => type.toLowerCase() === userType.toLowerCase());
|
|
9562
|
+
}, [isAuthenticated, user, allowedTypes]);
|
|
9563
|
+
const authorized = isAuthorized();
|
|
9564
|
+
// Determine redirect reason
|
|
9565
|
+
const getRedirectReason = React.useCallback(() => {
|
|
9566
|
+
if (isLoading) {
|
|
9567
|
+
return null;
|
|
9568
|
+
}
|
|
9569
|
+
if (!isAuthenticated) {
|
|
9570
|
+
return 'unauthenticated';
|
|
9571
|
+
}
|
|
9572
|
+
if (!authorized) {
|
|
9573
|
+
return 'unauthorized';
|
|
9574
|
+
}
|
|
9575
|
+
return null;
|
|
9576
|
+
}, [isLoading, isAuthenticated, authorized]);
|
|
9577
|
+
const redirectReason = getRedirectReason();
|
|
9578
|
+
// Validate session on mount
|
|
9579
|
+
React.useEffect(() => {
|
|
9580
|
+
if (validateOnMount && isAuthenticated) {
|
|
9581
|
+
validateSession().then(({ isValid }) => {
|
|
9582
|
+
if (!isValid) {
|
|
9583
|
+
if (enableLogging) {
|
|
9584
|
+
console.warn('useAuthGuard: Session validation failed');
|
|
9585
|
+
}
|
|
9586
|
+
// Call session expired handler
|
|
9587
|
+
if (onSessionExpired) {
|
|
9588
|
+
onSessionExpired();
|
|
9589
|
+
}
|
|
9590
|
+
// Redirect to login
|
|
9591
|
+
if (onRedirect) {
|
|
9592
|
+
onRedirect(loginRedirectPath, 'session-expired');
|
|
9593
|
+
}
|
|
9594
|
+
}
|
|
9595
|
+
}).catch(error => {
|
|
9596
|
+
if (enableLogging) {
|
|
9597
|
+
console.error('useAuthGuard: Session validation error:', error);
|
|
9598
|
+
}
|
|
9599
|
+
});
|
|
9600
|
+
}
|
|
9601
|
+
}, [validateOnMount, isAuthenticated, validateSession, onSessionExpired, onRedirect, loginRedirectPath, enableLogging]);
|
|
9602
|
+
// Handle authentication redirects
|
|
9603
|
+
React.useEffect(() => {
|
|
9604
|
+
if (isLoading || !onRedirect) {
|
|
9605
|
+
return;
|
|
9606
|
+
}
|
|
9607
|
+
if (!isAuthenticated) {
|
|
9608
|
+
if (enableLogging) {
|
|
9609
|
+
console.warn('useAuthGuard: User not authenticated, redirecting to login');
|
|
9610
|
+
}
|
|
9611
|
+
onRedirect(loginRedirectPath, 'unauthenticated');
|
|
9612
|
+
return;
|
|
9613
|
+
}
|
|
9614
|
+
if (!authorized) {
|
|
9615
|
+
if (enableLogging) {
|
|
9616
|
+
console.warn('useAuthGuard: User not authorized for this page, redirecting to access denied');
|
|
9617
|
+
}
|
|
9618
|
+
onRedirect(accessDeniedPath, 'unauthorized');
|
|
9619
|
+
return;
|
|
9620
|
+
}
|
|
9621
|
+
}, [isLoading, isAuthenticated, authorized, onRedirect, loginRedirectPath, accessDeniedPath, enableLogging]);
|
|
9622
|
+
return {
|
|
9623
|
+
user,
|
|
9624
|
+
isAuthenticated,
|
|
9625
|
+
isLoading,
|
|
9626
|
+
isAuthorized: authorized,
|
|
9627
|
+
validateSession,
|
|
9628
|
+
redirectReason
|
|
9629
|
+
};
|
|
9630
|
+
}
|
|
9631
|
+
/**
|
|
9632
|
+
* Simple authentication guard hook with automatic redirects
|
|
9633
|
+
*
|
|
9634
|
+
* This is a simplified version that uses window.location for redirects
|
|
9635
|
+
* Suitable for simple React apps without complex routing
|
|
9636
|
+
*
|
|
9637
|
+
* @param options Hook options
|
|
9638
|
+
* @returns Authentication guard result
|
|
9639
|
+
*/
|
|
9640
|
+
function useSimpleAuthGuard(options = {}) {
|
|
9641
|
+
var _a;
|
|
9642
|
+
const handleRedirect = React.useCallback((path, reason) => {
|
|
9643
|
+
if (typeof window !== 'undefined') {
|
|
9644
|
+
// Add current path as redirect parameter
|
|
9645
|
+
const currentPath = window.location.pathname + window.location.search;
|
|
9646
|
+
const redirectUrl = reason === 'unauthenticated'
|
|
9647
|
+
? `${path}?redirect=${encodeURIComponent(currentPath)}`
|
|
9648
|
+
: path;
|
|
9649
|
+
window.location.href = redirectUrl;
|
|
9650
|
+
}
|
|
9651
|
+
}, []);
|
|
9652
|
+
return useAuthGuard({
|
|
9653
|
+
...options,
|
|
9654
|
+
onRedirect: handleRedirect,
|
|
9655
|
+
enableLogging: (_a = options.enableLogging) !== null && _a !== void 0 ? _a : true
|
|
9656
|
+
});
|
|
9657
|
+
}
|
|
9658
|
+
|
|
9563
9659
|
/**
|
|
9564
9660
|
* Bridge API Raw Hook for React
|
|
9565
9661
|
*
|
|
@@ -9639,65 +9735,6 @@ function useBridgeApiRaw(instanceId) {
|
|
|
9639
9735
|
};
|
|
9640
9736
|
}
|
|
9641
9737
|
|
|
9642
|
-
/**
|
|
9643
|
-
* Server Authentication Hook for React
|
|
9644
|
-
*
|
|
9645
|
-
* Provides a hook for handling authentication with automatic redirects
|
|
9646
|
-
*/
|
|
9647
|
-
/**
|
|
9648
|
-
* Hook for handling authentication with automatic redirects
|
|
9649
|
-
*
|
|
9650
|
-
* @param options Hook options
|
|
9651
|
-
* @returns Authentication hook result
|
|
9652
|
-
*/
|
|
9653
|
-
function useServerAuth({ loginRedirectPath = '/login', allowedTypes = ['authenticated'], validateOnMount = true, instanceId, onRedirect } = {}) {
|
|
9654
|
-
const { user, isAuthenticated, isLoading, validateSession } = useAuth(instanceId);
|
|
9655
|
-
// Default redirect function
|
|
9656
|
-
const defaultRedirect = (path) => {
|
|
9657
|
-
if (typeof window !== 'undefined') {
|
|
9658
|
-
const currentPath = window.location.pathname;
|
|
9659
|
-
const redirectUrl = `${path}?redirect=${encodeURIComponent(currentPath)}`;
|
|
9660
|
-
window.location.href = redirectUrl;
|
|
9661
|
-
}
|
|
9662
|
-
};
|
|
9663
|
-
const redirect = onRedirect || defaultRedirect;
|
|
9664
|
-
React.useEffect(() => {
|
|
9665
|
-
// Validate session on mount if configured
|
|
9666
|
-
if (validateOnMount) {
|
|
9667
|
-
validateSession().then(({ isValid }) => {
|
|
9668
|
-
if (!isValid) {
|
|
9669
|
-
redirect(loginRedirectPath);
|
|
9670
|
-
}
|
|
9671
|
-
});
|
|
9672
|
-
}
|
|
9673
|
-
}, [validateOnMount, loginRedirectPath, validateSession, redirect]);
|
|
9674
|
-
React.useEffect(() => {
|
|
9675
|
-
// Skip if still loading
|
|
9676
|
-
if (isLoading) {
|
|
9677
|
-
return;
|
|
9678
|
-
}
|
|
9679
|
-
// Redirect if not authenticated
|
|
9680
|
-
if (!isAuthenticated) {
|
|
9681
|
-
redirect(loginRedirectPath);
|
|
9682
|
-
return;
|
|
9683
|
-
}
|
|
9684
|
-
// Check user type if allowedTypes doesn't include 'authenticated'
|
|
9685
|
-
if (!allowedTypes.includes('authenticated') && user) {
|
|
9686
|
-
const userType = user.userType || '';
|
|
9687
|
-
const isAllowed = allowedTypes.some(type => type.toLowerCase() === userType.toLowerCase());
|
|
9688
|
-
if (!isAllowed) {
|
|
9689
|
-
redirect('/access-denied');
|
|
9690
|
-
}
|
|
9691
|
-
}
|
|
9692
|
-
}, [isLoading, isAuthenticated, user, allowedTypes, loginRedirectPath, redirect]);
|
|
9693
|
-
return {
|
|
9694
|
-
user,
|
|
9695
|
-
isAuthenticated,
|
|
9696
|
-
isLoading,
|
|
9697
|
-
validateSession
|
|
9698
|
-
};
|
|
9699
|
-
}
|
|
9700
|
-
|
|
9701
9738
|
/**
|
|
9702
9739
|
* Search Query Builder Hook for React
|
|
9703
9740
|
*
|
|
@@ -9935,6 +9972,7 @@ exports.ThemeProvider = ThemeProvider;
|
|
|
9935
9972
|
exports.createStyles = createStyles;
|
|
9936
9973
|
exports.generateCSSVariables = generateCSSVariables;
|
|
9937
9974
|
exports.useAuth = useAuth;
|
|
9975
|
+
exports.useAuthGuard = useAuthGuard;
|
|
9938
9976
|
exports.useBridgeApi = useBridgeApi;
|
|
9939
9977
|
exports.useBridgeApiRaw = useBridgeApiRaw;
|
|
9940
9978
|
exports.useBridgeCrud = useBridgeCrud;
|
|
@@ -9943,7 +9981,7 @@ exports.useBridgeQuery = useBridgeQuery;
|
|
|
9943
9981
|
exports.useNetworkStatus = useNetworkStatus;
|
|
9944
9982
|
exports.useRequireAuth = useRequireAuth;
|
|
9945
9983
|
exports.useSearchQueryBuilder = useSearchQueryBuilder;
|
|
9946
|
-
exports.
|
|
9984
|
+
exports.useSimpleAuthGuard = useSimpleAuthGuard;
|
|
9947
9985
|
exports.useTheme = useTheme;
|
|
9948
9986
|
Object.keys(core).forEach(function (k) {
|
|
9949
9987
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|