@jmruthers/pace-core 0.5.108 → 0.5.110

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 (195) hide show
  1. package/CHANGELOG.md +93 -173
  2. package/dist/{AuthService-1D2ifNfa.d.ts → AuthService-DrHrvXNZ.d.ts} +8 -1
  3. package/dist/{DataTable-WFCHVWTY.js → DataTable-D3BK2FCN.js} +7 -7
  4. package/dist/{UnifiedAuthProvider-XU4BHFXZ.js → UnifiedAuthProvider-A7I23UCN.js} +3 -3
  5. package/dist/{api-KG4A2X7P.js → api-PIE4JRFS.js} +2 -2
  6. package/dist/{chunk-DMNMZKWS.js → chunk-2W4WKJVF.js} +4 -4
  7. package/dist/{chunk-B3QX32P5.js → chunk-3J5N2T2N.js} +85 -28
  8. package/dist/chunk-3J5N2T2N.js.map +1 -0
  9. package/dist/{chunk-MOMYOQMC.js → chunk-7GBEBJLR.js} +29 -37
  10. package/dist/chunk-7GBEBJLR.js.map +1 -0
  11. package/dist/{chunk-X4FRXJV6.js → chunk-AUXS7XSO.js} +57 -6
  12. package/dist/{chunk-X4FRXJV6.js.map → chunk-AUXS7XSO.js.map} +1 -1
  13. package/dist/{chunk-VJ7MPS2K.js → chunk-AWK2FAUN.js} +6 -6
  14. package/dist/{chunk-LT6RKRA7.js → chunk-D6MEKC27.js} +2 -2
  15. package/dist/{chunk-KBG34SVL.js → chunk-EYSXQ756.js} +2 -2
  16. package/dist/{chunk-ZXY5NTJB.js → chunk-EZ64QG2I.js} +2 -2
  17. package/dist/chunk-GZRXOUBE.js +176 -0
  18. package/dist/chunk-GZRXOUBE.js.map +1 -0
  19. package/dist/{chunk-QDDUU625.js → chunk-HADXAZT3.js} +4 -4
  20. package/dist/{chunk-IMZGJ2X7.js → chunk-HGZSO43Y.js} +4 -4
  21. package/dist/{chunk-S63MFSY6.js → chunk-XRSP3H52.js} +15 -8
  22. package/dist/chunk-XRSP3H52.js.map +1 -0
  23. package/dist/{chunk-GVRSXXAA.js → chunk-YFMENCR4.js} +3 -3
  24. package/dist/components.js +9 -9
  25. package/dist/{database-BXAfr2Y_.d.ts → database-C6jy7EOu.d.ts} +21 -9
  26. package/dist/{formatting-BiEv5oEk.d.ts → formatting-B1jSqgl-.d.ts} +16 -1
  27. package/dist/hooks.d.ts +2 -2
  28. package/dist/hooks.js +7 -7
  29. package/dist/index.d.ts +6 -6
  30. package/dist/index.js +16 -14
  31. package/dist/index.js.map +1 -1
  32. package/dist/providers.d.ts +4 -3
  33. package/dist/providers.js +2 -2
  34. package/dist/rbac/index.d.ts +35 -23
  35. package/dist/rbac/index.js +8 -8
  36. package/dist/types.d.ts +2 -2
  37. package/dist/{usePublicRouteParams-CnM-IK2I.d.ts → usePublicRouteParams-BdF8bZgs.d.ts} +1 -1
  38. package/dist/utils.d.ts +2 -15
  39. package/dist/utils.js +4 -145
  40. package/dist/utils.js.map +1 -1
  41. package/dist/validation.d.ts +1 -1
  42. package/docs/api/classes/ColumnFactory.md +1 -1
  43. package/docs/api/classes/ErrorBoundary.md +1 -1
  44. package/docs/api/classes/InvalidScopeError.md +1 -1
  45. package/docs/api/classes/MissingUserContextError.md +1 -1
  46. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  47. package/docs/api/classes/PermissionDeniedError.md +1 -1
  48. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  49. package/docs/api/classes/RBACAuditManager.md +1 -1
  50. package/docs/api/classes/RBACCache.md +1 -1
  51. package/docs/api/classes/RBACEngine.md +9 -8
  52. package/docs/api/classes/RBACError.md +1 -1
  53. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  54. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  55. package/docs/api/classes/StorageUtils.md +1 -1
  56. package/docs/api/enums/FileCategory.md +1 -1
  57. package/docs/api/interfaces/AggregateConfig.md +1 -1
  58. package/docs/api/interfaces/ButtonProps.md +1 -1
  59. package/docs/api/interfaces/CardProps.md +1 -1
  60. package/docs/api/interfaces/ColorPalette.md +1 -1
  61. package/docs/api/interfaces/ColorShade.md +1 -1
  62. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  63. package/docs/api/interfaces/DataRecord.md +1 -1
  64. package/docs/api/interfaces/DataTableAction.md +1 -1
  65. package/docs/api/interfaces/DataTableColumn.md +3 -3
  66. package/docs/api/interfaces/DataTableProps.md +1 -1
  67. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  68. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  69. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  70. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  71. package/docs/api/interfaces/FileMetadata.md +1 -1
  72. package/docs/api/interfaces/FileReference.md +1 -1
  73. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  74. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  75. package/docs/api/interfaces/FileUploadProps.md +1 -1
  76. package/docs/api/interfaces/FooterProps.md +1 -1
  77. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  78. package/docs/api/interfaces/InputProps.md +1 -1
  79. package/docs/api/interfaces/LabelProps.md +1 -1
  80. package/docs/api/interfaces/LoginFormProps.md +1 -1
  81. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  82. package/docs/api/interfaces/NavigationContextType.md +1 -1
  83. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  84. package/docs/api/interfaces/NavigationItem.md +1 -1
  85. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  86. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  87. package/docs/api/interfaces/Organisation.md +1 -1
  88. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  89. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  90. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  91. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  92. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  93. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  94. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  95. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  96. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  97. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  98. package/docs/api/interfaces/PaletteData.md +1 -1
  99. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  100. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  101. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  102. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  103. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  104. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  105. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  106. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  107. package/docs/api/interfaces/RBACConfig.md +19 -8
  108. package/docs/api/interfaces/RBACLogger.md +5 -5
  109. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  110. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  111. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  112. package/docs/api/interfaces/RouteConfig.md +1 -1
  113. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  114. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  115. package/docs/api/interfaces/StorageConfig.md +1 -1
  116. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  117. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  118. package/docs/api/interfaces/StorageListOptions.md +1 -1
  119. package/docs/api/interfaces/StorageListResult.md +1 -1
  120. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  121. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  122. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  123. package/docs/api/interfaces/StyleImport.md +1 -1
  124. package/docs/api/interfaces/SwitchProps.md +1 -1
  125. package/docs/api/interfaces/ToastActionElement.md +1 -1
  126. package/docs/api/interfaces/ToastProps.md +1 -1
  127. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  128. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  129. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  130. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  131. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  132. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  133. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +1 -1
  134. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  135. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  136. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  137. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  138. package/docs/api/interfaces/UserEventAccess.md +1 -1
  139. package/docs/api/interfaces/UserMenuProps.md +1 -1
  140. package/docs/api/interfaces/UserProfile.md +1 -1
  141. package/docs/api/modules.md +55 -20
  142. package/docs/api-reference/hooks.md +53 -0
  143. package/docs/api-reference/providers.md +60 -0
  144. package/docs/core-concepts/authentication.md +2 -0
  145. package/docs/documentation-index.md +0 -2
  146. package/docs/implementation-guides/authentication.md +1 -0
  147. package/docs/rbac/README.md +114 -38
  148. package/docs/rbac/api-reference.md +63 -16
  149. package/docs/rbac/getting-started.md +16 -16
  150. package/docs/rbac/quick-start.md +110 -35
  151. package/docs/rbac/troubleshooting.md +125 -2
  152. package/docs/security/README.md +59 -0
  153. package/package.json +1 -1
  154. package/src/components/NavigationMenu/NavigationMenu.test.tsx +38 -4
  155. package/src/components/NavigationMenu/NavigationMenu.tsx +71 -6
  156. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +2 -2
  157. package/src/components/PaceAppLayout/PaceAppLayout.tsx +48 -16
  158. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +2 -1
  159. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +9 -9
  160. package/src/index.ts +3 -0
  161. package/src/providers/services/AuthServiceProvider.tsx +4 -3
  162. package/src/providers/services/UnifiedAuthProvider.tsx +1 -1
  163. package/src/rbac/api.test.ts +2 -2
  164. package/src/rbac/api.ts +2 -1
  165. package/src/rbac/components/PagePermissionGuard.tsx +21 -38
  166. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +1 -1
  167. package/src/rbac/config.ts +2 -0
  168. package/src/rbac/engine.ts +17 -5
  169. package/src/rbac/security.ts +1 -1
  170. package/src/services/AuthService.ts +79 -1
  171. package/src/services/__tests__/AuthService.test.ts +184 -0
  172. package/src/types/database.ts +21 -9
  173. package/src/types/rbac-functions.ts +2 -1
  174. package/src/utils/__tests__/sessionTracking.unit.test.ts +6 -171
  175. package/src/utils/sessionTracking.ts +7 -81
  176. package/dist/chunk-B3QX32P5.js.map +0 -1
  177. package/dist/chunk-MOMYOQMC.js.map +0 -1
  178. package/dist/chunk-NFPV7MRN.js +0 -94
  179. package/dist/chunk-NFPV7MRN.js.map +0 -1
  180. package/dist/chunk-S63MFSY6.js.map +0 -1
  181. package/docs/rbac/breaking-changes-v3.md +0 -222
  182. package/docs/rbac/migration-guide.md +0 -260
  183. package/src/providers/AuthProvider.simplified.tsx +0 -974
  184. package/dist/{DataTable-WFCHVWTY.js.map → DataTable-D3BK2FCN.js.map} +0 -0
  185. package/dist/{UnifiedAuthProvider-XU4BHFXZ.js.map → UnifiedAuthProvider-A7I23UCN.js.map} +0 -0
  186. package/dist/{api-KG4A2X7P.js.map → api-PIE4JRFS.js.map} +0 -0
  187. package/dist/{chunk-DMNMZKWS.js.map → chunk-2W4WKJVF.js.map} +0 -0
  188. package/dist/{chunk-VJ7MPS2K.js.map → chunk-AWK2FAUN.js.map} +0 -0
  189. package/dist/{chunk-LT6RKRA7.js.map → chunk-D6MEKC27.js.map} +0 -0
  190. package/dist/{chunk-KBG34SVL.js.map → chunk-EYSXQ756.js.map} +0 -0
  191. package/dist/{chunk-ZXY5NTJB.js.map → chunk-EZ64QG2I.js.map} +0 -0
  192. package/dist/{chunk-QDDUU625.js.map → chunk-HADXAZT3.js.map} +0 -0
  193. package/dist/{chunk-IMZGJ2X7.js.map → chunk-HGZSO43Y.js.map} +0 -0
  194. package/dist/{chunk-GVRSXXAA.js.map → chunk-YFMENCR4.js.map} +0 -0
  195. package/dist/{validation-D8VcbTzC.d.ts → validation-DnhrNMju.d.ts} +2 -2
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.108](../README.md) / [Exports](../modules.md) / UsePublicEventReturn
1
+ [@jmruthers/pace-core - v0.5.110](../README.md) / [Exports](../modules.md) / UsePublicEventReturn
2
2
 
