@jmruthers/pace-core 0.5.21 → 0.5.23

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.
Files changed (100) hide show
  1. package/dist/{chunk-ULP6OIQE.js → chunk-O2VJ5KRZ.js} +122 -7
  2. package/dist/chunk-O2VJ5KRZ.js.map +1 -0
  3. package/dist/index.js +1 -1
  4. package/dist/rbac/index.js +1 -1
  5. package/docs/api/classes/ErrorBoundary.md +1 -1
  6. package/docs/api/classes/InvalidScopeError.md +1 -1
  7. package/docs/api/classes/MissingUserContextError.md +1 -1
  8. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  9. package/docs/api/classes/PermissionDeniedError.md +1 -1
  10. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  11. package/docs/api/classes/RBACAuditManager.md +1 -1
  12. package/docs/api/classes/RBACCache.md +1 -1
  13. package/docs/api/classes/RBACEngine.md +1 -1
  14. package/docs/api/classes/RBACError.md +1 -1
  15. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  16. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  17. package/docs/api/interfaces/AggregateConfig.md +1 -1
  18. package/docs/api/interfaces/ButtonProps.md +1 -1
  19. package/docs/api/interfaces/CardProps.md +1 -1
  20. package/docs/api/interfaces/ColorPalette.md +1 -1
  21. package/docs/api/interfaces/ColorShade.md +1 -1
  22. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  23. package/docs/api/interfaces/DataTableAction.md +1 -1
  24. package/docs/api/interfaces/DataTableColumn.md +1 -1
  25. package/docs/api/interfaces/DataTableProps.md +1 -1
  26. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  27. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  28. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  29. package/docs/api/interfaces/EventContextType.md +1 -1
  30. package/docs/api/interfaces/EventLogoProps.md +1 -1
  31. package/docs/api/interfaces/EventProviderProps.md +1 -1
  32. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  33. package/docs/api/interfaces/FileUploadProps.md +1 -1
  34. package/docs/api/interfaces/FooterProps.md +1 -1
  35. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  36. package/docs/api/interfaces/InputProps.md +1 -1
  37. package/docs/api/interfaces/LabelProps.md +1 -1
  38. package/docs/api/interfaces/LoginFormProps.md +1 -1
  39. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  40. package/docs/api/interfaces/NavigationContextType.md +1 -1
  41. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  42. package/docs/api/interfaces/NavigationItem.md +1 -1
  43. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  44. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  45. package/docs/api/interfaces/Organisation.md +1 -1
  46. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  47. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  48. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  49. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  50. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  51. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  52. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  53. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  54. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  55. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  56. package/docs/api/interfaces/PaletteData.md +1 -1
  57. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  58. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  59. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  60. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  61. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  62. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  63. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  64. package/docs/api/interfaces/RBACConfig.md +1 -1
  65. package/docs/api/interfaces/RBACContextType.md +1 -1
  66. package/docs/api/interfaces/RBACLogger.md +1 -1
  67. package/docs/api/interfaces/RBACProviderProps.md +1 -1
  68. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  69. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  70. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  71. package/docs/api/interfaces/RouteConfig.md +1 -1
  72. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  73. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  74. package/docs/api/interfaces/StorageConfig.md +1 -1
  75. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  76. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  77. package/docs/api/interfaces/StorageListOptions.md +1 -1
  78. package/docs/api/interfaces/StorageListResult.md +1 -1
  79. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  80. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  81. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  82. package/docs/api/interfaces/StyleImport.md +1 -1
  83. package/docs/api/interfaces/ToastActionElement.md +1 -1
  84. package/docs/api/interfaces/ToastProps.md +1 -1
  85. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  86. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  87. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  88. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  89. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  90. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  91. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  92. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  93. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  94. package/docs/api/interfaces/UserEventAccess.md +1 -1
  95. package/docs/api/interfaces/UserMenuProps.md +1 -1
  96. package/docs/api/interfaces/UserProfile.md +1 -1
  97. package/docs/api/modules.md +3 -3
  98. package/package.json +1 -1
  99. package/src/rbac/components/PagePermissionGuard.tsx +146 -6
  100. package/dist/chunk-ULP6OIQE.js.map +0 -1
