@jmruthers/pace-core 0.6.4 → 0.6.6

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 (387) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/README.md +5 -403
  3. package/core-usage-manifest.json +93 -0
  4. package/cursor-rules/00-pace-core-compliance.mdc +128 -26
  5. package/cursor-rules/01-standards-compliance.mdc +49 -8
  6. package/cursor-rules/02-project-structure.mdc +6 -0
  7. package/cursor-rules/03-solid-principles.mdc +2 -0
  8. package/cursor-rules/04-testing-standards.mdc +2 -0
  9. package/cursor-rules/05-bug-reports-and-features.mdc +2 -0
  10. package/cursor-rules/06-code-quality.mdc +2 -0
  11. package/cursor-rules/07-tech-stack-compliance.mdc +2 -0
  12. package/cursor-rules/08-markup-quality.mdc +52 -27
  13. package/cursor-rules/09-rbac-compliance.mdc +462 -0
  14. package/cursor-rules/10-error-handling-patterns.mdc +179 -0
  15. package/cursor-rules/11-performance-optimization.mdc +169 -0
  16. package/cursor-rules/12-ci-cd-integration.mdc +150 -0
  17. package/dist/{AuthService-Cb34EQs3.d.ts → AuthService-DmfO5rGS.d.ts} +10 -0
  18. package/dist/{DataTable-BMRU8a1j.d.ts → DataTable-2N_tqbfq.d.ts} +1 -1
  19. package/dist/DataTable-LRJL4IRV.js +15 -0
  20. package/dist/{PublicPageProvider-DEMpysFR.d.ts → PublicPageProvider-BBH6Vqg7.d.ts} +72 -139
  21. package/dist/UnifiedAuthProvider-ZT6TIGM7.js +7 -0
  22. package/dist/api-Y4MQWOFW.js +4 -0
  23. package/dist/audit-MYQXYZFU.js +3 -0
  24. package/dist/{chunk-J36DSWQK.js → chunk-2HGJFNAH.js} +8 -28
  25. package/dist/{chunk-OEWDTMG7.js → chunk-3O3WHILE.js} +38 -121
  26. package/dist/{chunk-M43Y4SSO.js → chunk-3QC3KRHK.js} +1 -14
  27. package/dist/{chunk-DGUM43GV.js → chunk-3RG5ZIWI.js} +1 -4
  28. package/dist/{chunk-QXHPKYJV.js → chunk-4SXLQIZO.js} +1 -26
  29. package/dist/chunk-4T7OBVTU.js +62 -0
  30. package/dist/{chunk-E66EQZE6.js → chunk-6GLLNA6U.js} +3 -9
  31. package/dist/{chunk-ZSAAAMVR.js → chunk-6QYDGKQY.js} +1 -4
  32. package/dist/{chunk-NN6WWZ5U.js → chunk-7TYHROIV.js} +579 -563
  33. package/dist/{chunk-M7MPQISP.js → chunk-A55DK444.js} +9 -16
  34. package/dist/{chunk-63FOKYGO.js → chunk-AHU7G2R5.js} +2 -11
  35. package/dist/{chunk-L4OXEN46.js → chunk-BVP2BCJF.js} +2 -16
  36. package/dist/chunk-C7NSAPTL.js +1 -0
  37. package/dist/{chunk-YKRAFF5K.js → chunk-FENMYN2U.js} +73 -149
  38. package/dist/{chunk-AVMLPIM7.js → chunk-FTCRZOG2.js} +284 -432
  39. package/dist/{chunk-G37KK66H.js → chunk-FYHN4DD5.js} +60 -19
  40. package/dist/{chunk-VBXEHIUJ.js → chunk-HF6O3O37.js} +6 -88
  41. package/dist/{chunk-I6DAQMWX.js → chunk-LAZMKTTF.js} +930 -891
  42. package/dist/{chunk-5EC5MEWX.js → chunk-MAGBIDNS.js} +77 -222
  43. package/dist/chunk-MBADTM7L.js +64 -0
  44. package/dist/chunk-OHIK3MIO.js +994 -0
  45. package/dist/{chunk-6SOIHG6Z.js → chunk-S7DKJPLT.js} +115 -44
  46. package/dist/{chunk-FMUCXFII.js → chunk-SD6WQY43.js} +1 -5
  47. package/dist/{chunk-PWLANIRT.js → chunk-TTRFSOKR.js} +1 -7
  48. package/dist/{chunk-5DRSZLL2.js → chunk-UH3NTO3F.js} +1 -6
  49. package/dist/{chunk-FFQEQTNW.js → chunk-UIYSCEV7.js} +134 -45
  50. package/dist/{chunk-3LPHPB62.js → chunk-ZFYPMX46.js} +271 -87
  51. package/dist/{chunk-7JPAB3T5.js → chunk-ZS5VO5JB.js} +1989 -1283
  52. package/dist/components.d.ts +6 -6
  53. package/dist/components.js +57 -267
  54. package/dist/{database.generated-CzIvgcPu.d.ts → database.generated-CcnC_DRc.d.ts} +4795 -3691
  55. package/dist/eslint-rules/index.cjs +22 -0
  56. package/dist/eslint-rules/rules/compliance.cjs +348 -0
  57. package/dist/eslint-rules/rules/components.cjs +113 -0
  58. package/dist/eslint-rules/rules/imports.cjs +102 -0
  59. package/dist/eslint-rules/rules/rbac.cjs +790 -0
  60. package/dist/eslint-rules/utils/helpers.cjs +42 -0
  61. package/dist/eslint-rules/utils/manifest-loader.cjs +75 -0
  62. package/dist/hooks.d.ts +5 -5
  63. package/dist/hooks.js +62 -270
  64. package/dist/icons/index.d.ts +1 -0
  65. package/dist/icons/index.js +1 -0
  66. package/dist/index.d.ts +36 -26
  67. package/dist/index.js +87 -690
  68. package/dist/providers.d.ts +2 -2
  69. package/dist/providers.js +8 -35
  70. package/dist/rbac/eslint-rules.d.ts +46 -44
  71. package/dist/rbac/eslint-rules.js +7 -4
  72. package/dist/rbac/index.d.ts +124 -594
  73. package/dist/rbac/index.js +14 -207
  74. package/dist/styles/index.js +2 -12
  75. package/dist/theming/runtime.js +3 -19
  76. package/dist/{timezone-CHhWg6b4.d.ts → timezone-BZe_eUxx.d.ts} +175 -1
  77. package/dist/{types-CkbwOr4Y.d.ts → types-B-K_5VnO.d.ts} +4 -0
  78. package/dist/types-t9H8qKRw.d.ts +55 -0
  79. package/dist/types.d.ts +1 -1
  80. package/dist/types.js +7 -94
  81. package/dist/{usePublicRouteParams-i3qtoBgg.d.ts → usePublicRouteParams-COZ28Mvq.d.ts} +9 -9
  82. package/dist/utils.d.ts +24 -117
  83. package/dist/utils.js +54 -392
  84. package/docs/README.md +16 -6
  85. package/docs/api/README.md +4 -402
  86. package/docs/api/modules.md +454 -930
  87. package/docs/api-reference/components.md +3 -1
  88. package/docs/api-reference/deprecated.md +31 -6
  89. package/docs/api-reference/rpc-functions.md +78 -3
  90. package/docs/best-practices/accessibility.md +6 -3
  91. package/docs/getting-started/cursor-rules.md +3 -23
  92. package/docs/getting-started/dependencies.md +650 -0
  93. package/docs/getting-started/installation-guide.md +20 -7
  94. package/docs/getting-started/quick-start.md +23 -12
  95. package/docs/implementation-guides/permission-enforcement.md +4 -0
  96. package/docs/rbac/MIGRATION_GUIDE.md +819 -0
  97. package/docs/rbac/RBAC_CONTRACT.md +724 -0
  98. package/docs/rbac/README.md +12 -3
  99. package/docs/rbac/edge-functions-guide.md +376 -0
  100. package/docs/rbac/secure-client-protection.md +0 -34
  101. package/docs/standards/00-pace-core-compliance.md +967 -0
  102. package/docs/standards/01-standards-compliance.md +188 -0
  103. package/docs/standards/02-project-structure.md +985 -0
  104. package/docs/standards/03-solid-principles.md +39 -0
  105. package/docs/standards/04-testing-standards.md +36 -0
  106. package/docs/standards/05-bug-reports-and-features.md +27 -0
  107. package/docs/standards/{04-code-style-standard.md → 06-code-quality.md} +2 -0
  108. package/docs/standards/07-tech-stack-compliance.md +30 -0
  109. package/docs/standards/08-markup-quality.md +345 -0
  110. package/docs/standards/{07-rbac-and-rls-standard.md → 09-rbac-compliance.md} +149 -54
  111. package/docs/standards/10-error-handling-patterns.md +401 -0
  112. package/docs/standards/11-performance-optimization.md +348 -0
  113. package/docs/standards/12-ci-cd-integration.md +370 -0
  114. package/docs/standards/ALIGNMENT_REVIEW_SUMMARY.md +192 -0
  115. package/docs/standards/README.md +62 -33
  116. package/docs/troubleshooting/organisation-context-setup.md +42 -19
  117. package/eslint-config-pace-core.cjs +20 -4
  118. package/package.json +31 -21
  119. package/scripts/audit/audit-compliance.cjs +1295 -0
  120. package/scripts/audit/audit-components.cjs +260 -0
  121. package/scripts/audit/audit-dependencies.cjs +395 -0
  122. package/scripts/audit/audit-rbac.cjs +954 -0
  123. package/scripts/audit/audit-standards.cjs +1268 -0
  124. package/scripts/audit/index.cjs +1898 -194
  125. package/scripts/install-cursor-rules.cjs +259 -8
  126. package/scripts/validate-master.js +1 -1
  127. package/src/__tests__/fixtures/supabase.ts +1 -1
  128. package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +1 -1
  129. package/src/__tests__/helpers/__tests__/optimized-test-setup.test.ts +1 -1
  130. package/src/__tests__/helpers/__tests__/supabaseMock.test.ts +1 -1
  131. package/src/__tests__/helpers/__tests__/test-utils.test.tsx +3 -3
  132. package/src/__tests__/helpers/component-test-utils.tsx +1 -1
  133. package/src/__tests__/helpers/supabaseMock.ts +2 -2
  134. package/src/__tests__/public-recipe-view.test.ts +38 -9
  135. package/src/components/Button/Button.tsx +5 -1
  136. package/src/components/ContextSelector/ContextSelector.tsx +42 -39
  137. package/src/components/DataTable/__tests__/keyboard.test.tsx +15 -2
  138. package/src/components/DataTable/components/DataTableBody.tsx +55 -31
  139. package/src/components/DataTable/components/DataTableCore.tsx +186 -13
  140. package/src/components/DataTable/components/DataTableLayout.tsx +30 -5
  141. package/src/components/DataTable/components/EditFields.tsx +23 -3
  142. package/src/components/DataTable/components/EditableRow.tsx +7 -2
  143. package/src/components/DataTable/components/ImportModal.tsx +4 -6
  144. package/src/components/DataTable/components/RowComponent.tsx +12 -0
  145. package/src/components/DataTable/components/ViewRowModal.tsx +4 -4
  146. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +455 -96
  147. package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +122 -58
  148. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +0 -4
  149. package/src/components/DataTable/core/DataTableContext.tsx +1 -1
  150. package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +51 -47
  151. package/src/components/DataTable/hooks/useDataTablePermissions.ts +24 -21
  152. package/src/components/DataTable/hooks/useDataTableState.ts +125 -9
  153. package/src/components/DataTable/hooks/useTableColumns.ts +40 -2
  154. package/src/components/DataTable/hooks/useTableHandlers.ts +11 -0
  155. package/src/components/DataTable/types.ts +5 -0
  156. package/src/components/DateTimeField/DateTimeField.tsx +20 -20
  157. package/src/components/DateTimeField/README.md +5 -2
  158. package/src/components/Dialog/Dialog.test.tsx +361 -318
  159. package/src/components/Dialog/Dialog.tsx +1154 -323
  160. package/src/components/Dialog/index.ts +3 -3
  161. package/src/components/FileDisplay/FileDisplay.test.tsx +45 -2
  162. package/src/components/FileDisplay/FileDisplay.tsx +28 -22
  163. package/src/components/Form/Form.test.tsx +9 -10
  164. package/src/components/Form/Form.tsx +369 -9
  165. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +28 -28
  166. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +40 -54
  167. package/src/components/LoginForm/LoginForm.tsx +2 -2
  168. package/src/components/NavigationMenu/NavigationMenu.test.tsx +14 -13
  169. package/src/components/NavigationMenu/NavigationMenu.tsx +2 -2
  170. package/src/components/NavigationMenu/useNavigationFiltering.ts +11 -21
  171. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +6 -4
  172. package/src/components/PaceAppLayout/PaceAppLayout.tsx +30 -41
  173. package/src/components/PaceAppLayout/README.md +10 -9
  174. package/src/components/PaceAppLayout/test-setup.tsx +40 -31
  175. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +108 -61
  176. package/src/components/PaceLoginPage/PaceLoginPage.tsx +27 -3
  177. package/src/components/PasswordChange/PasswordChangeForm.test.tsx +61 -0
  178. package/src/components/PasswordChange/PasswordChangeForm.tsx +20 -13
  179. package/src/components/PublicLayout/PublicLayout.test.tsx +7 -3
  180. package/src/components/PublicLayout/PublicPageLayout.tsx +5 -8
  181. package/src/components/Select/Select.tsx +23 -21
  182. package/src/components/Select/types.ts +1 -1
  183. package/src/components/UserMenu/UserMenu.test.tsx +38 -6
  184. package/src/components/UserMenu/UserMenu.tsx +39 -34
  185. package/src/components/index.ts +3 -4
  186. package/src/eslint-rules/index.cjs +22 -0
  187. package/src/eslint-rules/rules/compliance.cjs +348 -0
  188. package/src/eslint-rules/rules/components.cjs +113 -0
  189. package/src/eslint-rules/rules/imports.cjs +102 -0
  190. package/src/eslint-rules/rules/rbac.cjs +790 -0
  191. package/src/eslint-rules/utils/helpers.cjs +42 -0
  192. package/src/eslint-rules/utils/manifest-loader.cjs +75 -0
  193. package/src/hooks/__tests__/hooks.integration.test.tsx +6 -8
  194. package/src/hooks/__tests__/useAppConfig.unit.test.ts +129 -67
  195. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +149 -67
  196. package/src/hooks/__tests__/usePublicEvent.test.ts +149 -79
  197. package/src/hooks/__tests__/usePublicEvent.unit.test.ts +158 -109
  198. package/src/hooks/__tests__/useSessionDraft.test.ts +163 -0
  199. package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +10 -5
  200. package/src/hooks/public/usePublicEvent.ts +62 -190
  201. package/src/hooks/public/usePublicEventLogo.test.ts +70 -17
  202. package/src/hooks/public/usePublicEventLogo.ts +19 -9
  203. package/src/hooks/useAppConfig.ts +26 -24
  204. package/src/hooks/useEventTheme.test.ts +211 -233
  205. package/src/hooks/useEventTheme.ts +19 -28
  206. package/src/hooks/useEvents.ts +11 -7
  207. package/src/hooks/useKeyboardShortcuts.ts +1 -1
  208. package/src/hooks/useOrganisationPermissions.ts +9 -11
  209. package/src/hooks/useOrganisations.ts +13 -7
  210. package/src/hooks/useQueryCache.ts +0 -1
  211. package/src/hooks/useSessionDraft.ts +380 -0
  212. package/src/hooks/useSessionRestoration.ts +3 -1
  213. package/src/icons/index.ts +27 -0
  214. package/src/index.ts +16 -1
  215. package/src/providers/OrganisationProvider.tsx +23 -14
  216. package/src/providers/services/EventServiceProvider.tsx +1 -24
  217. package/src/providers/services/UnifiedAuthProvider.tsx +5 -48
  218. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +3 -0
  219. package/src/rbac/README.md +20 -20
  220. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +7 -457
  221. package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +33 -7
  222. package/src/rbac/adapters.tsx +7 -295
  223. package/src/rbac/api.test.ts +44 -56
  224. package/src/rbac/api.ts +10 -17
  225. package/src/rbac/cache-invalidation.ts +0 -1
  226. package/src/rbac/compliance/index.ts +10 -0
  227. package/src/rbac/compliance/pattern-detector.ts +553 -0
  228. package/src/rbac/compliance/runtime-compliance.ts +22 -0
  229. package/src/rbac/components/AccessDenied.tsx +150 -0
  230. package/src/rbac/components/NavigationGuard.tsx +12 -20
  231. package/src/rbac/components/PagePermissionGuard.tsx +4 -24
  232. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +21 -8
  233. package/src/rbac/components/index.ts +3 -41
  234. package/src/rbac/eslint-rules.js +1 -1
  235. package/src/rbac/hooks/index.ts +0 -3
  236. package/src/rbac/hooks/permissions/index.ts +0 -3
  237. package/src/rbac/hooks/permissions/useAccessLevel.ts +4 -8
  238. package/src/rbac/hooks/usePermissions.ts +0 -3
  239. package/src/rbac/hooks/useRBAC.test.ts +21 -3
  240. package/src/rbac/hooks/useRBAC.ts +4 -3
  241. package/src/rbac/hooks/useResolvedScope.test.ts +57 -47
  242. package/src/rbac/hooks/useResolvedScope.ts +58 -140
  243. package/src/rbac/hooks/useResourcePermissions.test.ts +241 -60
  244. package/src/rbac/hooks/useResourcePermissions.ts +182 -63
  245. package/src/rbac/hooks/useRoleManagement.test.ts +65 -22
  246. package/src/rbac/hooks/useRoleManagement.ts +147 -19
  247. package/src/rbac/hooks/useSecureSupabase.ts +4 -8
  248. package/src/rbac/index.ts +7 -9
  249. package/src/rbac/permissions.ts +17 -17
  250. package/src/rbac/utils/contextValidator.ts +45 -7
  251. package/src/services/AuthService.ts +132 -23
  252. package/src/services/EventService.ts +4 -97
  253. package/src/services/InactivityService.ts +155 -58
  254. package/src/services/OrganisationService.ts +7 -44
  255. package/src/services/__tests__/OrganisationService.test.ts +26 -8
  256. package/src/services/base/BaseService.ts +0 -3
  257. package/src/styles/core.css +4 -0
  258. package/src/types/database.generated.ts +4733 -3809
  259. package/src/utils/__tests__/organisationContext.unit.test.ts +9 -10
  260. package/src/utils/context/organisationContext.test.ts +13 -28
  261. package/src/utils/context/organisationContext.ts +21 -52
  262. package/src/utils/dynamic/dynamicUtils.ts +1 -1
  263. package/src/utils/file-reference/index.ts +39 -15
  264. package/src/utils/formatting/formatDateTime.test.ts +3 -2
  265. package/src/utils/formatting/formatTime.test.ts +3 -2
  266. package/src/utils/google-places/loadGoogleMapsScript.ts +29 -4
  267. package/src/utils/index.ts +4 -1
  268. package/src/utils/persistence/__tests__/keyDerivation.test.ts +135 -0
  269. package/src/utils/persistence/__tests__/sensitiveFieldDetection.test.ts +123 -0
  270. package/src/utils/persistence/keyDerivation.ts +304 -0
  271. package/src/utils/persistence/sensitiveFieldDetection.ts +212 -0
  272. package/src/utils/security/secureStorage.ts +5 -5
  273. package/src/utils/storage/helpers.ts +3 -3
  274. package/src/utils/supabase/createBaseClient.ts +147 -0
  275. package/src/utils/timezone/timezone.test.ts +1 -2
  276. package/src/utils/timezone/timezone.ts +1 -1
  277. package/src/utils/validation/csrf.ts +4 -4
  278. package/cursor-rules/CHANGELOG.md +0 -119
  279. package/cursor-rules/README.md +0 -192
  280. package/dist/DataTable-E7YQZD7D.js +0 -175
  281. package/dist/DataTable-E7YQZD7D.js.map +0 -1
  282. package/dist/UnifiedAuthProvider-QPXO24B4.js +0 -18
  283. package/dist/UnifiedAuthProvider-QPXO24B4.js.map +0 -1
  284. package/dist/api-6LVZTHDS.js +0 -52
  285. package/dist/api-6LVZTHDS.js.map +0 -1
  286. package/dist/audit-V53FV5AG.js +0 -17
  287. package/dist/audit-V53FV5AG.js.map +0 -1
  288. package/dist/chunk-36LVWXB2.js +0 -227
  289. package/dist/chunk-36LVWXB2.js.map +0 -1
  290. package/dist/chunk-3LPHPB62.js.map +0 -1
  291. package/dist/chunk-5DRSZLL2.js.map +0 -1
  292. package/dist/chunk-5EC5MEWX.js.map +0 -1
  293. package/dist/chunk-63FOKYGO.js.map +0 -1
  294. package/dist/chunk-6SOIHG6Z.js.map +0 -1
  295. package/dist/chunk-7JPAB3T5.js.map +0 -1
  296. package/dist/chunk-ATKZM7RX.js +0 -2053
  297. package/dist/chunk-ATKZM7RX.js.map +0 -1
  298. package/dist/chunk-AVMLPIM7.js.map +0 -1
  299. package/dist/chunk-DGUM43GV.js.map +0 -1
  300. package/dist/chunk-E66EQZE6.js.map +0 -1
  301. package/dist/chunk-FFQEQTNW.js.map +0 -1
  302. package/dist/chunk-FMUCXFII.js.map +0 -1
  303. package/dist/chunk-G37KK66H.js.map +0 -1
  304. package/dist/chunk-I6DAQMWX.js.map +0 -1
  305. package/dist/chunk-J36DSWQK.js.map +0 -1
  306. package/dist/chunk-KQCRWDSA.js +0 -1
  307. package/dist/chunk-KQCRWDSA.js.map +0 -1
  308. package/dist/chunk-L4OXEN46.js.map +0 -1
  309. package/dist/chunk-LMC26NLJ.js +0 -84
  310. package/dist/chunk-LMC26NLJ.js.map +0 -1
  311. package/dist/chunk-M43Y4SSO.js.map +0 -1
  312. package/dist/chunk-M7MPQISP.js.map +0 -1
  313. package/dist/chunk-NN6WWZ5U.js.map +0 -1
  314. package/dist/chunk-OEWDTMG7.js.map +0 -1
  315. package/dist/chunk-PWLANIRT.js.map +0 -1
  316. package/dist/chunk-QXHPKYJV.js.map +0 -1
  317. package/dist/chunk-VBXEHIUJ.js.map +0 -1
  318. package/dist/chunk-YKRAFF5K.js.map +0 -1
  319. package/dist/chunk-ZSAAAMVR.js.map +0 -1
  320. package/dist/components.js.map +0 -1
  321. package/dist/contextValidator-OOPCLPZW.js +0 -9
  322. package/dist/contextValidator-OOPCLPZW.js.map +0 -1
  323. package/dist/eslint-rules/pace-core-compliance.cjs +0 -510
  324. package/dist/hooks.js.map +0 -1
  325. package/dist/index.js.map +0 -1
  326. package/dist/providers.js.map +0 -1
  327. package/dist/rbac/eslint-rules.js.map +0 -1
  328. package/dist/rbac/index.js.map +0 -1
  329. package/dist/styles/index.js.map +0 -1
  330. package/dist/theming/runtime.js.map +0 -1
  331. package/dist/types.js.map +0 -1
  332. package/dist/utils.js.map +0 -1
  333. package/docs/standards/01-architecture-standard.md +0 -44
  334. package/docs/standards/02-api-and-rpc-standard.md +0 -39
  335. package/docs/standards/03-component-standard.md +0 -32
  336. package/docs/standards/05-security-standard.md +0 -44
  337. package/docs/standards/06-testing-and-docs-standard.md +0 -29
  338. package/docs/standards/pace-core-compliance.md +0 -432
  339. package/scripts/audit/core/checks/accessibility.cjs +0 -197
  340. package/scripts/audit/core/checks/api-usage.cjs +0 -191
  341. package/scripts/audit/core/checks/bundle.cjs +0 -142
  342. package/scripts/audit/core/checks/compliance.cjs +0 -2706
  343. package/scripts/audit/core/checks/config.cjs +0 -54
  344. package/scripts/audit/core/checks/coverage.cjs +0 -84
  345. package/scripts/audit/core/checks/dependencies.cjs +0 -994
  346. package/scripts/audit/core/checks/documentation.cjs +0 -268
  347. package/scripts/audit/core/checks/environment.cjs +0 -116
  348. package/scripts/audit/core/checks/error-handling.cjs +0 -340
  349. package/scripts/audit/core/checks/forms.cjs +0 -172
  350. package/scripts/audit/core/checks/heuristics.cjs +0 -68
  351. package/scripts/audit/core/checks/hooks.cjs +0 -334
  352. package/scripts/audit/core/checks/imports.cjs +0 -244
  353. package/scripts/audit/core/checks/performance.cjs +0 -325
  354. package/scripts/audit/core/checks/routes.cjs +0 -117
  355. package/scripts/audit/core/checks/state.cjs +0 -130
  356. package/scripts/audit/core/checks/structure.cjs +0 -65
  357. package/scripts/audit/core/checks/style.cjs +0 -584
  358. package/scripts/audit/core/checks/testing.cjs +0 -122
  359. package/scripts/audit/core/checks/typescript.cjs +0 -61
  360. package/scripts/audit/core/scanner.cjs +0 -199
  361. package/scripts/audit/core/utils.cjs +0 -137
  362. package/scripts/audit/reporters/console.cjs +0 -151
  363. package/scripts/audit/reporters/json.cjs +0 -54
  364. package/scripts/audit/reporters/markdown.cjs +0 -124
  365. package/scripts/audit-consuming-app.cjs +0 -86
  366. package/src/eslint-rules/pace-core-compliance.cjs +0 -510
  367. package/src/eslint-rules/pace-core-compliance.js +0 -638
  368. package/src/rbac/components/EnhancedNavigationMenu.test.tsx +0 -555
  369. package/src/rbac/components/EnhancedNavigationMenu.tsx +0 -293
  370. package/src/rbac/components/NavigationProvider.test.tsx +0 -481
  371. package/src/rbac/components/NavigationProvider.tsx +0 -345
  372. package/src/rbac/components/PagePermissionProvider.test.tsx +0 -476
  373. package/src/rbac/components/PagePermissionProvider.tsx +0 -279
  374. package/src/rbac/components/PermissionEnforcer.tsx +0 -312
  375. package/src/rbac/components/RoleBasedRouter.tsx +0 -440
  376. package/src/rbac/components/SecureDataProvider.test.tsx +0 -543
  377. package/src/rbac/components/SecureDataProvider.tsx +0 -339
  378. package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +0 -620
  379. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +0 -726
  380. package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +0 -661
  381. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +0 -881
  382. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +0 -783
  383. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +0 -645
  384. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +0 -659
  385. package/src/rbac/hooks/permissions/useCachedPermissions.ts +0 -79
  386. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +0 -90
  387. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +0 -90
