@pubflow/react 0.2.1 → 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 +271 -256
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +271 -257
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -209,67 +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]); // ✅ OPTIMIZED: Only enableDebugTools as dependency
|
|
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
|
-
|
|
226
|
+
if (showSessionAlerts && typeof window !== 'undefined') {
|
|
227
|
+
console.log('Session refreshed');
|
|
255
228
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
}
|
|
259
|
-
}, [onSessionRefreshed, showSessionAlerts]);
|
|
229
|
+
}, [showSessionAlerts]);
|
|
230
|
+
// Initialize instances
|
|
260
231
|
React.useEffect(() => {
|
|
261
232
|
let isMounted = true;
|
|
262
233
|
const initialize = async () => {
|
|
263
234
|
var _a, _b;
|
|
264
235
|
try {
|
|
265
|
-
// Initialize instances
|
|
266
236
|
const instancesMap = {};
|
|
267
237
|
if (instances && instances.length > 0) {
|
|
268
238
|
// Initialize multiple instances
|
|
269
239
|
for (const instanceConfig of instances) {
|
|
270
240
|
if (!isMounted)
|
|
271
|
-
return;
|
|
272
|
-
// Initialize configuration
|
|
241
|
+
return;
|
|
273
242
|
const fullConfig = core.initConfig({
|
|
274
243
|
...instanceConfig,
|
|
275
244
|
sessionConfig: {
|
|
@@ -278,38 +247,21 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
278
247
|
onSessionRefreshed: handleSessionRefreshed
|
|
279
248
|
}
|
|
280
249
|
}, instanceConfig.id);
|
|
281
|
-
// Create storage adapter
|
|
282
250
|
const storage = new BrowserStorageAdapter({
|
|
283
251
|
prefix: (_a = fullConfig.storageConfig) === null || _a === void 0 ? void 0 : _a.prefix
|
|
284
252
|
});
|
|
285
|
-
// Create API client
|
|
286
253
|
const apiClient = new core.ApiClient(fullConfig, storage);
|
|
287
|
-
// Create auth service
|
|
288
254
|
const authService = new core.AuthService(apiClient, storage, fullConfig);
|
|
289
|
-
// Get current user (
|
|
255
|
+
// Get current user (non-blocking)
|
|
290
256
|
let user = null;
|
|
291
257
|
let isAuthenticated = false;
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
[instanceConfig.id]: {
|
|
300
|
-
...prev.instances[instanceConfig.id],
|
|
301
|
-
user: currentUser,
|
|
302
|
-
isAuthenticated: true,
|
|
303
|
-
isLoading: false
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
}));
|
|
307
|
-
}
|
|
308
|
-
}).catch(error => {
|
|
309
|
-
console.error(`Error getting current user for instance ${instanceConfig.id}:`, error);
|
|
310
|
-
});
|
|
311
|
-
// Create instance with optimized functions
|
|
312
|
-
const createInstanceFunctions = (id) => ({
|
|
258
|
+
instancesMap[instanceConfig.id] = {
|
|
259
|
+
config: fullConfig,
|
|
260
|
+
apiClient,
|
|
261
|
+
authService,
|
|
262
|
+
user,
|
|
263
|
+
isAuthenticated,
|
|
264
|
+
isLoading: true,
|
|
313
265
|
login: async (credentials) => {
|
|
314
266
|
const result = await authService.login(credentials);
|
|
315
267
|
if (result.success && result.user && isMounted) {
|
|
@@ -317,10 +269,11 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
317
269
|
...prev,
|
|
318
270
|
instances: {
|
|
319
271
|
...prev.instances,
|
|
320
|
-
[id]: {
|
|
321
|
-
...prev.instances[id],
|
|
272
|
+
[instanceConfig.id]: {
|
|
273
|
+
...prev.instances[instanceConfig.id],
|
|
322
274
|
user: result.user,
|
|
323
|
-
isAuthenticated: true
|
|
275
|
+
isAuthenticated: true,
|
|
276
|
+
isLoading: false
|
|
324
277
|
}
|
|
325
278
|
}
|
|
326
279
|
}));
|
|
@@ -334,10 +287,11 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
334
287
|
...prev,
|
|
335
288
|
instances: {
|
|
336
289
|
...prev.instances,
|
|
337
|
-
[id]: {
|
|
338
|
-
...prev.instances[id],
|
|
290
|
+
[instanceConfig.id]: {
|
|
291
|
+
...prev.instances[instanceConfig.id],
|
|
339
292
|
user: null,
|
|
340
|
-
isAuthenticated: false
|
|
293
|
+
isAuthenticated: false,
|
|
294
|
+
isLoading: false
|
|
341
295
|
}
|
|
342
296
|
}
|
|
343
297
|
}));
|
|
@@ -350,31 +304,52 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
350
304
|
...prev,
|
|
351
305
|
instances: {
|
|
352
306
|
...prev.instances,
|
|
353
|
-
[id]: {
|
|
354
|
-
...prev.instances[id],
|
|
307
|
+
[instanceConfig.id]: {
|
|
308
|
+
...prev.instances[instanceConfig.id],
|
|
355
309
|
user: result.user || null,
|
|
356
|
-
isAuthenticated: result.isValid
|
|
310
|
+
isAuthenticated: result.isValid,
|
|
311
|
+
isLoading: false
|
|
357
312
|
}
|
|
358
313
|
}
|
|
359
314
|
}));
|
|
360
315
|
}
|
|
361
316
|
return result;
|
|
362
317
|
}
|
|
363
|
-
});
|
|
364
|
-
instancesMap[instanceConfig.id] = {
|
|
365
|
-
config: fullConfig,
|
|
366
|
-
apiClient,
|
|
367
|
-
authService,
|
|
368
|
-
user,
|
|
369
|
-
isAuthenticated,
|
|
370
|
-
isLoading: true, // Start as loading
|
|
371
|
-
...createInstanceFunctions(instanceConfig.id)
|
|
372
318
|
};
|
|
319
|
+
// Load user asynchronously
|
|
320
|
+
authService.getCurrentUser().then(currentUser => {
|
|
321
|
+
if (isMounted) {
|
|
322
|
+
setContextValue(prev => ({
|
|
323
|
+
...prev,
|
|
324
|
+
instances: {
|
|
325
|
+
...prev.instances,
|
|
326
|
+
[instanceConfig.id]: {
|
|
327
|
+
...prev.instances[instanceConfig.id],
|
|
328
|
+
user: currentUser,
|
|
329
|
+
isAuthenticated: !!currentUser,
|
|
330
|
+
isLoading: false
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}));
|
|
334
|
+
}
|
|
335
|
+
}).catch(() => {
|
|
336
|
+
if (isMounted) {
|
|
337
|
+
setContextValue(prev => ({
|
|
338
|
+
...prev,
|
|
339
|
+
instances: {
|
|
340
|
+
...prev.instances,
|
|
341
|
+
[instanceConfig.id]: {
|
|
342
|
+
...prev.instances[instanceConfig.id],
|
|
343
|
+
isLoading: false
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}));
|
|
347
|
+
}
|
|
348
|
+
});
|
|
373
349
|
}
|
|
374
350
|
}
|
|
375
351
|
else if (config) {
|
|
376
|
-
//
|
|
377
|
-
// Initialize configuration
|
|
352
|
+
// Single instance mode (simplified)
|
|
378
353
|
const fullConfig = core.initConfig({
|
|
379
354
|
...config,
|
|
380
355
|
sessionConfig: {
|
|
@@ -382,37 +357,22 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
382
357
|
onSessionExpired: handleSessionExpired,
|
|
383
358
|
onSessionRefreshed: handleSessionRefreshed
|
|
384
359
|
}
|
|
385
|
-
}, defaultInstance);
|
|
386
|
-
// Create storage adapter
|
|
360
|
+
}, config.id || defaultInstance);
|
|
387
361
|
const storage = new BrowserStorageAdapter({
|
|
388
362
|
prefix: (_b = fullConfig.storageConfig) === null || _b === void 0 ? void 0 : _b.prefix
|
|
389
363
|
});
|
|
390
|
-
// Create API client
|
|
391
364
|
const apiClient = new core.ApiClient(fullConfig, storage);
|
|
392
|
-
// Create auth service
|
|
393
365
|
const authService = new core.AuthService(apiClient, storage, fullConfig);
|
|
394
|
-
// Get current user
|
|
395
|
-
let user = null;
|
|
396
|
-
let isAuthenticated = false;
|
|
397
|
-
try {
|
|
398
|
-
user = await authService.getCurrentUser();
|
|
399
|
-
isAuthenticated = !!user;
|
|
400
|
-
}
|
|
401
|
-
catch (error) {
|
|
402
|
-
console.error('Error getting current user:', error);
|
|
403
|
-
}
|
|
404
|
-
// Create instance
|
|
405
366
|
instancesMap[defaultInstance] = {
|
|
406
367
|
config: fullConfig,
|
|
407
368
|
apiClient,
|
|
408
369
|
authService,
|
|
409
|
-
user,
|
|
410
|
-
isAuthenticated,
|
|
411
|
-
isLoading:
|
|
370
|
+
user: null,
|
|
371
|
+
isAuthenticated: false,
|
|
372
|
+
isLoading: true,
|
|
412
373
|
login: async (credentials) => {
|
|
413
374
|
const result = await authService.login(credentials);
|
|
414
|
-
if (result.success && result.user) {
|
|
415
|
-
// Update instance
|
|
375
|
+
if (result.success && result.user && isMounted) {
|
|
416
376
|
setContextValue(prev => ({
|
|
417
377
|
...prev,
|
|
418
378
|
instances: {
|
|
@@ -420,7 +380,8 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
420
380
|
[defaultInstance]: {
|
|
421
381
|
...prev.instances[defaultInstance],
|
|
422
382
|
user: result.user,
|
|
423
|
-
isAuthenticated: true
|
|
383
|
+
isAuthenticated: true,
|
|
384
|
+
isLoading: false
|
|
424
385
|
}
|
|
425
386
|
}
|
|
426
387
|
}));
|
|
@@ -429,65 +390,107 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
429
390
|
},
|
|
430
391
|
logout: async () => {
|
|
431
392
|
await authService.logout();
|
|
432
|
-
|
|
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) {
|
|
433
430
|
setContextValue(prev => ({
|
|
434
431
|
...prev,
|
|
435
432
|
instances: {
|
|
436
433
|
...prev.instances,
|
|
437
434
|
[defaultInstance]: {
|
|
438
435
|
...prev.instances[defaultInstance],
|
|
439
|
-
user:
|
|
440
|
-
isAuthenticated:
|
|
436
|
+
user: currentUser,
|
|
437
|
+
isAuthenticated: !!currentUser,
|
|
438
|
+
isLoading: false
|
|
441
439
|
}
|
|
442
440
|
}
|
|
443
441
|
}));
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
// Update instance
|
|
442
|
+
}
|
|
443
|
+
}).catch(() => {
|
|
444
|
+
if (isMounted) {
|
|
448
445
|
setContextValue(prev => ({
|
|
449
446
|
...prev,
|
|
450
447
|
instances: {
|
|
451
448
|
...prev.instances,
|
|
452
449
|
[defaultInstance]: {
|
|
453
450
|
...prev.instances[defaultInstance],
|
|
454
|
-
|
|
455
|
-
isAuthenticated: result.isValid
|
|
451
|
+
isLoading: false
|
|
456
452
|
}
|
|
457
453
|
}
|
|
458
454
|
}));
|
|
459
|
-
return result;
|
|
460
455
|
}
|
|
461
|
-
};
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
if (isMounted) {
|
|
459
|
+
setContextValue({
|
|
460
|
+
instances: instancesMap,
|
|
461
|
+
defaultInstance
|
|
462
|
+
});
|
|
462
463
|
}
|
|
463
|
-
// Set context value
|
|
464
|
-
setContextValue({
|
|
465
|
-
instances: instancesMap,
|
|
466
|
-
defaultInstance
|
|
467
|
-
});
|
|
468
|
-
// Set initialized
|
|
469
|
-
setIsInitialized(true);
|
|
470
464
|
}
|
|
471
465
|
catch (error) {
|
|
472
466
|
console.error('Error initializing Pubflow:', error);
|
|
473
467
|
}
|
|
474
468
|
};
|
|
475
469
|
initialize();
|
|
476
|
-
// Cleanup function
|
|
477
470
|
return () => {
|
|
478
471
|
isMounted = false;
|
|
479
472
|
};
|
|
480
473
|
}, [config, instances, defaultInstance, handleSessionExpired, handleSessionRefreshed]);
|
|
481
|
-
//
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
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 }) }));
|
|
491
494
|
}
|
|
492
495
|
|
|
493
496
|
/**
|
|
@@ -503,7 +506,6 @@ function PubflowProvider({ children, config, instances, defaultInstance = 'defau
|
|
|
503
506
|
*/
|
|
504
507
|
function useAuth(instanceId) {
|
|
505
508
|
const context = React.useContext(PubflowContext);
|
|
506
|
-
const [isLoading, setIsLoading] = React.useState(false);
|
|
507
509
|
if (!context) {
|
|
508
510
|
throw new Error('useAuth must be used within a PubflowProvider');
|
|
509
511
|
}
|
|
@@ -512,68 +514,14 @@ function useAuth(instanceId) {
|
|
|
512
514
|
if (!pubflowInstance) {
|
|
513
515
|
throw new Error(`Pubflow instance '${instance}' not found`);
|
|
514
516
|
}
|
|
515
|
-
// Wrap login to handle loading state
|
|
516
|
-
const login = React.useCallback(async (credentials) => {
|
|
517
|
-
setIsLoading(true);
|
|
518
|
-
try {
|
|
519
|
-
return await pubflowInstance.login(credentials);
|
|
520
|
-
}
|
|
521
|
-
finally {
|
|
522
|
-
setIsLoading(false);
|
|
523
|
-
}
|
|
524
|
-
}, [pubflowInstance]);
|
|
525
|
-
// Wrap logout to handle loading state
|
|
526
|
-
const logout = React.useCallback(async () => {
|
|
527
|
-
setIsLoading(true);
|
|
528
|
-
try {
|
|
529
|
-
await pubflowInstance.logout();
|
|
530
|
-
}
|
|
531
|
-
finally {
|
|
532
|
-
setIsLoading(false);
|
|
533
|
-
}
|
|
534
|
-
}, [pubflowInstance]);
|
|
535
|
-
// Wrap validateSession to handle loading state
|
|
536
|
-
const validateSession = React.useCallback(async () => {
|
|
537
|
-
setIsLoading(true);
|
|
538
|
-
try {
|
|
539
|
-
return await pubflowInstance.validateSession();
|
|
540
|
-
}
|
|
541
|
-
finally {
|
|
542
|
-
setIsLoading(false);
|
|
543
|
-
}
|
|
544
|
-
}, [pubflowInstance]);
|
|
545
|
-
// Add refreshUser function to manually refresh user data
|
|
546
|
-
const refreshUser = React.useCallback(async () => {
|
|
547
|
-
setIsLoading(true);
|
|
548
|
-
try {
|
|
549
|
-
const result = await pubflowInstance.validateSession();
|
|
550
|
-
return result.user || null;
|
|
551
|
-
}
|
|
552
|
-
finally {
|
|
553
|
-
setIsLoading(false);
|
|
554
|
-
}
|
|
555
|
-
}, [pubflowInstance]);
|
|
556
|
-
// Validate session on mount
|
|
557
|
-
React.useEffect(() => {
|
|
558
|
-
const validate = async () => {
|
|
559
|
-
try {
|
|
560
|
-
await validateSession();
|
|
561
|
-
}
|
|
562
|
-
catch (error) {
|
|
563
|
-
console.error('Error validating session:', error);
|
|
564
|
-
}
|
|
565
|
-
};
|
|
566
|
-
validate();
|
|
567
|
-
}, [validateSession]);
|
|
568
517
|
return {
|
|
569
518
|
// Ensure user is never undefined
|
|
570
519
|
user: pubflowInstance.user || null,
|
|
571
520
|
isAuthenticated: pubflowInstance.isAuthenticated,
|
|
572
|
-
isLoading,
|
|
573
|
-
login,
|
|
574
|
-
logout,
|
|
575
|
-
validateSession
|
|
576
|
-
refreshUser
|
|
521
|
+
isLoading: pubflowInstance.isLoading,
|
|
522
|
+
login: pubflowInstance.login,
|
|
523
|
+
logout: pubflowInstance.logout,
|
|
524
|
+
validateSession: pubflowInstance.validateSession
|
|
577
525
|
};
|
|
578
526
|
}
|
|
579
527
|
|
|
@@ -9583,6 +9531,131 @@ function createStyles(theme) {
|
|
|
9583
9531
|
};
|
|
9584
9532
|
}
|
|
9585
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
|
+
|
|
9586
9659
|
/**
|
|
9587
9660
|
* Bridge API Raw Hook for React
|
|
9588
9661
|
*
|
|
@@ -9662,65 +9735,6 @@ function useBridgeApiRaw(instanceId) {
|
|
|
9662
9735
|
};
|
|
9663
9736
|
}
|
|
9664
9737
|
|
|
9665
|
-
/**
|
|
9666
|
-
* Server Authentication Hook for React
|
|
9667
|
-
*
|
|
9668
|
-
* Provides a hook for handling authentication with automatic redirects
|
|
9669
|
-
*/
|
|
9670
|
-
/**
|
|
9671
|
-
* Hook for handling authentication with automatic redirects
|
|
9672
|
-
*
|
|
9673
|
-
* @param options Hook options
|
|
9674
|
-
* @returns Authentication hook result
|
|
9675
|
-
*/
|
|
9676
|
-
function useServerAuth({ loginRedirectPath = '/login', allowedTypes = ['authenticated'], validateOnMount = true, instanceId, onRedirect } = {}) {
|
|
9677
|
-
const { user, isAuthenticated, isLoading, validateSession } = useAuth(instanceId);
|
|
9678
|
-
// Default redirect function
|
|
9679
|
-
const defaultRedirect = (path) => {
|
|
9680
|
-
if (typeof window !== 'undefined') {
|
|
9681
|
-
const currentPath = window.location.pathname;
|
|
9682
|
-
const redirectUrl = `${path}?redirect=${encodeURIComponent(currentPath)}`;
|
|
9683
|
-
window.location.href = redirectUrl;
|
|
9684
|
-
}
|
|
9685
|
-
};
|
|
9686
|
-
const redirect = onRedirect || defaultRedirect;
|
|
9687
|
-
React.useEffect(() => {
|
|
9688
|
-
// Validate session on mount if configured
|
|
9689
|
-
if (validateOnMount) {
|
|
9690
|
-
validateSession().then(({ isValid }) => {
|
|
9691
|
-
if (!isValid) {
|
|
9692
|
-
redirect(loginRedirectPath);
|
|
9693
|
-
}
|
|
9694
|
-
});
|
|
9695
|
-
}
|
|
9696
|
-
}, [validateOnMount, loginRedirectPath, validateSession, redirect]);
|
|
9697
|
-
React.useEffect(() => {
|
|
9698
|
-
// Skip if still loading
|
|
9699
|
-
if (isLoading) {
|
|
9700
|
-
return;
|
|
9701
|
-
}
|
|
9702
|
-
// Redirect if not authenticated
|
|
9703
|
-
if (!isAuthenticated) {
|
|
9704
|
-
redirect(loginRedirectPath);
|
|
9705
|
-
return;
|
|
9706
|
-
}
|
|
9707
|
-
// Check user type if allowedTypes doesn't include 'authenticated'
|
|
9708
|
-
if (!allowedTypes.includes('authenticated') && user) {
|
|
9709
|
-
const userType = user.userType || '';
|
|
9710
|
-
const isAllowed = allowedTypes.some(type => type.toLowerCase() === userType.toLowerCase());
|
|
9711
|
-
if (!isAllowed) {
|
|
9712
|
-
redirect('/access-denied');
|
|
9713
|
-
}
|
|
9714
|
-
}
|
|
9715
|
-
}, [isLoading, isAuthenticated, user, allowedTypes, loginRedirectPath, redirect]);
|
|
9716
|
-
return {
|
|
9717
|
-
user,
|
|
9718
|
-
isAuthenticated,
|
|
9719
|
-
isLoading,
|
|
9720
|
-
validateSession
|
|
9721
|
-
};
|
|
9722
|
-
}
|
|
9723
|
-
|
|
9724
9738
|
/**
|
|
9725
9739
|
* Search Query Builder Hook for React
|
|
9726
9740
|
*
|
|
@@ -9958,6 +9972,7 @@ exports.ThemeProvider = ThemeProvider;
|
|
|
9958
9972
|
exports.createStyles = createStyles;
|
|
9959
9973
|
exports.generateCSSVariables = generateCSSVariables;
|
|
9960
9974
|
exports.useAuth = useAuth;
|
|
9975
|
+
exports.useAuthGuard = useAuthGuard;
|
|
9961
9976
|
exports.useBridgeApi = useBridgeApi;
|
|
9962
9977
|
exports.useBridgeApiRaw = useBridgeApiRaw;
|
|
9963
9978
|
exports.useBridgeCrud = useBridgeCrud;
|
|
@@ -9966,7 +9981,7 @@ exports.useBridgeQuery = useBridgeQuery;
|
|
|
9966
9981
|
exports.useNetworkStatus = useNetworkStatus;
|
|
9967
9982
|
exports.useRequireAuth = useRequireAuth;
|
|
9968
9983
|
exports.useSearchQueryBuilder = useSearchQueryBuilder;
|
|
9969
|
-
exports.
|
|
9984
|
+
exports.useSimpleAuthGuard = useSimpleAuthGuard;
|
|
9970
9985
|
exports.useTheme = useTheme;
|
|
9971
9986
|
Object.keys(core).forEach(function (k) {
|
|
9972
9987
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|