3
3
  # Interface: UsePublicEventReturn
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.108](../README.md) / [Exports](../modules.md) / UsePublicFileDisplayOptions
1
+ [@jmruthers/pace-core - v0.5.110](../README.md) / [Exports](../modules.md) / UsePublicFileDisplayOptions
2
2
 
3
3
  # Interface: UsePublicFileDisplayOptions
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.108](../README.md) / [Exports](../modules.md) / UsePublicFileDisplayReturn
1
+ [@jmruthers/pace-core - v0.5.110](../README.md) / [Exports](../modules.md) / UsePublicFileDisplayReturn
2
2
 
3
3
  # Interface: UsePublicFileDisplayReturn
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.108](../README.md) / [Exports](../modules.md) / UsePublicRouteParamsReturn
1
+ [@jmruthers/pace-core - v0.5.110](../README.md) / [Exports](../modules.md) / UsePublicRouteParamsReturn
2
2
 
3
3
  # Interface: UsePublicRouteParamsReturn
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.108](../README.md) / [Exports](../modules.md) / UseResolvedScopeOptions
1
+ [@jmruthers/pace-core - v0.5.110](../README.md) / [Exports](../modules.md) / UseResolvedScopeOptions
2
2
 
3
3
  # Interface: UseResolvedScopeOptions
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.108](../README.md) / [Exports](../modules.md) / UseResolvedScopeReturn
1
+ [@jmruthers/pace-core - v0.5.110](../README.md) / [Exports](../modules.md) / UseResolvedScopeReturn
2
2
 