@@ -1,10 +1,11 @@
1
- import { U as UUID, g as PermissionCacheKey, h as AuditEventSource, i as RBACAuditEvent, a as PermissionCheck, S as Scope, A as AccessLevel, b as PermissionMap, j as RBACAppContext, k as RBACRoleContext, P as Permission, l as UserRBACContext } from '../types-BeoeWV5I.js';
1
+ import { U as UUID, g as PermissionCacheKey, h as AuditEventSource, i as RBACAuditEvent, a as PermissionCheck, S as Scope, A as AccessLevel, b as PermissionMap, j as RBACAppContext, k as RBACRoleContext, l as UserRBACContext, P as Permission } from '../types-BeoeWV5I.js';
2
2
  export { E as EventAppRole, G as GlobalRole, I as InvalidScopeError, M as MissingUserContextError, O as Operation, e as OrganisationContextRequiredError, c as OrganisationRole, d as PermissionDeniedError, R as RBACError, f as RBACNotInitializedError } from '../types-BeoeWV5I.js';
3
3
  export { A as AccessLevelContext, s as AuditEventType, P as PermissionSource, d as RBACAccessValidateParams, e as RBACAccessValidateResult, q as RBACAuditLogParams, r as RBACAuditLogResult, t as RBACContext, w as RBACErrorCode, v as RBACFunctionResponse, f as RBACPageAccessCheckParams, R as RBACPermissionCheckParams, a as RBACPermissionCheckResult, b as RBACPermissionsGetParams, c as RBACPermissionsGetResult, u as RBACResult, g as RBACRoleGrantParams, h as RBACRoleGrantResult, i as RBACRoleRevokeParams, j as RBACRoleRevokeResult, m as RBACRoleValidateParams, n as RBACRoleValidateResult, k as RBACRolesListParams, l as RBACRolesListResult, o as RBACSessionTrackParams, p as RBACSessionTrackResult, x as RPCFunction, S as SessionType } from '../functions-DHebl8-F.js';
