@jmruthers/pace-core 0.6.2 → 0.6.3
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/CHANGELOG.md +45 -0
- package/cursor-rules/00-pace-core-compliance.mdc +34 -2
- package/dist/{AuthService-BPvc3Ka0.d.ts → AuthService-Cb34EQs3.d.ts} +9 -1
- package/dist/{DataTable-TPTKCX4D.js → DataTable-THFPBKTP.js} +9 -8
- package/dist/{PublicPageProvider-DC6kCaqf.d.ts → PublicPageProvider-DEMpysFR.d.ts} +45 -67
- package/dist/{UnifiedAuthProvider-CVcTjx-d.d.ts → UnifiedAuthProvider-CKvHP1MK.d.ts} +1 -8
- package/dist/{UnifiedAuthProvider-CH6Z342H.js → UnifiedAuthProvider-KAGUYQ4J.js} +5 -4
- package/dist/{api-MVVQZLJI.js → api-IAGWF3ZG.js} +10 -10
- package/dist/{audit-B5P6FFIR.js → audit-V53FV5AG.js} +2 -2
- package/dist/{chunk-SFZUDBL5.js → chunk-2T2IG7T7.js} +70 -56
- package/dist/chunk-2T2IG7T7.js.map +1 -0
- package/dist/{chunk-MMZ7JXPU.js → chunk-6Z7LTB3D.js} +13 -21
- package/dist/{chunk-MMZ7JXPU.js.map → chunk-6Z7LTB3D.js.map} +1 -1
- package/dist/{chunk-6J4GEEJR.js → chunk-CNCQDFLN.js} +53 -27
- package/dist/chunk-CNCQDFLN.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/{chunk-EHMR7VYL.js → chunk-DWUBLJJM.js} +361 -187
- package/dist/chunk-DWUBLJJM.js.map +1 -0
- package/dist/{chunk-2UOI2FG5.js → chunk-HFZBI76P.js} +4 -4
- package/dist/{chunk-F2IMUDXZ.js → chunk-M7MPQISP.js} +2 -2
- package/dist/{chunk-3XC4CPTD.js → chunk-PQBSKX33.js} +244 -5727
- package/dist/chunk-PQBSKX33.js.map +1 -0
- package/dist/chunk-QRPVRXYT.js +226 -0
- package/dist/chunk-QRPVRXYT.js.map +1 -0
- package/dist/{chunk-24UVZUZG.js → chunk-RWEBCB47.js} +129 -387
- package/dist/chunk-RWEBCB47.js.map +1 -0
- package/dist/{chunk-XWQCNGTQ.js → chunk-YDQHOZNA.js} +173 -79
- package/dist/chunk-YDQHOZNA.js.map +1 -0
- package/dist/{chunk-NECFR5MM.js → chunk-ZNIWI3UC.js} +562 -644
- package/dist/chunk-ZNIWI3UC.js.map +1 -0
- package/dist/components.d.ts +2 -2
- package/dist/components.js +12 -13
- package/dist/contextValidator-3JNZKUTX.js +9 -0
- package/dist/contextValidator-3JNZKUTX.js.map +1 -0
- package/dist/eslint-rules/pace-core-compliance.cjs +106 -0
- package/dist/hooks.d.ts +2 -2
- package/dist/hooks.js +7 -6
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.js +21 -16
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +3 -3
- package/dist/providers.js +4 -3
- package/dist/rbac/index.d.ts +67 -27
- package/dist/rbac/index.js +15 -8
- package/dist/styles/index.js +1 -1
- package/dist/theming/runtime.js +1 -1
- package/dist/types.js +1 -1
- package/dist/{usePublicRouteParams-1oMokgLF.d.ts → usePublicRouteParams-i3qtoBgg.d.ts} +7 -16
- package/dist/utils.js +5 -7
- package/dist/utils.js.map +1 -1
- package/docs/api/README.md +14 -16
- package/docs/api/modules.md +3796 -2513
- package/docs/components/context-selector.md +126 -0
- package/docs/migration/RBAC_SCOPE_MIGRATION.md +385 -0
- package/docs/pace-mint-fix-auto-selection.md +218 -0
- package/docs/pace-mint-rbac-setup.md +391 -0
- package/docs/rbac/secure-client-protection.md +330 -0
- package/package.json +3 -3
- package/scripts/audit/core/checks/compliance.cjs +72 -0
- package/scripts/audit/core/checks/dependencies.cjs +559 -28
- package/scripts/audit/core/checks/documentation.cjs +68 -3
- package/scripts/audit/core/checks/environment.cjs +2 -14
- package/scripts/audit/core/checks/error-handling.cjs +47 -6
- package/src/components/ContextSelector/ContextSelector.tsx +384 -0
- package/src/components/ContextSelector/index.ts +3 -0
- package/src/components/DataTable/components/RowComponent.tsx +19 -19
- package/src/components/DataTable/components/UnifiedTableBody.tsx +2 -2
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +8 -6
- package/src/components/Dialog/Dialog.tsx +29 -1
- package/src/components/FileDisplay/FileDisplay.tsx +42 -10
- package/src/components/Header/Header.test.tsx +43 -73
- package/src/components/Header/Header.tsx +44 -45
- package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +10 -19
- package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +2 -2
- package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +5 -5
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +9 -9
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +135 -33
- package/src/components/PaceAppLayout/README.md +14 -17
- package/src/components/PaceAppLayout/test-setup.tsx +2 -2
- package/src/components/index.ts +5 -5
- package/src/eslint-rules/pace-core-compliance.cjs +106 -0
- package/src/hooks/__tests__/useAppConfig.unit.test.ts +4 -98
- package/src/hooks/useAppConfig.ts +15 -30
- package/src/hooks/useFileDisplay.ts +77 -50
- package/src/index.ts +4 -5
- package/src/providers/services/AuthServiceProvider.tsx +17 -7
- package/src/providers/services/EventServiceProvider.tsx +33 -5
- package/src/providers/services/UnifiedAuthProvider.tsx +90 -134
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +1 -1
- package/src/rbac/adapters.tsx +2 -2
- package/src/rbac/api.test.ts +59 -51
- package/src/rbac/api.ts +178 -132
- package/src/rbac/components/PagePermissionGuard.tsx +38 -10
- package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +32 -21
- package/src/rbac/hooks/permissions/useAccessLevel.ts +1 -1
- package/src/rbac/hooks/permissions/useCan.ts +41 -11
- package/src/rbac/hooks/permissions/useHasAllPermissions.ts +1 -1
- package/src/rbac/hooks/permissions/useHasAnyPermission.ts +1 -1
- package/src/rbac/hooks/permissions/useMultiplePermissions.ts +1 -1
- package/src/rbac/hooks/useCan.test.ts +0 -9
- package/src/rbac/hooks/useRBAC.test.ts +1 -5
- package/src/rbac/hooks/useRBAC.ts +36 -37
- package/src/rbac/hooks/useResolvedScope.test.ts +120 -35
- package/src/rbac/hooks/useResolvedScope.ts +35 -40
- package/src/rbac/hooks/useSecureSupabase.ts +7 -7
- package/src/rbac/index.ts +7 -0
- package/src/rbac/secureClient.test.ts +22 -18
- package/src/rbac/secureClient.ts +103 -16
- package/src/rbac/security.ts +0 -17
- package/src/rbac/types.ts +1 -0
- package/src/rbac/utils/__tests__/contextValidator.test.ts +64 -86
- package/src/rbac/utils/clientSecurity.ts +93 -0
- package/src/rbac/utils/contextValidator.ts +77 -168
- package/src/services/AuthService.ts +39 -7
- package/src/services/EventService.ts +186 -54
- package/src/services/OrganisationService.ts +81 -14
- package/src/services/__tests__/EventService.test.ts +1 -2
- package/src/services/base/BaseService.ts +3 -0
- package/src/utils/dynamic/dynamicUtils.ts +7 -4
- package/dist/chunk-24UVZUZG.js.map +0 -1
- package/dist/chunk-3XC4CPTD.js.map +0 -1
- package/dist/chunk-6J4GEEJR.js.map +0 -1
- package/dist/chunk-7D4SUZUM.js +0 -38
- package/dist/chunk-EHMR7VYL.js.map +0 -1
- package/dist/chunk-NECFR5MM.js.map +0 -1
- package/dist/chunk-SFZUDBL5.js.map +0 -1
- package/dist/chunk-XWQCNGTQ.js.map +0 -1
- package/docs/api/classes/ColumnFactory.md +0 -243
- package/docs/api/classes/InvalidScopeError.md +0 -73
- package/docs/api/classes/Logger.md +0 -178
- package/docs/api/classes/MissingUserContextError.md +0 -66
- package/docs/api/classes/OrganisationContextRequiredError.md +0 -66
- package/docs/api/classes/PermissionDeniedError.md +0 -73
- package/docs/api/classes/RBACAuditManager.md +0 -297
- package/docs/api/classes/RBACCache.md +0 -322
- package/docs/api/classes/RBACEngine.md +0 -171
- package/docs/api/classes/RBACError.md +0 -76
- package/docs/api/classes/RBACNotInitializedError.md +0 -66
- package/docs/api/classes/SecureSupabaseClient.md +0 -163
- package/docs/api/classes/StorageUtils.md +0 -328
- package/docs/api/enums/FileCategory.md +0 -184
- package/docs/api/enums/LogLevel.md +0 -54
- package/docs/api/enums/RBACErrorCode.md +0 -228
- package/docs/api/enums/RPCFunction.md +0 -118
- package/docs/api/interfaces/AddressFieldProps.md +0 -241
- package/docs/api/interfaces/AddressFieldRef.md +0 -94
- package/docs/api/interfaces/AggregateConfig.md +0 -43
- package/docs/api/interfaces/AutocompleteOptions.md +0 -75
- package/docs/api/interfaces/AvatarProps.md +0 -128
- package/docs/api/interfaces/BadgeProps.md +0 -34
- package/docs/api/interfaces/ButtonProps.md +0 -56
- package/docs/api/interfaces/CalendarProps.md +0 -73
- package/docs/api/interfaces/CardProps.md +0 -69
- package/docs/api/interfaces/ColorPalette.md +0 -7
- package/docs/api/interfaces/ColorShade.md +0 -66
- package/docs/api/interfaces/ComplianceResult.md +0 -30
- package/docs/api/interfaces/DataAccessRecord.md +0 -96
- package/docs/api/interfaces/DataRecord.md +0 -11
- package/docs/api/interfaces/DataTableAction.md +0 -252
- package/docs/api/interfaces/DataTableColumn.md +0 -504
- package/docs/api/interfaces/DataTableProps.md +0 -625
- package/docs/api/interfaces/DataTableToolbarButton.md +0 -96
- package/docs/api/interfaces/DatabaseComplianceResult.md +0 -85
- package/docs/api/interfaces/DatabaseIssue.md +0 -41
- package/docs/api/interfaces/EmptyStateConfig.md +0 -61
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +0 -235
- package/docs/api/interfaces/ErrorBoundaryProps.md +0 -147
- package/docs/api/interfaces/ErrorBoundaryProviderProps.md +0 -36
- package/docs/api/interfaces/ErrorBoundaryState.md +0 -75
- package/docs/api/interfaces/EventAppRoleData.md +0 -71
- package/docs/api/interfaces/ExportColumn.md +0 -90
- package/docs/api/interfaces/ExportOptions.md +0 -126
- package/docs/api/interfaces/FileDisplayProps.md +0 -249
- package/docs/api/interfaces/FileMetadata.md +0 -129
- package/docs/api/interfaces/FileReference.md +0 -118
- package/docs/api/interfaces/FileSizeLimits.md +0 -7
- package/docs/api/interfaces/FileUploadOptions.md +0 -139
- package/docs/api/interfaces/FileUploadProps.md +0 -296
- package/docs/api/interfaces/FooterProps.md +0 -107
- package/docs/api/interfaces/FormFieldProps.md +0 -166
- package/docs/api/interfaces/FormProps.md +0 -113
- package/docs/api/interfaces/GrantEventAppRoleParams.md +0 -122
- package/docs/api/interfaces/InactivityWarningModalProps.md +0 -115
- package/docs/api/interfaces/InputProps.md +0 -56
- package/docs/api/interfaces/LabelProps.md +0 -107
- package/docs/api/interfaces/LoggerConfig.md +0 -62
- package/docs/api/interfaces/LoginFormProps.md +0 -187
- package/docs/api/interfaces/NavigationAccessRecord.md +0 -107
- package/docs/api/interfaces/NavigationContextType.md +0 -164
- package/docs/api/interfaces/NavigationGuardProps.md +0 -139
- package/docs/api/interfaces/NavigationItem.md +0 -120
- package/docs/api/interfaces/NavigationMenuProps.md +0 -221
- package/docs/api/interfaces/NavigationProviderProps.md +0 -117
- package/docs/api/interfaces/Organisation.md +0 -140
- package/docs/api/interfaces/OrganisationContextType.md +0 -388
- package/docs/api/interfaces/OrganisationMembership.md +0 -140
- package/docs/api/interfaces/OrganisationProviderProps.md +0 -76
- package/docs/api/interfaces/OrganisationSecurityError.md +0 -62
- package/docs/api/interfaces/PaceAppLayoutProps.md +0 -409
- package/docs/api/interfaces/PaceLoginPageProps.md +0 -49
- package/docs/api/interfaces/PageAccessRecord.md +0 -85
- package/docs/api/interfaces/PagePermissionContextType.md +0 -140
- package/docs/api/interfaces/PagePermissionGuardProps.md +0 -153
- package/docs/api/interfaces/PagePermissionProviderProps.md +0 -119
- package/docs/api/interfaces/PaletteData.md +0 -41
- package/docs/api/interfaces/ParsedAddress.md +0 -120
- package/docs/api/interfaces/PermissionEnforcerProps.md +0 -153
- package/docs/api/interfaces/ProgressProps.md +0 -42
- package/docs/api/interfaces/ProtectedRouteProps.md +0 -78
- package/docs/api/interfaces/PublicPageFooterProps.md +0 -112
- package/docs/api/interfaces/PublicPageHeaderProps.md +0 -125
- package/docs/api/interfaces/PublicPageLayoutProps.md +0 -185
- package/docs/api/interfaces/QuickFix.md +0 -52
- package/docs/api/interfaces/RBACAccessValidateParams.md +0 -52
- package/docs/api/interfaces/RBACAccessValidateResult.md +0 -41
- package/docs/api/interfaces/RBACAuditLogParams.md +0 -85
- package/docs/api/interfaces/RBACAuditLogResult.md +0 -52
- package/docs/api/interfaces/RBACConfig.md +0 -133
- package/docs/api/interfaces/RBACContext.md +0 -52
- package/docs/api/interfaces/RBACLogger.md +0 -112
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +0 -74
- package/docs/api/interfaces/RBACPerformanceMetrics.md +0 -138
- package/docs/api/interfaces/RBACPermissionCheckParams.md +0 -74
- package/docs/api/interfaces/RBACPermissionCheckResult.md +0 -52
- package/docs/api/interfaces/RBACPermissionsGetParams.md +0 -63
- package/docs/api/interfaces/RBACPermissionsGetResult.md +0 -63
- package/docs/api/interfaces/RBACResult.md +0 -58
- package/docs/api/interfaces/RBACRoleGrantParams.md +0 -63
- package/docs/api/interfaces/RBACRoleGrantResult.md +0 -52
- package/docs/api/interfaces/RBACRoleRevokeParams.md +0 -63
- package/docs/api/interfaces/RBACRoleRevokeResult.md +0 -52
- package/docs/api/interfaces/RBACRoleValidateParams.md +0 -52
- package/docs/api/interfaces/RBACRoleValidateResult.md +0 -63
- package/docs/api/interfaces/RBACRolesListParams.md +0 -52
- package/docs/api/interfaces/RBACRolesListResult.md +0 -74
- package/docs/api/interfaces/RBACSessionTrackParams.md +0 -74
- package/docs/api/interfaces/RBACSessionTrackResult.md +0 -52
- package/docs/api/interfaces/ResourcePermissions.md +0 -155
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +0 -100
- package/docs/api/interfaces/RoleBasedRouterContextType.md +0 -151
- package/docs/api/interfaces/RoleBasedRouterProps.md +0 -156
- package/docs/api/interfaces/RoleManagementResult.md +0 -52
- package/docs/api/interfaces/RouteAccessRecord.md +0 -107
- package/docs/api/interfaces/RouteConfig.md +0 -134
- package/docs/api/interfaces/RuntimeComplianceResult.md +0 -55
- package/docs/api/interfaces/SecureDataContextType.md +0 -168
- package/docs/api/interfaces/SecureDataProviderProps.md +0 -132
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +0 -34
- package/docs/api/interfaces/SetupIssue.md +0 -41
- package/docs/api/interfaces/StorageConfig.md +0 -41
- package/docs/api/interfaces/StorageFileInfo.md +0 -74
- package/docs/api/interfaces/StorageFileMetadata.md +0 -151
- package/docs/api/interfaces/StorageListOptions.md +0 -99
- package/docs/api/interfaces/StorageListResult.md +0 -41
- package/docs/api/interfaces/StorageUploadOptions.md +0 -101
- package/docs/api/interfaces/StorageUploadResult.md +0 -63
- package/docs/api/interfaces/StorageUrlOptions.md +0 -60
- package/docs/api/interfaces/StyleImport.md +0 -19
- package/docs/api/interfaces/SwitchProps.md +0 -34
- package/docs/api/interfaces/TabsContentProps.md +0 -9
- package/docs/api/interfaces/TabsListProps.md +0 -9
- package/docs/api/interfaces/TabsProps.md +0 -9
- package/docs/api/interfaces/TabsTriggerProps.md +0 -50
- package/docs/api/interfaces/TextareaProps.md +0 -53
- package/docs/api/interfaces/ToastActionElement.md +0 -12
- package/docs/api/interfaces/ToastProps.md +0 -9
- package/docs/api/interfaces/UnifiedAuthContextType.md +0 -823
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +0 -173
- package/docs/api/interfaces/UseFormDialogOptions.md +0 -62
- package/docs/api/interfaces/UseFormDialogReturn.md +0 -117
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +0 -138
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +0 -123
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +0 -87
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +0 -84
- package/docs/api/interfaces/UsePublicEventOptions.md +0 -34
- package/docs/api/interfaces/UsePublicEventReturn.md +0 -71
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +0 -47
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +0 -123
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +0 -97
- package/docs/api/interfaces/UseResolvedScopeOptions.md +0 -47
- package/docs/api/interfaces/UseResolvedScopeReturn.md +0 -47
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +0 -34
- package/docs/api/interfaces/UserEventAccess.md +0 -121
- package/docs/api/interfaces/UserMenuProps.md +0 -88
- package/docs/api/interfaces/UserProfile.md +0 -63
- package/src/components/EventSelector/EventSelector.test.tsx +0 -720
- package/src/components/EventSelector/EventSelector.tsx +0 -423
- package/src/components/EventSelector/index.ts +0 -3
- package/src/components/OrganisationSelector/OrganisationSelector.test.tsx +0 -784
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +0 -327
- package/src/components/OrganisationSelector/index.ts +0 -9
- /package/dist/{DataTable-TPTKCX4D.js.map → DataTable-THFPBKTP.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-CH6Z342H.js.map → UnifiedAuthProvider-KAGUYQ4J.js.map} +0 -0
- /package/dist/{api-MVVQZLJI.js.map → api-IAGWF3ZG.js.map} +0 -0
- /package/dist/{audit-B5P6FFIR.js.map → audit-V53FV5AG.js.map} +0 -0
- /package/dist/{chunk-7D4SUZUM.js.map → chunk-DGUM43GV.js.map} +0 -0
- /package/dist/{chunk-2UOI2FG5.js.map → chunk-HFZBI76P.js.map} +0 -0
- /package/dist/{chunk-F2IMUDXZ.js.map → chunk-M7MPQISP.js.map} +0 -0
|
@@ -3,76 +3,19 @@ import {
|
|
|
3
3
|
emitAuditEvent,
|
|
4
4
|
setGlobalAuditManager
|
|
5
5
|
} from "./chunk-63FOKYGO.js";
|
|
6
|
+
import {
|
|
7
|
+
ContextValidator,
|
|
8
|
+
InvalidScopeError,
|
|
9
|
+
MissingUserContextError,
|
|
10
|
+
OrganisationContextRequiredError,
|
|
11
|
+
PermissionDeniedError,
|
|
12
|
+
RBACError,
|
|
13
|
+
RBACNotInitializedError
|
|
14
|
+
} from "./chunk-QRPVRXYT.js";
|
|
6
15
|
import {
|
|
7
16
|
createLogger
|
|
8
17
|
} from "./chunk-PWLANIRT.js";
|
|
9
18
|
|
|
10
|
-
// src/rbac/types.ts
|
|
11
|
-
var RBACError = class extends Error {
|
|
12
|
-
constructor(message, code, context) {
|
|
13
|
-
super(message);
|
|
14
|
-
this.code = code;
|
|
15
|
-
this.context = context;
|
|
16
|
-
this.name = "RBACError";
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
var PermissionDeniedError = class extends RBACError {
|
|
20
|
-
constructor(permission, context) {
|
|
21
|
-
super(
|
|
22
|
-
`Permission denied: ${permission}`,
|
|
23
|
-
"PERMISSION_DENIED",
|
|
24
|
-
{ permission, ...context }
|
|
25
|
-
);
|
|
26
|
-
this.name = "PermissionDeniedError";
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
var OrganisationContextRequiredError = class extends RBACError {
|
|
30
|
-
constructor() {
|
|
31
|
-
super(
|
|
32
|
-
"Organisation context is required for this operation",
|
|
33
|
-
"ORGANISATION_CONTEXT_REQUIRED"
|
|
34
|
-
);
|
|
35
|
-
this.name = "OrganisationContextRequiredError";
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
var EventContextRequiredError = class extends RBACError {
|
|
39
|
-
constructor() {
|
|
40
|
-
super(
|
|
41
|
-
"Event context is required for this operation",
|
|
42
|
-
"EVENT_CONTEXT_REQUIRED"
|
|
43
|
-
);
|
|
44
|
-
this.name = "EventContextRequiredError";
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
var RBACNotInitializedError = class extends RBACError {
|
|
48
|
-
constructor() {
|
|
49
|
-
super(
|
|
50
|
-
"RBAC system not initialized. Please call setupRBAC(supabase) before using any RBAC components or hooks. See: https://docs.pace-core.dev/rbac/setup",
|
|
51
|
-
"RBAC_NOT_INITIALIZED"
|
|
52
|
-
);
|
|
53
|
-
this.name = "RBACNotInitializedError";
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
var InvalidScopeError = class extends RBACError {
|
|
57
|
-
constructor(scope, reason) {
|
|
58
|
-
super(
|
|
59
|
-
`Invalid scope provided: ${JSON.stringify(scope)}. ${reason}`,
|
|
60
|
-
"INVALID_SCOPE",
|
|
61
|
-
{ scope, reason }
|
|
62
|
-
);
|
|
63
|
-
this.name = "InvalidScopeError";
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
var MissingUserContextError = class extends RBACError {
|
|
67
|
-
constructor() {
|
|
68
|
-
super(
|
|
69
|
-
"User context is required but not available. Make sure to wrap your app with an auth provider.",
|
|
70
|
-
"MISSING_USER_CONTEXT"
|
|
71
|
-
);
|
|
72
|
-
this.name = "MissingUserContextError";
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
|
|
76
19
|
// src/rbac/cache.ts
|
|
77
20
|
var RBACCache = class {
|
|
78
21
|
constructor() {
|
|
@@ -694,228 +637,8 @@ function mapErrorCategoryToSecurityEventType(category) {
|
|
|
694
637
|
}
|
|
695
638
|
}
|
|
696
639
|
|
|
697
|
-
// src/rbac/utils/eventContext.ts
|
|
698
|
-
var orgDerivationCache = /* @__PURE__ */ new Map();
|
|
699
|
-
var MAX_CACHE_SIZE = 100;
|
|
700
|
-
async function getOrganisationFromEvent(supabase, eventId) {
|
|
701
|
-
if (orgDerivationCache.has(eventId)) {
|
|
702
|
-
return orgDerivationCache.get(eventId) ?? null;
|
|
703
|
-
}
|
|
704
|
-
const { data, error } = await supabase.from("core_events").select("organisation_id").eq("event_id", eventId).single();
|
|
705
|
-
let organisationId = null;
|
|
706
|
-
if (error || !data) {
|
|
707
|
-
organisationId = null;
|
|
708
|
-
} else if (data.organisation_id) {
|
|
709
|
-
organisationId = data.organisation_id;
|
|
710
|
-
} else {
|
|
711
|
-
organisationId = null;
|
|
712
|
-
}
|
|
713
|
-
if (orgDerivationCache.size >= MAX_CACHE_SIZE) {
|
|
714
|
-
const firstKey = orgDerivationCache.keys().next().value;
|
|
715
|
-
if (firstKey) {
|
|
716
|
-
orgDerivationCache.delete(firstKey);
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
orgDerivationCache.set(eventId, organisationId);
|
|
720
|
-
return organisationId;
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
// src/rbac/utils/contextValidator.ts
|
|
724
|
-
var log2 = createLogger("ContextValidator");
|
|
725
|
-
function allowsOptionalContexts(appName) {
|
|
726
|
-
return appName === "PORTAL" || appName === "ADMIN";
|
|
727
|
-
}
|
|
728
|
-
var ContextValidator = class {
|
|
729
|
-
/**
|
|
730
|
-
* Validate scope against app requirements
|
|
731
|
-
*
|
|
732
|
-
* @param scope - Current scope
|
|
733
|
-
* @param appConfig - App configuration (requires_event flag)
|
|
734
|
-
* @param appName - App name (for PORTAL/ADMIN special case)
|
|
735
|
-
* @returns Validation result with resolved scope
|
|
736
|
-
*/
|
|
737
|
-
static async validateScope(scope, appConfig, appName) {
|
|
738
|
-
if (allowsOptionalContexts(appName)) {
|
|
739
|
-
return {
|
|
740
|
-
isValid: true,
|
|
741
|
-
resolvedScope: {
|
|
742
|
-
organisationId: scope.organisationId,
|
|
743
|
-
eventId: scope.eventId,
|
|
744
|
-
appId: scope.appId
|
|
745
|
-
},
|
|
746
|
-
error: null
|
|
747
|
-
};
|
|
748
|
-
}
|
|
749
|
-
if (!appConfig) {
|
|
750
|
-
if (!scope.organisationId) {
|
|
751
|
-
return {
|
|
752
|
-
isValid: false,
|
|
753
|
-
resolvedScope: null,
|
|
754
|
-
error: new OrganisationContextRequiredError()
|
|
755
|
-
};
|
|
756
|
-
}
|
|
757
|
-
return {
|
|
758
|
-
isValid: true,
|
|
759
|
-
resolvedScope: scope,
|
|
760
|
-
error: null
|
|
761
|
-
};
|
|
762
|
-
}
|
|
763
|
-
if (appConfig.requires_event) {
|
|
764
|
-
if (!scope.eventId) {
|
|
765
|
-
return {
|
|
766
|
-
isValid: false,
|
|
767
|
-
resolvedScope: null,
|
|
768
|
-
error: new EventContextRequiredError()
|
|
769
|
-
};
|
|
770
|
-
}
|
|
771
|
-
return {
|
|
772
|
-
isValid: true,
|
|
773
|
-
resolvedScope: scope,
|
|
774
|
-
error: null
|
|
775
|
-
};
|
|
776
|
-
}
|
|
777
|
-
if (!scope.organisationId) {
|
|
778
|
-
return {
|
|
779
|
-
isValid: false,
|
|
780
|
-
resolvedScope: null,
|
|
781
|
-
error: new OrganisationContextRequiredError()
|
|
782
|
-
};
|
|
783
|
-
}
|
|
784
|
-
return {
|
|
785
|
-
isValid: true,
|
|
786
|
-
resolvedScope: scope,
|
|
787
|
-
error: null
|
|
788
|
-
};
|
|
789
|
-
}
|
|
790
|
-
/**
|
|
791
|
-
* Resolve required context and derive missing values
|
|
792
|
-
*
|
|
793
|
-
* @param scope - Current scope
|
|
794
|
-
* @param appConfig - App configuration
|
|
795
|
-
* @param appName - App name (for PORTAL/ADMIN special case)
|
|
796
|
-
* @param supabase - Supabase client (for deriving org from event)
|
|
797
|
-
* @returns Resolved scope with all required context
|
|
798
|
-
*/
|
|
799
|
-
static async resolveRequiredContext(scope, appConfig, appName, supabase) {
|
|
800
|
-
if (allowsOptionalContexts(appName)) {
|
|
801
|
-
return {
|
|
802
|
-
isValid: true,
|
|
803
|
-
resolvedScope: {
|
|
804
|
-
organisationId: scope.organisationId,
|
|
805
|
-
eventId: scope.eventId,
|
|
806
|
-
appId: scope.appId
|
|
807
|
-
},
|
|
808
|
-
error: null
|
|
809
|
-
};
|
|
810
|
-
}
|
|
811
|
-
if (!appConfig) {
|
|
812
|
-
if (!scope.organisationId) {
|
|
813
|
-
return {
|
|
814
|
-
isValid: false,
|
|
815
|
-
resolvedScope: null,
|
|
816
|
-
error: new OrganisationContextRequiredError()
|
|
817
|
-
};
|
|
818
|
-
}
|
|
819
|
-
return {
|
|
820
|
-
isValid: true,
|
|
821
|
-
resolvedScope: scope,
|
|
822
|
-
error: null
|
|
823
|
-
};
|
|
824
|
-
}
|
|
825
|
-
if (appConfig.requires_event) {
|
|
826
|
-
if (!scope.eventId) {
|
|
827
|
-
return {
|
|
828
|
-
isValid: false,
|
|
829
|
-
resolvedScope: null,
|
|
830
|
-
error: new EventContextRequiredError()
|
|
831
|
-
};
|
|
832
|
-
}
|
|
833
|
-
let organisationId = scope.organisationId;
|
|
834
|
-
if (!organisationId && supabase && scope.eventId) {
|
|
835
|
-
try {
|
|
836
|
-
const derivedOrgId = await this.deriveOrgFromEvent(supabase, scope.eventId);
|
|
837
|
-
organisationId = derivedOrgId || void 0;
|
|
838
|
-
if (!organisationId) {
|
|
839
|
-
return {
|
|
840
|
-
isValid: false,
|
|
841
|
-
resolvedScope: null,
|
|
842
|
-
error: new Error("Could not resolve organisation from event context")
|
|
843
|
-
};
|
|
844
|
-
}
|
|
845
|
-
} catch (error) {
|
|
846
|
-
log2.error("Failed to derive org from event:", error);
|
|
847
|
-
return {
|
|
848
|
-
isValid: false,
|
|
849
|
-
resolvedScope: null,
|
|
850
|
-
error: error instanceof Error ? error : new Error("Failed to derive organisation from event")
|
|
851
|
-
};
|
|
852
|
-
}
|
|
853
|
-
} else if (!organisationId) {
|
|
854
|
-
return {
|
|
855
|
-
isValid: false,
|
|
856
|
-
resolvedScope: null,
|
|
857
|
-
error: new Error("Event context requires organisationId but it could not be derived (supabase client not available)")
|
|
858
|
-
};
|
|
859
|
-
}
|
|
860
|
-
return {
|
|
861
|
-
isValid: true,
|
|
862
|
-
resolvedScope: {
|
|
863
|
-
organisationId,
|
|
864
|
-
eventId: scope.eventId,
|
|
865
|
-
appId: scope.appId
|
|
866
|
-
},
|
|
867
|
-
error: null
|
|
868
|
-
};
|
|
869
|
-
}
|
|
870
|
-
if (!scope.organisationId) {
|
|
871
|
-
return {
|
|
872
|
-
isValid: false,
|
|
873
|
-
resolvedScope: null,
|
|
874
|
-
error: new OrganisationContextRequiredError()
|
|
875
|
-
};
|
|
876
|
-
}
|
|
877
|
-
return {
|
|
878
|
-
isValid: true,
|
|
879
|
-
resolvedScope: scope,
|
|
880
|
-
error: null
|
|
881
|
-
};
|
|
882
|
-
}
|
|
883
|
-
/**
|
|
884
|
-
* Derive organisation ID from event ID
|
|
885
|
-
*
|
|
886
|
-
* @param supabase - Supabase client
|
|
887
|
-
* @param eventId - Event ID
|
|
888
|
-
* @returns Organisation ID or null
|
|
889
|
-
*/
|
|
890
|
-
static async deriveOrgFromEvent(supabase, eventId) {
|
|
891
|
-
return getOrganisationFromEvent(supabase, eventId);
|
|
892
|
-
}
|
|
893
|
-
/**
|
|
894
|
-
* Check if context is ready for permission checks
|
|
895
|
-
*
|
|
896
|
-
* @param scope - Current scope
|
|
897
|
-
* @param appConfig - App configuration
|
|
898
|
-
* @param appName - App name
|
|
899
|
-
* @param hasSelectedEvent - Whether event is selected
|
|
900
|
-
* @param hasSelectedOrganisation - Whether organisation is selected
|
|
901
|
-
* @returns True if context is ready
|
|
902
|
-
*/
|
|
903
|
-
static isContextReady(scope, appConfig, appName, hasSelectedEvent, hasSelectedOrganisation) {
|
|
904
|
-
if (allowsOptionalContexts(appName)) {
|
|
905
|
-
return true;
|
|
906
|
-
}
|
|
907
|
-
if (!appConfig) {
|
|
908
|
-
return !!hasSelectedOrganisation || !!scope.organisationId;
|
|
909
|
-
}
|
|
910
|
-
if (appConfig.requires_event) {
|
|
911
|
-
return !!hasSelectedEvent || !!scope.eventId;
|
|
912
|
-
}
|
|
913
|
-
return !!hasSelectedOrganisation || !!scope.organisationId;
|
|
914
|
-
}
|
|
915
|
-
};
|
|
916
|
-
|
|
917
640
|
// src/rbac/security.ts
|
|
918
|
-
var
|
|
641
|
+
var log2 = createLogger("RBACSecurity");
|
|
919
642
|
var RBACSecurityValidator = class {
|
|
920
643
|
/**
|
|
921
644
|
* Validate permission string format
|
|
@@ -1021,17 +744,6 @@ var RBACSecurityValidator = class {
|
|
|
1021
744
|
static async checkRateLimit(userId, operation) {
|
|
1022
745
|
return true;
|
|
1023
746
|
}
|
|
1024
|
-
/**
|
|
1025
|
-
* Validate context requirements for security
|
|
1026
|
-
* @param scope - Scope object
|
|
1027
|
-
* @param appConfig - App configuration
|
|
1028
|
-
* @param appName - App name (for PORTAL special case)
|
|
1029
|
-
* @returns True if context is valid, false otherwise
|
|
1030
|
-
*/
|
|
1031
|
-
static async validateContextRequirements(scope, appConfig, appName) {
|
|
1032
|
-
const validation = await ContextValidator.validateScope(scope, appConfig || null, appName);
|
|
1033
|
-
return validation.isValid;
|
|
1034
|
-
}
|
|
1035
747
|
// Only warn once per 5 seconds per user
|
|
1036
748
|
static logSecurityEvent(event) {
|
|
1037
749
|
const securityEvent = {
|
|
@@ -1049,7 +761,7 @@ var RBACSecurityValidator = class {
|
|
|
1049
761
|
this.rateLimitWarningCount.set(event.userId, userWarning);
|
|
1050
762
|
return;
|
|
1051
763
|
} else {
|
|
1052
|
-
|
|
764
|
+
log2.warn("Security event (throttled):", {
|
|
1053
765
|
...securityEvent,
|
|
1054
766
|
details: {
|
|
1055
767
|
...securityEvent.details,
|
|
@@ -1062,11 +774,11 @@ var RBACSecurityValidator = class {
|
|
|
1062
774
|
}
|
|
1063
775
|
} else {
|
|
1064
776
|
this.rateLimitWarningCount.set(event.userId, { count: 0, lastWarning: now });
|
|
1065
|
-
|
|
777
|
+
log2.warn("Security event:", securityEvent);
|
|
1066
778
|
return;
|
|
1067
779
|
}
|
|
1068
780
|
}
|
|
1069
|
-
|
|
781
|
+
log2.warn("Security event:", securityEvent);
|
|
1070
782
|
}
|
|
1071
783
|
/**
|
|
1072
784
|
* Get severity level for security event
|
|
@@ -1896,7 +1608,7 @@ function getInFlightRequestCount() {
|
|
|
1896
1608
|
}
|
|
1897
1609
|
|
|
1898
1610
|
// src/rbac/api.ts
|
|
1899
|
-
var
|
|
1611
|
+
var log3 = createLogger("RBACAPI");
|
|
1900
1612
|
var globalEngine = null;
|
|
1901
1613
|
function setupRBAC(supabase, config) {
|
|
1902
1614
|
const logger = getRBACLogger();
|
|
@@ -1927,28 +1639,27 @@ function setupRBAC(supabase, config) {
|
|
|
1927
1639
|
enablePerformanceMonitoring();
|
|
1928
1640
|
}
|
|
1929
1641
|
}
|
|
1642
|
+
function isRBACInitialized() {
|
|
1643
|
+
return globalEngine !== null;
|
|
1644
|
+
}
|
|
1930
1645
|
function getEngine() {
|
|
1931
1646
|
if (!globalEngine) {
|
|
1932
1647
|
throw new RBACNotInitializedError();
|
|
1933
1648
|
}
|
|
1934
1649
|
return globalEngine;
|
|
1935
1650
|
}
|
|
1936
|
-
async function getAccessLevel(input,
|
|
1651
|
+
async function getAccessLevel(input, appName) {
|
|
1937
1652
|
try {
|
|
1938
1653
|
const engine = getEngine();
|
|
1939
1654
|
const isSuperAdminUser = await engine["checkSuperAdmin"](input.userId);
|
|
1940
1655
|
if (isSuperAdminUser) {
|
|
1941
1656
|
return "super";
|
|
1942
1657
|
}
|
|
1943
|
-
|
|
1944
|
-
let resolvedAppName = appName;
|
|
1945
|
-
if (!resolvedAppConfig && input.scope.appId) {
|
|
1946
|
-
resolvedAppConfig = await getAppConfig(input.scope.appId);
|
|
1947
|
-
}
|
|
1948
|
-
const validation = await ContextValidator.resolveRequiredContext(
|
|
1658
|
+
const validation = await ContextValidator.resolveScopeForPage(
|
|
1949
1659
|
input.scope,
|
|
1950
|
-
|
|
1951
|
-
|
|
1660
|
+
"organisation",
|
|
1661
|
+
// Default to organisation scope when no page context
|
|
1662
|
+
appName,
|
|
1952
1663
|
engine["supabase"]
|
|
1953
1664
|
);
|
|
1954
1665
|
if (!validation.isValid || !validation.resolvedScope) {
|
|
@@ -1962,18 +1673,14 @@ async function getAccessLevel(input, appConfig, appName) {
|
|
|
1962
1673
|
throw error;
|
|
1963
1674
|
}
|
|
1964
1675
|
}
|
|
1965
|
-
async function getPermissionMap(input,
|
|
1676
|
+
async function getPermissionMap(input, appName) {
|
|
1966
1677
|
try {
|
|
1967
1678
|
const engine = getEngine();
|
|
1968
|
-
|
|
1969
|
-
let resolvedAppName = appName;
|
|
1970
|
-
if (!resolvedAppConfig && input.scope.appId) {
|
|
1971
|
-
resolvedAppConfig = await getAppConfig(input.scope.appId);
|
|
1972
|
-
}
|
|
1973
|
-
const validation = await ContextValidator.resolveRequiredContext(
|
|
1679
|
+
const validation = await ContextValidator.resolveScopeForPage(
|
|
1974
1680
|
input.scope,
|
|
1975
|
-
|
|
1976
|
-
|
|
1681
|
+
"organisation",
|
|
1682
|
+
// Default to organisation scope when no page context
|
|
1683
|
+
appName,
|
|
1977
1684
|
engine["supabase"]
|
|
1978
1685
|
);
|
|
1979
1686
|
if (!validation.isValid || !validation.resolvedScope) {
|
|
@@ -1995,17 +1702,13 @@ async function resolveAppContext(input) {
|
|
|
1995
1702
|
throw error;
|
|
1996
1703
|
}
|
|
1997
1704
|
}
|
|
1998
|
-
async function getRoleContext(input,
|
|
1705
|
+
async function getRoleContext(input, appName) {
|
|
1999
1706
|
const engine = getEngine();
|
|
2000
|
-
|
|
2001
|
-
let resolvedAppName = appName;
|
|
2002
|
-
if (!resolvedAppConfig && input.scope.appId) {
|
|
2003
|
-
resolvedAppConfig = await getAppConfig(input.scope.appId);
|
|
2004
|
-
}
|
|
2005
|
-
const validation = await ContextValidator.resolveRequiredContext(
|
|
1707
|
+
const validation = await ContextValidator.resolveScopeForPage(
|
|
2006
1708
|
input.scope,
|
|
2007
|
-
|
|
2008
|
-
|
|
1709
|
+
"organisation",
|
|
1710
|
+
// Default to organisation scope when no page context
|
|
1711
|
+
appName,
|
|
2009
1712
|
engine["supabase"]
|
|
2010
1713
|
);
|
|
2011
1714
|
if (!validation.isValid || !validation.resolvedScope) {
|
|
@@ -2016,7 +1719,7 @@ async function getRoleContext(input, appConfig, appName) {
|
|
|
2016
1719
|
scope: validation.resolvedScope
|
|
2017
1720
|
});
|
|
2018
1721
|
}
|
|
2019
|
-
async function isPermitted(input,
|
|
1722
|
+
async function isPermitted(input, appName, precomputedSuperAdmin = null) {
|
|
2020
1723
|
const engine = getEngine();
|
|
2021
1724
|
if (precomputedSuperAdmin === true) {
|
|
2022
1725
|
return true;
|
|
@@ -2027,11 +1730,7 @@ async function isPermitted(input, appConfig, appName, precomputedSuperAdmin = nu
|
|
|
2027
1730
|
return true;
|
|
2028
1731
|
}
|
|
2029
1732
|
}
|
|
2030
|
-
let resolvedAppConfig = appConfig ?? null;
|
|
2031
1733
|
let resolvedAppName = appName;
|
|
2032
|
-
if (!resolvedAppConfig && input.scope.appId) {
|
|
2033
|
-
resolvedAppConfig = await getAppConfig(input.scope.appId);
|
|
2034
|
-
}
|
|
2035
1734
|
if (!resolvedAppName && input.scope.appId) {
|
|
2036
1735
|
try {
|
|
2037
1736
|
const { data } = await engine["supabase"].from("rbac_apps").select("name").eq("id", input.scope.appId).eq("is_active", true).single();
|
|
@@ -2041,9 +1740,28 @@ async function isPermitted(input, appConfig, appName, precomputedSuperAdmin = nu
|
|
|
2041
1740
|
} catch (err) {
|
|
2042
1741
|
}
|
|
2043
1742
|
}
|
|
2044
|
-
|
|
1743
|
+
let pageScopeType;
|
|
1744
|
+
if (input.pageId) {
|
|
1745
|
+
try {
|
|
1746
|
+
const scopeType = await getPageScopeType(
|
|
1747
|
+
input.pageId,
|
|
1748
|
+
input.scope.appId,
|
|
1749
|
+
resolvedAppName
|
|
1750
|
+
);
|
|
1751
|
+
if (!scopeType) {
|
|
1752
|
+
throw new Error(`Page ${input.pageId} does not have scope_type set`);
|
|
1753
|
+
}
|
|
1754
|
+
pageScopeType = scopeType;
|
|
1755
|
+
} catch (err) {
|
|
1756
|
+
log3.error("Failed to get page scope type:", err);
|
|
1757
|
+
throw new Error(`Failed to determine page scope type: ${err instanceof Error ? err.message : String(err)}`);
|
|
1758
|
+
}
|
|
1759
|
+
} else {
|
|
1760
|
+
pageScopeType = "organisation";
|
|
1761
|
+
}
|
|
1762
|
+
const validation = await ContextValidator.resolveScopeForPage(
|
|
2045
1763
|
input.scope,
|
|
2046
|
-
|
|
1764
|
+
pageScopeType,
|
|
2047
1765
|
resolvedAppName,
|
|
2048
1766
|
engine["supabase"]
|
|
2049
1767
|
);
|
|
@@ -2051,6 +1769,44 @@ async function isPermitted(input, appConfig, appName, precomputedSuperAdmin = nu
|
|
|
2051
1769
|
throw validation.error || new OrganisationContextRequiredError();
|
|
2052
1770
|
}
|
|
2053
1771
|
const validatedScope = validation.resolvedScope;
|
|
1772
|
+
if (pageScopeType === "both" && input.pageId) {
|
|
1773
|
+
const eventScope = {
|
|
1774
|
+
organisationId: validatedScope.organisationId,
|
|
1775
|
+
// Org derived from event
|
|
1776
|
+
eventId: validatedScope.eventId,
|
|
1777
|
+
appId: validatedScope.appId
|
|
1778
|
+
};
|
|
1779
|
+
const eventSecurityContext = {
|
|
1780
|
+
userId: input.userId,
|
|
1781
|
+
organisationId: eventScope.organisationId || null,
|
|
1782
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
1783
|
+
};
|
|
1784
|
+
const eventInput = {
|
|
1785
|
+
...input,
|
|
1786
|
+
scope: eventScope
|
|
1787
|
+
};
|
|
1788
|
+
const hasEventPermission = await engine.isPermitted(eventInput, eventSecurityContext);
|
|
1789
|
+
if (validatedScope.organisationId && validatedScope.eventId) {
|
|
1790
|
+
const orgScope = {
|
|
1791
|
+
organisationId: validatedScope.organisationId,
|
|
1792
|
+
eventId: void 0,
|
|
1793
|
+
// Clear event for org-only check
|
|
1794
|
+
appId: validatedScope.appId
|
|
1795
|
+
};
|
|
1796
|
+
const orgSecurityContext = {
|
|
1797
|
+
userId: input.userId,
|
|
1798
|
+
organisationId: orgScope.organisationId || null,
|
|
1799
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
1800
|
+
};
|
|
1801
|
+
const orgInput = {
|
|
1802
|
+
...input,
|
|
1803
|
+
scope: orgScope
|
|
1804
|
+
};
|
|
1805
|
+
const hasOrgPermission = await engine.isPermitted(orgInput, orgSecurityContext);
|
|
1806
|
+
return hasEventPermission || hasOrgPermission;
|
|
1807
|
+
}
|
|
1808
|
+
return hasEventPermission;
|
|
1809
|
+
}
|
|
2054
1810
|
const securityContext = {
|
|
2055
1811
|
userId: input.userId,
|
|
2056
1812
|
organisationId: validatedScope.organisationId || null,
|
|
@@ -2063,7 +1819,7 @@ async function isPermitted(input, appConfig, appName, precomputedSuperAdmin = nu
|
|
|
2063
1819
|
};
|
|
2064
1820
|
return engine.isPermitted(validatedInput, securityContext);
|
|
2065
1821
|
}
|
|
2066
|
-
async function isPermittedCached(input,
|
|
1822
|
+
async function isPermittedCached(input, appName) {
|
|
2067
1823
|
const { userId, scope, permission, pageId } = input;
|
|
2068
1824
|
const cacheKey = RBACCache.generatePermissionKey({
|
|
2069
1825
|
userId,
|
|
@@ -2078,14 +1834,14 @@ async function isPermittedCached(input, appConfig, appName) {
|
|
|
2078
1834
|
return cached;
|
|
2079
1835
|
}
|
|
2080
1836
|
return getOrCreateRequest(input, async (checkInput) => {
|
|
2081
|
-
const result = await isPermitted(checkInput,
|
|
1837
|
+
const result = await isPermitted(checkInput, appName, null);
|
|
2082
1838
|
const isPageLevelCheck = !!pageId || permission.includes("page.");
|
|
2083
1839
|
rbacCache.set(cacheKey, result, void 0, isPageLevelCheck);
|
|
2084
1840
|
return result;
|
|
2085
1841
|
});
|
|
2086
1842
|
}
|
|
2087
1843
|
async function hasPermission(input) {
|
|
2088
|
-
return isPermitted(input
|
|
1844
|
+
return isPermitted(input);
|
|
2089
1845
|
}
|
|
2090
1846
|
async function hasAnyPermission(input) {
|
|
2091
1847
|
const { permissions, ...baseInput } = input;
|
|
@@ -2093,7 +1849,7 @@ async function hasAnyPermission(input) {
|
|
|
2093
1849
|
const hasPermission2 = await isPermitted({
|
|
2094
1850
|
...baseInput,
|
|
2095
1851
|
permission
|
|
2096
|
-
}
|
|
1852
|
+
});
|
|
2097
1853
|
if (hasPermission2) {
|
|
2098
1854
|
return true;
|
|
2099
1855
|
}
|
|
@@ -2106,7 +1862,7 @@ async function hasAllPermissions(input) {
|
|
|
2106
1862
|
const hasPermission2 = await isPermitted({
|
|
2107
1863
|
...baseInput,
|
|
2108
1864
|
permission
|
|
2109
|
-
}
|
|
1865
|
+
});
|
|
2110
1866
|
if (!hasPermission2) {
|
|
2111
1867
|
return false;
|
|
2112
1868
|
}
|
|
@@ -2117,50 +1873,40 @@ async function isSuperAdmin(userId) {
|
|
|
2117
1873
|
const engine = getEngine();
|
|
2118
1874
|
return engine["checkSuperAdmin"](userId);
|
|
2119
1875
|
}
|
|
2120
|
-
async function
|
|
1876
|
+
async function getPageScopeType(pageId, appId, appName) {
|
|
1877
|
+
const engine = getEngine();
|
|
2121
1878
|
try {
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
return null;
|
|
1879
|
+
let resolvedAppId = appId;
|
|
1880
|
+
if (!resolvedAppId && appName) {
|
|
1881
|
+
const { data: app } = await engine["supabase"].from("rbac_apps").select("id").eq("name", appName).eq("is_active", true).single();
|
|
1882
|
+
resolvedAppId = app?.id;
|
|
2127
1883
|
}
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
}
|
|
2131
|
-
async function getAppConfigWithClient(client, appId) {
|
|
2132
|
-
if (!client) {
|
|
2133
|
-
return null;
|
|
2134
|
-
}
|
|
2135
|
-
const cacheKey = `app_config:${appId}`;
|
|
2136
|
-
const cached = rbacCache.get(cacheKey, true);
|
|
2137
|
-
if (cached !== null) {
|
|
2138
|
-
return cached;
|
|
2139
|
-
}
|
|
2140
|
-
try {
|
|
2141
|
-
const { data, error } = await client.from("rbac_apps").select("requires_event, name").eq("id", appId).eq("is_active", true).single();
|
|
2142
|
-
if (error || !data) {
|
|
2143
|
-
return null;
|
|
1884
|
+
if (!resolvedAppId) {
|
|
1885
|
+
throw new Error(`Could not resolve appId for page ${pageId}`);
|
|
2144
1886
|
}
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
}
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
if (error
|
|
2158
|
-
|
|
1887
|
+
let resolvedPageId = pageId;
|
|
1888
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
1889
|
+
if (!uuidRegex.test(pageId)) {
|
|
1890
|
+
const { data: page } = await engine["supabase"].from("rbac_app_pages").select("id").eq("app_id", resolvedAppId).eq("page_name", pageId).maybeSingle();
|
|
1891
|
+
resolvedPageId = page?.id || pageId;
|
|
1892
|
+
}
|
|
1893
|
+
if (!uuidRegex.test(resolvedPageId)) {
|
|
1894
|
+
throw new Error(`Could not resolve pageId ${pageId} to a valid UUID`);
|
|
1895
|
+
}
|
|
1896
|
+
const { data, error } = await engine["supabase"].rpc("get_page_scope_type", {
|
|
1897
|
+
p_page_id: resolvedPageId
|
|
1898
|
+
});
|
|
1899
|
+
if (error) {
|
|
1900
|
+
log3.error("Error fetching page scope type:", { pageId, appId, error });
|
|
1901
|
+
throw new Error(`Failed to get page scope type: ${error.message}`);
|
|
1902
|
+
}
|
|
1903
|
+
if (!data) {
|
|
1904
|
+
throw new Error(`Page ${resolvedPageId} does not have scope_type set`);
|
|
2159
1905
|
}
|
|
2160
|
-
return
|
|
1906
|
+
return data;
|
|
2161
1907
|
} catch (err) {
|
|
2162
|
-
|
|
2163
|
-
|
|
1908
|
+
log3.error("Error fetching page scope type:", err);
|
|
1909
|
+
throw err instanceof Error ? err : new Error(`Failed to get page scope type: ${String(err)}`);
|
|
2164
1910
|
}
|
|
2165
1911
|
}
|
|
2166
1912
|
async function isOrganisationAdmin(userId, organisationId) {
|
|
@@ -2203,12 +1949,9 @@ function clearCache() {
|
|
|
2203
1949
|
}
|
|
2204
1950
|
|
|
2205
1951
|
export {
|
|
2206
|
-
OrganisationContextRequiredError,
|
|
2207
|
-
RBACNotInitializedError,
|
|
2208
1952
|
RBACCache,
|
|
2209
1953
|
rbacCache,
|
|
2210
1954
|
CACHE_PATTERNS,
|
|
2211
|
-
ContextValidator,
|
|
2212
1955
|
createRBACConfig,
|
|
2213
1956
|
getRBACConfig,
|
|
2214
1957
|
getRBACLogger,
|
|
@@ -2227,6 +1970,7 @@ export {
|
|
|
2227
1970
|
clearInFlightRequests,
|
|
2228
1971
|
getInFlightRequestCount,
|
|
2229
1972
|
setupRBAC,
|
|
1973
|
+
isRBACInitialized,
|
|
2230
1974
|
getAccessLevel,
|
|
2231
1975
|
getPermissionMap,
|
|
2232
1976
|
resolveAppContext,
|
|
@@ -2237,9 +1981,7 @@ export {
|
|
|
2237
1981
|
hasAnyPermission,
|
|
2238
1982
|
hasAllPermissions,
|
|
2239
1983
|
isSuperAdmin,
|
|
2240
|
-
|
|
2241
|
-
getAppConfigWithClient,
|
|
2242
|
-
getAppConfigByName,
|
|
1984
|
+
getPageScopeType,
|
|
2243
1985
|
isOrganisationAdmin,
|
|
2244
1986
|
isEventAdmin,
|
|
2245
1987
|
invalidateUserCache,
|
|
@@ -2248,4 +1990,4 @@ export {
|
|
|
2248
1990
|
invalidateAppCache,
|
|
2249
1991
|
clearCache
|
|
2250
1992
|
};
|
|
2251
|
-
//# sourceMappingURL=chunk-
|
|
1993
|
+
//# sourceMappingURL=chunk-RWEBCB47.js.map
|