@jmruthers/pace-core 0.5.54 → 0.5.56

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 (396) hide show
  1. package/README.md +0 -4
  2. package/dist/{DataTable-7FMFXA7A.js → DataTable-DJQTKX33.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-NRK4AIHQ.js → chunk-2DFCT6D3.js} +3 -3
  9. package/dist/{chunk-GIO7BFE7.js → chunk-3JKVVLD3.js} +66 -169
  10. package/dist/{chunk-GIO7BFE7.js.map → chunk-3JKVVLD3.js.map} +1 -1
  11. package/dist/{chunk-MZBUOP4P.js → chunk-5BSLGBYI.js} +4 -3
  12. package/dist/chunk-5BSLGBYI.js.map +1 -0
  13. package/dist/{chunk-I5Z3QH5X.js → chunk-66C4BSAY.js} +2 -2
  14. package/dist/{chunk-I5Z3QH5X.js.map → chunk-66C4BSAY.js.map} +1 -1
  15. package/dist/{chunk-EL2O4IUX.js → chunk-ASXSJGPW.js} +20 -24
  16. package/dist/{chunk-EL2O4IUX.js.map → chunk-ASXSJGPW.js.map} +1 -1
  17. package/dist/{chunk-7BNPOCLL.js → chunk-B2WTCLCV.js} +6 -2
  18. package/dist/chunk-B2WTCLCV.js.map +1 -0
  19. package/dist/{chunk-WJARTBCT.js → chunk-D7ARGIA3.js} +16 -7
  20. package/dist/chunk-D7ARGIA3.js.map +1 -0
  21. package/dist/{chunk-MYP2EGHX.js → chunk-GIDCWCHF.js} +21 -14
  22. package/dist/chunk-GIDCWCHF.js.map +1 -0
  23. package/dist/{chunk-MSFACPQQ.js → chunk-HYNGIE5T.js} +11 -11
  24. package/dist/{chunk-MSFACPQQ.js.map → chunk-HYNGIE5T.js.map} +1 -1
  25. package/dist/{chunk-TRIZ7IB7.js → chunk-I5GID3EX.js} +148 -288
  26. package/dist/chunk-I5GID3EX.js.map +1 -0
  27. package/dist/{chunk-GWSBHC4J.js → chunk-KLPVOPRI.js} +261 -38
  28. package/dist/chunk-KLPVOPRI.js.map +1 -0
  29. package/dist/{chunk-BC3S53OZ.js → chunk-N6XMGSGD.js} +30 -14
  30. package/dist/chunk-N6XMGSGD.js.map +1 -0
  31. package/dist/{chunk-6MTY77WU.js → chunk-QB4GXDUM.js} +3 -3
  32. package/dist/{chunk-YDJW5XTN.js → chunk-STT7INZR.js} +25 -1
  33. package/dist/chunk-STT7INZR.js.map +1 -0
  34. package/dist/{chunk-NYUJ4FJR.js → chunk-UETTVYKU.js} +7 -7
  35. package/dist/chunk-UETTVYKU.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-NZ655MWE.js → chunk-YEHO6FDW.js} +5 -4
  39. package/dist/chunk-YEHO6FDW.js.map +1 -0
  40. package/dist/{chunk-SS3E6QLB.js → chunk-YNUBMSMV.js} +2 -2
  41. package/dist/chunk-YNUBMSMV.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 +25 -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/core.css +0 -125
  273. package/src/types/file-reference.ts +77 -0
  274. package/src/types/rbac-functions.ts +290 -0
  275. package/src/types/supabase.ts +10 -28
  276. package/src/types/unified.ts +4 -1
  277. package/src/utils/__tests__/bundleAnalysis.unit.test.ts +81 -55
  278. package/src/utils/__tests__/lazyLoad.unit.test.tsx +21 -12
  279. package/src/utils/__tests__/organisationContext.unit.test.ts +13 -7
  280. package/src/utils/__tests__/performanceBudgets.unit.test.ts +3 -3
  281. package/src/utils/__tests__/sessionTracking.unit.test.ts +32 -12
  282. package/src/utils/appConfig.ts +1 -1
  283. package/src/utils/appIdResolver.test.ts +503 -0
  284. package/src/utils/appIdResolver.ts +1 -1
  285. package/src/utils/appNameResolver.test.ts +494 -0
  286. package/src/utils/appNameResolver.ts +3 -2
  287. package/src/utils/bundleAnalysis.ts +3 -3
  288. package/src/utils/debugLogger.ts +1 -1
  289. package/src/utils/file-reference.ts +263 -0
  290. package/src/utils/formatDate.test.ts +2 -2
  291. package/src/utils/organisationContext.test.ts +340 -0
  292. package/src/utils/organisationContext.ts +19 -6
  293. package/src/utils/performanceBudgets.ts +2 -2
  294. package/src/utils/permissionUtils.test.ts +393 -0
  295. package/src/utils/permissionUtils.ts +5 -2
  296. package/src/utils/secureDataAccess.test.ts +715 -0
  297. package/src/utils/secureDataAccess.ts +21 -5
  298. package/src/utils/sessionTracking.ts +34 -4
  299. package/src/utils/storage/__tests__/helpers.unit.test.ts +328 -0
  300. package/src/utils/storage/__tests__/index.unit.test.ts +16 -0
  301. package/src/utils/storage/helpers.ts +20 -25
  302. package/src/utils/storage/index.ts +29 -1
  303. package/src/vite-env.d.ts +17 -0
  304. package/dist/chunk-22KLBHPS.js.map +0 -1
  305. package/dist/chunk-7BNPOCLL.js.map +0 -1
  306. package/dist/chunk-BC3S53OZ.js.map +0 -1
  307. package/dist/chunk-GWSBHC4J.js.map +0 -1
  308. package/dist/chunk-MYP2EGHX.js.map +0 -1
  309. package/dist/chunk-MZBUOP4P.js.map +0 -1
  310. package/dist/chunk-NYUJ4FJR.js.map +0 -1
  311. package/dist/chunk-NZ655MWE.js.map +0 -1
  312. package/dist/chunk-SS3E6QLB.js.map +0 -1
  313. package/dist/chunk-TRIZ7IB7.js.map +0 -1
  314. package/dist/chunk-WJARTBCT.js.map +0 -1
  315. package/dist/chunk-YDJW5XTN.js.map +0 -1
  316. package/docs/print-components/README.md +0 -258
  317. package/docs/print-components/api-reference.md +0 -636
  318. package/docs/print-components/examples/README.md +0 -204
  319. package/docs/print-components/examples/basic-report.tsx +0 -92
  320. package/docs/print-components/examples/card-catalog.tsx +0 -149
  321. package/docs/print-components/examples/cover-page-report.tsx +0 -163
  322. package/docs/print-components/quick-start.md +0 -363
  323. package/src/components/PrintButton/PrintButton.tsx +0 -321
  324. package/src/components/PrintButton/PrintButtonGroup.tsx +0 -84
  325. package/src/components/PrintButton/PrintToolbar.tsx +0 -94
  326. package/src/components/PrintButton/__tests__/PrintButton.test.tsx +0 -271
  327. package/src/components/PrintButton/examples/PrintButtonShowcase.tsx +0 -438
  328. package/src/components/PrintButton/index.ts +0 -33
  329. package/src/components/PrintButton/types.ts +0 -173
  330. package/src/components/PrintCard/PrintCard.tsx +0 -154
  331. package/src/components/PrintCard/PrintCardContent.tsx +0 -57
  332. package/src/components/PrintCard/PrintCardFooter.tsx +0 -60
  333. package/src/components/PrintCard/PrintCardGrid.tsx +0 -91
  334. package/src/components/PrintCard/PrintCardHeader.tsx +0 -78
  335. package/src/components/PrintCard/PrintCardImage.tsx +0 -81
  336. package/src/components/PrintCard/examples/PrintCardShowcase.tsx +0 -239
  337. package/src/components/PrintCard/index.ts +0 -34
  338. package/src/components/PrintCard/types.ts +0 -171
  339. package/src/components/PrintDataTable/PrintDataTable.tsx +0 -215
  340. package/src/components/PrintDataTable/PrintTableGroup.tsx +0 -90
  341. package/src/components/PrintDataTable/PrintTableRow.tsx +0 -76
  342. package/src/components/PrintDataTable/index.ts +0 -25
  343. package/src/components/PrintDataTable/types.ts +0 -67
  344. package/src/components/PrintFooter/PrintFooter.tsx +0 -183
  345. package/src/components/PrintFooter/PrintFooterContent.tsx +0 -71
  346. package/src/components/PrintFooter/PrintFooterInfo.tsx +0 -86
  347. package/src/components/PrintFooter/PrintPageNumber.tsx +0 -90
  348. package/src/components/PrintFooter/examples/PrintFooterShowcase.tsx +0 -390
  349. package/src/components/PrintFooter/index.ts +0 -30
  350. package/src/components/PrintFooter/types.ts +0 -149
  351. package/src/components/PrintGrid/PrintGrid.tsx +0 -180
  352. package/src/components/PrintGrid/PrintGridBreakpoint.tsx +0 -109
  353. package/src/components/PrintGrid/PrintGridContainer.tsx +0 -128
  354. package/src/components/PrintGrid/PrintGridItem.tsx +0 -220
  355. package/src/components/PrintGrid/examples/PrintGridShowcase.tsx +0 -359
  356. package/src/components/PrintGrid/index.ts +0 -31
  357. package/src/components/PrintGrid/types.ts +0 -159
  358. package/src/components/PrintHeader/PrintCoverHeader.tsx +0 -230
  359. package/src/components/PrintHeader/PrintHeader.tsx +0 -150
  360. package/src/components/PrintHeader/index.ts +0 -17
  361. package/src/components/PrintHeader/types.ts +0 -42
  362. package/src/components/PrintLayout/PrintLayout.tsx +0 -122
  363. package/src/components/PrintLayout/PrintLayoutContext.tsx +0 -66
  364. package/src/components/PrintLayout/PrintPageBreak.tsx +0 -52
  365. package/src/components/PrintLayout/examples/PrintShowcase.tsx +0 -230
  366. package/src/components/PrintLayout/index.ts +0 -19
  367. package/src/components/PrintLayout/types.ts +0 -37
  368. package/src/components/PrintPageBreak/PrintPageBreak.tsx +0 -120
  369. package/src/components/PrintPageBreak/PrintPageBreakGroup.tsx +0 -90
  370. package/src/components/PrintPageBreak/PrintPageBreakIndicator.tsx +0 -112
  371. package/src/components/PrintPageBreak/examples/PrintPageBreakShowcase.tsx +0 -279
  372. package/src/components/PrintPageBreak/index.ts +0 -23
  373. package/src/components/PrintPageBreak/types.ts +0 -94
  374. package/src/components/PrintSection/PrintColumn.tsx +0 -104
  375. package/src/components/PrintSection/PrintDivider.tsx +0 -101
  376. package/src/components/PrintSection/PrintSection.tsx +0 -129
  377. package/src/components/PrintSection/PrintSectionContent.tsx +0 -75
  378. package/src/components/PrintSection/PrintSectionHeader.tsx +0 -97
  379. package/src/components/PrintSection/examples/PrintSectionShowcase.tsx +0 -258
  380. package/src/components/PrintSection/index.ts +0 -33
  381. package/src/components/PrintSection/types.ts +0 -155
  382. package/src/components/PrintText/PrintText.tsx +0 -116
  383. package/src/components/PrintText/index.ts +0 -16
  384. package/src/components/PrintText/types.ts +0 -24
  385. package/src/rbac/__tests__/integration.test.tsx +0 -218
  386. package/src/utils/print/PrintDataProcessor.ts +0 -390
  387. package/src/utils/print/examples/PrintUtilitiesShowcase.tsx +0 -397
  388. package/src/utils/print/index.ts +0 -29
  389. package/src/utils/print/types.ts +0 -196
  390. package/src/utils/print/usePrintOptimization.ts +0 -272
  391. /package/dist/{DataTable-7FMFXA7A.js.map → DataTable-DJQTKX33.js.map} +0 -0
  392. /package/dist/{api-H5A3H4IR.js.map → api-LUNF5O6M.js.map} +0 -0
  393. /package/dist/{appNameResolver-7GHF5ED2.js.map → appNameResolver-UURKN7NF.js.map} +0 -0
  394. /package/dist/{audit-BUW3LMJB.js.map → audit-6TOCAMKO.js.map} +0 -0
  395. /package/dist/{chunk-NRK4AIHQ.js.map → chunk-2DFCT6D3.js.map} +0 -0
  396. /package/dist/{chunk-6MTY77WU.js.map → chunk-QB4GXDUM.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
+ });