@jmruthers/pace-core 0.5.190 → 0.5.193
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/{AuthService-CbP_utw2.d.ts → AuthService-DjnJHDtC.d.ts} +1 -0
- package/dist/{DataTable-ON3IXISJ.js → DataTable-5FU7IESH.js} +7 -6
- package/dist/{DataTable-IVYljGJ6.d.ts → DataTable-Be6dH_dR.d.ts} +1 -1
- package/dist/{PublicPageProvider-C4uxosp6.d.ts → PublicPageProvider-C0Sm_e5k.d.ts} +4 -2
- package/dist/{UnifiedAuthProvider-BYA9qB-o.d.ts → UnifiedAuthProvider-185Ih4dj.d.ts} +2 -0
- package/dist/{UnifiedAuthProvider-X5NXANVI.js → UnifiedAuthProvider-RGJTDE2C.js} +3 -3
- package/dist/{api-I6UCQ5S6.js → api-N774RPUA.js} +2 -2
- package/dist/chunk-6C4YBBJM 5.js +628 -0
- package/dist/chunk-7D4SUZUM.js 2.map +1 -0
- package/dist/{chunk-73HSNNOQ.js → chunk-7EQTDTTJ.js} +47 -74
- package/dist/chunk-7EQTDTTJ.js 2.map +1 -0
- package/dist/chunk-7EQTDTTJ.js.map +1 -0
- package/dist/{chunk-J2XXC7R5.js → chunk-7FLMSG37.js} +409 -244
- package/dist/chunk-7FLMSG37.js 2.map +1 -0
- package/dist/chunk-7FLMSG37.js.map +1 -0
- package/dist/{chunk-NIU6J6OX.js → chunk-BC4IJKSL.js} +23 -32
- package/dist/chunk-BC4IJKSL.js.map +1 -0
- package/dist/{chunk-SDMHPX3X.js → chunk-E3SPN4VZ 5.js } +198 -53
- package/dist/chunk-E3SPN4VZ.js +12917 -0
- package/dist/{chunk-SDMHPX3X.js.map → chunk-E3SPN4VZ.js.map} +1 -1
- package/dist/chunk-E66EQZE6 5.js +37 -0
- package/dist/chunk-E66EQZE6.js 2.map +1 -0
- package/dist/{chunk-DZWK57KZ.js → chunk-G37KK66H.js} +1 -1
- package/dist/{chunk-DZWK57KZ.js.map → chunk-G37KK66H.js.map} +1 -1
- package/dist/{chunk-STYK4OH2.js → chunk-HWIIPPNI.js} +44 -225
- package/dist/chunk-HWIIPPNI.js.map +1 -0
- package/dist/chunk-I7PSE6JW 5.js +191 -0
- package/dist/chunk-I7PSE6JW.js 2.map +1 -0
- package/dist/{chunk-Y4BUBBHD.js → chunk-IIELH4DL.js} +211 -136
- package/dist/chunk-IIELH4DL.js.map +1 -0
- package/dist/{chunk-RUYZKXOD.js → chunk-KNC55RTG.js} +17 -5
- package/dist/chunk-KNC55RTG.js 5.map +1 -0
- package/dist/chunk-KNC55RTG.js.map +1 -0
- package/dist/chunk-KQCRWDSA.js 5.map +1 -0
- package/dist/{chunk-4QYC5L4K.js → chunk-LFNCN2SP.js} +26 -30
- package/dist/chunk-LFNCN2SP.js 2.map +1 -0
- package/dist/chunk-LFNCN2SP.js.map +1 -0
- package/dist/chunk-LMC26NLJ 2.js +84 -0
- package/dist/{chunk-VVBAW5A5.js → chunk-NOAYCWCX 5.js } +118 -110
- package/dist/chunk-NOAYCWCX.js +4993 -0
- package/dist/chunk-NOAYCWCX.js.map +1 -0
- package/dist/chunk-QWWZ5CAQ.js 3.map +1 -0
- package/dist/chunk-QXHPKYJV 3.js +113 -0
- package/dist/chunk-R77UEZ4E 3.js +68 -0
- package/dist/chunk-VBXEHIUJ.js 6.map +1 -0
- package/dist/{chunk-HQVPB5MZ.js → chunk-XNXXZ43G.js} +77 -33
- package/dist/chunk-XNXXZ43G.js.map +1 -0
- package/dist/chunk-ZSAAAMVR 6.js +25 -0
- package/dist/components.d.ts +4 -4
- package/dist/components.js +8 -8
- package/dist/components.js 5.map +1 -0
- package/dist/{database.generated-DI89OQeI.d.ts → database.generated-CzIvgcPu.d.ts} +165 -201
- package/dist/hooks.d.ts +12 -12
- package/dist/hooks.js +9 -9
- package/dist/index.d.ts +11 -11
- package/dist/index.js +20 -27
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +3 -3
- package/dist/providers.js +2 -2
- package/dist/rbac/index.d.ts +2 -20
- package/dist/rbac/index.js +7 -9
- package/dist/styles/index 2.js +12 -0
- package/dist/styles/index.js 5.map +1 -0
- package/dist/theming/runtime 5.js +19 -0
- package/dist/theming/runtime.js 5.map +1 -0
- package/dist/{types-Bwgl--Xo.d.ts → types-CEpcvwwF.d.ts} +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/{usePublicRouteParams-DxIDS4bC.d.ts → usePublicRouteParams-TZe0gy-4.d.ts} +1 -1
- package/dist/utils.d.ts +8 -8
- package/dist/utils.js +2 -2
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/Logger.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 +2 -2
- package/docs/api/classes/RBACAuditManager.md +2 -2
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +2 -2
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +10 -10
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/enums/LogLevel.md +1 -1
- package/docs/api/enums/RBACErrorCode.md +1 -1
- package/docs/api/enums/RPCFunction.md +1 -1
- package/docs/api/interfaces/AddressFieldProps.md +1 -1
- package/docs/api/interfaces/AddressFieldRef.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/AutocompleteOptions.md +1 -1
- package/docs/api/interfaces/AvatarProps.md +1 -1
- package/docs/api/interfaces/BadgeProps.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CalendarProps.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/ComplianceResult.md +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataRecord.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/DatabaseComplianceResult.md +1 -1
- package/docs/api/interfaces/DatabaseIssue.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventAppRoleData.md +1 -1
- package/docs/api/interfaces/ExportColumn.md +1 -1
- package/docs/api/interfaces/ExportOptions.md +1 -1
- package/docs/api/interfaces/FileDisplayProps.md +24 -11
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/FormFieldProps.md +1 -1
- package/docs/api/interfaces/FormProps.md +1 -1
- package/docs/api/interfaces/GrantEventAppRoleParams.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/LoggerConfig.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +2 -2
- 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 +2 -2
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/ParsedAddress.md +2 -2
- package/docs/api/interfaces/PermissionEnforcerProps.md +4 -4
- package/docs/api/interfaces/ProgressProps.md +1 -1
- package/docs/api/interfaces/ProtectedRouteProps.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/QuickFix.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
- package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
- package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +2 -2
- package/docs/api/interfaces/RBACContext.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckResult.md +2 -2
- package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
- package/docs/api/interfaces/RBACResult.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantParams.md +2 -2
- package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeParams.md +2 -2
- package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateParams.md +2 -2
- package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
- package/docs/api/interfaces/RBACRolesListParams.md +1 -1
- package/docs/api/interfaces/RBACRolesListResult.md +2 -2
- package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
- package/docs/api/interfaces/ResourcePermissions.md +1 -1
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RoleManagementResult.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +2 -2
- package/docs/api/interfaces/RouteConfig.md +2 -2
- package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
- package/docs/api/interfaces/SetupIssue.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/SwitchProps.md +1 -1
- package/docs/api/interfaces/TabsContentProps.md +1 -1
- package/docs/api/interfaces/TabsListProps.md +1 -1
- package/docs/api/interfaces/TabsProps.md +1 -1
- package/docs/api/interfaces/TabsTriggerProps.md +1 -1
- package/docs/api/interfaces/TextareaProps.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 +60 -38
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
- package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
- package/docs/api/interfaces/UseFormDialogReturn.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 +2 -2
- 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/UsePublicFileDisplayOptions.md +2 -2
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +2 -2
- package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
- package/docs/api/interfaces/UseResourcePermissionsOptions.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 +202 -217
- package/docs/migration/README.md +18 -0
- package/docs/migration/database-changes-december-2025.md +768 -0
- package/docs/migration/person-scoped-profiles-migration-guide.md +472 -0
- package/docs/rbac/event-based-apps.md +124 -6
- package/package.json +1 -1
- package/scripts/check-pace-core-compliance.cjs +292 -57
- package/src/__tests__/public-recipe-view.test.ts +10 -10
- package/src/__tests__/rls-policies.test.ts +16 -14
- package/src/components/AddressField/README.md +6 -6
- package/src/components/DataTable/__tests__/DataTable.default-state.test.tsx +172 -45
- package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +121 -28
- package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +9 -8
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +20 -52
- package/src/components/DataTable/__tests__/a11y.basic.test.tsx +170 -34
- package/src/components/DataTable/__tests__/keyboard.test.tsx +75 -12
- package/src/components/DataTable/__tests__/pagination.modes.test.tsx +75 -11
- package/src/components/DataTable/components/UnifiedTableBody.tsx +85 -14
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +75 -10
- package/src/components/FileDisplay/FileDisplay.test.tsx +2 -1
- package/src/components/FileDisplay/FileDisplay.tsx +16 -4
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +6 -4
- package/src/components/NavigationMenu/NavigationMenu.tsx +1 -10
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +35 -16
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +25 -2
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +97 -68
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +0 -7
- package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +5 -9
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +0 -1
- package/src/components/PublicLayout/PublicPageProvider.tsx +0 -1
- package/src/components/Select/Select.test.tsx +4 -1
- package/src/components/Select/Select.tsx +60 -15
- package/src/hooks/__tests__/usePermissionCache.simple.test.ts +192 -0
- package/src/hooks/__tests__/usePermissionCache.unit.test.ts +741 -0
- package/src/hooks/__tests__/usePublicEvent.simple.test.ts +703 -0
- package/src/hooks/__tests__/usePublicEvent.unit.test.ts +581 -0
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +23 -15
- package/src/hooks/public/usePublicEvent.ts +8 -8
- package/src/hooks/public/usePublicFileDisplay.ts +2 -2
- package/src/hooks/services/useAuthService.ts +21 -3
- package/src/hooks/services/useEventService.ts +21 -3
- package/src/hooks/services/useInactivityService.ts +21 -3
- package/src/hooks/services/useOrganisationService.ts +21 -3
- package/src/hooks/useFileDisplay.ts +18 -26
- package/src/hooks/useQueryCache.ts +6 -6
- package/src/hooks/useSecureDataAccess.test.ts +24 -17
- package/src/hooks/useSecureDataAccess.ts +18 -13
- package/src/providers/__tests__/OrganisationProvider.test.tsx +27 -21
- package/src/providers/services/EventServiceProvider.tsx +0 -8
- package/src/providers/services/UnifiedAuthProvider.tsx +174 -24
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +10 -16
- package/src/rbac/__tests__/isSuperAdmin.real.test.ts +82 -0
- package/src/rbac/adapters.tsx +3 -22
- package/src/rbac/api.test.ts +2 -2
- package/src/rbac/api.ts +7 -1
- package/src/rbac/components/EnhancedNavigationMenu.tsx +2 -15
- package/src/rbac/components/NavigationGuard.tsx +1 -10
- package/src/rbac/components/NavigationProvider.tsx +0 -1
- package/src/rbac/components/PermissionEnforcer.tsx +45 -12
- package/src/rbac/components/SecureDataProvider.tsx +0 -1
- package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +7 -43
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +4 -11
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +3 -3
- package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +1 -1
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +1 -1
- package/src/rbac/engine.ts +14 -2
- package/src/rbac/hooks/index.ts +0 -3
- package/src/rbac/hooks/usePermissions.ts +51 -11
- package/src/rbac/hooks/useRBAC.simple.test.ts +95 -0
- package/src/rbac/hooks/useRBAC.ts +3 -13
- package/src/rbac/hooks/useResolvedScope.test.ts +75 -54
- package/src/rbac/hooks/useResolvedScope.ts +58 -33
- package/src/rbac/hooks/useSecureSupabase.ts +4 -9
- package/src/rbac/secureClient.ts +31 -0
- package/src/rbac/utils/__tests__/eventContext.test.ts +2 -2
- package/src/rbac/utils/__tests__/eventContext.unit.test.ts +490 -0
- package/src/rbac/utils/eventContext.ts +5 -2
- package/src/services/AuthService.ts +37 -8
- package/src/services/EventService.ts +4 -57
- package/src/services/InactivityService.ts +127 -34
- package/src/services/OrganisationService.ts +160 -149
- package/src/services/__tests__/OrganisationService.pagination.test.ts +34 -8
- package/src/services/__tests__/OrganisationService.test.ts +218 -86
- package/src/types/database.generated.ts +166 -201
- package/src/types/supabase.ts +2 -2
- package/src/utils/__tests__/secureDataAccess.unit.test.ts +3 -2
- package/src/utils/file-reference/index.ts +4 -4
- package/src/utils/google-places/googlePlacesUtils.ts +1 -1
- package/src/utils/google-places/types.ts +1 -1
- package/src/utils/request-deduplication.ts +4 -4
- package/src/utils/security/secureDataAccess.test.ts +1 -1
- package/src/utils/security/secureDataAccess.ts +7 -4
- package/src/utils/storage/README.md +1 -1
- package/dist/chunk-4QYC5L4K.js.map +0 -1
- package/dist/chunk-73HSNNOQ.js.map +0 -1
- package/dist/chunk-HQVPB5MZ.js.map +0 -1
- package/dist/chunk-J2XXC7R5.js.map +0 -1
- package/dist/chunk-NIU6J6OX.js.map +0 -1
- package/dist/chunk-RUYZKXOD.js.map +0 -1
- package/dist/chunk-STYK4OH2.js.map +0 -1
- package/dist/chunk-VVBAW5A5.js.map +0 -1
- package/dist/chunk-Y4BUBBHD.js.map +0 -1
- package/scripts/check-pace-core-compliance.js +0 -512
- package/src/rbac/hooks/useSuperAdminBypass.ts +0 -126
- package/src/utils/context/superAdminOverride.ts +0 -58
- /package/dist/{DataTable-ON3IXISJ.js.map → DataTable-5FU7IESH.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-X5NXANVI.js.map → UnifiedAuthProvider-RGJTDE2C.js.map} +0 -0
- /package/dist/{api-I6UCQ5S6.js.map → api-N774RPUA.js.map} +0 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createLogger
|
|
3
|
+
} from "./chunk-PWLANIRT.js";
|
|
4
|
+
import {
|
|
5
|
+
__require
|
|
6
|
+
} from "./chunk-7D4SUZUM.js";
|
|
7
|
+
|
|
8
|
+
// src/utils/app/appNameResolver.ts
|
|
9
|
+
var log = createLogger("AppNameResolver");
|
|
10
|
+
function getAppNameFromPackageJson() {
|
|
11
|
+
if (typeof window === "undefined" && typeof __require !== "undefined") {
|
|
12
|
+
try {
|
|
13
|
+
const fs = __require("fs");
|
|
14
|
+
const path = __require("path");
|
|
15
|
+
const possiblePaths = [
|
|
16
|
+
// Only use process.cwd() if we're in a Node.js environment
|
|
17
|
+
...typeof process !== "undefined" && process.cwd ? [path.join(process.cwd(), "package.json")] : [],
|
|
18
|
+
path.join(__dirname, "../../package.json"),
|
|
19
|
+
path.join(__dirname, "../../../package.json")
|
|
20
|
+
];
|
|
21
|
+
for (const packagePath of possiblePaths) {
|
|
22
|
+
try {
|
|
23
|
+
if (fs.existsSync(packagePath)) {
|
|
24
|
+
const packageJsonContent = fs.readFileSync(packagePath, "utf8");
|
|
25
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
26
|
+
if (packageJson.name) {
|
|
27
|
+
const name = packageJson.name.split("/").pop() || packageJson.name;
|
|
28
|
+
return name;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
} catch (error) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
} catch (error) {
|
|
36
|
+
log.warn("Could not read app name from package.json:", error);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
function getAppNameFromBuildTime() {
|
|
42
|
+
if (typeof window !== "undefined") {
|
|
43
|
+
try {
|
|
44
|
+
const buildTimeEnv = globalThis.__RBAC_APP_NAME__;
|
|
45
|
+
if (buildTimeEnv && buildTimeEnv.trim()) {
|
|
46
|
+
return buildTimeEnv.trim();
|
|
47
|
+
}
|
|
48
|
+
} catch (error) {
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
function getAppNameFromGlobal() {
|
|
54
|
+
if (typeof window !== "undefined") {
|
|
55
|
+
try {
|
|
56
|
+
const globalAppName = globalThis.RBAC_APP_NAME;
|
|
57
|
+
if (globalAppName && globalAppName.trim()) {
|
|
58
|
+
return globalAppName.trim();
|
|
59
|
+
}
|
|
60
|
+
} catch (error) {
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
function getAppNameFromEnvironment() {
|
|
66
|
+
const envVars = [
|
|
67
|
+
"VITE_APP_NAME",
|
|
68
|
+
"REACT_APP_NAME",
|
|
69
|
+
"NEXT_PUBLIC_APP_NAME",
|
|
70
|
+
"APP_NAME",
|
|
71
|
+
"NODE_APP_NAME"
|
|
72
|
+
];
|
|
73
|
+
for (const envVar of envVars) {
|
|
74
|
+
const value = import.meta.env[envVar];
|
|
75
|
+
if (value && value.trim()) {
|
|
76
|
+
return value.trim();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
function getCurrentAppName() {
|
|
82
|
+
const globalName = getAppNameFromGlobal();
|
|
83
|
+
if (globalName) {
|
|
84
|
+
return globalName;
|
|
85
|
+
}
|
|
86
|
+
const buildTimeName = getAppNameFromBuildTime();
|
|
87
|
+
if (buildTimeName) {
|
|
88
|
+
return buildTimeName;
|
|
89
|
+
}
|
|
90
|
+
const packageJsonName = getAppNameFromPackageJson();
|
|
91
|
+
if (packageJsonName) {
|
|
92
|
+
return packageJsonName;
|
|
93
|
+
}
|
|
94
|
+
const envName = getAppNameFromEnvironment();
|
|
95
|
+
if (envName) {
|
|
96
|
+
return envName;
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
function setRBACAppName(appName) {
|
|
101
|
+
if (typeof window !== "undefined") {
|
|
102
|
+
globalThis.RBAC_APP_NAME = appName.trim();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function getCurrentAppNameWithFallback(fallback = "default-app") {
|
|
106
|
+
return getCurrentAppName() || fallback;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// src/utils/performance/performanceBudgets.ts
|
|
110
|
+
var PERFORMANCE_BUDGETS = {
|
|
111
|
+
COMPONENT_RENDER: { threshold: 50 },
|
|
112
|
+
BUNDLE_SIZE: { threshold: 15e4 },
|
|
113
|
+
CHUNK_COUNT: { threshold: 10 },
|
|
114
|
+
TREESHAKING_SCORE: { threshold: 70 },
|
|
115
|
+
ERROR_BOUNDARY_TRIGGER: { threshold: 5 },
|
|
116
|
+
MEMORY_INCREASE: { threshold: 1e3 },
|
|
117
|
+
LARGE_LIST_RENDER: { threshold: 500 }
|
|
118
|
+
};
|
|
119
|
+
var PerformanceBudgetMonitor = class {
|
|
120
|
+
constructor() {
|
|
121
|
+
this.metrics = /* @__PURE__ */ new Map();
|
|
122
|
+
this.budgets = [];
|
|
123
|
+
}
|
|
124
|
+
measure(metric, value, metadata) {
|
|
125
|
+
this.metrics.set(metric, value);
|
|
126
|
+
if (import.meta.env.MODE === "development" || import.meta.env.MODE === "test" || false) {
|
|
127
|
+
console.log("\u{1F4CA} Performance Metric: " + metric + " = " + value, metadata);
|
|
128
|
+
}
|
|
129
|
+
const budgetConfig = PERFORMANCE_BUDGETS[metric];
|
|
130
|
+
const threshold = budgetConfig?.threshold || 100;
|
|
131
|
+
const passed = value <= threshold;
|
|
132
|
+
return {
|
|
133
|
+
passed,
|
|
134
|
+
value,
|
|
135
|
+
threshold
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
setBudget(metric, budget, threshold = "warning") {
|
|
139
|
+
this.budgets.push({ metric, budget, actual: 0, threshold });
|
|
140
|
+
}
|
|
141
|
+
checkBudgets() {
|
|
142
|
+
const violations = [];
|
|
143
|
+
for (const budget of this.budgets) {
|
|
144
|
+
const actual = this.metrics.get(budget.metric) || 0;
|
|
145
|
+
budget.actual = actual;
|
|
146
|
+
if (actual > budget.budget) {
|
|
147
|
+
violations.push(budget);
|
|
148
|
+
if (import.meta.env.MODE === "development" || import.meta.env.MODE === "test" || false) {
|
|
149
|
+
if (budget.threshold === "error") {
|
|
150
|
+
console.error("\u274C Performance budget exceeded: " + budget.metric + " (" + actual + " > " + budget.budget + ")");
|
|
151
|
+
} else if (budget.threshold === "warning") {
|
|
152
|
+
console.warn("\u26A0\uFE0F Performance budget exceeded: " + budget.metric + " (" + actual + " > " + budget.budget + ")");
|
|
153
|
+
} else {
|
|
154
|
+
console.info("\u2139\uFE0F Performance budget exceeded: " + budget.metric + " (" + actual + " > " + budget.budget + ")");
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return violations;
|
|
160
|
+
}
|
|
161
|
+
getMetrics() {
|
|
162
|
+
return {
|
|
163
|
+
bundleSize: this.metrics.get("BUNDLE_SIZE") || 0,
|
|
164
|
+
chunkCount: this.metrics.get("CHUNK_COUNT") || 0,
|
|
165
|
+
treeshakingEffectiveness: this.metrics.get("TREESHAKING_SCORE") || 0,
|
|
166
|
+
dynamicImportUsage: this.metrics.get("DYNAMIC_IMPORTS") || 0
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
reset() {
|
|
170
|
+
this.metrics.clear();
|
|
171
|
+
this.budgets.length = 0;
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
var performanceBudgetMonitor = new PerformanceBudgetMonitor();
|
|
175
|
+
performanceBudgetMonitor.setBudget("BUNDLE_SIZE", 15e4, "error");
|
|
176
|
+
performanceBudgetMonitor.setBudget("CHUNK_COUNT", 10, "warning");
|
|
177
|
+
performanceBudgetMonitor.setBudget("TREESHAKING_SCORE", 70, "warning");
|
|
178
|
+
performanceBudgetMonitor.setBudget("ERROR_BOUNDARY_TRIGGER", 5, "error");
|
|
179
|
+
|
|
180
|
+
export {
|
|
181
|
+
getAppNameFromPackageJson,
|
|
182
|
+
getAppNameFromBuildTime,
|
|
183
|
+
getAppNameFromGlobal,
|
|
184
|
+
getAppNameFromEnvironment,
|
|
185
|
+
getCurrentAppName,
|
|
186
|
+
setRBACAppName,
|
|
187
|
+
getCurrentAppNameWithFallback,
|
|
188
|
+
PERFORMANCE_BUDGETS,
|
|
189
|
+
performanceBudgetMonitor
|
|
190
|
+
};
|
|
191
|
+
//# sourceMappingURL=chunk-I7PSE6JW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/app/appNameResolver.ts","../src/utils/performance/performanceBudgets.ts"],"sourcesContent":["/**\n * Utility to resolve the current app name from various sources\n * Priority: package.json > environment variables > fallback\n */\n\nimport { createLogger } from '../core/logger';\n\nconst log = createLogger('AppNameResolver');\n\ninterface PackageJson {\n name: string;\n [key: string]: unknown;\n}\n\n/**\n * Get the app name from package.json at build time\n * This works by reading package.json during the build process\n */\nexport function getAppNameFromPackageJson(): string | null {\n // Check if we're in a Node.js environment (build time)\n if (typeof window === 'undefined' && typeof require !== 'undefined') {\n try {\n // Try to read package.json from the current working directory\n // This works in most Node.js environments\n const fs = require('fs');\n const path = require('path');\n \n // Look for package.json in common locations\n const possiblePaths = [\n // Only use process.cwd() if we're in a Node.js environment\n ...(typeof process !== 'undefined' && process.cwd ? [path.join(process.cwd(), 'package.json')] : []),\n path.join(__dirname, '../../package.json'),\n path.join(__dirname, '../../../package.json'),\n ];\n \n for (const packagePath of possiblePaths) {\n try {\n if (fs.existsSync(packagePath)) {\n const packageJsonContent = fs.readFileSync(packagePath, 'utf8');\n const packageJson: PackageJson = JSON.parse(packageJsonContent);\n \n if (packageJson.name) {\n // Extract the app name from the package name\n // Handle scoped packages like @org/app-name\n const name = packageJson.name.split('/').pop() || packageJson.name;\n return name;\n }\n }\n } catch (error) {\n // Continue to next path\n continue;\n }\n }\n } catch (error) {\n // package.json not found or not readable\n log.warn('Could not read app name from package.json:', error);\n }\n }\n \n // In browser environments, we can't read package.json\n // This will fall back to environment variables\n return null;\n}\n\n/**\n * Get the app name from build-time injected variables\n * This is the preferred method for browser environments\n */\nexport function getAppNameFromBuildTime(): string | null {\n // Check for build-time injected app name\n // This would be set by the build process reading package.json\n if (typeof window !== 'undefined') {\n // Try to access build-time injected variables\n try {\n // @ts-ignore - These are injected at build time\n const buildTimeEnv = (globalThis as any).__RBAC_APP_NAME__;\n if (buildTimeEnv && buildTimeEnv.trim()) {\n return buildTimeEnv.trim();\n }\n } catch (error) {\n // Build-time injection not available\n }\n }\n \n return null;\n}\n\n/**\n * Get the app name from a global variable set by the consuming app\n * This is the simplest approach for browser environments\n */\nexport function getAppNameFromGlobal(): string | null {\n if (typeof window !== 'undefined') {\n // Check for global app name set by consuming app\n try {\n // @ts-ignore - This is set by the consuming app\n const globalAppName = (globalThis as any).RBAC_APP_NAME;\n if (globalAppName && globalAppName.trim()) {\n return globalAppName.trim();\n }\n } catch (error) {\n // Global variable not set\n }\n }\n \n return null;\n}\n\n/**\n * Get the app name from environment variables\n * Fallback method for when package.json is not available\n */\nexport function getAppNameFromEnvironment(): string | null {\n // Try different environment variable patterns used by various frameworks\n const envVars = [\n 'VITE_APP_NAME',\n 'REACT_APP_NAME', \n 'NEXT_PUBLIC_APP_NAME',\n 'APP_NAME',\n 'NODE_APP_NAME'\n ];\n \n for (const envVar of envVars) {\n const value = import.meta.env[envVar];\n if (value && value.trim()) {\n return value.trim();\n }\n }\n \n return null;\n}\n\n/**\n * Get the current app name from the most reliable source\n * Priority: global variable > build-time injection > package.json > environment variables > null\n */\nexport function getCurrentAppName(): string | null {\n // First try global variable (set by consuming app)\n const globalName = getAppNameFromGlobal();\n if (globalName) {\n return globalName;\n }\n \n // Then try build-time injection (most reliable for browser)\n const buildTimeName = getAppNameFromBuildTime();\n if (buildTimeName) {\n return buildTimeName;\n }\n \n // Then try package.json (works in Node.js environments)\n const packageJsonName = getAppNameFromPackageJson();\n if (packageJsonName) {\n return packageJsonName;\n }\n \n // Fallback to environment variables\n const envName = getAppNameFromEnvironment();\n if (envName) {\n return envName;\n }\n \n return null;\n}\n\n/**\n * Set the app name globally for RBAC resolution\n * Call this in your app's main entry point (e.g., main.tsx, index.tsx)\n * \n * @param appName - The app name from your package.json\n * \n * @example\n * ```tsx\n * // In your main.tsx or index.tsx\n * import { setRBACAppName } from '@jmruthers/pace-core/utils';\n * \n * // Set the app name from package.json\n * setRBACAppName('CAKE');\n * \n * // Rest of your app setup...\n * ```\n */\nexport function setRBACAppName(appName: string): void {\n if (typeof window !== 'undefined') {\n // @ts-ignore - Setting global variable\n (globalThis as any).RBAC_APP_NAME = appName.trim();\n }\n}\n\n/**\n * Get the app name with fallback to a default\n * Useful when you need a guaranteed app name\n */\nexport function getCurrentAppNameWithFallback(fallback: string = 'default-app'): string {\n return getCurrentAppName() || fallback;\n}\n","\ninterface PerformanceBudget {\n metric: string;\n budget: number;\n actual: number;\n threshold: 'error' | 'warning' | 'info';\n}\n\ninterface PerformanceMetrics {\n bundleSize: number;\n chunkCount: number;\n treeshakingEffectiveness: number;\n dynamicImportUsage: number;\n}\n\ninterface MeasurementResult {\n passed: boolean;\n value: number;\n threshold: number;\n}\n\n// Performance budget thresholds with index signature\nexport const PERFORMANCE_BUDGETS: { [key: string]: { threshold: number } } = {\n COMPONENT_RENDER: { threshold: 50 },\n BUNDLE_SIZE: { threshold: 150000 },\n CHUNK_COUNT: { threshold: 10 },\n TREESHAKING_SCORE: { threshold: 70 },\n ERROR_BOUNDARY_TRIGGER: { threshold: 5 },\n MEMORY_INCREASE: { threshold: 1000 },\n LARGE_LIST_RENDER: { threshold: 500 },\n} as const;\n\nclass PerformanceBudgetMonitor {\n private metrics: Map<string, number> = new Map();\n private budgets: PerformanceBudget[] = [];\n\n measure(metric: string, value: number, metadata?: Record<string, unknown>): MeasurementResult {\n this.metrics.set(metric, value);\n \n // In production, this would send to a proper logging service\n // For now, we'll log to console for testing purposes\n if (import.meta.env.MODE === 'development' || import.meta.env.MODE === 'test' || process.env.NODE_ENV === 'test') {\n console.log('📊 Performance Metric: ' + metric + ' = ' + value, metadata);\n }\n\n // Get threshold for this metric\n const budgetConfig = PERFORMANCE_BUDGETS[metric];\n const threshold = budgetConfig?.threshold || 100;\n const passed = value <= threshold;\n\n return {\n passed,\n value,\n threshold\n };\n }\n\n setBudget(metric: string, budget: number, threshold: 'error' | 'warning' | 'info' = 'warning'): void {\n this.budgets.push({ metric, budget, actual: 0, threshold });\n }\n\n checkBudgets(): PerformanceBudget[] {\n const violations: PerformanceBudget[] = [];\n \n for (const budget of this.budgets) {\n const actual = this.metrics.get(budget.metric) || 0;\n budget.actual = actual;\n \n if (actual > budget.budget) {\n violations.push(budget);\n \n // In production, this would send to a proper logging service\n // For now, we'll log to console for testing purposes\n if (import.meta.env.MODE === 'development' || import.meta.env.MODE === 'test' || process.env.NODE_ENV === 'test') {\n if (budget.threshold === 'error') {\n console.error('❌ Performance budget exceeded: ' + budget.metric + ' (' + actual + ' > ' + budget.budget + ')');\n } else if (budget.threshold === 'warning') {\n console.warn('⚠️ Performance budget exceeded: ' + budget.metric + ' (' + actual + ' > ' + budget.budget + ')');\n } else {\n console.info('ℹ️ Performance budget exceeded: ' + budget.metric + ' (' + actual + ' > ' + budget.budget + ')');\n }\n }\n }\n }\n \n return violations;\n }\n\n getMetrics(): PerformanceMetrics {\n return {\n bundleSize: this.metrics.get('BUNDLE_SIZE') || 0,\n chunkCount: this.metrics.get('CHUNK_COUNT') || 0,\n treeshakingEffectiveness: this.metrics.get('TREESHAKING_SCORE') || 0,\n dynamicImportUsage: this.metrics.get('DYNAMIC_IMPORTS') || 0,\n };\n }\n\n reset(): void {\n this.metrics.clear();\n this.budgets.length = 0;\n }\n}\n\nexport const performanceBudgetMonitor = new PerformanceBudgetMonitor();\n\n// Set default performance budgets\nperformanceBudgetMonitor.setBudget('BUNDLE_SIZE', 150000, 'error'); // 150KB\nperformanceBudgetMonitor.setBudget('CHUNK_COUNT', 10, 'warning');\nperformanceBudgetMonitor.setBudget('TREESHAKING_SCORE', 70, 'warning');\nperformanceBudgetMonitor.setBudget('ERROR_BOUNDARY_TRIGGER', 5, 'error');\n"],"mappings":"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","names":[]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useEventService,
|
|
3
|
+
useOrganisations,
|
|
3
4
|
useUnifiedAuth
|
|
4
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-7FLMSG37.js";
|
|
5
6
|
import {
|
|
6
|
-
ContextValidator
|
|
7
|
-
|
|
8
|
-
} from "./chunk-RUYZKXOD.js";
|
|
7
|
+
ContextValidator
|
|
8
|
+
} from "./chunk-KNC55RTG.js";
|
|
9
9
|
import {
|
|
10
10
|
getCurrentAppName,
|
|
11
11
|
performanceBudgetMonitor
|
|
@@ -114,30 +114,45 @@ function useResolvedScope({
|
|
|
114
114
|
let appConfig = null;
|
|
115
115
|
if (supabase && appName2) {
|
|
116
116
|
try {
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
appId = cached.appId;
|
|
121
|
-
appConfig = cached.appConfig;
|
|
117
|
+
const { data: session } = await supabase.auth.getSession();
|
|
118
|
+
if (!session?.session) {
|
|
119
|
+
log.debug(`Skipping app resolution for "${appName2}" - user not authenticated`);
|
|
122
120
|
} else {
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
|
|
121
|
+
const cached = appConfigCache.get(appName2);
|
|
122
|
+
const now = Date.now();
|
|
123
|
+
if (cached && now - cached.timestamp < CACHE_TTL) {
|
|
124
|
+
appId = cached.appId;
|
|
125
|
+
appConfig = cached.appConfig;
|
|
126
|
+
} else {
|
|
127
|
+
const { data: app, error: error2 } = await supabase.from("rbac_apps").select("id, name, requires_event, is_active").eq("name", appName2).eq("is_active", true).single();
|
|
128
|
+
if (error2) {
|
|
129
|
+
if (error2.code === "406" || error2.code === "PGRST116" || error2.message?.includes("406")) {
|
|
130
|
+
log.debug(`App resolution blocked by RLS for "${appName2}" - user may not be authenticated`);
|
|
131
|
+
appId = void 0;
|
|
132
|
+
} else {
|
|
133
|
+
const { data: inactiveApp } = await supabase.from("rbac_apps").select("id, name, is_active").eq("name", appName2).single();
|
|
134
|
+
if (inactiveApp) {
|
|
135
|
+
log.error(`App "${appName2}" exists but is inactive (is_active: ${inactiveApp.is_active})`);
|
|
136
|
+
appId = void 0;
|
|
137
|
+
} else {
|
|
138
|
+
log.error(`App "${appName2}" not found in rbac_apps table`, { error: error2 });
|
|
139
|
+
appId = void 0;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
} else if (app) {
|
|
143
|
+
appId = app.id;
|
|
144
|
+
appConfig = { requires_event: app.requires_event ?? false };
|
|
145
|
+
appConfigCache.set(appName2, { appId, appConfig, timestamp: now });
|
|
132
146
|
}
|
|
133
|
-
} else if (app) {
|
|
134
|
-
appId = app.id;
|
|
135
|
-
appConfig = { requires_event: app.requires_event ?? false };
|
|
136
|
-
appConfigCache.set(appName2, { appId, appConfig, timestamp: now });
|
|
137
147
|
}
|
|
138
148
|
}
|
|
139
149
|
} catch (error2) {
|
|
140
|
-
|
|
150
|
+
const errorMessage = error2 instanceof Error ? error2.message : String(error2);
|
|
151
|
+
if (!errorMessage.includes("406") && !errorMessage.includes("PGRST116")) {
|
|
152
|
+
log.error("Unexpected error resolving app config:", error2);
|
|
153
|
+
} else {
|
|
154
|
+
log.debug("App resolution skipped - authentication required");
|
|
155
|
+
}
|
|
141
156
|
}
|
|
142
157
|
}
|
|
143
158
|
const initialScope = {
|
|
@@ -399,7 +414,6 @@ function PublicPageProvider({ children, appName }) {
|
|
|
399
414
|
return null;
|
|
400
415
|
}
|
|
401
416
|
const client = createClient(supabaseUrl, supabaseKey);
|
|
402
|
-
logger.info("PublicPageProvider", "Supabase client created successfully for public pages");
|
|
403
417
|
return client;
|
|
404
418
|
}, [supabaseUrl, supabaseKey]);
|
|
405
419
|
const contextValue = {
|
|
@@ -481,124 +495,185 @@ function useAppConfig() {
|
|
|
481
495
|
}
|
|
482
496
|
}
|
|
483
497
|
|
|
484
|
-
// src/
|
|
485
|
-
import {
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
enabled,
|
|
492
|
-
reason = "client_request"
|
|
493
|
-
}) {
|
|
494
|
-
if (!supabase) {
|
|
495
|
-
return;
|
|
496
|
-
}
|
|
497
|
-
try {
|
|
498
|
-
const { error } = await supabase.rpc("set_super_admin_override", {
|
|
499
|
-
p_enabled: enabled,
|
|
500
|
-
p_reason: reason
|
|
501
|
-
});
|
|
502
|
-
if (error) {
|
|
503
|
-
log2.error("Failed to toggle super admin override", {
|
|
504
|
-
enabled,
|
|
505
|
-
reason,
|
|
506
|
-
error: error.message
|
|
507
|
-
});
|
|
508
|
-
} else {
|
|
509
|
-
log2.debug("Super admin override flag updated", { enabled, reason });
|
|
510
|
-
}
|
|
511
|
-
} catch (rpcError) {
|
|
512
|
-
log2.error("Unexpected error toggling super admin override", {
|
|
513
|
-
enabled,
|
|
514
|
-
reason,
|
|
515
|
-
error: rpcError instanceof Error ? rpcError.message : rpcError
|
|
516
|
-
});
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
// src/rbac/hooks/useSuperAdminBypass.ts
|
|
521
|
-
var log3 = createLogger("useSuperAdminBypass");
|
|
522
|
-
function useSafeUnifiedAuth() {
|
|
523
|
-
try {
|
|
524
|
-
return useUnifiedAuth();
|
|
525
|
-
} catch (error) {
|
|
526
|
-
log3.debug("useSuperAdminBypass", "UnifiedAuthProvider not available, falling back to defaults", {
|
|
527
|
-
error: error instanceof Error ? error.message : error
|
|
528
|
-
});
|
|
529
|
-
return null;
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
function useSuperAdminBypass() {
|
|
533
|
-
const authContext = useSafeUnifiedAuth();
|
|
534
|
-
const user = authContext?.user ?? null;
|
|
535
|
-
const supabase = authContext?.supabase ?? null;
|
|
536
|
-
const metadataHint = Boolean(user?.app_metadata?.is_super_admin) || Boolean(user?.user_metadata?.is_super_admin);
|
|
537
|
-
const [isSuperAdminState, setIsSuperAdminState] = useState2(metadataHint);
|
|
538
|
-
const [hasVerified, setHasVerified] = useState2(!user?.id);
|
|
539
|
-
const [isLoading, setIsLoading] = useState2(!!user?.id);
|
|
540
|
-
const [error, setError] = useState2(null);
|
|
541
|
-
const lastOverrideValueRef = useRef3(null);
|
|
498
|
+
// src/hooks/useOrganisationSecurity.ts
|
|
499
|
+
import { useCallback, useMemo as useMemo5, useEffect as useEffect2, useState as useState2 } from "react";
|
|
500
|
+
var useOrganisationSecurity = () => {
|
|
501
|
+
const { user, session, supabase } = useUnifiedAuth();
|
|
502
|
+
const { selectedOrganisation, getUserRole, validateOrganisationAccess: validateAccess } = useOrganisations();
|
|
503
|
+
const [isSuperAdmin, setIsSuperAdmin] = useState2(false);
|
|
504
|
+
const [isCheckingSuperAdmin, setIsCheckingSuperAdmin] = useState2(false);
|
|
542
505
|
useEffect2(() => {
|
|
543
|
-
if (!user
|
|
544
|
-
|
|
545
|
-
setHasVerified(true);
|
|
546
|
-
setIsLoading(false);
|
|
547
|
-
setError(null);
|
|
506
|
+
if (!user || !session || !supabase) {
|
|
507
|
+
setIsSuperAdmin(false);
|
|
548
508
|
return;
|
|
549
509
|
}
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
510
|
+
const checkSuperAdmin = async () => {
|
|
511
|
+
setIsCheckingSuperAdmin(true);
|
|
512
|
+
try {
|
|
513
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
514
|
+
const { data, error } = await supabase.from("rbac_global_roles").select("role").eq("user_id", user.id).eq("role", "super_admin").lte("valid_from", now).or(`valid_to.is.null,valid_to.gte.${now}`).limit(1);
|
|
515
|
+
setIsSuperAdmin(!error && data && data.length > 0);
|
|
516
|
+
} catch (error) {
|
|
517
|
+
logger.error("useOrganisationSecurity", "Error checking super admin status:", error);
|
|
518
|
+
setIsSuperAdmin(false);
|
|
519
|
+
} finally {
|
|
520
|
+
setIsCheckingSuperAdmin(false);
|
|
556
521
|
}
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
522
|
+
};
|
|
523
|
+
checkSuperAdmin();
|
|
524
|
+
}, [user, session, supabase]);
|
|
525
|
+
const superAdminContext = useMemo5(() => {
|
|
526
|
+
return {
|
|
527
|
+
isSuperAdmin,
|
|
528
|
+
hasGlobalAccess: isSuperAdmin,
|
|
529
|
+
canManageAllOrganisations: isSuperAdmin
|
|
530
|
+
};
|
|
531
|
+
}, [isSuperAdmin]);
|
|
532
|
+
const validateOrganisationAccess = useCallback(async (orgId) => {
|
|
533
|
+
if (!user || !session || !supabase) return false;
|
|
534
|
+
try {
|
|
535
|
+
if (superAdminContext.isSuperAdmin) {
|
|
536
|
+
return true;
|
|
562
537
|
}
|
|
563
|
-
const
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
log3.error("Unable to verify super admin status", normalisedError);
|
|
568
|
-
}).finally(() => {
|
|
569
|
-
if (!cancelled) {
|
|
570
|
-
setIsLoading(false);
|
|
538
|
+
const { data, error } = await supabase.from("rbac_organisation_roles").select("id").eq("user_id", user.id).eq("organisation_id", orgId).eq("status", "active").is("revoked_at", null).in("role", ["org_admin", "leader", "member"]).single();
|
|
539
|
+
if (error) {
|
|
540
|
+
logger.error("useOrganisationSecurity", "Error validating organisation access:", error);
|
|
541
|
+
return false;
|
|
571
542
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
}, [user?.id]);
|
|
577
|
-
const shouldBypass = hasVerified && isSuperAdminState;
|
|
578
|
-
useEffect2(() => {
|
|
579
|
-
if (!supabase) {
|
|
580
|
-
return;
|
|
543
|
+
return !!data;
|
|
544
|
+
} catch (error) {
|
|
545
|
+
logger.error("useOrganisationSecurity", "Exception validating organisation access:", error);
|
|
546
|
+
return false;
|
|
581
547
|
}
|
|
582
|
-
|
|
583
|
-
|
|
548
|
+
}, [user, session, supabase, superAdminContext.isSuperAdmin]);
|
|
549
|
+
const hasMinimumRole = useCallback((minRole, orgId) => {
|
|
550
|
+
if (superAdminContext.isSuperAdmin) {
|
|
551
|
+
return true;
|
|
584
552
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
}, [
|
|
593
|
-
|
|
594
|
-
()
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
}
|
|
553
|
+
const targetOrgId = orgId || selectedOrganisation?.id;
|
|
554
|
+
if (!targetOrgId) return false;
|
|
555
|
+
const userRole = getUserRole(targetOrgId);
|
|
556
|
+
const roleHierarchy = ["supporter", "member", "leader", "org_admin"];
|
|
557
|
+
const userRoleIndex = roleHierarchy.indexOf(userRole);
|
|
558
|
+
const minRoleIndex = roleHierarchy.indexOf(minRole);
|
|
559
|
+
return userRoleIndex >= minRoleIndex;
|
|
560
|
+
}, [selectedOrganisation, getUserRole, superAdminContext.isSuperAdmin]);
|
|
561
|
+
const canAccessChildOrganisations = useCallback((orgId) => {
|
|
562
|
+
if (superAdminContext.isSuperAdmin) {
|
|
563
|
+
return true;
|
|
564
|
+
}
|
|
565
|
+
const targetOrgId = orgId || selectedOrganisation?.id;
|
|
566
|
+
if (!targetOrgId) return false;
|
|
567
|
+
const userRole = getUserRole(targetOrgId);
|
|
568
|
+
return userRole === "org_admin";
|
|
569
|
+
}, [selectedOrganisation, getUserRole, superAdminContext.isSuperAdmin]);
|
|
570
|
+
const hasPermission = useCallback(async (permission, orgId) => {
|
|
571
|
+
if (superAdminContext.isSuperAdmin) {
|
|
572
|
+
return true;
|
|
573
|
+
}
|
|
574
|
+
const targetOrgId = orgId || selectedOrganisation?.id;
|
|
575
|
+
if (!targetOrgId || !user) return false;
|
|
576
|
+
try {
|
|
577
|
+
const { isPermittedCached } = await import("./api-N774RPUA.js");
|
|
578
|
+
const scope = {
|
|
579
|
+
organisationId: targetOrgId,
|
|
580
|
+
eventId: user.user_metadata?.eventId || user.app_metadata?.eventId,
|
|
581
|
+
appId: user.user_metadata?.appId || user.app_metadata?.appId
|
|
582
|
+
};
|
|
583
|
+
return await isPermittedCached({
|
|
584
|
+
userId: user.id,
|
|
585
|
+
scope,
|
|
586
|
+
permission
|
|
587
|
+
});
|
|
588
|
+
} catch (error) {
|
|
589
|
+
logger.error("useOrganisationSecurity", "Exception checking permission:", error);
|
|
590
|
+
return false;
|
|
591
|
+
}
|
|
592
|
+
}, [selectedOrganisation, user, superAdminContext.isSuperAdmin]);
|
|
593
|
+
const getUserPermissions = useCallback(async (orgId) => {
|
|
594
|
+
if (superAdminContext.isSuperAdmin) {
|
|
595
|
+
return ["*"];
|
|
596
|
+
}
|
|
597
|
+
const targetOrgId = orgId || selectedOrganisation?.id;
|
|
598
|
+
if (!targetOrgId || !user) return [];
|
|
599
|
+
try {
|
|
600
|
+
const { getPermissionMap } = await import("./api-N774RPUA.js");
|
|
601
|
+
const scope = {
|
|
602
|
+
organisationId: targetOrgId,
|
|
603
|
+
eventId: user.user_metadata?.eventId || user.app_metadata?.eventId,
|
|
604
|
+
appId: user.user_metadata?.appId || user.app_metadata?.appId
|
|
605
|
+
};
|
|
606
|
+
const permissionMap = await getPermissionMap({
|
|
607
|
+
userId: user.id,
|
|
608
|
+
scope
|
|
609
|
+
});
|
|
610
|
+
const allPermissions = Object.entries(permissionMap).filter(([, allowed]) => allowed).map(([permission]) => permission);
|
|
611
|
+
return [...new Set(allPermissions)];
|
|
612
|
+
} catch (error) {
|
|
613
|
+
logger.error("useOrganisationSecurity", "Exception getting user permissions:", error);
|
|
614
|
+
return [];
|
|
615
|
+
}
|
|
616
|
+
}, [selectedOrganisation, user, getUserRole, superAdminContext.isSuperAdmin]);
|
|
617
|
+
const logOrganisationAccess = useCallback(async (action, details) => {
|
|
618
|
+
if (!user || !selectedOrganisation) return;
|
|
619
|
+
try {
|
|
620
|
+
if (selectedOrganisation.id) {
|
|
621
|
+
const { emitAuditEvent } = await import("./audit-B5P6FFIR.js");
|
|
622
|
+
await emitAuditEvent({
|
|
623
|
+
type: "permission_check",
|
|
624
|
+
userId: user.id,
|
|
625
|
+
organisationId: selectedOrganisation.id,
|
|
626
|
+
permission: action,
|
|
627
|
+
decision: true,
|
|
628
|
+
// Assume access was granted if we're logging it
|
|
629
|
+
source: "api",
|
|
630
|
+
duration_ms: 0,
|
|
631
|
+
// No actual permission check performed here
|
|
632
|
+
metadata: details || {}
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
} catch (error) {
|
|
636
|
+
logger.error("useOrganisationSecurity", "Error logging organisation access:", error);
|
|
637
|
+
}
|
|
638
|
+
}, [user, selectedOrganisation]);
|
|
639
|
+
const ensureOrganisationAccess = useCallback(async (orgId) => {
|
|
640
|
+
const hasAccess = await validateOrganisationAccess(orgId);
|
|
641
|
+
if (!hasAccess) {
|
|
642
|
+
const error = new Error(`User does not have access to organisation ${orgId}`);
|
|
643
|
+
error.name = "OrganisationSecurityError";
|
|
644
|
+
error.code = "ACCESS_DENIED";
|
|
645
|
+
error.organisationId = orgId;
|
|
646
|
+
error.userId = user?.id;
|
|
647
|
+
throw error;
|
|
648
|
+
}
|
|
649
|
+
}, [validateOrganisationAccess, user]);
|
|
650
|
+
const validateUserAccess = useCallback(async (userId, orgId) => {
|
|
651
|
+
if (!supabase) return false;
|
|
652
|
+
try {
|
|
653
|
+
if (superAdminContext.isSuperAdmin) {
|
|
654
|
+
return true;
|
|
655
|
+
}
|
|
656
|
+
if (userId !== user?.id) {
|
|
657
|
+
return false;
|
|
658
|
+
}
|
|
659
|
+
return await validateOrganisationAccess(orgId);
|
|
660
|
+
} catch (error) {
|
|
661
|
+
logger.error("useOrganisationSecurity", "Exception validating user access:", error);
|
|
662
|
+
return false;
|
|
663
|
+
}
|
|
664
|
+
}, [supabase, superAdminContext.isSuperAdmin, user, validateOrganisationAccess]);
|
|
665
|
+
return {
|
|
666
|
+
superAdminContext,
|
|
667
|
+
validateOrganisationAccess,
|
|
668
|
+
hasMinimumRole,
|
|
669
|
+
canAccessChildOrganisations,
|
|
670
|
+
hasPermission,
|
|
671
|
+
getUserPermissions,
|
|
672
|
+
logOrganisationAccess,
|
|
673
|
+
ensureOrganisationAccess,
|
|
674
|
+
validateUserAccess
|
|
675
|
+
};
|
|
676
|
+
};
|
|
602
677
|
|
|
603
678
|
export {
|
|
604
679
|
useEvents,
|
|
@@ -609,6 +684,6 @@ export {
|
|
|
609
684
|
usePublicPageContext,
|
|
610
685
|
useIsPublicPage,
|
|
611
686
|
useAppConfig,
|
|
612
|
-
|
|
687
|
+
useOrganisationSecurity
|
|
613
688
|
};
|
|
614
|
-
//# sourceMappingURL=chunk-
|
|
689
|
+
//# sourceMappingURL=chunk-IIELH4DL.js.map
|