@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.
- package/dist/{chunk-ULP6OIQE.js → chunk-O2VJ5KRZ.js} +122 -7
- package/dist/chunk-O2VJ5KRZ.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/rbac/index.js +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +1 -1
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +1 -1
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +1 -1
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventContextType.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +1 -1
- package/docs/api/interfaces/EventProviderProps.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/NavigationProviderProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
- package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +1 -1
- package/docs/api/interfaces/RBACContextType.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACProviderProps.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +1 -1
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +3 -3
- package/package.json +1 -1
- package/src/rbac/components/PagePermissionGuard.tsx +146 -6
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
}
|