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