@jmruthers/pace-core 0.5.53 → 0.5.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (398) hide show
  1. package/README.md +0 -4
  2. package/dist/{DataTable-7FMFXA7A.js → DataTable-4T627QFJ.js} +11 -11
  3. package/dist/{PublicLoadingSpinner-Bq_-BeK-.d.ts → PublicLoadingSpinner-SL8WaQN7.d.ts} +2 -21
  4. package/dist/{api-H5A3H4IR.js → api-LUNF5O6M.js} +3 -3
  5. package/dist/{appConfig-BVGyuvI7.d.ts → appConfig-DjpeG6P-.d.ts} +9 -1
  6. package/dist/{appNameResolver-7GHF5ED2.js → appNameResolver-UURKN7NF.js} +2 -2
  7. package/dist/{audit-BUW3LMJB.js → audit-6TOCAMKO.js} +2 -2
  8. package/dist/{chunk-MZBUOP4P.js → chunk-5BSLGBYI.js} +4 -3
  9. package/dist/chunk-5BSLGBYI.js.map +1 -0
  10. package/dist/{chunk-I5Z3QH5X.js → chunk-66C4BSAY.js} +2 -2
  11. package/dist/{chunk-I5Z3QH5X.js.map → chunk-66C4BSAY.js.map} +1 -1
  12. package/dist/{chunk-MYP2EGHX.js → chunk-AJ2KMES7.js} +21 -14
  13. package/dist/chunk-AJ2KMES7.js.map +1 -0
  14. package/dist/{chunk-EL2O4IUX.js → chunk-AQFRLC7K.js} +16 -24
  15. package/dist/{chunk-EL2O4IUX.js.map → chunk-AQFRLC7K.js.map} +1 -1
  16. package/dist/{chunk-7BNPOCLL.js → chunk-B2WTCLCV.js} +6 -2
  17. package/dist/chunk-B2WTCLCV.js.map +1 -0
  18. package/dist/{chunk-WJARTBCT.js → chunk-D7ARGIA3.js} +16 -7
  19. package/dist/chunk-D7ARGIA3.js.map +1 -0
  20. package/dist/{chunk-NRK4AIHQ.js → chunk-KBRACSJI.js} +3 -3
  21. package/dist/{chunk-NYUJ4FJR.js → chunk-KJDPSM64.js} +7 -7
  22. package/dist/chunk-KJDPSM64.js.map +1 -0
  23. package/dist/{chunk-GWSBHC4J.js → chunk-KLPVOPRI.js} +261 -38
  24. package/dist/chunk-KLPVOPRI.js.map +1 -0
  25. package/dist/{chunk-TRIZ7IB7.js → chunk-MPQDF75X.js} +148 -288
  26. package/dist/chunk-MPQDF75X.js.map +1 -0
  27. package/dist/{chunk-MSFACPQQ.js → chunk-PAEM3OWN.js} +11 -11
  28. package/dist/{chunk-MSFACPQQ.js.map → chunk-PAEM3OWN.js.map} +1 -1
  29. package/dist/{chunk-GIO7BFE7.js → chunk-RQD3D2CO.js} +66 -169
  30. package/dist/{chunk-GIO7BFE7.js.map → chunk-RQD3D2CO.js.map} +1 -1
  31. package/dist/{chunk-YDJW5XTN.js → chunk-STT7INZR.js} +25 -1
  32. package/dist/chunk-STT7INZR.js.map +1 -0
  33. package/dist/{chunk-6MTY77WU.js → chunk-TNMXZLDR.js} +3 -3
  34. package/dist/{chunk-BC3S53OZ.js → chunk-UQE2Y64H.js} +30 -14
  35. package/dist/chunk-UQE2Y64H.js.map +1 -0
  36. package/dist/{chunk-22KLBHPS.js → chunk-W66AZIOH.js} +2 -2
  37. package/dist/chunk-W66AZIOH.js.map +1 -0
  38. package/dist/{chunk-SS3E6QLB.js → chunk-YNUBMSMV.js} +2 -2
  39. package/dist/chunk-YNUBMSMV.js.map +1 -0
  40. package/dist/{chunk-NZ655MWE.js → chunk-ZOD2ZY6X.js} +5 -4
  41. package/dist/chunk-ZOD2ZY6X.js.map +1 -0
  42. package/dist/{chunk-74C6SNEC.js → chunk-ZPK5656W.js} +3 -3
  43. package/dist/{chunk-74C6SNEC.js.map → chunk-ZPK5656W.js.map} +1 -1
  44. package/dist/components.d.ts +22 -899
  45. package/dist/components.js +436 -3118
  46. package/dist/components.js.map +1 -1
  47. package/dist/file-reference-9xUOnwyt.d.ts +70 -0
  48. package/dist/hooks.d.ts +2 -2
  49. package/dist/hooks.js +10 -10
  50. package/dist/hooks.js.map +1 -1
  51. package/dist/index.d.ts +49 -9
  52. package/dist/index.js +190 -25
  53. package/dist/index.js.map +1 -1
  54. package/dist/{organisation-CO3Sh3_D.d.ts → organisation-t-vvQC3g.d.ts} +1 -8
  55. package/dist/providers.d.ts +2 -2
  56. package/dist/providers.js +5 -5
  57. package/dist/rbac/index.d.ts +65 -46
  58. package/dist/rbac/index.js +10 -12
  59. package/dist/styles/core.css +0 -125
  60. package/dist/types.d.ts +2 -1
  61. package/dist/types.js +3 -1
  62. package/dist/types.js.map +1 -1
  63. package/dist/{usePublicRouteParams-B2OcAsur.d.ts → usePublicRouteParams-CdoFxnJK.d.ts} +1 -1
  64. package/dist/utils.d.ts +3 -4
  65. package/dist/utils.js +44 -13
  66. package/dist/utils.js.map +1 -1
  67. package/docs/FILE_REFERENCE_SYSTEM.md +440 -0
  68. package/docs/INDEX.md +7 -5
  69. package/docs/README.md +0 -1
  70. package/docs/api/README.md +0 -4
  71. package/docs/api/classes/ErrorBoundary.md +1 -1
  72. package/docs/api/classes/InvalidScopeError.md +1 -1
  73. package/docs/api/classes/MissingUserContextError.md +1 -1
  74. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  75. package/docs/api/classes/PermissionDeniedError.md +2 -2
  76. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  77. package/docs/api/classes/RBACAuditManager.md +12 -12
  78. package/docs/api/classes/RBACCache.md +1 -1
  79. package/docs/api/classes/RBACEngine.md +6 -6
  80. package/docs/api/classes/RBACError.md +1 -1
  81. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  82. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  83. package/docs/api/classes/StorageUtils.md +281 -0
  84. package/docs/api/interfaces/AggregateConfig.md +1 -1
  85. package/docs/api/interfaces/ButtonProps.md +1 -1
  86. package/docs/api/interfaces/CardProps.md +1 -1
  87. package/docs/api/interfaces/ColorPalette.md +1 -1
  88. package/docs/api/interfaces/ColorShade.md +1 -1
  89. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  90. package/docs/api/interfaces/DataTableAction.md +1 -1
  91. package/docs/api/interfaces/DataTableColumn.md +1 -1
  92. package/docs/api/interfaces/DataTableProps.md +1 -1
  93. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  94. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  95. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  96. package/docs/api/interfaces/EventContextType.md +1 -1
  97. package/docs/api/interfaces/EventLogoProps.md +1 -1
  98. package/docs/api/interfaces/EventProviderProps.md +1 -1
  99. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  100. package/docs/api/interfaces/FileUploadProps.md +1 -1
  101. package/docs/api/interfaces/FooterProps.md +1 -1
  102. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  103. package/docs/api/interfaces/InputProps.md +1 -1
  104. package/docs/api/interfaces/LabelProps.md +1 -1
  105. package/docs/api/interfaces/LoginFormProps.md +1 -1
  106. package/docs/api/interfaces/NavigationAccessRecord.md +2 -2
  107. package/docs/api/interfaces/NavigationContextType.md +1 -1
  108. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  109. package/docs/api/interfaces/NavigationItem.md +1 -1
  110. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  111. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  112. package/docs/api/interfaces/Organisation.md +1 -1
  113. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  114. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  115. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  116. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  117. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  118. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  119. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  120. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  121. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  122. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  123. package/docs/api/interfaces/PaletteData.md +1 -1
  124. package/docs/api/interfaces/PermissionEnforcerProps.md +4 -4
  125. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  126. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  127. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  128. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  129. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  130. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  131. package/docs/api/interfaces/RBACConfig.md +1 -1
  132. package/docs/api/interfaces/RBACContextType.md +1 -1
  133. package/docs/api/interfaces/RBACLogger.md +1 -1
  134. package/docs/api/interfaces/RBACProviderProps.md +1 -1
  135. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  136. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  137. package/docs/api/interfaces/RouteAccessRecord.md +2 -2
  138. package/docs/api/interfaces/RouteConfig.md +2 -2
  139. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  140. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  141. package/docs/api/interfaces/StorageConfig.md +1 -1
  142. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  143. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  144. package/docs/api/interfaces/StorageListOptions.md +1 -1
  145. package/docs/api/interfaces/StorageListResult.md +1 -1
  146. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  147. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  148. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  149. package/docs/api/interfaces/StyleImport.md +1 -1
  150. package/docs/api/interfaces/ToastActionElement.md +1 -1
  151. package/docs/api/interfaces/ToastProps.md +1 -1
  152. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  153. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  154. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  155. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  156. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  157. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  158. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  159. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  160. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  161. package/docs/api/interfaces/UserEventAccess.md +1 -1
  162. package/docs/api/interfaces/UserMenuProps.md +1 -1
  163. package/docs/api/interfaces/UserProfile.md +1 -1
  164. package/docs/api/modules.md +204 -200
  165. package/docs/api-reference/components.md +141 -163
  166. package/docs/api-reference/hooks.md +347 -0
  167. package/docs/core-concepts/rbac-system.md +69 -16
  168. package/docs/getting-started/examples/basic-auth-app.md +0 -1
  169. package/docs/implementation-guides/datatable-rbac-usage.md +12 -11
  170. package/docs/implementation-guides/file-upload-storage.md +733 -0
  171. package/docs/implementation-guides/inactivity-tracking.md +779 -0
  172. package/docs/implementation-guides/organisation-security.md +748 -0
  173. package/docs/implementation-guides/public-pages-advanced.md +1022 -0
  174. package/docs/migration/MIGRATION_GUIDE.md +684 -0
  175. package/docs/migration/README.md +13 -2
  176. package/docs/migration/rbac-migration.md +73 -0
  177. package/docs/rbac/examples/rbac-rls-integration-example.md +11 -13
  178. package/docs/style-guide.md +269 -1
  179. package/package.json +1 -1
  180. package/src/__tests__/TESTING_GUIDELINES.md +331 -18
  181. package/src/__tests__/helpers/supabaseMock.ts +99 -0
  182. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +10 -7
  183. package/src/__tests__/shared.ts +6 -0
  184. package/src/components/DataTable/components/ActionButtons.tsx +2 -2
  185. package/src/components/DataTable/components/DataTableCore.tsx +2 -2
  186. package/src/components/DataTable/components/UnifiedTableBody.tsx +1 -1
  187. package/src/components/DataTable/utils/debugTools.ts +2 -2
  188. package/src/components/Dialog/Dialog.test.tsx +12 -2
  189. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +6 -6
  190. package/src/components/ErrorBoundary/ErrorBoundary.tsx +2 -2
  191. package/src/components/FileDisplay.tsx +233 -0
  192. package/src/components/FileUpload.tsx +176 -0
  193. package/src/components/Footer/Footer.test.tsx +7 -7
  194. package/src/components/NavigationMenu/NavigationMenu.test.tsx +13 -6
  195. package/src/components/OrganisationSelector/OrganisationSelector.test.tsx +30 -3
  196. package/src/components/OrganisationSelector/OrganisationSelector.tsx +1 -1
  197. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +558 -0
  198. package/src/components/PublicLayout/PublicErrorBoundary.tsx +1 -1
  199. package/src/components/PublicLayout/PublicPageDebugger.tsx +2 -2
  200. package/src/components/PublicLayout/PublicPageDiagnostic.tsx +2 -2
  201. package/src/components/PublicLayout/PublicPageProvider.tsx +2 -2
  202. package/src/components/Select/Select.test.tsx +50 -15
  203. package/src/components/SuperAdminGuard.tsx +2 -2
  204. package/src/components/__tests__/SuperAdminGuard.test.tsx +559 -0
  205. package/src/components/index.ts +0 -183
  206. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +2 -2
  207. package/src/hooks/__tests__/usePermissionCache.unit.test.ts +1 -1
  208. package/src/hooks/__tests__/useRBAC.unit.test.ts +191 -138
  209. package/src/hooks/public/usePublicEvent.ts +2 -2
  210. package/src/hooks/useAppConfig.ts +3 -3
  211. package/src/hooks/useComponentPerformance.ts +1 -1
  212. package/src/hooks/useDataTablePerformance.ts +1 -1
  213. package/src/hooks/useFileReference.ts +232 -0
  214. package/src/hooks/useOrganisationPermissions.test.ts +254 -344
  215. package/src/hooks/useOrganisationPermissions.ts +15 -7
  216. package/src/hooks/useOrganisationSecurity.test.ts +390 -402
  217. package/src/hooks/usePerformanceMonitor.ts +1 -1
  218. package/src/hooks/usePermissionCache.test.ts +264 -395
  219. package/src/hooks/usePermissionCache.ts +34 -4
  220. package/src/hooks/useSecureDataAccess.test.ts +486 -0
  221. package/src/hooks/useSecureDataAccess.ts +4 -1
  222. package/src/providers/InactivityProvider.tsx +2 -2
  223. package/src/providers/OrganisationProvider.test.simple.tsx +168 -0
  224. package/src/providers/OrganisationProvider.test.tsx +168 -0
  225. package/src/providers/OrganisationProvider.tsx +18 -31
  226. package/src/providers/UnifiedAuthProvider.test.simple.tsx +205 -0
  227. package/src/providers/UnifiedAuthProvider.test.tsx +128 -0
  228. package/src/providers/__tests__/InactivityProvider.test.tsx +3 -4
  229. package/src/providers/__tests__/OrganisationProvider.test.tsx +19 -14
  230. package/src/rbac/__tests__/integration.authflow.test.tsx +123 -0
  231. package/src/rbac/__tests__/integration.navigation.test.tsx +72 -0
  232. package/src/rbac/__tests__/integration.securedata.test.tsx +92 -0
  233. package/src/rbac/__tests__/integration.smoke.test.tsx +73 -0
  234. package/src/rbac/__tests__/rbac-core.test.tsx +26 -22
  235. package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +411 -0
  236. package/src/rbac/__tests__/rbac-engine-simplified.test.ts +285 -0
  237. package/src/rbac/__tests__/rbac-functions.test.ts +655 -0
  238. package/src/rbac/__tests__/rbac-integration.test.ts +532 -0
  239. package/src/rbac/__tests__/scenarios.user-role.test.tsx +196 -0
  240. package/src/rbac/api.test.ts +6 -6
  241. package/src/rbac/api.ts +2 -2
  242. package/src/rbac/audit.test.ts +485 -0
  243. package/src/rbac/audit.ts +7 -1
  244. package/src/rbac/cache-invalidation.ts +318 -0
  245. package/src/rbac/cache.test.ts +286 -0
  246. package/src/rbac/components/EnhancedNavigationMenu.test.tsx +559 -0
  247. package/src/rbac/components/EnhancedNavigationMenu.tsx +29 -23
  248. package/src/rbac/components/NavigationProvider.test.tsx +449 -0
  249. package/src/rbac/components/PagePermissionGuard.tsx +4 -4
  250. package/src/rbac/components/PagePermissionProvider.test.tsx +479 -0
  251. package/src/rbac/components/SecureDataProvider.test.tsx +511 -0
  252. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +159 -430
  253. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +4 -5
  254. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +112 -118
  255. package/src/rbac/config.test.ts +410 -0
  256. package/src/rbac/engine.test.simple.ts +237 -0
  257. package/src/rbac/engine.test.ts +233 -0
  258. package/src/rbac/engine.ts +37 -41
  259. package/src/rbac/examples/CompleteRBACExample.tsx +3 -3
  260. package/src/rbac/examples/EventBasedApp.tsx +4 -4
  261. package/src/rbac/hooks/useRBAC.simple.test.ts +16 -0
  262. package/src/rbac/hooks/useRBAC.test.ts +207 -455
  263. package/src/rbac/hooks/useRBAC.ts +30 -22
  264. package/src/rbac/permissions.test.ts +128 -0
  265. package/src/rbac/permissions.ts +56 -141
  266. package/src/rbac/providers/RBACProvider.tsx +1 -1
  267. package/src/rbac/secureClient.test.ts +444 -0
  268. package/src/rbac/security.test.ts +390 -0
  269. package/src/rbac/security.ts +1 -1
  270. package/src/rbac/types.test.ts +382 -0
  271. package/src/rbac/types.ts +2 -2
  272. package/src/styles/base.css +208 -0
  273. package/src/styles/core.css +0 -125
  274. package/src/styles/semantic.css +24 -0
  275. package/src/types/file-reference.ts +77 -0
  276. package/src/types/rbac-functions.ts +290 -0
  277. package/src/types/supabase.ts +10 -28
  278. package/src/types/unified.ts +4 -1
  279. package/src/utils/__tests__/bundleAnalysis.unit.test.ts +81 -55
  280. package/src/utils/__tests__/lazyLoad.unit.test.tsx +21 -12
  281. package/src/utils/__tests__/organisationContext.unit.test.ts +13 -7
  282. package/src/utils/__tests__/performanceBudgets.unit.test.ts +3 -3
  283. package/src/utils/__tests__/sessionTracking.unit.test.ts +32 -12
  284. package/src/utils/appConfig.ts +1 -1
  285. package/src/utils/appIdResolver.test.ts +503 -0
  286. package/src/utils/appIdResolver.ts +1 -1
  287. package/src/utils/appNameResolver.test.ts +494 -0
  288. package/src/utils/appNameResolver.ts +3 -2
  289. package/src/utils/bundleAnalysis.ts +3 -3
  290. package/src/utils/debugLogger.ts +1 -1
  291. package/src/utils/file-reference.ts +263 -0
  292. package/src/utils/formatDate.test.ts +2 -2
  293. package/src/utils/organisationContext.test.ts +340 -0
  294. package/src/utils/organisationContext.ts +19 -6
  295. package/src/utils/performanceBudgets.ts +2 -2
  296. package/src/utils/permissionUtils.test.ts +393 -0
  297. package/src/utils/permissionUtils.ts +5 -2
  298. package/src/utils/secureDataAccess.test.ts +715 -0
  299. package/src/utils/secureDataAccess.ts +21 -5
  300. package/src/utils/sessionTracking.ts +34 -4
  301. package/src/utils/storage/__tests__/helpers.unit.test.ts +328 -0
  302. package/src/utils/storage/__tests__/index.unit.test.ts +16 -0
  303. package/src/utils/storage/helpers.ts +20 -25
  304. package/src/utils/storage/index.ts +29 -1
  305. package/src/vite-env.d.ts +17 -0
  306. package/dist/chunk-22KLBHPS.js.map +0 -1
  307. package/dist/chunk-7BNPOCLL.js.map +0 -1
  308. package/dist/chunk-BC3S53OZ.js.map +0 -1
  309. package/dist/chunk-GWSBHC4J.js.map +0 -1
  310. package/dist/chunk-MYP2EGHX.js.map +0 -1
  311. package/dist/chunk-MZBUOP4P.js.map +0 -1
  312. package/dist/chunk-NYUJ4FJR.js.map +0 -1
  313. package/dist/chunk-NZ655MWE.js.map +0 -1
  314. package/dist/chunk-SS3E6QLB.js.map +0 -1
  315. package/dist/chunk-TRIZ7IB7.js.map +0 -1
  316. package/dist/chunk-WJARTBCT.js.map +0 -1
  317. package/dist/chunk-YDJW5XTN.js.map +0 -1
  318. package/docs/print-components/README.md +0 -258
  319. package/docs/print-components/api-reference.md +0 -636
  320. package/docs/print-components/examples/README.md +0 -204
  321. package/docs/print-components/examples/basic-report.tsx +0 -92
  322. package/docs/print-components/examples/card-catalog.tsx +0 -149
  323. package/docs/print-components/examples/cover-page-report.tsx +0 -163
  324. package/docs/print-components/quick-start.md +0 -363
  325. package/src/components/PrintButton/PrintButton.tsx +0 -321
  326. package/src/components/PrintButton/PrintButtonGroup.tsx +0 -84
  327. package/src/components/PrintButton/PrintToolbar.tsx +0 -94
  328. package/src/components/PrintButton/__tests__/PrintButton.test.tsx +0 -271
  329. package/src/components/PrintButton/examples/PrintButtonShowcase.tsx +0 -438
  330. package/src/components/PrintButton/index.ts +0 -33
  331. package/src/components/PrintButton/types.ts +0 -173
  332. package/src/components/PrintCard/PrintCard.tsx +0 -154
  333. package/src/components/PrintCard/PrintCardContent.tsx +0 -57
  334. package/src/components/PrintCard/PrintCardFooter.tsx +0 -60
  335. package/src/components/PrintCard/PrintCardGrid.tsx +0 -91
  336. package/src/components/PrintCard/PrintCardHeader.tsx +0 -78
  337. package/src/components/PrintCard/PrintCardImage.tsx +0 -81
  338. package/src/components/PrintCard/examples/PrintCardShowcase.tsx +0 -239
  339. package/src/components/PrintCard/index.ts +0 -34
  340. package/src/components/PrintCard/types.ts +0 -171
  341. package/src/components/PrintDataTable/PrintDataTable.tsx +0 -215
  342. package/src/components/PrintDataTable/PrintTableGroup.tsx +0 -90
  343. package/src/components/PrintDataTable/PrintTableRow.tsx +0 -76
  344. package/src/components/PrintDataTable/index.ts +0 -25
  345. package/src/components/PrintDataTable/types.ts +0 -67
  346. package/src/components/PrintFooter/PrintFooter.tsx +0 -183
  347. package/src/components/PrintFooter/PrintFooterContent.tsx +0 -71
  348. package/src/components/PrintFooter/PrintFooterInfo.tsx +0 -86
  349. package/src/components/PrintFooter/PrintPageNumber.tsx +0 -90
  350. package/src/components/PrintFooter/examples/PrintFooterShowcase.tsx +0 -390
  351. package/src/components/PrintFooter/index.ts +0 -30
  352. package/src/components/PrintFooter/types.ts +0 -149
  353. package/src/components/PrintGrid/PrintGrid.tsx +0 -180
  354. package/src/components/PrintGrid/PrintGridBreakpoint.tsx +0 -109
  355. package/src/components/PrintGrid/PrintGridContainer.tsx +0 -128
  356. package/src/components/PrintGrid/PrintGridItem.tsx +0 -220
  357. package/src/components/PrintGrid/examples/PrintGridShowcase.tsx +0 -359
  358. package/src/components/PrintGrid/index.ts +0 -31
  359. package/src/components/PrintGrid/types.ts +0 -159
  360. package/src/components/PrintHeader/PrintCoverHeader.tsx +0 -230
  361. package/src/components/PrintHeader/PrintHeader.tsx +0 -150
  362. package/src/components/PrintHeader/index.ts +0 -17
  363. package/src/components/PrintHeader/types.ts +0 -42
  364. package/src/components/PrintLayout/PrintLayout.tsx +0 -122
  365. package/src/components/PrintLayout/PrintLayoutContext.tsx +0 -66
  366. package/src/components/PrintLayout/PrintPageBreak.tsx +0 -52
  367. package/src/components/PrintLayout/examples/PrintShowcase.tsx +0 -230
  368. package/src/components/PrintLayout/index.ts +0 -19
  369. package/src/components/PrintLayout/types.ts +0 -37
  370. package/src/components/PrintPageBreak/PrintPageBreak.tsx +0 -120
  371. package/src/components/PrintPageBreak/PrintPageBreakGroup.tsx +0 -90
  372. package/src/components/PrintPageBreak/PrintPageBreakIndicator.tsx +0 -112
  373. package/src/components/PrintPageBreak/examples/PrintPageBreakShowcase.tsx +0 -279
  374. package/src/components/PrintPageBreak/index.ts +0 -23
  375. package/src/components/PrintPageBreak/types.ts +0 -94
  376. package/src/components/PrintSection/PrintColumn.tsx +0 -104
  377. package/src/components/PrintSection/PrintDivider.tsx +0 -101
  378. package/src/components/PrintSection/PrintSection.tsx +0 -129
  379. package/src/components/PrintSection/PrintSectionContent.tsx +0 -75
  380. package/src/components/PrintSection/PrintSectionHeader.tsx +0 -97
  381. package/src/components/PrintSection/examples/PrintSectionShowcase.tsx +0 -258
  382. package/src/components/PrintSection/index.ts +0 -33
  383. package/src/components/PrintSection/types.ts +0 -155
  384. package/src/components/PrintText/PrintText.tsx +0 -116
  385. package/src/components/PrintText/index.ts +0 -16
  386. package/src/components/PrintText/types.ts +0 -24
  387. package/src/rbac/__tests__/integration.test.tsx +0 -218
  388. package/src/utils/print/PrintDataProcessor.ts +0 -390
  389. package/src/utils/print/examples/PrintUtilitiesShowcase.tsx +0 -397
  390. package/src/utils/print/index.ts +0 -29
  391. package/src/utils/print/types.ts +0 -196
  392. package/src/utils/print/usePrintOptimization.ts +0 -272
  393. /package/dist/{DataTable-7FMFXA7A.js.map → DataTable-4T627QFJ.js.map} +0 -0
  394. /package/dist/{api-H5A3H4IR.js.map → api-LUNF5O6M.js.map} +0 -0
  395. /package/dist/{appNameResolver-7GHF5ED2.js.map → appNameResolver-UURKN7NF.js.map} +0 -0
  396. /package/dist/{audit-BUW3LMJB.js.map → audit-6TOCAMKO.js.map} +0 -0
  397. /package/dist/{chunk-NRK4AIHQ.js.map → chunk-KBRACSJI.js.map} +0 -0
  398. /package/dist/{chunk-6MTY77WU.js.map → chunk-TNMXZLDR.js.map} +0 -0