4
4
  import { SupabaseClient } from '@supabase/supabase-js';
5
- import { D as Database } from '../database.generated-CzIvgcPu.js';
5
+ import { D as Database } from '../database.generated-CcnC_DRc.js';
6
6
  import * as react_jsx_runtime from 'react/jsx-runtime';
7
- import React__default, { ReactNode } from 'react';
7
+ import React__default from 'react';
8
+ import { a as NavigationItem } from '../types-t9H8qKRw.js';
8
9
  import '../core-CUElvH_C.js';
9
10
 
10
11
  /**
@@ -842,63 +843,6 @@ declare class RBACEngine {
842
843
  */
843
844
  declare function createRBACEngine(supabase: SupabaseClient<Database>, securityConfig?: Partial<RBACSecurityConfig>): RBACEngine;
844
845
 
845
- interface PagePermissionContextType {
846
- /** Check if user has permission for a page */
847
- hasPagePermission: (pageName: string, operation: string, pageId?: string, scope?: Scope) => boolean;
848
- /** Get all page permissions for current user */
849
- getPagePermissions: () => Record<string, string[]>;
850
- /** Check if page permission checking is enabled */
851
- isEnabled: boolean;
852
- /** Check if strict mode is enabled */
853
- isStrictMode: boolean;
854
- /** Check if audit logging is enabled */
855
- isAuditLogEnabled: boolean;
856
- /** Get page access history */
857
- getPageAccessHistory: () => PageAccessRecord[];
858
- /** Clear page access history */
859
- clearPageAccessHistory: () => void;
860
- }
861
- interface PageAccessRecord {
862
- pageName: string;
863
- operation: string;
864
- userId: UUID;
865
- scope: Scope;
866
- allowed: boolean;
867
- timestamp: string;
868
- pageId?: string;
869
- }
870
- interface PagePermissionProviderProps {
871
- /** Child components */
872
- children: React__default.ReactNode;
873
- /** Enable strict mode to prevent bypassing (default: true) */
874
- strictMode?: boolean;
875
- /** Enable audit logging (default: true) */
876
- auditLog?: boolean;
877
- /** Callback when page access is attempted */
878
- onPageAccess?: (pageName: string, operation: string, allowed: boolean, record: PageAccessRecord) => void;
879
- /** Callback when strict mode violation occurs */
880
- onStrictModeViolation?: (pageName: string, operation: string, record: PageAccessRecord) => void;
881
- /** Maximum number of access records to keep in history */
882
- maxHistorySize?: number;
883
- }
884
- /**
885
- * PagePermissionProvider - Manages page-level permissions across the app
886
- *
887
- * This provider ensures that all pages are properly protected and provides
888
- * centralized page permission management with strict enforcement.
889
- *
890
- * @param props - Provider props
891
- * @returns React element with page permission context
892
- */
893
- declare function PagePermissionProvider({ children, strictMode, auditLog, onPageAccess, onStrictModeViolation, maxHistorySize }: PagePermissionProviderProps): react_jsx_runtime.JSX.Element;
894
- /**
895
- * Hook to use page permission context
896
- *
897
- * @returns Page permission context
898
- * @throws Error if used outside of PagePermissionProvider
899
- */
900
- declare function usePagePermissions(): PagePermissionContextType;
901
-
902
846
  interface PagePermissionGuardProps {
903
847
  /** Name of the page being protected */
904
848
  pageName: string;
@@ -923,281 +867,6 @@ interface PagePermissionGuardProps {
923
867
  }
924
868
  declare const PagePermissionGuard: React__default.MemoExoticComponent<({ pageName, operation, children, fallback, strictMode, auditLog, pageId, scope, onDenied, loading }: PagePermissionGuardProps) => string | number | bigint | boolean | Iterable<React__default.ReactNode> | Promise<string | number | bigint | boolean | React__default.ReactPortal | React__default.ReactElement<unknown, string | React__default.JSXElementConstructor<any>> | Iterable<React__default.ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null>;
925
869
 
926
- interface DataAccessRecord {
927
- table: string;
928
- operation: string;
929
- userId: UUID;
930
- scope: Scope;
931
- allowed: boolean;
932
- timestamp: string;
933
- query?: string;
934
- filters?: Record<string, any>;
935
- }
936
- interface SecureDataContextType {
937
- /** Check if data access is allowed for a table and operation */
938
- isDataAccessAllowed: (table: string, operation: string, scope?: Scope) => boolean;
939
- /** Get all data access permissions for current user */
940
- getDataAccessPermissions: () => Record<string, string[]>;
941
- /** Check if secure data access is enabled */
942
- isEnabled: boolean;
943
- /** Check if strict mode is enabled */
944
- isStrictMode: boolean;
945
- /** Check if audit logging is enabled */
946
- isAuditLogEnabled: boolean;
947
- /** Get data access history */
948
- getDataAccessHistory: () => DataAccessRecord[];
949
- /** Clear data access history */
950
- clearDataAccessHistory: () => void;
951
- /** Validate data access attempt */
952
- validateDataAccess: (table: string, operation: string, scope?: Scope) => boolean;
953
- }
954
- interface SecureDataProviderProps {
955
- /** Child components */
956
- children: React__default.ReactNode;
957
- /** Enable strict mode to prevent bypassing (default: true) */
958
- strictMode?: boolean;
959
- /** Enable audit logging (default: true) */
960
- auditLog?: boolean;
961
- /** Callback when data access is attempted */
962
- onDataAccess?: (table: string, operation: string, allowed: boolean, record: DataAccessRecord) => void;
963
- /** Callback when strict mode violation occurs */
964
- onStrictModeViolation?: (table: string, operation: string, record: DataAccessRecord) => void;
965
- /** Maximum number of access records to keep in history */
966
- maxHistorySize?: number;
967
- /** Enable RLS enforcement (default: true) */
968
- enforceRLS?: boolean;
969
- }
970
- /**
971
- * SecureDataProvider - Prevents direct Supabase access and enforces secure data patterns
972
- *
973
- * This provider ensures that all data access goes through the secure RBAC system
974
- * and prevents apps from bypassing data access controls.
975
- *
976
- * @param props - Provider props
977
- * @returns React element with secure data context
978
- */
979
- declare function SecureDataProvider({ children, strictMode, auditLog, onDataAccess, onStrictModeViolation, maxHistorySize, enforceRLS }: SecureDataProviderProps): react_jsx_runtime.JSX.Element;
980
- /**
981
- * Hook to use secure data context
982
- *
983
- * @returns Secure data context
984
- * @throws Error if used outside of SecureDataProvider
985
- */
986
- declare function useSecureData(): SecureDataContextType;
987
-
988
- interface PermissionEnforcerProps {
989
- /** Permissions required for access */
990
- permissions: Permission[];
991
- /** Operation being performed */
992
- operation: string;
993
- /** Content to render when user has permission */
994
- children: React__default.ReactNode;
995
- /** Content to render when user lacks permission */
996
- fallback?: React__default.ReactNode;
997
- /** Enable strict mode to prevent bypassing (default: true) */
998
- strictMode?: boolean;
999
- /** Force audit logging for this operation (default: true) */
1000
- auditLog?: boolean;
1001
- /** Custom scope for permission checking */
1002
- scope?: Scope;
1003
- /** Callback when access is denied */
1004
- onDenied?: (permissions: Permission[], operation: string) => void;
1005
- /** Loading state content */
1006
- loading?: React__default.ReactNode;
1007
- /** Require all permissions (AND) or any permission (OR) */
1008
- requireAll?: boolean;
1009
- }
1010
- /**
1011
- * PermissionEnforcer - Enforces permissions for operations
1012
- *
1013
- * This component ensures that users can only perform operations they have permission for.
1014
- * It integrates with the existing RBAC system and provides strict enforcement to
1015
- * prevent apps from bypassing permission checks.
1016
- *
1017
- * @param props - Component props
1018
- * @returns React element with permission enforcement
1019
- */
1020
- declare function PermissionEnforcer({ permissions, operation, children, fallback, strictMode, auditLog, scope, onDenied, loading, requireAll }: PermissionEnforcerProps): react_jsx_runtime.JSX.Element;
1021
-
1022
- interface RouteConfig {
1023
- /** Route path */
1024
- path: string;
1025
- /** React component to render */
1026
- component: React__default.ComponentType;
1027
- /** Permissions required for this route */
1028
- permissions: Permission[];
1029
- /** If true, this route is public and doesn't require permission checks */
1030
- public?: boolean;
1031
- /** Roles that can access this route */
1032
- roles?: string[];
1033
- /** Minimum access level required */
1034
- accessLevel?: AccessLevel;
1035
- /** Page ID for permission checking */
1036
- pageId?: string;
1037
- /** Enable strict mode for this route */
1038
- strictMode?: boolean;
1039
- /** Route metadata */
1040
- meta?: {
1041
- title?: string;
1042
- description?: string;
1043
- requiresAuth?: boolean;
1044
- hidden?: boolean;
1045
- };
1046
- }
1047
- interface RouteAccessRecord {
1048
- route: string;
1049
- permissions: Permission[];
1050
- userId: UUID;
1051
- scope: Scope;
1052
- allowed: boolean;
1053
- timestamp: string;
1054
- pageId?: string;
1055
- roles?: string[];
1056
- accessLevel?: AccessLevel;
1057
- }
1058
- interface RoleBasedRouterContextType {
1059
- /** Get all accessible routes for current user */
1060
- getAccessibleRoutes: () => RouteConfig[];
1061
- /** Check if user can access a specific route */
1062
- canAccessRoute: (path: string) => boolean;
1063
- /** Get route configuration for a path */
1064
- getRouteConfig: (path: string) => RouteConfig | null;
1065
- /** Get route access history */
1066
- getRouteAccessHistory: () => RouteAccessRecord[];
1067
- /** Clear route access history */
1068
- clearRouteAccessHistory: () => void;
1069
- /** Check if strict mode is enabled */
1070
- isStrictMode: boolean;
1071
- /** Check if audit logging is enabled */
1072
- isAuditLogEnabled: boolean;
1073
- }
1074
- interface RoleBasedRouterProps {
1075
- /** Route configuration */
1076
- routes: RouteConfig[];
1077
- /** Fallback route for unauthorized access */
1078
- fallbackRoute?: string;
1079
- /** Child components */
1080
- children: React__default.ReactNode;
1081
- /** Enable strict mode to prevent bypassing (default: true) */
1082
- strictMode?: boolean;
1083
- /** Enable audit logging (default: true) */
1084
- auditLog?: boolean;
1085
- /** Callback when route access is attempted */
1086
- onRouteAccess?: (route: string, allowed: boolean, record: RouteAccessRecord) => void;
1087
- /** Callback when strict mode violation occurs */
1088
- onStrictModeViolation?: (route: string, record: RouteAccessRecord) => void;
1089
- /** Maximum number of access records to keep in history */
1090
- maxHistorySize?: number;
1091
- /** Custom unauthorized component */
1092
- unauthorizedComponent?: React__default.ComponentType<{
1093
- route: string;
1094
- reason: string;
1095
- }>;
1096
- }
1097
- /**
1098
- * RoleBasedRouter - Centralized routing control with role-based protection
1099
- *
1100
- * This component ensures that all routes are properly protected and provides
1101
- * centralized routing control to prevent apps from bypassing route protection.
1102
- *
1103
- * @param props - Router props
1104
- * @returns React element with role-based routing
1105
- */
1106
- declare function RoleBasedRouter({ routes, fallbackRoute, children, strictMode, auditLog, onRouteAccess, onStrictModeViolation, maxHistorySize, unauthorizedComponent: UnauthorizedComponent }: RoleBasedRouterProps): react_jsx_runtime.JSX.Element;
1107
- /**
1108
- * Hook to use role-based router context
1109
- *
1110
- * @returns Role-based router context
1111
- * @throws Error if used outside of RoleBasedRouter
1112
- */
1113
- declare function useRoleBasedRouter(): RoleBasedRouterContextType;
1114
-
1115
- interface NavigationItem {
1116
- /** Unique identifier for the navigation item */
1117
- id: string;
1118
- /** Display label for the navigation item */
1119
- label: string;
1120
- /** Navigation path/URL */
1121
- path: string;
1122
- /** Permissions required for this navigation item */
1123
- permissions: Permission[];
1124
- /** Roles that can access this navigation item */
1125
- roles?: string[];
1126
- /** Minimum access level required */
1127
- accessLevel?: 'viewer' | 'participant' | 'planner' | 'admin' | 'super';
1128
- /** Page ID for permission checking */
1129
- pageId?: string;
1130
- /** Enable strict mode for this navigation item */
1131
- strictMode?: boolean;
1132
- /** Navigation item metadata */
1133
- meta?: {
1134
- icon?: string;
1135
- description?: string;
1136
- hidden?: boolean;
1137
- order?: number;
1138
- };
1139
- }
1140
- interface NavigationAccessRecord {
1141
- navigationItem: string;
1142
- permissions: Permission[];
1143
- userId: UUID;
1144
- scope: Scope;
1145
- allowed: boolean;
1146
- timestamp: string;
1147
- pageId?: string;
1148
- roles?: string[];
1149
- accessLevel?: string;
1150
- }
1151
- interface NavigationContextType {
1152
- /** Check if user has permission for a navigation item */
1153
- hasNavigationPermission: (item: NavigationItem) => boolean;
1154
- /** Get all navigation permissions for current user */
1155
- getNavigationPermissions: () => Record<string, string[]>;
1156
- /** Get filtered navigation items based on permissions */
1157
- getFilteredNavigationItems: (items: NavigationItem[]) => NavigationItem[];
1158
- /** Check if navigation permission checking is enabled */
1159
- isEnabled: boolean;
1160
- /** Check if strict mode is enabled */
1161
- isStrictMode: boolean;
1162
- /** Check if audit logging is enabled */
1163
- isAuditLogEnabled: boolean;
1164
- /** Get navigation access history */
1165
- getNavigationAccessHistory: () => NavigationAccessRecord[];
1166
- /** Clear navigation access history */
1167
- clearNavigationAccessHistory: () => void;
1168
- }
1169
- interface NavigationProviderProps {
1170
- /** Child components */
1171
- children: React__default.ReactNode;
1172
- /** Enable strict mode to prevent bypassing (default: true) */
1173
- strictMode?: boolean;
1174
- /** Enable audit logging (default: true) */
1175
- auditLog?: boolean;
1176
- /** Callback when navigation access is attempted */
1177
- onNavigationAccess?: (item: NavigationItem, allowed: boolean, record: NavigationAccessRecord) => void;
1178
- /** Callback when strict mode violation occurs */
1179
- onStrictModeViolation?: (item: NavigationItem, record: NavigationAccessRecord) => void;
1180
- /** Maximum number of access records to keep in history */
1181
- maxHistorySize?: number;
1182
- }
1183
- /**
1184
- * NavigationProvider - Manages navigation-level permissions across the app
1185
- *
1186
- * This provider ensures that all navigation items are properly protected and provides
1187
- * centralized navigation permission management with strict enforcement.
1188
- *
1189
- * @param props - Provider props
1190
- * @returns React element with navigation permission context
1191
- */
1192
- declare function NavigationProvider({ children, strictMode, auditLog, onNavigationAccess, onStrictModeViolation, maxHistorySize }: NavigationProviderProps): react_jsx_runtime.JSX.Element;
1193
- /**
1194
- * Hook to use navigation permission context
1195
- *
1196
- * @returns Navigation permission context
1197
- * @throws Error if used outside of NavigationProvider
1198
- */
1199
- declare function useNavigationPermissions(): NavigationContextType;
1200
-
1201
870
  interface NavigationGuardProps {
1202
871
  /** Navigation item being protected */
1203
872
  navigationItem: NavigationItem;
@@ -1230,44 +899,72 @@ interface NavigationGuardProps {
1230
899
  */
1231
900
  declare function NavigationGuard({ navigationItem, children, fallback, strictMode, auditLog, scope, onDenied, loading, requireAll }: NavigationGuardProps): react_jsx_runtime.JSX.Element;
1232
901
 
1233
- interface EnhancedNavigationMenuProps {
1234
- /** Navigation items to display */
1235
- items: NavigationItem[];
1236
- /** Enable strict mode to prevent bypassing (default: true) */
1237
- strictMode?: boolean;
1238
- /** Enable audit logging (default: true) */
1239
- auditLog?: boolean;
1240
- /** Callback when navigation access is attempted */
1241
- onNavigationAccess?: (item: NavigationItem, allowed: boolean) => void;
1242
- /** Callback when strict mode violation occurs */
1243
- onStrictModeViolation?: (item: NavigationItem) => void;
1244
- /** Custom className for the navigation menu */
902
+ /**
903
+ * @file Access Denied Component
904
+ * @package @jmruthers/pace-core
905
+ * @module RBAC/Components/AccessDenied
906
+ * @since 2.0.0
907
+ *
908
+ * Standard access denied component for consistent error messaging across all PACE apps.
909
+ * This component provides a uniform user experience when users lack permissions.
910
+ *
911
+ * Features:
912
+ * - Consistent styling and behavior across all apps
913
+ * - Configurable message and actions
914
+ * - Accessibility compliant
915
+ * - Responsive design
916
+ *
917
+ * @example
918
+ * ```tsx
919
+ * // Basic usage
920
+ * <AccessDenied />
921
+ *
922
+ * // With custom message
923
+ * <AccessDenied message="You don't have permission to view this page." />
924
+ *
925
+ * // With custom actions
926
+ * <AccessDenied
927
+ * onGoBack={() => navigate('/dashboard')}
928
+ * onSignOut={handleSignOut}
929
+ * />
930
+ * ```
931
+ *
932
+ * @accessibility
933
+ * - Proper ARIA labels and roles
934
+ * - High contrast support
935
+ * - Screen reader friendly
936
+ * - Keyboard navigation support
937
+ *
938
+ * @dependencies
939
+ * - React 19+
940
+ * - pace-core Button component
941
+ */
942
+ interface AccessDeniedProps {
943
+ /** Custom error message */
944
+ message?: string;
945
+ /** Resource or page name that was denied */
946
+ resource?: string;
947
+ /** Operation that was denied */
948
+ operation?: string;
949
+ /** Callback when "Go Back" is clicked */
950
+ onGoBack?: () => void;
951
+ /** Callback when "Sign Out" is clicked */
952
+ onSignOut?: () => void;
953
+ /** Custom class names */
1245
954
  className?: string;
1246
- /** Custom className for navigation items */
1247
- itemClassName?: string;
1248
- /** Custom className for active navigation items */
1249
- activeItemClassName?: string;
1250
- /** Custom className for disabled navigation items */
1251
- disabledItemClassName?: string;
1252
- /** Show/hide navigation items that user doesn't have permission for */
1253
- hideUnauthorizedItems?: boolean;
1254
- /** Custom render function for navigation items */
1255
- renderItem?: (item: NavigationItem, isAuthorized: boolean) => React__default.ReactNode;
1256
- /** Current active path for highlighting */
1257
- activePath?: string;
1258
- /** Navigation item click handler */
1259
- onItemClick?: (item: NavigationItem) => void;
955
+ /** Show sign out button */
956
+ showSignOut?: boolean;
1260
957
  }
1261
958
  /**
1262
- * EnhancedNavigationMenu - Secure navigation menu with RBAC integration
959
+ * Standard access denied component
1263
960
  *
1264
- * This component provides a navigation menu that automatically filters items based on
1265
- * user permissions and enforces strict security controls.
961
+ * This component is displayed when users lack the necessary permissions.
962
+ * It provides clear messaging and actionable next steps.
1266
963
  *
1267
- * @param props - Component props
1268
- * @returns React element with enhanced navigation menu
964
+ * @param props - Component configuration
965
+ * @returns JSX.Element - The rendered access denied page
1269
966
  */
1270
- declare function EnhancedNavigationMenu({ items, strictMode, auditLog, onNavigationAccess, onStrictModeViolation, className, itemClassName, activeItemClassName, disabledItemClassName, hideUnauthorizedItems, renderItem, activePath, onItemClick }: EnhancedNavigationMenuProps): react_jsx_runtime.JSX.Element;
967
+ declare function AccessDenied({ message, resource, operation, onGoBack, onSignOut, className, showSignOut }: AccessDeniedProps): react_jsx_runtime.JSX.Element;
1271
968
 
1272
969
  /**
1273
970
  * @file RBAC Hook
@@ -1301,6 +998,8 @@ interface UseResolvedScopeOptions {
1301
998
  selectedOrganisationId: string | null;
1302
999
  /** Selected event ID */
1303
1000
  selectedEventId: string | null;
1001
+ /** Selected event organisation ID (from selectedEvent.organisation_id) - allows immediate context without querying */
1002
+ selectedEventOrganisationId?: string | null;
1304
1003
  }
1305
1004
  interface UseResolvedScopeReturn {
1306
1005
  /** Resolved scope, or null if not yet resolved */
@@ -1334,7 +1033,7 @@ interface UseResolvedScopeReturn {
1334
1033
  * const permission = useCan(userId, resolvedScope, permission);
1335
1034
  * ```
1336
1035
  */
1337
- declare function useResolvedScope({ supabase, selectedOrganisationId, selectedEventId }: UseResolvedScopeOptions): UseResolvedScopeReturn;
1036
+ declare function useResolvedScope({ supabase, selectedOrganisationId, selectedEventId, selectedEventOrganisationId }: UseResolvedScopeOptions): UseResolvedScopeReturn;
1338
1037
 
1339
1038
  /**
1340
1039
  * @file useResourcePermissions Hook
@@ -1408,15 +1107,22 @@ interface ResourcePermissions {
1408
1107
  * and provides a simple API for permission checking.
1409
1108
  *
1410
1109
  * **Page Permission Support:**
1411
- * When an `appId` is available in the resolved scope, the resource name is passed
1412
- * as `pageId` to enable page-based permission checks. This allows the hook to work
1413
- * with both resource-based permissions (when appId is not available) and page-based
1414
- * permissions (when appId is available and the resource is a registered page).
1110
+ * When an `appId` is available in the resolved scope, the hook automatically:
1111
+ * 1. Waits for scope resolution to complete (including `appId` being set)
1112
+ * 2. Constructs permission strings with the `page.` prefix (e.g., `create:page.planning`)
1113
+ * 3. Passes the resource name as `pageId` to enable page-based permission checks
1114
+ *
1115
+ * This ensures permission strings match the format returned by `rbac_permissions_get`
1116
+ * (e.g., `create:page.planning`) rather than resource-based format (e.g., `create:planning`).
1117
+ *
1118
+ * **Scope Resolution Timing:**
1119
+ * The hook waits for scope resolution to complete before constructing permission strings.
1120
+ * This prevents timing issues where permission checks use the wrong format (e.g., `delete:planning`
1121
+ * instead of `delete:page.planning`) when `appId` is not yet available in the scope.
1415
1122
  *
1416
- * The RPC function `rbac_check_permission_simplified` will automatically resolve
1417
- * the page name to a page ID and check page permissions if the resource matches
1418
- * a registered page in `rbac_app_pages`. If the resource is not a registered page,
1419
- * it will fall back to resource-based permission checking.
1123
+ * The RPC function `rbac_check_permission_simplified` will resolve the page name to a page ID
1124
+ * and check page permissions if the resource matches a registered page in `rbac_app_pages`.
1125
+ * If the resource is not a registered page, it will fall back to resource-based permission checking.
1420
1126
  *
1421
1127
  * @param resource - The resource name (e.g., 'contacts', 'risks', 'planning')
1422
1128
  * Can be a resource name or a page name registered in rbac_app_pages
@@ -1489,38 +1195,6 @@ declare function useAccessLevel(userId: UUID, scope: Scope): {
1489
1195
  refetch: () => Promise<void>;
1490
1196
  };
1491
1197
 
1492
- /**
1493
- * Hook to get cached permissions with TTL management
1494
- *
1495
- * @param userId - User ID
1496
- * @param scope - Scope for permission checking
1497
- * @returns Cached permission state and methods
1498
- *
1499
- * @example
1500
- * ```tsx
1501
- * function MyComponent() {
1502
- * const { permissions, isLoading, error, invalidateCache } = useCachedPermissions(userId, scope);
1503
- *
1504
- * if (isLoading) return <div>Loading cached permissions...</div>;
1505
- * if (error) return <div>Error: {error.message}</div>;
1506
- *
1507
- * return (
1508
- * <div>
1509
- * {permissions['read:users'] && <UserList />}
1510
- * <button onClick={invalidateCache}>Refresh Permissions</button>
1511
- * </div>
1512
- * );
1513
- * }
1514
- * ```
1515
- */
1516
- declare function useCachedPermissions(userId: UUID, scope: Scope): {
1517
- permissions: PermissionMap;
1518
- isLoading: boolean;
1519
- error: Error | null;
1520
- invalidateCache: () => void;
1521
- refetch: () => Promise<void>;
1522
- };
1523
-
1524
1198
  /**
1525
1199
  * Hook to check if user can perform an action
1526
1200
  *
@@ -1558,70 +1232,6 @@ precomputedSuperAdmin?: boolean | null, appName?: string): {
1558
1232
  refetch: () => Promise<void>;
1559
1233
  };
1560
1234
 
1561
- /**
1562
- * Hook to check if user has all of the specified permissions
1563
- *
1564
- * @param userId - User ID
1565
- * @param scope - Scope for permission checking
1566
- * @param permissions - Array of permissions to check
1567
- * @param useCache - Whether to use cached results
1568
- * @returns Whether user has all of the permissions
1569
- *
1570
- * @example
1571
- * ```tsx
1572
- * function MyComponent() {
1573
- * const { hasAll, isLoading, error } = useHasAllPermissions(
1574
- * userId,
1575
- * scope,
1576
- * ['read:users', 'create:users', 'update:users']
1577
- * );
1578
- *
1579
- * if (isLoading) return <div>Checking permissions...</div>;
1580
- * if (error) return <div>Error: {error.message}</div>;
1581
- *
1582
- * return hasAll ? <FullUserManagementPanel /> : <div>Insufficient permissions</div>;
1583
- * }
1584
- * ```
1585
- */
1586
- declare function useHasAllPermissions(userId: UUID, scope: Scope, permissions: Permission[], useCache?: boolean): {
1587
- hasAll: boolean;
1588
- isLoading: boolean;
1589
- error: Error | null;
1590
- refetch: () => Promise<void>;
1591
- };
1592
-
1593
- /**
1594
- * Hook to check if user has any of the specified permissions
1595
- *
1596
- * @param userId - User ID
1597
- * @param scope - Scope for permission checking
1598
- * @param permissions - Array of permissions to check
1599
- * @param useCache - Whether to use cached results
1600
- * @returns Whether user has any of the permissions
1601
- *
1602
- * @example
1603
- * ```tsx
1604
- * function MyComponent() {
1605
- * const { hasAny, isLoading, error } = useHasAnyPermission(
1606
- * userId,
1607
- * scope,
1608
- * ['read:users', 'create:users']
1609
- * );
1610
- *
1611
- * if (isLoading) return <div>Checking permissions...</div>;
1612
- * if (error) return <div>Error: {error.message}</div>;
1613
- *
1614
- * return hasAny ? <UserManagementPanel /> : <div>No user permissions</div>;
1615
- * }
1616
- * ```
1617
- */
1618
- declare function useHasAnyPermission(userId: UUID, scope: Scope, permissions: Permission[], useCache?: boolean): {
1619
- hasAny: boolean;
1620
- isLoading: boolean;
1621
- error: Error | null;
1622
- refetch: () => Promise<void>;
1623
- };
1624
-
1625
1235
  /**
1626
1236
  * Hook to check multiple permissions at once
1627
1237
  *
@@ -1972,95 +1582,16 @@ declare function useSecureSupabase(baseClient?: SupabaseClient<Database> | null)
1972
1582
  * @module RBAC/Adapters
1973
1583
  * @since 1.0.0
1974
1584
  *
1975
- * This module provides adapters for different frameworks and server runtimes.
1976
- */
1977
-
1978
- /**
1979
- * Permission Guard Component
1585
+ * This module provides server-side adapters for different frameworks and server runtimes.
1980
1586
  *
1981
- * A React component that conditionally renders children based on permissions.
1982
- * Can auto-infer userId from context if not provided.
1587
+ * NOTE: React components (PermissionGuard, AccessLevelGuard) have been removed.
1588
+ * Use PagePermissionGuard from @jmruthers/pace-core/rbac for all client-side permission enforcement.
1589
+ * Use useAccessLevel hook + conditional rendering for access level checks.
1983
1590
  *
1984
- * @example
1985
- * ```tsx
1986
- * // With explicit userId and scope
1987
- * <PermissionGuard
1988
- * userId="user-123"
1989
- * scope={{ organisationId: 'org-456' }}
1990
- * permission="update:events"
1991
- * pageId="page-789"
1992
- * fallback={<AccessDenied />}
1993
- * >
1994
- * <AdminPanel />
1995
- * </PermissionGuard>
1996
- *
1997
- * // With context inference (requires auth context)
1998
- * <PermissionGuard
1999
- * permission="update:events"
2000
- * scope={{ organisationId: 'org-456' }}
2001
- * fallback={<AccessDenied />}
2002
- * >
2003
- * <AdminPanel />
2004
- * </PermissionGuard>
2005
- * ```
1591
+ * Server adapters are provided for server-side route protection (Next.js, Express, etc.).
1592
+ * These are optional utilities for server-side applications.
2006
1593
  */
2007
- declare function PermissionGuard({ userId, scope, permission, pageId, children, fallback, onDenied, loading, strictMode, auditLog, enforceAudit, }: {
2008
- userId?: UUID;
2009
- scope: {
2010
- organisationId: UUID;
2011
- eventId?: string;
2012
- appId?: UUID;
2013
- };
2014
- permission: Permission;
2015
- pageId?: UUID;
2016
- children: ReactNode;
2017
- fallback?: ReactNode;
2018
- onDenied?: () => void;
2019
- loading?: ReactNode;
2020
- strictMode?: boolean;
2021
- auditLog?: boolean;
2022
- enforceAudit?: boolean;
2023
- }): React__default.ReactNode;
2024
- /**
2025
- * Access Level Guard Component
2026
- *
2027
- * A React component that conditionally renders children based on access level.
2028
- * Can auto-infer userId from context if not provided.
2029
- *
2030
- * @example
2031
- * ```tsx
2032
- * // With explicit userId and scope
2033
- * <AccessLevelGuard
2034
- * userId="user-123"
2035
- * scope={{ organisationId: 'org-456' }}
2036
- * minLevel="admin"
2037
- * fallback={<AccessDenied />}
2038
- * >
2039
- * <AdminPanel />
2040
- * </AccessLevelGuard>
2041
- *
2042
- * // With context inference (requires auth context)
2043
- * <AccessLevelGuard
2044
- * minLevel="admin"
2045
- * scope={{ organisationId: 'org-456' }}
2046
- * fallback={<AccessDenied />}
2047
- * >
2048
- * <AdminPanel />
2049
- * </AccessLevelGuard>
2050
- * ```
2051
- */
2052
- declare function AccessLevelGuard({ userId, scope, minLevel, children, fallback, loading, }: {
2053
- userId?: UUID;
2054
- scope: {
2055
- organisationId: UUID;
2056
- eventId?: string;
2057
- appId?: UUID;
2058
- };
2059
- minLevel: 'viewer' | 'participant' | 'planner' | 'admin' | 'super';
2060
- children: ReactNode;
2061
- fallback?: ReactNode;
2062
- loading?: ReactNode;
2063
- }): React__default.ReactNode;
1594
+
2064
1595
  /**
2065
1596
  * Permission Guard for Server Handlers
2066
1597
  *
@@ -2210,34 +1741,6 @@ declare function createRBACExpressMiddleware(config: {
2210
1741
  json: (data: object) => void;
2211
1742
  };
2212
1743
  }, next: () => void) => Promise<void>;
2213
- /**
2214
- * Check if a user has a permission (synchronous cache check only)
2215
- *
2216
- * @param userId - User ID
2217
- * @param scope - Permission scope
2218
- * @param permission - Permission to check
2219
- * @param pageId - Optional page ID
2220
- * @returns True if permission is cached and granted
2221
- */
2222
- declare function hasPermissionCached(userId: UUID, scope: {
2223
- organisationId: UUID;
2224
- eventId?: string;
2225
- appId?: UUID;
2226
- }, _permission: Permission, _pageId?: UUID): boolean;
2227
- /**
2228
- * Check if a user has any of the specified permissions (synchronous cache check only)
2229
- *
2230
- * @param userId - User ID
2231
- * @param scope - Permission scope
2232
- * @param permissions - Array of permissions to check
2233
- * @param pageId - Optional page ID
2234
- * @returns True if any permission is cached and granted
2235
- */
2236
- declare function hasAnyPermissionCached(userId: UUID, scope: {
2237
- organisationId: UUID;
2238
- eventId?: string;
2239
- appId?: UUID;
2240
- }, permissions: Permission[], pageId?: UUID): boolean;
2241
1744
 
2242
1745
  /**
2243
1746
  * RBAC Main API Functions
@@ -2344,13 +1847,6 @@ precomputedSuperAdmin?: boolean | null): Promise<boolean>;
2344
1847
  * @returns Promise resolving to permission result
2345
1848
  */
2346
1849
  declare function isPermittedCached(input: PermissionCheck, appName?: string): Promise<boolean>;
2347
- /**
2348
- * Check if a user has a specific permission (alias for isPermitted)
2349
- *
2350
- * @param input - Permission check parameters
2351
- * @returns Promise<boolean> - True if user has permission
2352
- */
2353
- declare function hasPermission(input: PermissionCheck): Promise<boolean>;
2354
1850
  /**
2355
1851
  * Check if user has any of the specified permissions
2356
1852
  *
@@ -2575,6 +2071,39 @@ declare function getSetupIssues(): SetupIssue[];
2575
2071
  */
2576
2072
  declare function validateRBACSetup(): ComplianceResult;
2577
2073
 
2074
+ /**
2075
+ * Pattern Detector for RBAC Compliance
2076
+ * @package @jmruthers/pace-core
2077
+ * @module RBAC/Compliance/PatternDetector
2078
+ * @since 1.0.0
2079
+ *
2080
+ * This module provides static and runtime pattern detection for RBAC violations.
2081
+ * It detects direct RPC calls, direct table queries, and other non-standard patterns.
2082
+ */
2083
+ interface PatternViolation {
2084
+ type: 'direct-rpc-call' | 'direct-table-query' | 'bypass-pattern' | 'custom-component' | 'hardcoded-role-check' | 'custom-permission-utility' | 'ui-only-access-control' | 'permission-bypass-comment' | 'resource-permission-string-literal' | 'permission-wrapper-function';
2085
+ file?: string;
2086
+ line?: number;
2087
+ message: string;
2088
+ recommendation: string;
2089
+ }
2090
+ interface PatternDetectionResult {
2091
+ violations: PatternViolation[];
2092
+ isCompliant: boolean;
2093
+ summary: {
2094
+ directRpcCalls: number;
2095
+ directTableQueries: number;
2096
+ bypassPatterns: number;
2097
+ customComponents: number;
2098
+ hardcodedRoleChecks: number;
2099
+ customPermissionUtilities: number;
2100
+ uiOnlyAccessControl: number;
2101
+ permissionBypassComments: number;
2102
+ resourcePermissionStringLiterals: number;
2103
+ permissionWrapperFunctions: number;
2104
+ };
2105
+ }
2106
+
2578
2107
  /**
2579
2108
  * Runtime Compliance Checking
2580
2109
  * @package @jmruthers/pace-core
@@ -2594,6 +2123,7 @@ interface RuntimeComplianceResult {
2594
2123
  available: boolean;
2595
2124
  message?: string;
2596
2125
  };
2126
+ patternDetection?: PatternDetectionResult;
2597
2127
  }
2598
2128
  /**
2599
2129
  * Check runtime compliance
@@ -2680,4 +2210,4 @@ declare function getDirectSupabaseAuthFixes(): QuickFix;
2680
2210
  */
2681
2211
  declare function getQuickFixes(issueType: string, details?: Record<string, any>): QuickFix[];
2682
2212
 
2683
- export { ALL_PERMISSIONS, AccessLevel, AccessLevelGuard, type AllPermissions, CACHE_PATTERNS, type ComplianceResult, type DataAccessRecord, type DatabaseComplianceResult, type DatabaseIssue, EVENT_APP_PERMISSIONS, EnhancedNavigationMenu, type EnhancedNavigationMenuProps, type EventAppRoleData, GLOBAL_PERMISSIONS, type GrantEventAppRoleParams, type LogLevel, type NavigationAccessRecord, type NavigationContextType, NavigationGuard, type NavigationGuardProps, type NavigationItem, NavigationProvider, type NavigationProviderProps, ORGANISATION_PERMISSIONS, PAGE_PERMISSIONS, type PageAccessRecord, type PagePermissionContextType, PagePermissionGuard, type PagePermissionGuardProps, PagePermissionProvider, type PagePermissionProviderProps, Permission, PermissionCheck, PermissionEnforcer, type PermissionEnforcerProps, PermissionGuard, PermissionMap, type QuickFix, RBACAuditManager, RBACCache, type RBACConfig, RBACEngine, type RBACLogger, type RBACPerformanceMetrics, type ResourcePermissions, type RevokeEventAppRoleParams, RoleBasedRouter, type RoleBasedRouterContextType, type RoleBasedRouterProps, type RoleManagementResult, type RouteAccessRecord, type RouteConfig, type RuntimeComplianceResult, SECURE_CLIENT_SYMBOL, Scope, type SecureDataContextType, SecureDataProvider, type SecureDataProviderProps, SecureSupabaseClient, type SetupIssue, UUID, type UseResolvedScopeOptions, type UseResolvedScopeReturn, type UseResourcePermissionsOptions, checkRuntimeCompliance, clearInFlightRequests, createAuditManager, createRBACConfig, createRBACEngine, createRBACExpressMiddleware, createRBACMiddleware, createSecureClient, disablePerformanceMonitoring, emitAuditEvent, enablePerformanceMonitoring, fromSupabaseClient, getAccessLevel, getCustomAuthCodeFixes, getDirectSupabaseAuthFixes, getDuplicateConfigFixes, getGlobalAuditManager, getInFlightRequestCount, getPerformanceMetrics, getPerformanceSummary, getPermissionMap, getQuickFixes, getRBACConfig, getRBACLogger, getRoleContext, getSetupIssues, getUnprotectedPageFixes, hasAllPermissions, hasAnyPermission, hasAnyPermissionCached, hasPermission, hasPermissionCached, isDebugMode, isDevelopmentMode, isPerformanceMonitoringEnabled, isPermitted, isPermittedCached, isRBACInitialized, isSecureClient, isValidPermission, rbacCache, recordAuditEvent, recordPermissionCheck, resetPerformanceMetrics, resolveAppContext, setGlobalAuditManager, setupRBAC, useAccessLevel, useCachedPermissions, useCan, useHasAllPermissions, useHasAnyPermission, useMultiplePermissions, useNavigationPermissions, usePagePermissions, usePermissions, useRBAC, useResolvedScope, useResourcePermissions, useRoleBasedRouter, useRoleManagement, useSecureData, useSecureSupabase, validateAndWarn, validateDatabaseConfiguration, validateRBACSetup, warnIfInsecureClient, withAccessLevelGuard, withPermissionGuard, withRoleGuard };
2213
+ export { ALL_PERMISSIONS, AccessDenied, type AccessDeniedProps, AccessLevel, type AllPermissions, CACHE_PATTERNS, type ComplianceResult, type DatabaseComplianceResult, type DatabaseIssue, EVENT_APP_PERMISSIONS, type EventAppRoleData, GLOBAL_PERMISSIONS, type GrantEventAppRoleParams, type LogLevel, NavigationGuard, type NavigationGuardProps, ORGANISATION_PERMISSIONS, PAGE_PERMISSIONS, PagePermissionGuard, type PagePermissionGuardProps, Permission, PermissionCheck, PermissionMap, type QuickFix, RBACAuditManager, RBACCache, type RBACConfig, RBACEngine, type RBACLogger, type RBACPerformanceMetrics, type ResourcePermissions, type RevokeEventAppRoleParams, type RoleManagementResult, type RuntimeComplianceResult, SECURE_CLIENT_SYMBOL, Scope, SecureSupabaseClient, type SetupIssue, UUID, type UseResolvedScopeOptions, type UseResolvedScopeReturn, type UseResourcePermissionsOptions, checkRuntimeCompliance, clearInFlightRequests, createAuditManager, createRBACConfig, createRBACEngine, createRBACExpressMiddleware, createRBACMiddleware, createSecureClient, disablePerformanceMonitoring, emitAuditEvent, enablePerformanceMonitoring, fromSupabaseClient, getAccessLevel, getCustomAuthCodeFixes, getDirectSupabaseAuthFixes, getDuplicateConfigFixes, getGlobalAuditManager, getInFlightRequestCount, getPerformanceMetrics, getPerformanceSummary, getPermissionMap, getQuickFixes, getRBACConfig, getRBACLogger, getRoleContext, getSetupIssues, getUnprotectedPageFixes, hasAllPermissions, hasAnyPermission, isDebugMode, isDevelopmentMode, isPerformanceMonitoringEnabled, isPermitted, isPermittedCached, isRBACInitialized, isSecureClient, isValidPermission, rbacCache, recordAuditEvent, recordPermissionCheck, resetPerformanceMetrics, resolveAppContext, setGlobalAuditManager, setupRBAC, useAccessLevel, useCan, useMultiplePermissions, usePermissions, useRBAC, useResolvedScope, useResourcePermissions, useRoleManagement, useSecureSupabase, validateAndWarn, validateDatabaseConfiguration, validateRBACSetup, warnIfInsecureClient, withAccessLevelGuard, withPermissionGuard, withRoleGuard };