@@ -131,6 +131,23 @@ const PagePermissionGuardComponent = ({
131
131
  // Generate a unique instance ID for debugging
132
132
  const instanceId = useMemo(() => Math.random().toString(36).substr(2, 9), []);
133
133
 
134
+ // Track render count for debugging
135
+ const renderCountRef = useRef(0);
136
+ renderCountRef.current += 1;
137
+
138
+ console.log(`[PagePermissionGuard] RENDER #${renderCountRef.current} for ${pageName}:${operation}`, {
139
+ instanceId,
140
+ timestamp: new Date().toISOString()
141
+ });
142
+
143
+ // Track component lifecycle
144
+ useEffect(() => {
145
+ console.log(`[PagePermissionGuard] MOUNTED: ${pageName}:${operation}`, { instanceId });
146
+ return () => {
147
+ console.log(`[PagePermissionGuard] UNMOUNTED: ${pageName}:${operation}`, { instanceId });
148
+ };
149
+ }, [pageName, operation, instanceId]);
150
+
134
151
  const { user, selectedOrganisationId, selectedEventId, supabase } = useUnifiedAuth();
135
152
  const [hasChecked, setHasChecked] = useState(false);
136
153
  const [checkError, setCheckError] = useState<Error | null>(null);
@@ -358,6 +375,18 @@ const PagePermissionGuardComponent = ({
358
375
  true // Use cache
359
376
  );
360
377
 
378
+ // Debug useCan results
379
+ console.log(`[PagePermissionGuard] useCan result for ${pageName}:${operation}`, {
380
+ instanceId,
381
+ can,
382
+ canIsLoading,
383
+ canError: !!canError,
384
+ userId: user?.id,
385
+ stableScope,
386
+ permission,
387
+ effectivePageId
388
+ });
389
+
361
390
  // Combine loading states - we're loading if either scope is resolving OR permission check is loading
362
391
  const isLoading = !resolvedScope || canIsLoading;
363
392
  const error = checkError || canError;
@@ -432,29 +461,138 @@ const PagePermissionGuardComponent = ({
432
461
  });
433
462
  }, [isLoading, hasChecked, resolvedScope, checkError, can, shouldShowAccessDenied, shouldShowContent, permissionKey, instanceId]);
434
463
 
464
+ // CRITICAL DEBUG: Log every render decision with full context
465
+ const renderDecision = {
466
+ instanceId,
467
+ timestamp: new Date().toISOString(),
468
+ renderCount: renderCountRef.current,
469
+ // State values
470
+ isLoading,
471
+ hasValidScope,
472
+ hasValidUser,
473
+ hasChecked,
474
+ checkError: !!checkError,
475
+ can,
476
+ // Calculated values
477
+ shouldShowAccessDenied,
478
+ shouldShowContent,
479
+ // Render conditions
480
+ willShowLoading: isLoading || !hasValidScope || !hasValidUser || !hasChecked,
481
+ willShowError: checkError && !can,
482
+ willShowDenied: shouldShowAccessDenied,
483
+ willShowContent: shouldShowContent,
484
+ // Raw data for debugging
485
+ resolvedScope: resolvedScope ? {
486
+ organisationId: resolvedScope.organisationId,
487
+ eventId: resolvedScope.eventId,
488
+ appId: resolvedScope.appId
489
+ } : null,
490
+ user: user ? { id: user.id, email: user.email } : null
491
+ };
492
+
493
+ console.log('[PagePermissionGuard] RENDER DECISION:', renderDecision);
494
+
495
+ // CRITICAL: If we have permission but shouldShowContent is false, this is the bug!
496
+ if (can && !shouldShowContent) {
497
+ console.error('[PagePermissionGuard] CRITICAL BUG DETECTED: Has permission but shouldShowContent is false!', {
498
+ ...renderDecision,
499
+ bug: 'PERMISSION_GRANTED_BUT_CONTENT_NOT_SHOWING'
500
+ });
501
+ }
502
+
503
+ // CRITICAL: If shouldShowContent is true but we're not rendering content, this is the bug!
504
+ if (shouldShowContent && !(isLoading || !hasValidScope || !hasValidUser || !hasChecked) && !(checkError && !can) && !shouldShowAccessDenied) {
505
+ console.log('[PagePermissionGuard] SHOULD RENDER CONTENT - This is the correct path!', {
506
+ ...renderDecision,
507
+ status: 'CONTENT_SHOULD_BE_RENDERED'
508
+ });
509
+ }
510
+
435
511
  // Show loading state - if we're still loading or don't have valid state
436
512
  if (isLoading || !hasValidScope || !hasValidUser || !hasChecked) {
437
- return <div key={`loading-${permissionKey}`}>{loading}</div>;
513
+ console.log('[PagePermissionGuard] RENDERING: LOADING STATE');
514
+ return (
515
+ <div key={`loading-${permissionKey}`} style={{ border: '3px solid orange', padding: '5px', backgroundColor: 'lightyellow' }}>
516
+ <div style={{ color: 'orange', fontWeight: 'bold' }}>🔄 LOADING STATE</div>
517
+ {loading}
518
+ </div>
519
+ );
438
520
  }
439
521
 
440
522
  // Show error state - only if we have an error AND no permission
441
523
  if (checkError && !can) {
442
- return <div key={`error-${permissionKey}`}>{fallback}</div>;
524
+ console.log('[PagePermissionGuard] RENDERING: ERROR STATE');
525
+ return (
526
+ <div key={`error-${permissionKey}`} style={{ border: '3px solid red', padding: '5px', backgroundColor: 'lightcoral' }}>
527
+ <div style={{ color: 'red', fontWeight: 'bold' }}>❌ ERROR STATE</div>
528
+ {fallback}
529
+ </div>
530
+ );
443
531
  }
444
532
 
445
533
  // Show access denied - if permission check is complete and user doesn't have permission
446
534
  if (shouldShowAccessDenied) {
447
- return <div key={`denied-${permissionKey}`}>{fallback}</div>;
535
+ console.log('[PagePermissionGuard] RENDERING: ACCESS DENIED STATE');
536
+ return (
537
+ <div key={`denied-${permissionKey}`} style={{ border: '3px solid red', padding: '5px', backgroundColor: 'lightcoral' }}>
538
+ <div style={{ color: 'red', fontWeight: 'bold' }}>🚫 ACCESS DENIED STATE</div>
539
+ {fallback}
540
+ </div>
541
+ );
448
542
  }
449
543
 
450
544
  // Show protected content - if permission check is complete and user has permission
451
545
  if (shouldShowContent) {
452
- return <div key={`content-${permissionKey}`}>{children}</div>;
546
+ console.log('[PagePermissionGuard] RENDERING: CONTENT STATE - SHOWING CHILDREN');
547
+ console.log('[PagePermissionGuard] CONTENT RENDER SUCCESS - This should fix the Access Denied issue!');
548
+
549
+ // FORCE RENDER: Create a very obvious visual indicator that cannot be missed
550
+ const forceRenderContent = (
551
+ <div
552
+ key={`content-${permissionKey}`}
553
+ style={{
554
+ border: '5px solid red',
555
+ padding: '10px',
556
+ margin: '10px',
557
+ backgroundColor: 'yellow',
558
+ position: 'relative',
559
+ zIndex: 9999
560
+ }}
561
+ >
562
+ <div style={{
563
+ background: 'red',
564
+ color: 'white',
565
+ padding: '10px',
566
+ fontSize: '16px',
567
+ fontWeight: 'bold',
568
+ marginBottom: '10px',
569
+ textAlign: 'center'
570
+ }}>
571
+ 🚨 FORCE RENDER: PagePermissionGuard Content is ACTUALLY RENDERING! 🚨
572
+ </div>
573
+ <div style={{
574
+ background: 'lightgreen',
575
+ padding: '5px',
576
+ fontSize: '14px',
577
+ marginBottom: '10px',
578
+ border: '2px solid green'
579
+ }}>
580
+ ✅ This proves the PagePermissionGuard is working correctly!
581
+ </div>
582
+ <div style={{ border: '2px solid blue', padding: '5px' }}>
583
+ <strong>Original Children:</strong>
584
+ {children}
585
+ </div>
586
+ </div>
587
+ );
588
+
589
+ console.log('[PagePermissionGuard] RETURNING FORCE RENDER CONTENT');
590
+ return forceRenderContent;
453
591
  }
454
592
 
455
593
  // Fallback: This should never happen, but just in case
456
594
  // If we get here, something went wrong with our state logic
457
- console.warn('[PagePermissionGuard] Unexpected state - falling back to loading', {
595
+ console.error('[PagePermissionGuard] CRITICAL: UNEXPECTED STATE - FALLING BACK TO LOADING', {
458
596
  instanceId,
459
597
  isLoading,
460
598
  hasValidScope,
@@ -463,7 +601,9 @@ const PagePermissionGuardComponent = ({
463
601
  checkError: !!checkError,
464
602
  can,
465
603
  shouldShowAccessDenied,
466
- shouldShowContent
604
+ shouldShowContent,
605
+ resolvedScope,
606
+ user: user ? { id: user.id, email: user.email } : null
467
607
  });
468
608
  return <div key={`fallback-${permissionKey}`}>{loading}</div>;
469
609
  }