3
3
  # Interface: UseResolvedScopeReturn
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.108](../README.md) / [Exports](../modules.md) / UserEventAccess
1
+ [@jmruthers/pace-core - v0.5.110](../README.md) / [Exports](../modules.md) / UserEventAccess
2
2
 
3
3
  # Interface: UserEventAccess
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.108](../README.md) / [Exports](../modules.md) / UserMenuProps
1
+ [@jmruthers/pace-core - v0.5.110](../README.md) / [Exports](../modules.md) / UserMenuProps
2
2
 
3
3
  # Interface: UserMenuProps
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.108](../README.md) / [Exports](../modules.md) / UserProfile
1
+ [@jmruthers/pace-core - v0.5.110](../README.md) / [Exports](../modules.md) / UserProfile
2
2
 
3
3
  # Interface: UserProfile
4
4
 
@@ -1,6 +1,6 @@
1
- [@jmruthers/pace-core - v0.5.108](README.md) / Exports
1
+ [@jmruthers/pace-core - v0.5.110](README.md) / Exports
2
2
 
3
- # @jmruthers/pace-core - v0.5.108
3
+ # @jmruthers/pace-core - v0.5.110
4
4
 
5
5
  **`File`**
6
6
 
@@ -371,6 +371,7 @@ import { Dialog, NavigationMenu } from '@jmruthers/pace-core/components';
371
371
  - [formatCompactNumber](modules.md#formatcompactnumber)
372
372
  - [formatFileSize](modules.md#formatfilesize)
373
373
  - [createSecureDataAccess](modules.md#createsecuredataaccess)
374
+ - [useSessionTracking](modules.md#usesessiontracking)
374
375
  - [getFileSizeLimit](modules.md#getfilesizelimit)
375
376
  - [getBucketName](modules.md#getbucketname)
376
377
  - [validateFileSize](modules.md#validatefilesize)
@@ -498,7 +499,7 @@ ___
498
499
 
499
500
  #### Defined in
500
501
 
501
- [packages/core/src/rbac/config.ts:13](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L13)
502
+ [packages/core/src/rbac/config.ts:14](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L14)
502
503
 
503
504
  ___
504
505
 
@@ -5026,7 +5027,7 @@ const accessLevel = await getAccessLevel({
5026
5027
 
5027
5028
  #### Defined in
5028
5029
 
5029
- [packages/core/src/rbac/api.ts:88](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L88)
5030
+ [packages/core/src/rbac/api.ts:89](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L89)
5030
5031
 
5031
5032
  ___
5032
5033
 
@@ -5065,7 +5066,7 @@ const permissions = await getPermissionMap({
5065
5066
 
5066
5067
  #### Defined in
5067
5068
 
5068
- [packages/core/src/rbac/api.ts:114](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L114)
5069
+ [packages/core/src/rbac/api.ts:115](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L115)
5069
5070
 
5070
5071
  ___
5071
5072
 
@@ -5087,7 +5088,7 @@ ___
5087
5088
 
5088
5089
  #### Defined in
5089
5090
 
5090
- [packages/core/src/rbac/api.ts:122](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L122)
5091
+ [packages/core/src/rbac/api.ts:123](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L123)
5091
5092
 
5092
5093
  ___
5093
5094
 
@@ -5109,7 +5110,7 @@ ___
5109
5110
 
5110
5111
  #### Defined in
5111
5112
 
5112
- [packages/core/src/rbac/api.ts:130](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L130)
5113
+ [packages/core/src/rbac/api.ts:131](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L131)
5113
5114
 
5114
5115
  ___
5115
5116
 
@@ -5144,7 +5145,7 @@ const canManage = await isPermitted({
5144
5145
 
5145
5146
  #### Defined in
5146
5147
 
5147
- [packages/core/src/rbac/api.ts:154](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L154)
5148
+ [packages/core/src/rbac/api.ts:155](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L155)
5148
5149
 
5149
5150
  ___
5150
5151
 
@@ -5168,7 +5169,7 @@ Promise resolving to permission result
5168
5169
 
5169
5170
  #### Defined in
5170
5171
 
5171
- [packages/core/src/rbac/api.ts:175](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L175)
5172
+ [packages/core/src/rbac/api.ts:176](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L176)
5172
5173
 
5173
5174
  ___
5174
5175
 
@@ -5192,7 +5193,7 @@ Promise<boolean> - True if user has permission
5192
5193
 
5193
5194
  #### Defined in
5194
5195
 
5195
- [packages/core/src/rbac/api.ts:208](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L208)
5196
+ [packages/core/src/rbac/api.ts:209](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L209)
5196
5197
 
5197
5198
  ___
5198
5199
 
@@ -5220,7 +5221,7 @@ Promise resolving to true if user has any permission
5220
5221
 
5221
5222
  #### Defined in
5222
5223
 
5223
- [packages/core/src/rbac/api.ts:218](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L218)
5224
+ [packages/core/src/rbac/api.ts:219](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L219)
5224
5225
 
5225
5226
  ___
5226
5227
 
@@ -5248,7 +5249,7 @@ Promise resolving to true if user has all permissions
5248
5249
 
5249
5250
  #### Defined in
5250
5251
 
5251
- [packages/core/src/rbac/api.ts:246](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L246)
5252
+ [packages/core/src/rbac/api.ts:247](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/api.ts#L247)
5252
5253
 
5253
5254
  ___
5254
5255
 
@@ -5466,7 +5467,7 @@ React element with permission enforcement
5466
5467
 
5467
5468
  #### Defined in
5468
5469
 
5469
- [packages/core/src/rbac/components/PagePermissionGuard.tsx:550](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/components/PagePermissionGuard.tsx#L550)
5470
+ [packages/core/src/rbac/components/PagePermissionGuard.tsx:533](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/components/PagePermissionGuard.tsx#L533)
5470
5471
 
5471
5472
  ___
5472
5473
 
@@ -5661,7 +5662,7 @@ ___
5661
5662
 
5662
5663
  #### Defined in
5663
5664
 
5664
- [packages/core/src/rbac/config.ts:110](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L110)
5665
+ [packages/core/src/rbac/config.ts:112](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L112)
5665
5666
 
5666
5667
  ___
5667
5668
 
@@ -5675,7 +5676,7 @@ ___
5675
5676
 
5676
5677
  #### Defined in
5677
5678
 
5678
- [packages/core/src/rbac/config.ts:115](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L115)
5679
+ [packages/core/src/rbac/config.ts:117](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L117)
5679
5680
 
5680
5681
  ___
5681
5682
 
@@ -5689,7 +5690,7 @@ ___
5689
5690
 
5690
5691
  #### Defined in
5691
5692
 
5692
- [packages/core/src/rbac/config.ts:119](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L119)
5693
+ [packages/core/src/rbac/config.ts:121](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L121)
5693
5694
 
5694
5695
  ___
5695
5696
 
@@ -5703,7 +5704,7 @@ ___
5703
5704
 
5704
5705
  #### Defined in
5705
5706
 
5706
- [packages/core/src/rbac/config.ts:123](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L123)
5707
+ [packages/core/src/rbac/config.ts:125](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L125)
5707
5708
 
5708
5709
  ___
5709
5710
 
@@ -5717,13 +5718,13 @@ ___
5717
5718
 
5718
5719
  #### Defined in
5719
5720
 
5720
- [packages/core/src/rbac/config.ts:127](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L127)
5721
+ [packages/core/src/rbac/config.ts:129](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/config.ts#L129)
5721
5722
 
5722
5723
  ___
5723
5724
 
5724
5725
  ### createRBACEngine
5725
5726
 
5726
- ▸ **createRBACEngine**(`supabase`): [`RBACEngine`](classes/RBACEngine.md)
5727
+ ▸ **createRBACEngine**(`supabase`, `securityConfig?`): [`RBACEngine`](classes/RBACEngine.md)
5727
5728
 
5728
5729
  Create an RBAC engine instance
5729
5730
 
@@ -5732,6 +5733,7 @@ Create an RBAC engine instance
5732
5733
  | Name | Type | Description |
5733
5734
  | :------ | :------ | :------ |
5734
5735
  | `supabase` | `default`\<`Database`, ``"public"``, ``"public"``, `never`, {}\> | Supabase client |
5736
+ | `securityConfig?` | `Partial`\<`RBACSecurityConfig`\> | Optional security configuration |
5735
5737
 
5736
5738
  #### Returns
5737
5739
 
@@ -5741,7 +5743,7 @@ RBACEngine instance
5741
5743
 
5742
5744
  #### Defined in
5743
5745
 
5744
- [packages/core/src/rbac/engine.ts:592](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/engine.ts#L592)
5746
+ [packages/core/src/rbac/engine.ts:601](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/engine.ts#L601)
5745
5747
 
5746
5748
  ___
5747
5749
 
@@ -6705,6 +6707,39 @@ Secure data access utilities
6705
6707
 
6706
6708
  ___
6707
6709
 
6710
+ ### useSessionTracking
6711
+
6712
+ ▸ **useSessionTracking**(`supabaseClient`, `appName?`): `Object`
6713
+
6714
+ Hook for manual session tracking (event switches and session expiration).
6715
+
6716
+ Note: Login and logout tracking is automatically handled by UnifiedAuthProvider.
6717
+ You should only use this hook for tracking event switches or session expirations.
6718
+
6719
+ #### Parameters
6720
+
6721
+ | Name | Type | Description |
6722
+ | :------ | :------ | :------ |
6723
+ | `supabaseClient` | `default`\<`any`, ``"public"``, ``"public"``, `any`, `any`\> | Supabase client instance |
6724
+ | `appName?` | `string` | Optional application name for tracking |
6725
+
6726
+ #### Returns
6727
+
6728
+ `Object`
6729
+
6730
+ Object containing tracking functions for event switches and session expiration
6731
+
6732
+ | Name | Type |
6733
+ | :------ | :------ |
6734
+ | `trackEventSwitch` | (`eventId`: `string`) => `Promise`\<`void`\> |
6735
+ | `trackSessionExpired` | () => `Promise`\<`void`\> |
6736
+
6737
+ #### Defined in
6738
+
6739
+ [packages/core/src/utils/sessionTracking.ts:22](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/utils/sessionTracking.ts#L22)
6740
+
6741
+ ___
6742
+
6708
6743
  ### getFileSizeLimit
6709
6744
 
6710
6745
  ▸ **getFileSizeLimit**(`mimeType`): `number`
@@ -76,6 +76,59 @@ function App() {
76
76
  }
77
77
  ```
78
78
 
79
+ > **Note**: Login and logout tracking is automatically handled by `UnifiedAuthProvider`. No manual intervention is required.
80
+
81
+ ### useSessionTracking
82
+
83
+ Utility hook for manual session tracking of event switches and session expiration. **Note**: Login and logout are automatically tracked by `UnifiedAuthProvider`, so those methods are not available here.
84
+
85
+ ```typescript
86
+ function useSessionTracking(
87
+ supabaseClient: SupabaseClient,
88
+ appName?: string
89
+ ): {
90
+ trackEventSwitch: (eventId: string) => Promise<void>;
91
+ trackSessionExpired: () => Promise<void>;
92
+ }
93
+ ```
94
+
95
+ #### Usage
96
+
97
+ ```tsx
98
+ import { useSessionTracking } from '@jmruthers/pace-core';
99
+ import { supabase } from './lib/supabase';
100
+
101
+ function MyComponent() {
102
+ const { trackEventSwitch, trackSessionExpired } = useSessionTracking(
103
+ supabase,
104
+ 'MY_APP'
105
+ );
106
+
107
+ const handleEventSwitch = async (eventId: string) => {
108
+ await trackEventSwitch(eventId);
109
+ // Event switch logic...
110
+ };
111
+
112
+ const handleSessionExpiration = async () => {
113
+ await trackSessionExpired();
114
+ // Session expiration logic...
115
+ };
116
+
117
+ return (
118
+ // Component JSX
119
+ );
120
+ }
121
+ ```
122
+
123
+ #### Methods
124
+
125
+ | Method | Description |
126
+ |--------|-------------|
127
+ | `trackEventSwitch(eventId)` | Track when a user switches to a different event. |
128
+ | `trackSessionExpired()` | Track when a session expires. |
129
+
130
+ > **Automatic Tracking**: When using `UnifiedAuthProvider`, login and logout events are **automatically tracked**. You only need to use this hook for event switches or session expirations, which are not automatically tracked.
131
+
79
132
 
80
133
  ## Event Management Hooks
81
134
 
@@ -206,6 +206,66 @@ The inactivity tracker monitors the following user interactions:
206
206
  - **Automatic cleanup**: All timers and listeners are properly cleaned up
207
207
  - **Error handling**: Graceful fallback if localStorage or BroadcastChannel fail
208
208
 
209
+ #### Automatic Login History Tracking
210
+
211
+ The `UnifiedAuthProvider` automatically tracks all user logins for security auditing and compliance:
212
+
213
+ - **Automatic Tracking** - No manual intervention required, tracking happens automatically on login/logout
214
+ - **Complete Audit Trail** - Records user ID, email, timestamp, IP address, user agent, and application context
215
+ - **Database Storage** - All login events are stored in `rbac_user_login_history` table
216
+ - **Application Context** - Tracks which application the user logged into (when `appName` is provided)
217
+ - **Non-Blocking** - Tracking failures don't prevent authentication from succeeding
218
+ - **Privacy Compliant** - Users can only view their own login history (RLS enforced)
219
+
220
+ Login history is tracked automatically when you use `UnifiedAuthProvider`. No additional configuration is required:
221
+
222
+ ```tsx
223
+ <UnifiedAuthProvider
224
+ supabaseClient={supabase}
225
+ appName="MY_APP" // Enables app-specific tracking in login history
226
+ // ... other props
227
+ >
228
+ <AppContent />
229
+ </UnifiedAuthProvider>
230
+ ```
231
+
232
+ **What Gets Tracked:**
233
+
234
+ - User ID and email
235
+ - Login timestamp
236
+ - Session ID
237
+ - IP address (if available)
238
+ - User agent string
239
+ - Application ID (if `appName` is provided)
240
+ - Organisation ID
241
+ - Event ID (if applicable)
242
+
243
+ **Querying Login History:**
244
+
245
+ Login history can be queried directly from the database using RLS-protected queries:
246
+
247
+ ```sql
248
+ -- Get user's login history
249
+ SELECT
250
+ login_timestamp,
251
+ email,
252
+ ip_address,
253
+ user_agent,
254
+ app_id,
255
+ event_id
256
+ FROM rbac_user_login_history
257
+ WHERE user_id = auth.uid()
258
+ ORDER BY login_timestamp DESC
259
+ LIMIT 100;
260
+ ```
261
+
262
+ **Security Notes:**
263
+
264
+ - Login history insertion uses `SECURITY DEFINER` functions (bypasses RLS)
265
+ - RLS policies ensure users can only view their own login history
266
+ - Failed tracking attempts are logged as warnings but don't break authentication
267
+ - All tracking is asynchronous and non-blocking
268
+
209
269
  ## OrganisationProvider
210
270
 
211
271
  Manages multi-tenant organisation context and user organisation memberships. **Automatically sets database organisation context** to ensure RLS policies work correctly.
@@ -77,6 +77,7 @@ sequenceDiagram
77
77
  - **Persistent State** - Authentication state persists across page reloads
78
78
  - **Multi-Tab Support** - Authentication state synchronized across tabs
79
79
  - **Graceful Degradation** - Handles network issues and token expiry
80
+ - **Automatic Login History** - User login events are automatically tracked in `rbac_user_login_history` table
80
81
 
81
82
  ### Security Features
82
83
 
@@ -84,6 +85,7 @@ sequenceDiagram
84
85
  - **JWT Tokens** - Secure, stateless authentication
85
86
  - **CSRF Protection** - Cross-site request forgery prevention
86
87
  - **Audit Logging** - Complete action tracking for compliance
88
+ - **Login History Tracking** - Automatic tracking of all user logins with timestamps, IP addresses, user agents, and application context
87
89
 
88
90
  ## Multi-Tenancy
89
91
 
@@ -54,8 +54,6 @@ This index mirrors the folder layout in `packages/core/docs/` so teams can quick
54
54
  - [Advanced patterns](./rbac/advanced-patterns.md)
55
55
  - [Super admin guide](./rbac/super-admin-guide.md)
56
56
  - [RLS integration](./rbac/rbac-rls-integration.md)
57
- - [Migration guide](./rbac/migration-guide.md)
58
- - [Breaking changes v3](./rbac/breaking-changes-v3.md)
59
57
  - [Troubleshooting](./rbac/troubleshooting.md)
60
58
  - [Legacy RLS README](./rbac/README-rbac-rls-integration.md)
61
59
 
@@ -23,6 +23,7 @@ PACE Core provides a comprehensive authentication system built on Supabase that
23
23
  - **🔒 Session Persistence** - Secure session management with auto-refresh
24
24
  - **🎯 Permission Integration** - Built-in RBAC integration
25
25
  - **📊 Debug Support** - Comprehensive debugging and monitoring
26
+ - **📝 Automatic Login History** - All user logins automatically tracked for audit trails
26
27
 
27
28
  ## Quick Start
28
29
 
@@ -12,10 +12,35 @@ The PACE Core RBAC (Role-Based Access Control) system provides comprehensive per
12
12
 
13
13
  ## 🚨 Critical Rules (Follow These or It Won't Work)
14
14
 
15
- 1. **Never make direct database queries** to `rbac_apps`, `rbac_global_roles`, or other RBAC tables
16
- 2. **Always use `PagePermissionGuard`** for page-level permissions (not manual permission checks)
17
- 3. **Always set up providers correctly** in the exact order shown
18
- 4. **Use the exact app name** from your environment variable (must match database exactly)
15
+ **MANDATORY Setup Steps (in order):**
16
+
17
+ 1. **Call `setupRBAC(supabase)` FIRST** - Must be called before any RBAC components or hooks
18
+ ```typescript
19
+ // In main.tsx or App.tsx
20
+ import { setupRBAC } from '@jmruthers/pace-core/rbac';
21
+ setupRBAC(supabase); // Must be BEFORE rendering App
22
+ ```
23
+
24
+ 2. **Wrap app with providers** in exact order:
25
+ ```tsx
26
+ <UnifiedAuthProvider supabaseClient={supabase} appName={APP_NAME}>
27
+ <OrganisationProvider>
28
+ <YourApp />
29
+ </OrganisationProvider>
30
+ </UnifiedAuthProvider>
31
+ ```
32
+
33
+ 3. **Use `PagePermissionGuard` for ALL pages** - This is the ONLY correct way to protect pages
34
+ ```tsx
35
+ <PagePermissionGuard pageName="dashboard" operation="read">
36
+ <DashboardContent />
37
+ </PagePermissionGuard>
38
+ ```
39
+
40
+ 4. **Database must be configured** - App, pages, and permissions must exist in database
41
+ 5. **User must have organisation role** - Users need roles in `rbac_organisation_roles` table
42
+ 6. **App name must match exactly** - Environment variable must match `rbac_apps.name` (case-sensitive)
43
+ 7. **Never query RBAC tables directly** - Always use `PagePermissionGuard` or RBAC API functions
19
44
 
20
45
  ## 🚀 Quick Start
21
46
 
@@ -179,34 +204,58 @@ function App() {
179
204
  }
180
205
  ```
181
206
 
182
- ### 2. Check Permissions
207
+ ### 2. Protect Pages with PagePermissionGuard
208
+
209
+ **⚠️ CRITICAL: Always use `PagePermissionGuard` for page-level access. This is the ONLY way to ensure permissions are checked correctly.**
183
210
 
184
211
  ```tsx
185
212
  import { PagePermissionGuard } from '@jmruthers/pace-core/rbac';
186
213
 
187
- function UserActions() {
214
+ function UsersPage() {
188
215
  return (
189
- <div>
190
- <PagePermissionGuard
191
- pageName="users"
192
- operation="update"
193
- fallback={null}
194
- >
195
- <EditButton />
196
- </PagePermissionGuard>
197
-
198
- <PagePermissionGuard
199
- pageName="users"
200
- operation="delete"
201
- fallback={null}
202
- >
203
- <DeleteButton />
204
- </PagePermissionGuard>
205
- </div>
216
+ <PagePermissionGuard
217
+ pageName="users"
218
+ operation="read"
219
+ fallback={<div>You don't have permission to view this page</div>}
220
+ >
221
+ <div>
222
+ <h1>User Management</h1>
223
+
224
+ {/* Multiple operations on same page */}
225
+ <PagePermissionGuard
226
+ pageName="users"
227
+ operation="create"
228
+ fallback={null}
229
+ >
230
+ <AddUserButton />
231
+ </PagePermissionGuard>
232
+
233
+ <PagePermissionGuard
234
+ pageName="users"
235
+ operation="update"
236
+ fallback={null}
237
+ >
238
+ <EditUserButtons />
239
+ </PagePermissionGuard>
240
+
241
+ <PagePermissionGuard
242
+ pageName="users"
243
+ operation="delete"
244
+ fallback={null}
245
+ >
246
+ <DeleteUserButtons />
247
+ </PagePermissionGuard>
248
+ </div>
249
+ </PagePermissionGuard>
206
250
  );
207
251
  }
208
252
  ```
209
253
 
254
+ **Important**:
255
+ - `pageName` must match the `page_name` in `rbac_app_pages` table
256
+ - `operation` can be: `read`, `create`, `update`, or `delete`
257
+ - Permission checked in database is: `{operation}:page.{pageName}` (e.g., `read:page.users`)
258
+
210
259
  ### 3. Protect Components
211
260
 
212
261
  ```tsx
@@ -230,24 +279,51 @@ function AdminPanel() {
230
279
  The RBAC system uses **page-level permissions** with the format: `{operation}:page.{pageName}`
231
280
 
232
281
  ### Operations
233
- - `read` - View page content
282
+ - `read` - View page content (required for `PagePermissionGuard` with `operation="read"`)
234
283
  - `create` - Create new content on page
235
284
  - `update` - Modify existing content on page
236
285
  - `delete` - Remove content from page
237
- - `manage` - Full page management
238
-
239
- ### Page-Level Examples
240
- - `read:page.dashboard` - View dashboard page
241
- - `create:page.users` - Create users on users page
242
- - `update:page.settings` - Modify settings page
243
- - `delete:page.admin` - Remove content from admin page
244
- - `manage:page.system` - Full system page management
245
-
246
- ### Event-App Permissions
247
- - `read:events` - View event information
248
- - `create:events` - Create new events
249
- - `update:events` - Modify existing events
250
- - `delete:events` - Remove events
286
+
287
+ ### Page-Level Permission Format
288
+
289
+ When you use `PagePermissionGuard` with:
290
+ ```tsx
291
+ <PagePermissionGuard pageName="dashboard" operation="read">
292
+ ```
293
+
294
+ The system checks for permission: `read:page.dashboard` in the database.
295
+
296
+ ### Database Structure
297
+
298
+ Permissions are stored in `rbac_page_permissions` table with:
299
+ - `app_page_id` - Links to `rbac_app_pages` table
300
+ - `operation` - One of: `read`, `create`, `update`, `delete`
301
+ - `role_name` - User's role (e.g., `org_admin`, `leader`, `member`)
302
+ - `allowed` - Boolean (`true` if user has permission, `false` otherwise)
303
+ - `organisation_id` - Organisation context (must match user's organisation)
304
+
305
+ ### Examples
306
+
307
+ If you have a page named `"users"` and check `operation="read"`:
308
+ - System checks: `read:page.users` permission
309
+ - Database query looks in `rbac_page_permissions` for matching `operation='read'` and `page_name='users'`
310
+ - Permission is granted if user's role has `allowed=true` for that page, operation, and organisation
311
+
312
+ ### Complete Example
313
+
314
+ ```sql
315
+ -- Database setup for a "users" page with read permission for org_admin role
316
+ INSERT INTO rbac_page_permissions (app_page_id, operation, role_name, allowed, organisation_id)
317
+ VALUES (
318
+ (SELECT id FROM rbac_app_pages WHERE page_name = 'users'),
319
+ 'read',
320
+ 'org_admin',
321
+ true,
322
+ 'your-organisation-id'::uuid
323
+ );
324
+ ```
325
+
326
+ This allows users with `org_admin` role to access `<PagePermissionGuard pageName="users" operation="read">`.
251
327
 
252
328
  ## 🔒 Security Features
253
329