@@ -0,0 +1,532 @@
1
+ /**
2
+ * @file RBAC Integration Tests
3
+ * @package @jmruthers/pace-core
4
+ * @module RBAC/Tests
5
+ * @since 1.0.0
6
+ *
7
+ * Integration tests for complete RBAC permission flows.
8
+ */
9
+
10
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
11
+ import { createClient } from '@supabase/supabase-js';
12
+
13
+ // Mock Supabase client
14
+ const mockSupabase = {
15
+ rpc: vi.fn(),
16
+ from: vi.fn(() => ({
17
+ select: vi.fn(() => ({
18
+ eq: vi.fn(() => ({
19
+ single: vi.fn()
20
+ }))
21
+ }))
22
+ }))
23
+ };
24
+
25
+ // Test data
26
+ const testUser = {
27
+ id: 'user-123',
28
+ email: 'test@example.com'
29
+ };
30
+
31
+ const testOrganisation = {
32
+ id: 'org-123',
33
+ name: 'Test Organisation'
34
+ };
35
+
36
+ const testEvent = {
37
+ id: 'event-123',
38
+ name: 'Test Event',
39
+ organisation_id: 'org-123'
40
+ };
41
+
42
+ const testApp = {
43
+ id: 'app-123',
44
+ name: 'CAKE',
45
+ is_active: true
46
+ };
47
+
48
+ describe('RBAC Integration Tests', () => {
49
+ beforeEach(() => {
50
+ vi.clearAllMocks();
51
+ });
52
+
53
+ afterEach(() => {
54
+ vi.restoreAllMocks();
55
+ });
56
+
57
+ describe('Complete Permission Flow', () => {
58
+ it('should handle user login → permission check → data access flow', async () => {
59
+ // 1. User logs in and session is tracked
60
+ mockSupabase.rpc
61
+ .mockResolvedValueOnce({
62
+ data: [{
63
+ success: true,
64
+ session_id: 'session-123',
65
+ message: 'Session tracked successfully',
66
+ error_code: null
67
+ }],
68
+ error: null
69
+ })
70
+ // 2. Check if user has organisation access
71
+ .mockResolvedValueOnce({
72
+ data: [{ has_access: true, access_level: 'organisation', context_id: testOrganisation.id }],
73
+ error: null
74
+ })
75
+ // 3. Check page permission
76
+ .mockResolvedValueOnce({
77
+ data: true,
78
+ error: null
79
+ })
80
+ // 4. Get user permissions
81
+ .mockResolvedValueOnce({
82
+ data: [{
83
+ permission_type: 'organisation_access',
84
+ role_name: 'member',
85
+ has_permission: true,
86
+ granted_at: expect.any(String),
87
+ context_id: testOrganisation.id
88
+ }],
89
+ error: null
90
+ });
91
+
92
+ // Step 1: Track session
93
+ const sessionResult = await mockSupabase.rpc('rbac_session_track', {
94
+ p_user_id: testUser.id,
95
+ p_session_type: 'web',
96
+ p_organisation_id: testOrganisation.id
97
+ });
98
+
99
+ expect(sessionResult.data[0].success).toBe(true);
100
+
101
+ // Step 2: Validate organisation access
102
+ const accessResult = await mockSupabase.rpc('rbac_access_validate', {
103
+ p_resource_type: 'organisation',
104
+ p_resource_id: testOrganisation.id,
105
+ p_user_id: testUser.id
106
+ });
107
+
108
+ expect(accessResult.data[0].has_access).toBe(true);
109
+
110
+ // Step 3: Check page permission
111
+ const permissionResult = await mockSupabase.rpc('rbac_page_access_check', {
112
+ p_user_id: testUser.id,
113
+ p_app_id: testApp.id,
114
+ p_page_id: 'dashboard',
115
+ p_operation: 'read',
116
+ p_organisation_id: testOrganisation.id
117
+ });
118
+
119
+ expect(permissionResult.data).toBe(true);
120
+
121
+ // Step 4: Get all permissions
122
+ const permissionsResult = await mockSupabase.rpc('rbac_permissions_get', {
123
+ p_user_id: testUser.id,
124
+ p_organisation_id: testOrganisation.id
125
+ });
126
+
127
+ expect(permissionsResult.data[0].role_name).toBe('member');
128
+ });
129
+
130
+ it('should handle role grant → permission check → access granted flow', async () => {
131
+ // 1. Grant role to user
132
+ mockSupabase.rpc
133
+ .mockResolvedValueOnce({
134
+ data: [{
135
+ success: true,
136
+ message: 'Role granted successfully',
137
+ role_id: 'role-123',
138
+ error_code: null
139
+ }],
140
+ error: null
141
+ })
142
+ // 2. Log the role grant
143
+ .mockResolvedValueOnce({
144
+ data: [{
145
+ success: true,
146
+ audit_id: 'audit-123',
147
+ message: 'Audit event logged successfully',
148
+ error_code: null
149
+ }],
150
+ error: null
151
+ })
152
+ // 3. Validate the role is active
153
+ .mockResolvedValueOnce({
154
+ data: [{
155
+ is_valid: true,
156
+ role_id: 'role-123',
157
+ granted_at: expect.any(String),
158
+ expires_at: null,
159
+ status: 'active'
160
+ }],
161
+ error: null
162
+ })
163
+ // 4. Check permission with new role
164
+ .mockResolvedValueOnce({
165
+ data: [{ has_permission: true, role_name: 'member', permission_source: 'organisation', granted_at: expect.any(String) }],
166
+ error: null
167
+ });
168
+
169
+ // Step 1: Grant role
170
+ const grantResult = await mockSupabase.rpc('rbac_role_grant', {
171
+ p_user_id: testUser.id,
172
+ p_role_type: 'organisation',
173
+ p_role_name: 'member',
174
+ p_context_id: testOrganisation.id,
175
+ p_granted_by: 'admin-123'
176
+ });
177
+
178
+ expect(grantResult.data[0].success).toBe(true);
179
+
180
+ // Step 2: Log audit event
181
+ const auditResult = await mockSupabase.rpc('rbac_audit_log', {
182
+ p_event_type: 'role_granted',
183
+ p_user_id: testUser.id,
184
+ p_organisation_id: testOrganisation.id,
185
+ p_permission: 'member',
186
+ p_metadata: { role_id: 'role-123' }
187
+ });
188
+
189
+ expect(auditResult.data[0].success).toBe(true);
190
+
191
+ // Step 3: Validate role is active
192
+ const validateResult = await mockSupabase.rpc('rbac_role_validate', {
193
+ p_user_id: testUser.id,
194
+ p_role_type: 'organisation',
195
+ p_role_name: 'member',
196
+ p_context_id: testOrganisation.id
197
+ });
198
+
199
+ expect(validateResult.data[0].is_valid).toBe(true);
200
+
201
+ // Step 4: Check permission
202
+ const permissionResult = await mockSupabase.rpc('rbac_permission_check', {
203
+ p_operation: 'read',
204
+ p_page_name: 'dashboard',
205
+ p_user_id: testUser.id,
206
+ p_organisation_id: testOrganisation.id
207
+ });
208
+
209
+ expect(permissionResult.data[0].has_permission).toBe(true);
210
+ });
211
+
212
+ it('should handle role revoke → permission check → access denied flow', async () => {
213
+ // 1. Revoke role from user
214
+ mockSupabase.rpc
215
+ .mockResolvedValueOnce({
216
+ data: [{
217
+ success: true,
218
+ message: 'Role revoked successfully',
219
+ revoked_count: 1,
220
+ error_code: null
221
+ }],
222
+ error: null
223
+ })
224
+ // 2. Log the role revoke
225
+ .mockResolvedValueOnce({
226
+ data: [{
227
+ success: true,
228
+ audit_id: 'audit-456',
229
+ message: 'Audit event logged successfully',
230
+ error_code: null
231
+ }],
232
+ error: null
233
+ })
234
+ // 3. Validate the role is no longer active
235
+ .mockResolvedValueOnce({
236
+ data: [{
237
+ is_valid: false,
238
+ role_id: null,
239
+ granted_at: null,
240
+ expires_at: null,
241
+ status: 'inactive'
242
+ }],
243
+ error: null
244
+ })
245
+ // 4. Check permission (should be denied)
246
+ .mockResolvedValueOnce({
247
+ data: [{ has_permission: false, role_name: null, permission_source: 'none', granted_at: null }],
248
+ error: null
249
+ });
250
+
251
+ // Step 1: Revoke role
252
+ const revokeResult = await mockSupabase.rpc('rbac_role_revoke', {
253
+ p_user_id: testUser.id,
254
+ p_role_type: 'organisation',
255
+ p_role_name: 'member',
256
+ p_context_id: testOrganisation.id,
257
+ p_revoked_by: 'admin-123'
258
+ });
259
+
260
+ expect(revokeResult.data[0].success).toBe(true);
261
+
262
+ // Step 2: Log audit event
263
+ const auditResult = await mockSupabase.rpc('rbac_audit_log', {
264
+ p_event_type: 'role_revoked',
265
+ p_user_id: testUser.id,
266
+ p_organisation_id: testOrganisation.id,
267
+ p_permission: 'member',
268
+ p_metadata: { role_id: 'role-123' }
269
+ });
270
+
271
+ expect(auditResult.data[0].success).toBe(true);
272
+
273
+ // Step 3: Validate role is inactive
274
+ const validateResult = await mockSupabase.rpc('rbac_role_validate', {
275
+ p_user_id: testUser.id,
276
+ p_role_type: 'organisation',
277
+ p_role_name: 'member',
278
+ p_context_id: testOrganisation.id
279
+ });
280
+
281
+ expect(validateResult.data[0].is_valid).toBe(false);
282
+
283
+ // Step 4: Check permission (should be denied)
284
+ const permissionResult = await mockSupabase.rpc('rbac_permission_check', {
285
+ p_operation: 'read',
286
+ p_page_name: 'dashboard',
287
+ p_user_id: testUser.id,
288
+ p_organisation_id: testOrganisation.id
289
+ });
290
+
291
+ expect(permissionResult.data[0].has_permission).toBe(false);
292
+ });
293
+ });
294
+
295
+ describe('Cross-Organisation Access Prevention', () => {
296
+ it('should prevent access to other organisation\'s data', async () => {
297
+ const otherOrganisation = {
298
+ id: 'org-456',
299
+ name: 'Other Organisation'
300
+ };
301
+
302
+ // User tries to access other organisation's data
303
+ mockSupabase.rpc
304
+ .mockResolvedValueOnce({
305
+ data: [{ has_access: false, access_level: 'none', context_id: null }],
306
+ error: null
307
+ })
308
+ .mockResolvedValueOnce({
309
+ data: [{ has_permission: false, role_name: null, permission_source: 'none', granted_at: null }],
310
+ error: null
311
+ });
312
+
313
+ // Check access to other organisation
314
+ const accessResult = await mockSupabase.rpc('rbac_access_validate', {
315
+ p_user_id: testUser.id,
316
+ p_resource_type: 'organisation',
317
+ p_resource_id: otherOrganisation.id
318
+ });
319
+
320
+ expect(accessResult.data[0].has_access).toBe(false);
321
+
322
+ // Check permission in other organisation context
323
+ const permissionResult = await mockSupabase.rpc('rbac_permission_check', {
324
+ p_user_id: testUser.id,
325
+ p_operation: 'read',
326
+ p_page_name: 'dashboard',
327
+ p_organisation_id: otherOrganisation.id
328
+ });
329
+
330
+ expect(permissionResult.data[0].has_permission).toBe(false);
331
+ });
332
+
333
+ it('should prevent role grants to other organisations', async () => {
334
+ const otherOrganisation = {
335
+ id: 'org-456',
336
+ name: 'Other Organisation'
337
+ };
338
+
339
+ // Try to grant role in other organisation
340
+ mockSupabase.rpc.mockResolvedValueOnce({
341
+ data: [{
342
+ success: false,
343
+ message: 'Organisation not found',
344
+ role_id: null,
345
+ error_code: 'ORGANISATION_NOT_FOUND'
346
+ }],
347
+ error: null
348
+ });
349
+
350
+ const result = await mockSupabase.rpc('rbac_role_grant', {
351
+ p_user_id: testUser.id,
352
+ p_role_type: 'organisation',
353
+ p_role_name: 'member',
354
+ p_context_id: otherOrganisation.id,
355
+ p_granted_by: 'admin-123'
356
+ });
357
+
358
+ expect(result.data[0].success).toBe(false);
359
+ expect(result.data[0].error_code).toBe('ORGANISATION_NOT_FOUND');
360
+ });
361
+ });
362
+
363
+ describe('Super Admin Bypass', () => {
364
+ it('should allow super admin to access all resources', async () => {
365
+ // Super admin checks
366
+ mockSupabase.rpc
367
+ .mockResolvedValueOnce({
368
+ data: [{ has_permission: true, role_name: 'super_admin', permission_source: 'global', granted_at: expect.any(String) }],
369
+ error: null
370
+ })
371
+ .mockResolvedValueOnce({
372
+ data: [{ has_access: true, access_level: 'super_admin', context_id: 'global' }],
373
+ error: null
374
+ })
375
+ .mockResolvedValueOnce({
376
+ data: [{
377
+ permission_type: 'all_permissions',
378
+ role_name: 'super_admin',
379
+ has_permission: true,
380
+ granted_at: expect.any(String),
381
+ context_id: 'global'
382
+ }],
383
+ error: null
384
+ });
385
+
386
+ // Check permission
387
+ const permissionResult = await mockSupabase.rpc('rbac_permission_check', {
388
+ p_operation: 'delete',
389
+ p_page_name: 'admin-panel',
390
+ p_user_id: testUser.id
391
+ });
392
+
393
+ expect(permissionResult.data[0].has_permission).toBe(true);
394
+ expect(permissionResult.data[0].role_name).toBe('super_admin');
395
+
396
+ // Check access to any resource
397
+ const accessResult = await mockSupabase.rpc('rbac_access_validate', {
398
+ p_resource_type: 'organisation',
399
+ p_resource_id: 'any-org-id',
400
+ p_user_id: testUser.id
401
+ });
402
+
403
+ expect(accessResult.data[0].has_access).toBe(true);
404
+ expect(accessResult.data[0].access_level).toBe('super_admin');
405
+
406
+ // Get all permissions
407
+ const permissionsResult = await mockSupabase.rpc('rbac_permissions_get', {
408
+ p_user_id: testUser.id
409
+ });
410
+
411
+ expect(permissionsResult.data[0].permission_type).toBe('all_permissions');
412
+ });
413
+ });
414
+
415
+ describe('Event-App Role Flow', () => {
416
+ it('should handle event-app role grant and permission check', async () => {
417
+ // 1. Grant event-app role
418
+ mockSupabase.rpc
419
+ .mockResolvedValueOnce({
420
+ data: [{
421
+ success: true,
422
+ message: 'Role granted successfully',
423
+ role_id: 'event-role-123',
424
+ error_code: null
425
+ }],
426
+ error: null
427
+ })
428
+ // 2. Check event access
429
+ .mockResolvedValueOnce({
430
+ data: [{ has_access: true, access_level: 'event', context_id: testEvent.id }],
431
+ error: null
432
+ })
433
+ // 3. Check page permission in event context
434
+ .mockResolvedValueOnce({
435
+ data: [{ has_permission: true, role_name: 'participant', permission_source: 'event_app', granted_at: expect.any(String) }],
436
+ error: null
437
+ });
438
+
439
+ // Step 1: Grant event-app role
440
+ const grantResult = await mockSupabase.rpc('rbac_role_grant', {
441
+ p_user_id: testUser.id,
442
+ p_role_type: 'event_app',
443
+ p_role_name: 'participant',
444
+ p_context_id: `${testEvent.id}:${testApp.id}`,
445
+ p_granted_by: 'admin-123'
446
+ });
447
+
448
+ expect(grantResult.data[0].success).toBe(true);
449
+
450
+ // Step 2: Check event access
451
+ const accessResult = await mockSupabase.rpc('rbac_access_validate', {
452
+ p_resource_type: 'event',
453
+ p_resource_id: testEvent.id,
454
+ p_user_id: testUser.id
455
+ });
456
+
457
+ expect(accessResult.data[0].has_access).toBe(true);
458
+
459
+ // Step 3: Check page permission in event context
460
+ const permissionResult = await mockSupabase.rpc('rbac_permission_check', {
461
+ p_operation: 'read',
462
+ p_page_name: 'event-dashboard',
463
+ p_user_id: testUser.id,
464
+ p_event_id: testEvent.id,
465
+ p_app_id: testApp.id
466
+ });
467
+
468
+ expect(permissionResult.data[0].has_permission).toBe(true);
469
+ expect(permissionResult.data[0].role_name).toBe('participant');
470
+ });
471
+ });
472
+
473
+ describe('Error Handling and Edge Cases', () => {
474
+ it('should handle database errors gracefully', async () => {
475
+ mockSupabase.rpc.mockRejectedValueOnce(new Error('Database connection failed'));
476
+
477
+ try {
478
+ await mockSupabase.rpc('rbac_permission_check', {
479
+ p_operation: 'read',
480
+ p_page_name: 'dashboard',
481
+ p_user_id: testUser.id
482
+ });
483
+ } catch (error) {
484
+ expect(error).toBeInstanceOf(Error);
485
+ expect(error.message).toBe('Database connection failed');
486
+ }
487
+ });
488
+
489
+ it('should handle invalid parameters', async () => {
490
+ mockSupabase.rpc.mockResolvedValueOnce({
491
+ data: [{
492
+ success: false,
493
+ message: 'Invalid role type',
494
+ role_id: null,
495
+ error_code: 'INVALID_ROLE_TYPE'
496
+ }],
497
+ error: null
498
+ });
499
+
500
+ const result = await mockSupabase.rpc('rbac_role_grant', {
501
+ p_user_id: testUser.id,
502
+ p_role_type: 'invalid_type',
503
+ p_role_name: 'member'
504
+ });
505
+
506
+ expect(result.data[0].success).toBe(false);
507
+ expect(result.data[0].error_code).toBe('INVALID_ROLE_TYPE');
508
+ });
509
+
510
+ it('should handle missing required parameters', async () => {
511
+ mockSupabase.rpc.mockResolvedValueOnce({
512
+ data: [{
513
+ success: false,
514
+ message: 'Organisation ID required',
515
+ role_id: null,
516
+ error_code: 'MISSING_ORGANISATION_ID'
517
+ }],
518
+ error: null
519
+ });
520
+
521
+ const result = await mockSupabase.rpc('rbac_role_grant', {
522
+ p_user_id: testUser.id,
523
+ p_role_type: 'organisation',
524
+ p_role_name: 'member',
525
+ p_context_id: null
526
+ });
527
+
528
+ expect(result.data[0].success).toBe(false);
529
+ expect(result.data[0].error_code).toBe('MISSING_ORGANISATION_ID');
530
+ });
531
+ });
532
+ });