@jmruthers/pace-core 0.5.115 → 0.5.117

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 (235) hide show
  1. package/dist/{AuthService-CVgsgtaZ.d.ts → AuthService-D4646R4b.d.ts} +9 -4
  2. package/dist/{DataTable-H5KJCAIS.js → DataTable-ZOAKQ3SU.js} +10 -9
  3. package/dist/{UnifiedAuthProvider-KZZUO27W.js → UnifiedAuthProvider-YFN7YGVN.js} +4 -3
  4. package/dist/{api-PKU4PUBO.js → api-TNIBJWLM.js} +3 -3
  5. package/dist/{audit-H4YJJF7R.js → audit-T36HM7IM.js} +2 -2
  6. package/dist/{chunk-SYXOZQ4P.js → chunk-2GJ5GL77.js} +1 -1
  7. package/dist/chunk-2GJ5GL77.js.map +1 -0
  8. package/dist/{chunk-XYRZV7R5.js → chunk-2LM4QQGH.js} +30 -34
  9. package/dist/chunk-2LM4QQGH.js.map +1 -0
  10. package/dist/{chunk-3OGQLOJM.js → chunk-3DBFLLLU.js} +30 -1
  11. package/dist/chunk-3DBFLLLU.js.map +1 -0
  12. package/dist/{chunk-KTHLNIMA.js → chunk-ECOVPXYS.js} +13 -62
  13. package/dist/chunk-ECOVPXYS.js.map +1 -0
  14. package/dist/{chunk-HKWQN44G.js → chunk-IZXS7RZK.js} +15 -15
  15. package/dist/{chunk-OO3V7W4H.js → chunk-KA3PSVNV.js} +87 -40
  16. package/dist/chunk-KA3PSVNV.js.map +1 -0
  17. package/dist/{chunk-L36JW4KV.js → chunk-LFS45U62.js} +2 -2
  18. package/dist/{chunk-BUN7NMV7.js → chunk-O3FTRYEU.js} +2 -2
  19. package/dist/{chunk-F6QB26OS.js → chunk-P3PUOL6B.js} +80 -8
  20. package/dist/chunk-P3PUOL6B.js.map +1 -0
  21. package/dist/{chunk-ZPXWJA4H.js → chunk-PHDAXDHB.js} +131 -5
  22. package/dist/chunk-PHDAXDHB.js.map +1 -0
  23. package/dist/chunk-UJI6WSMD.js +201 -0
  24. package/dist/{chunk-5CDJCTOO.js.map → chunk-UJI6WSMD.js.map} +1 -1
  25. package/dist/{chunk-OUU3SP6I.js → chunk-UKZWNQMB.js} +50 -7
  26. package/dist/{chunk-OUU3SP6I.js.map → chunk-UKZWNQMB.js.map} +1 -1
  27. package/dist/{chunk-7H75SHXZ.js → chunk-VN3OOE35.js} +2 -2
  28. package/dist/{chunk-QKIVSZ2O.js → chunk-WP5I5GLN.js} +2 -2
  29. package/dist/{chunk-NEONKMTU.js → chunk-XN2LYHDI.js} +47 -6
  30. package/dist/chunk-XN2LYHDI.js.map +1 -0
  31. package/dist/components.d.ts +1 -1
  32. package/dist/components.js +12 -11
  33. package/dist/components.js.map +1 -1
  34. package/dist/hooks.d.ts +1 -1
  35. package/dist/hooks.js +10 -9
  36. package/dist/hooks.js.map +1 -1
  37. package/dist/index.d.ts +4 -4
  38. package/dist/index.js +19 -16
  39. package/dist/index.js.map +1 -1
  40. package/dist/providers.d.ts +2 -2
  41. package/dist/providers.js +3 -2
  42. package/dist/rbac/index.d.ts +82 -1
  43. package/dist/rbac/index.js +13 -10
  44. package/dist/{useToast-DVT4dMtf.d.ts → useToast-Cs_g32bg.d.ts} +1 -1
  45. package/dist/utils.js +6 -4
  46. package/dist/utils.js.map +1 -1
  47. package/dist/validation.js +3 -1
  48. package/dist/validation.js.map +1 -1
  49. package/docs/README.md +4 -0
  50. package/docs/api/classes/ColumnFactory.md +1 -1
  51. package/docs/api/classes/ErrorBoundary.md +1 -1
  52. package/docs/api/classes/InvalidScopeError.md +1 -1
  53. package/docs/api/classes/MissingUserContextError.md +1 -1
  54. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  55. package/docs/api/classes/PermissionDeniedError.md +1 -1
  56. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  57. package/docs/api/classes/RBACAuditManager.md +35 -12
  58. package/docs/api/classes/RBACCache.md +1 -1
  59. package/docs/api/classes/RBACEngine.md +1 -1
  60. package/docs/api/classes/RBACError.md +1 -1
  61. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  62. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  63. package/docs/api/classes/StorageUtils.md +1 -1
  64. package/docs/api/enums/FileCategory.md +1 -1
  65. package/docs/api/interfaces/AggregateConfig.md +1 -1
  66. package/docs/api/interfaces/ButtonProps.md +1 -1
  67. package/docs/api/interfaces/CardProps.md +1 -1
  68. package/docs/api/interfaces/ColorPalette.md +1 -1
  69. package/docs/api/interfaces/ColorShade.md +1 -1
  70. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  71. package/docs/api/interfaces/DataRecord.md +1 -1
  72. package/docs/api/interfaces/DataTableAction.md +1 -1
  73. package/docs/api/interfaces/DataTableColumn.md +1 -1
  74. package/docs/api/interfaces/DataTableProps.md +1 -1
  75. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  76. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  77. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  78. package/docs/api/interfaces/EventAppRoleData.md +71 -0
  79. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  80. package/docs/api/interfaces/FileMetadata.md +1 -1
  81. package/docs/api/interfaces/FileReference.md +1 -1
  82. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  83. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  84. package/docs/api/interfaces/FileUploadProps.md +1 -1
  85. package/docs/api/interfaces/FooterProps.md +1 -1
  86. package/docs/api/interfaces/GrantEventAppRoleParams.md +122 -0
  87. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  88. package/docs/api/interfaces/InputProps.md +1 -1
  89. package/docs/api/interfaces/LabelProps.md +1 -1
  90. package/docs/api/interfaces/LoginFormProps.md +1 -1
  91. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  92. package/docs/api/interfaces/NavigationContextType.md +1 -1
  93. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  94. package/docs/api/interfaces/NavigationItem.md +1 -1
  95. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  96. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  97. package/docs/api/interfaces/Organisation.md +1 -1
  98. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  99. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  100. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  101. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  102. package/docs/api/interfaces/PaceAppLayoutProps.md +27 -27
  103. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  104. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  105. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  106. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  107. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  108. package/docs/api/interfaces/PaletteData.md +1 -1
  109. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  110. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  111. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  112. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  113. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  114. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  115. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  116. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  117. package/docs/api/interfaces/RBACConfig.md +1 -1
  118. package/docs/api/interfaces/RBACLogger.md +1 -1
  119. package/docs/api/interfaces/RevokeEventAppRoleParams.md +100 -0
  120. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  121. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  122. package/docs/api/interfaces/RoleManagementResult.md +52 -0
  123. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  124. package/docs/api/interfaces/RouteConfig.md +1 -1
  125. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  126. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  127. package/docs/api/interfaces/StorageConfig.md +1 -1
  128. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  129. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  130. package/docs/api/interfaces/StorageListOptions.md +1 -1
  131. package/docs/api/interfaces/StorageListResult.md +1 -1
  132. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  133. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  134. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  135. package/docs/api/interfaces/StyleImport.md +1 -1
  136. package/docs/api/interfaces/SwitchProps.md +1 -1
  137. package/docs/api/interfaces/ToastActionElement.md +1 -1
  138. package/docs/api/interfaces/ToastProps.md +1 -1
  139. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  140. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  141. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  142. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  143. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  144. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  145. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +1 -1
  146. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  147. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  148. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  149. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  150. package/docs/api/interfaces/UserEventAccess.md +1 -1
  151. package/docs/api/interfaces/UserMenuProps.md +1 -1
  152. package/docs/api/interfaces/UserProfile.md +1 -1
  153. package/docs/api/modules.md +41 -14
  154. package/docs/architecture/rpc-function-standards.md +193 -0
  155. package/package.json +1 -1
  156. package/src/__tests__/TEST_STANDARD.md +244 -2
  157. package/src/components/DataTable/__tests__/a11y.basic.test.tsx +46 -16
  158. package/src/components/DataTable/__tests__/keyboard.test.tsx +276 -217
  159. package/src/components/DataTable/components/DataTableCore.tsx +29 -2
  160. package/src/components/DataTable/components/DataTableToolbar.tsx +3 -2
  161. package/src/components/DataTable/components/EditableRow.tsx +18 -1
  162. package/src/components/DataTable/components/ViewRowModal.tsx +1 -1
  163. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +735 -0
  164. package/src/components/DataTable/components/__tests__/BulkOperationsDropdown.test.tsx +572 -0
  165. package/src/components/DataTable/components/__tests__/ColumnVisibilityDropdown.test.tsx +708 -0
  166. package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +451 -0
  167. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +456 -0
  168. package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +454 -0
  169. package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +462 -0
  170. package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +423 -0
  171. package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +393 -0
  172. package/src/components/DataTable/components/__tests__/GroupingDropdown.test.tsx +617 -0
  173. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +734 -0
  174. package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +412 -0
  175. package/src/components/DataTable/hooks/useTableHandlers.ts +4 -0
  176. package/src/components/EventSelector/EventSelector.tsx +5 -25
  177. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +12 -7
  178. package/src/components/PaceAppLayout/PaceAppLayout.tsx +4 -0
  179. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.accessibility.test.tsx +7 -2
  180. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +13 -8
  181. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +109 -100
  182. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +18 -13
  183. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +17 -12
  184. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +2 -0
  185. package/src/components/PaceLoginPage/PaceLoginPage.tsx +11 -1
  186. package/src/components/PasswordReset/PasswordChangeForm.test.tsx +2 -2
  187. package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +648 -0
  188. package/src/components/ProtectedRoute/ProtectedRoute.tsx +10 -7
  189. package/src/components/PublicLayout/__tests__/PublicErrorBoundary.test.tsx +4 -12
  190. package/src/components/Select/Select.tsx +8 -0
  191. package/src/components/Toast/Toast.tsx +1 -1
  192. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +367 -3
  193. package/src/hooks/__tests__/usePublicFileDisplay.test.ts +916 -0
  194. package/src/hooks/useEventTheme.ts +49 -18
  195. package/src/hooks/usePermissionCache.ts +5 -3
  196. package/src/hooks/useSecureDataAccess.ts +56 -3
  197. package/src/hooks/useToast.ts +1 -1
  198. package/src/providers/services/EventServiceProvider.tsx +15 -8
  199. package/src/rbac/__tests__/cache-invalidation.test.ts +385 -0
  200. package/src/rbac/audit.test.ts +206 -0
  201. package/src/rbac/audit.ts +37 -2
  202. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +26 -23
  203. package/src/rbac/errors.test.ts +340 -0
  204. package/src/rbac/hooks/index.ts +9 -0
  205. package/src/rbac/hooks/useResolvedScope.test.ts +1063 -0
  206. package/src/rbac/hooks/useRoleManagement.test.ts +908 -0
  207. package/src/rbac/hooks/useRoleManagement.ts +255 -0
  208. package/src/services/AuthService.ts +10 -0
  209. package/src/services/EventService.ts +111 -50
  210. package/src/services/__tests__/AuthService.test.ts +1 -1
  211. package/src/services/__tests__/EventService.test.ts +60 -45
  212. package/src/services/interfaces/IEventService.ts +1 -1
  213. package/src/utils/__tests__/deviceFingerprint.unit.test.ts +320 -0
  214. package/src/utils/__tests__/logger.unit.test.ts +398 -0
  215. package/src/utils/__tests__/validation.unit.test.ts +225 -1
  216. package/src/utils/file-reference.test.ts +214 -0
  217. package/dist/chunk-3OGQLOJM.js.map +0 -1
  218. package/dist/chunk-5CDJCTOO.js +0 -190
  219. package/dist/chunk-F6QB26OS.js.map +0 -1
  220. package/dist/chunk-KTHLNIMA.js.map +0 -1
  221. package/dist/chunk-NEONKMTU.js.map +0 -1
  222. package/dist/chunk-OO3V7W4H.js.map +0 -1
  223. package/dist/chunk-SYXOZQ4P.js.map +0 -1
  224. package/dist/chunk-XYRZV7R5.js.map +0 -1
  225. package/dist/chunk-ZPXWJA4H.js.map +0 -1
  226. package/src/rbac/audit-enhanced.ts +0 -351
  227. /package/dist/{DataTable-H5KJCAIS.js.map → DataTable-ZOAKQ3SU.js.map} +0 -0
  228. /package/dist/{UnifiedAuthProvider-KZZUO27W.js.map → UnifiedAuthProvider-YFN7YGVN.js.map} +0 -0
  229. /package/dist/{api-PKU4PUBO.js.map → api-TNIBJWLM.js.map} +0 -0
  230. /package/dist/{audit-H4YJJF7R.js.map → audit-T36HM7IM.js.map} +0 -0
  231. /package/dist/{chunk-HKWQN44G.js.map → chunk-IZXS7RZK.js.map} +0 -0
  232. /package/dist/{chunk-L36JW4KV.js.map → chunk-LFS45U62.js.map} +0 -0
  233. /package/dist/{chunk-BUN7NMV7.js.map → chunk-O3FTRYEU.js.map} +0 -0
  234. /package/dist/{chunk-7H75SHXZ.js.map → chunk-VN3OOE35.js.map} +0 -0
  235. /package/dist/{chunk-QKIVSZ2O.js.map → chunk-WP5I5GLN.js.map} +0 -0
@@ -2,6 +2,7 @@
2
2
  var RBACAuditManager = class {
3
3
  constructor(supabase) {
4
4
  this.enabled = true;
5
+ this.fallbackEnabled = true;
5
6
  this.supabase = supabase;
6
7
  }
7
8
  /**
@@ -20,6 +21,14 @@ var RBACAuditManager = class {
20
21
  isEnabled() {
21
22
  return this.enabled;
22
23
  }
24
+ /**
25
+ * Enable or disable fallback logging (console logging when database fails)
26
+ *
27
+ * @param enabled - Whether to enable fallback logging
28
+ */
29
+ setFallbackEnabled(enabled) {
30
+ this.fallbackEnabled = enabled;
31
+ }
23
32
  /**
24
33
  * Emit an audit event
25
34
  *
@@ -93,11 +102,31 @@ var RBACAuditManager = class {
93
102
  hint: error.hint,
94
103
  event: auditEvent
95
104
  });
105
+ if (this.fallbackEnabled) {
106
+ this.logFallbackEvent(event, error);
107
+ }
96
108
  }
97
109
  } catch (error) {
98
110
  console.error("[RBAC Audit] Unexpected error during audit logging:", error);
111
+ if (this.fallbackEnabled) {
112
+ this.logFallbackEvent(event, error);
113
+ }
99
114
  }
100
115
  }
116
+ /**
117
+ * Log event to console as fallback when database logging fails
118
+ *
119
+ * @param event - Audit event payload
120
+ * @param error - The error that occurred
121
+ */
122
+ logFallbackEvent(event, error) {
123
+ console.log("[RBAC Audit Fallback]", {
124
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
125
+ event,
126
+ error: error?.message || error,
127
+ note: "Database audit logging failed, using console fallback"
128
+ });
129
+ }
101
130
  /**
102
131
  * Emit a permission check audit event
103
132
  *
@@ -205,4 +234,4 @@ export {
205
234
  getGlobalAuditManager,
206
235
  emitAuditEvent
207
236
  };
208
- //# sourceMappingURL=chunk-3OGQLOJM.js.map
237
+ //# sourceMappingURL=chunk-3DBFLLLU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/rbac/audit.ts"],"sourcesContent":["/**\n * RBAC Audit Events System\n * @package @jmruthers/pace-core\n * @module RBAC/Audit\n * @since 1.0.0\n * \n * This module provides structured audit event emission for all RBAC operations.\n */\n\nimport { SupabaseClient } from '@supabase/supabase-js';\nimport { Database } from '../types/database';\nimport { \n UUID, \n AuditEventSource, \n RBACAuditEvent \n} from './types';\n\n/**\n * Audit event payload for permission checks\n */\nexport interface PermissionCheckAuditEvent {\n type: 'permission_check';\n userId: UUID;\n organisationId: UUID;\n eventId?: string;\n appId?: UUID;\n pageId?: UUID;\n permission: string;\n decision: boolean;\n source: AuditEventSource;\n bypass?: boolean;\n duration_ms: number;\n cache_hit?: boolean;\n cache_source?: 'memory' | 'database' | 'rpc';\n metadata?: Record<string, any>;\n}\n\n/**\n * Audit event payload for permission denied\n */\nexport interface PermissionDeniedAuditEvent {\n type: 'permission_denied';\n userId: UUID;\n organisationId: UUID;\n eventId?: string;\n appId?: UUID;\n pageId?: UUID;\n permission: string;\n source: AuditEventSource;\n metadata?: Record<string, any>;\n}\n\n/**\n * Audit event payload for role granted\n */\nexport interface RoleGrantedAuditEvent {\n type: 'role_granted';\n userId: UUID;\n organisationId: UUID;\n eventId?: string;\n appId?: UUID;\n role: string;\n grantedBy: UUID;\n metadata?: Record<string, any>;\n}\n\n/**\n * Audit event payload for role revoked\n */\nexport interface RoleRevokedAuditEvent {\n type: 'role_denied';\n userId: UUID;\n organisationId: UUID;\n eventId?: string;\n appId?: UUID;\n role: string;\n revokedBy: UUID;\n metadata?: Record<string, any>;\n}\n\n/**\n * Audit event payload for RLS denied\n */\nexport interface RLSDeniedAuditEvent {\n type: 'rls_denied';\n userId: UUID;\n organisationId: UUID;\n table: string;\n operation: string;\n metadata?: Record<string, any>;\n}\n\n/**\n * Union type for all audit events\n */\nexport type AuditEventPayload = \n | PermissionCheckAuditEvent\n | PermissionDeniedAuditEvent\n | RoleGrantedAuditEvent\n | RoleRevokedAuditEvent\n | RLSDeniedAuditEvent;\n\n/**\n * RBAC Audit Manager\n * \n * Handles emission of structured audit events for all RBAC operations.\n */\nexport class RBACAuditManager {\n private supabase: SupabaseClient<Database>;\n private enabled: boolean = true;\n private fallbackEnabled: boolean = true;\n\n constructor(supabase: SupabaseClient<Database>) {\n this.supabase = supabase;\n }\n\n /**\n * Enable or disable audit logging\n * \n * @param enabled - Whether to enable audit logging\n */\n setEnabled(enabled: boolean): void {\n this.enabled = enabled;\n }\n\n /**\n * Check if audit logging is enabled\n * \n * @returns True if audit logging is enabled\n */\n isEnabled(): boolean {\n return this.enabled;\n }\n\n /**\n * Enable or disable fallback logging (console logging when database fails)\n * \n * @param enabled - Whether to enable fallback logging\n */\n setFallbackEnabled(enabled: boolean): void {\n this.fallbackEnabled = enabled;\n }\n\n /**\n * Emit an audit event\n * \n * @param event - Audit event payload\n * @returns Promise that resolves when event is logged\n */\n async emitEvent(event: AuditEventPayload): Promise<void> {\n if (!this.enabled) {\n return;\n }\n\n // Validate required fields before attempting to insert\n // MANDATORY: All audit events must have userId\n if (!event.userId) {\n console.error('[RBAC Audit] CRITICAL: Cannot log audit event without userId:', {\n eventType: event.type,\n organisationId: event.organisationId\n });\n return;\n }\n\n // WARNING: Some audit events may not have organisationId (e.g., global admin operations)\n // Log these for security monitoring even if organisationId is missing\n if (!event.organisationId) {\n console.warn('[RBAC Audit] Audit event without organisation context:', {\n userId: event.userId,\n eventType: event.type,\n note: 'This should be investigated for security compliance'\n });\n }\n\n try {\n // Since organisationId is now required in SecurityContext, this should rarely happen\n // But we still handle the edge case properly without masking it\n if (!event.organisationId) {\n console.warn('[RBAC Audit] Audit event without organisation context - this should be investigated:', {\n userId: event.userId,\n eventType: event.type,\n note: 'Organisation context is required for RBAC operations. This may indicate a security issue or missing context derivation.'\n });\n }\n\n // Validate pageId: only include in page_id column if it's a valid UUID\n // Otherwise, store it in metadata to avoid database errors\n const rawPageId = 'pageId' in event ? event.pageId : undefined;\n const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n const isValidPageIdUuid = rawPageId && uuidRegex.test(rawPageId);\n const pageIdUuid: UUID | undefined = isValidPageIdUuid ? (rawPageId as UUID) : undefined;\n const pageIdName: string | undefined = rawPageId && !isValidPageIdUuid ? rawPageId : undefined;\n\n const auditEvent: Omit<RBACAuditEvent, 'id' | 'created_at'> = {\n event_type: event.type,\n user_id: event.userId,\n // Store organisationId - nullable to properly track missing context cases\n // Do NOT use fallback UUID as it masks security issues\n organisation_id: event.organisationId || null, // Explicitly null if missing\n event_id: 'eventId' in event ? event.eventId : undefined,\n app_id: 'appId' in event ? event.appId : undefined,\n page_id: pageIdUuid, // Only set if it's a valid UUID\n permission: 'permission' in event ? event.permission : undefined,\n decision: 'decision' in event ? event.decision : undefined,\n source: 'source' in event ? event.source : 'api', // Default to 'api' if not provided\n bypass: 'bypass' in event ? event.bypass : undefined,\n duration_ms: 'duration_ms' in event ? event.duration_ms : undefined,\n metadata: {\n ...event.metadata,\n cache_hit: 'cache_hit' in event ? event.cache_hit : undefined,\n cache_source: 'cache_source' in event ? event.cache_source : undefined,\n // Explicit flag indicating this event had no organisation context\n no_organisation_context: !event.organisationId,\n // Store page name/identifier in metadata if it's not a UUID\n page_name: pageIdName,\n },\n };\n\n const { error } = await (this.supabase as any)\n .from('rbac_audit_events')\n .insert([auditEvent]);\n\n if (error) {\n // Log the error for debugging\n console.warn('[RBAC Audit] Failed to insert audit event:', {\n error: error.message,\n code: error.code,\n details: error.details,\n hint: error.hint,\n event: auditEvent\n });\n\n // Use fallback logging if enabled\n if (this.fallbackEnabled) {\n this.logFallbackEvent(event, error);\n }\n }\n } catch (error) {\n // Log unexpected errors\n console.error('[RBAC Audit] Unexpected error during audit logging:', error);\n \n // Use fallback logging if enabled\n if (this.fallbackEnabled) {\n this.logFallbackEvent(event, error);\n }\n }\n }\n\n /**\n * Log event to console as fallback when database logging fails\n * \n * @param event - Audit event payload\n * @param error - The error that occurred\n */\n private logFallbackEvent(event: AuditEventPayload, error: any): void {\n console.log('[RBAC Audit Fallback]', {\n timestamp: new Date().toISOString(),\n event,\n error: error?.message || error,\n note: 'Database audit logging failed, using console fallback'\n });\n }\n\n /**\n * Emit a permission check audit event\n * \n * @param event - Permission check event data\n */\n async emitPermissionCheck(event: Omit<PermissionCheckAuditEvent, 'type'>): Promise<void> {\n await this.emitEvent({\n type: 'permission_check',\n ...event,\n });\n }\n\n /**\n * Emit a permission denied audit event\n * \n * @param event - Permission denied event data\n */\n async emitPermissionDenied(event: Omit<PermissionDeniedAuditEvent, 'type'>): Promise<void> {\n await this.emitEvent({\n type: 'permission_denied',\n ...event,\n });\n }\n\n /**\n * Emit a role granted audit event\n * \n * @param event - Role granted event data\n */\n async emitRoleGranted(event: Omit<RoleGrantedAuditEvent, 'type'>): Promise<void> {\n await this.emitEvent({\n type: 'role_granted',\n ...event,\n });\n }\n\n /**\n * Emit a role revoked audit event\n * \n * @param event - Role revoked event data\n */\n async emitRoleRevoked(event: Omit<RoleRevokedAuditEvent, 'type'>): Promise<void> {\n await this.emitEvent({\n type: 'role_denied',\n ...event,\n });\n }\n\n /**\n * Emit an RLS denied audit event\n * \n * @param event - RLS denied event data\n */\n async emitRLSDenied(event: Omit<RLSDeniedAuditEvent, 'type'>): Promise<void> {\n await this.emitEvent({\n type: 'rls_denied',\n ...event,\n });\n }\n\n /**\n * Get audit events for a user\n * \n * @param userId - User ID\n * @param limit - Maximum number of events to return\n * @returns Promise resolving to audit events\n */\n async getUserAuditEvents(userId: UUID, limit: number = 100): Promise<RBACAuditEvent[]> {\n const { data, error } = await this.supabase\n .from('rbac_audit_events')\n .select('*')\n .eq('user_id', userId)\n .order('created_at', { ascending: false })\n .limit(limit);\n\n if (error) {\n throw new Error(`Failed to get audit events: ${error.message}`);\n }\n\n return data || [];\n }\n\n /**\n * Get audit events for an organisation\n * \n * @param organisationId - Organisation ID\n * @param limit - Maximum number of events to return\n * @returns Promise resolving to audit events\n */\n async getOrganisationAuditEvents(organisationId: UUID, limit: number = 100): Promise<RBACAuditEvent[]> {\n const { data, error } = await this.supabase\n .from('rbac_audit_events')\n .select('*')\n .eq('organisation_id', organisationId)\n .order('created_at', { ascending: false })\n .limit(limit);\n\n if (error) {\n throw new Error(`Failed to get audit events: ${error.message}`);\n }\n\n return data || [];\n }\n}\n\n/**\n * Create an audit manager instance\n * \n * @param supabase - Supabase client\n * @returns RBACAuditManager instance\n */\nexport function createAuditManager(supabase: SupabaseClient<Database>): RBACAuditManager {\n return new RBACAuditManager(supabase);\n}\n\n/**\n * Global audit manager instance\n * \n * This is set by the RBAC engine when it initializes.\n */\nlet globalAuditManager: RBACAuditManager | null = null;\n\n/**\n * Set the global audit manager\n * \n * @param manager - Audit manager instance\n */\nexport function setGlobalAuditManager(manager: RBACAuditManager): void {\n globalAuditManager = manager;\n}\n\n/**\n * Get the global audit manager\n * \n * @returns Global audit manager or null if not set\n */\nexport function getGlobalAuditManager(): RBACAuditManager | null {\n return globalAuditManager;\n}\n\n/**\n * Emit an audit event using the global audit manager\n * \n * @param event - Audit event payload\n */\nexport async function emitAuditEvent(event: AuditEventPayload): Promise<void> {\n if (globalAuditManager) {\n await globalAuditManager.emitEvent(event);\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,20 +1,14 @@
1
1
  import {
2
2
  init_OrganisationProvider,
3
3
  usePublicPageContext
4
- } from "./chunk-F6QB26OS.js";
4
+ } from "./chunk-P3PUOL6B.js";
5
5
  import {
6
6
  init_useOrganisations,
7
- useEvents,
8
7
  useOrganisations
9
- } from "./chunk-L36JW4KV.js";
8
+ } from "./chunk-LFS45U62.js";
10
9
  import {
11
10
  useUnifiedAuth
12
- } from "./chunk-OO3V7W4H.js";
13
- import {
14
- applyPalette,
15
- clearPalette,
16
- init_runtime
17
- } from "./chunk-SMJZMKYN.js";
11
+ } from "./chunk-KA3PSVNV.js";
18
12
 
19
13
  // src/hooks/useOrganisationSecurity.ts
20
14
  import { useCallback, useMemo, useEffect, useState } from "react";
@@ -96,7 +90,7 @@ var useOrganisationSecurity = () => {
96
90
  const targetOrgId = orgId || selectedOrganisation?.id;
97
91
  if (!targetOrgId || !user) return false;
98
92
  try {
99
- const { isPermitted } = await import("./api-PKU4PUBO.js");
93
+ const { isPermitted } = await import("./api-TNIBJWLM.js");
100
94
  const scope = {
101
95
  organisationId: targetOrgId,
102
96
  eventId: user.user_metadata?.eventId || user.app_metadata?.eventId,
@@ -119,7 +113,7 @@ var useOrganisationSecurity = () => {
119
113
  const targetOrgId = orgId || selectedOrganisation?.id;
120
114
  if (!targetOrgId || !user) return [];
121
115
  try {
122
- const { getPermissionMap } = await import("./api-PKU4PUBO.js");
116
+ const { getPermissionMap } = await import("./api-TNIBJWLM.js");
123
117
  const scope = {
124
118
  organisationId: targetOrgId,
125
119
  eventId: user.user_metadata?.eventId || user.app_metadata?.eventId,
@@ -140,7 +134,7 @@ var useOrganisationSecurity = () => {
140
134
  if (!user || !selectedOrganisation) return;
141
135
  try {
142
136
  if (selectedOrganisation.id) {
143
- const { emitAuditEvent } = await import("./audit-H4YJJF7R.js");
137
+ const { emitAuditEvent } = await import("./audit-T36HM7IM.js");
144
138
  await emitAuditEvent({
145
139
  type: "permission_check",
146
140
  userId: user.id,
@@ -306,50 +300,8 @@ function useOrganisationPermissions(orgId) {
306
300
  }), [userRole, organisationId, hasOrganisationAccess, hasPermission, getAllPermissions, permissions]);
307
301
  }
308
302
 
309
- // src/hooks/useEventTheme.ts
310
- import { useEffect as useEffect2 } from "react";
311
- import { useLocation } from "react-router-dom";
312
- init_runtime();
313
- function useEventTheme() {
314
- const { selectedEvent } = useEvents();
315
- const location = useLocation();
316
- useEffect2(() => {
317
- const isOnLoginRoute = location.pathname === "/login" || location.pathname.startsWith("/login");
318
- if (isOnLoginRoute) {
319
- clearPalette();
320
- return;
321
- }
322
- if (!selectedEvent) {
323
- clearPalette();
324
- return;
325
- }
326
- const eventColours = selectedEvent.event_colours;
327
- if (!eventColours || typeof eventColours !== "object") {
328
- clearPalette();
329
- return;
330
- }
331
- const palette = eventColours;
332
- if (!palette.main && !palette.sec && !palette.acc) {
333
- clearPalette();
334
- return;
335
- }
336
- const fullPalette = {
337
- main: palette.main || {},
338
- sec: palette.sec || {},
339
- acc: palette.acc || {}
340
- };
341
- try {
342
- applyPalette(fullPalette);
343
- } catch (error) {
344
- console.error("[useEventTheme] Failed to apply event palette:", error);
345
- }
346
- return () => {
347
- };
348
- }, [selectedEvent, location.pathname]);
349
- }
350
-
351
303
  // src/hooks/public/usePublicEvent.ts
352
- import { useState as useState2, useEffect as useEffect3, useCallback as useCallback2, useMemo as useMemo3 } from "react";
304
+ import { useState as useState2, useEffect as useEffect2, useCallback as useCallback2, useMemo as useMemo3 } from "react";
353
305
  import { createClient } from "@supabase/supabase-js";
354
306
  var publicDataCache = /* @__PURE__ */ new Map();
355
307
  function usePublicEvent(eventCode, options = {}) {
@@ -548,7 +500,7 @@ function usePublicEvent(eventCode, options = {}) {
548
500
  setIsLoading(false);
549
501
  }
550
502
  }, [eventCode, supabase, cacheTtl, enableCache]);
551
- useEffect3(() => {
503
+ useEffect2(() => {
552
504
  fetchEvent();
553
505
  }, [fetchEvent]);
554
506
  const refetch = useCallback2(async () => {
@@ -581,8 +533,8 @@ function getPublicEventCacheStats() {
581
533
  }
582
534
 
583
535
  // src/hooks/public/usePublicRouteParams.ts
584
- import { useState as useState3, useEffect as useEffect4, useCallback as useCallback3, useMemo as useMemo4 } from "react";
585
- import { useParams, useLocation as useLocation2 } from "react-router-dom";
536
+ import { useState as useState3, useEffect as useEffect3, useCallback as useCallback3, useMemo as useMemo4 } from "react";
537
+ import { useParams, useLocation } from "react-router-dom";
586
538
  function validateEventCodeFormat(eventCode) {
587
539
  if (!eventCode || typeof eventCode !== "string") return false;
588
540
  const eventCodeRegex = /^[a-zA-Z0-9][a-zA-Z0-9_-]{1,48}[a-zA-Z0-9]$/;
@@ -600,7 +552,7 @@ function usePublicRouteParams(options = {}) {
600
552
  validateEventCode = true
601
553
  } = options;
602
554
  const params = useParams();
603
- const location = useLocation2();
555
+ const location = useLocation();
604
556
  const [error, setError] = useState3(null);
605
557
  const eventCode = useMemo4(() => {
606
558
  const code = params[eventCodeParam];
@@ -641,7 +593,7 @@ function usePublicRouteParams(options = {}) {
641
593
  if (!fetchEventData) return;
642
594
  await refetchEvent();
643
595
  }, [fetchEventData, refetchEvent]);
644
- useEffect4(() => {
596
+ useEffect3(() => {
645
597
  if (eventCode && event) {
646
598
  console.log("[usePublicRouteParams] Public route accessed:", {
647
599
  eventCode,
@@ -697,7 +649,6 @@ function extractEventCodeFromPath(path) {
697
649
  export {
698
650
  useOrganisationSecurity,
699
651
  useOrganisationPermissions,
700
- useEventTheme,
701
652
  usePublicEvent,
702
653
  clearPublicEventCache,
703
654
  getPublicEventCacheStats,
@@ -706,4 +657,4 @@ export {
706
657
  generatePublicRoutePath,
707
658
  extractEventCodeFromPath
708
659
  };
709
- //# sourceMappingURL=chunk-KTHLNIMA.js.map
660
+ //# sourceMappingURL=chunk-ECOVPXYS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/useOrganisationSecurity.ts","../src/hooks/useOrganisationPermissions.ts","../src/hooks/public/usePublicEvent.ts","../src/hooks/public/usePublicRouteParams.ts"],"sourcesContent":["/**\n * @file Organisation Security Hook\n * @package @jmruthers/pace-core\n * @module Hooks/OrganisationSecurity\n * @since 0.4.0\n *\n * Security-focused hook for organisation access validation and super admin functionality.\n * Provides utilities for validating user access to organisations and checking permissions.\n */\n\nimport { useCallback, useMemo, useEffect, useState } from 'react';\nimport { useUnifiedAuth } from '../providers';\nimport { useOrganisations } from './useOrganisations';\n// Legacy useRBAC hook removed - use new RBAC system instead\nimport type { OrganisationSecurityError, SuperAdminContext } from '../types/organisation';\nimport type { Permission } from '../rbac/types';\n\nexport interface OrganisationSecurityHook {\n // Super admin context\n superAdminContext: SuperAdminContext;\n \n // Access validation\n validateOrganisationAccess: (orgId: string) => Promise<boolean>;\n hasMinimumRole: (minRole: string, orgId?: string) => boolean;\n canAccessChildOrganisations: (orgId?: string) => boolean;\n \n // Permission checks\n hasPermission: (permission: string, orgId?: string) => Promise<boolean>;\n getUserPermissions: (orgId?: string) => Promise<string[]>;\n \n // Audit logging\n logOrganisationAccess: (action: string, details?: any) => Promise<void>;\n \n // Security utilities\n ensureOrganisationAccess: (orgId: string) => Promise<void>;\n validateUserAccess: (userId: string, orgId: string) => Promise<boolean>;\n}\n\nexport const useOrganisationSecurity = (): OrganisationSecurityHook => {\n const { user, session, supabase } = useUnifiedAuth();\n const { selectedOrganisation, getUserRole, validateOrganisationAccess: validateAccess } = useOrganisations();\n \n // Super admin status - query database for security (user_metadata can be spoofed)\n const [isSuperAdmin, setIsSuperAdmin] = useState<boolean>(false);\n const [isCheckingSuperAdmin, setIsCheckingSuperAdmin] = useState(false);\n\n // Check super admin status from database\n useEffect(() => {\n if (!user || !session || !supabase) {\n setIsSuperAdmin(false);\n return;\n }\n\n const checkSuperAdmin = async () => {\n setIsCheckingSuperAdmin(true);\n try {\n const now = new Date().toISOString();\n const { data, error } = await supabase\n .from('rbac_global_roles')\n .select('role')\n .eq('user_id', user.id)\n .eq('role', 'super_admin')\n .lte('valid_from', now)\n .or(`valid_to.is.null,valid_to.gte.${now}`)\n .limit(1);\n\n setIsSuperAdmin(!error && data && data.length > 0);\n } catch (error) {\n console.error('[useOrganisationSecurity] Error checking super admin status:', error);\n setIsSuperAdmin(false);\n } finally {\n setIsCheckingSuperAdmin(false);\n }\n };\n\n checkSuperAdmin();\n }, [user, session, supabase]);\n\n // Super admin context\n const superAdminContext = useMemo((): SuperAdminContext => {\n return {\n isSuperAdmin,\n hasGlobalAccess: isSuperAdmin,\n canManageAllOrganisations: isSuperAdmin\n };\n }, [isSuperAdmin]);\n\n // Validate organisation access with database check\n const validateOrganisationAccess = useCallback(async (orgId: string): Promise<boolean> => {\n if (!user || !session || !supabase) return false;\n \n try {\n // Super admin has access to all organisations\n if (superAdminContext.isSuperAdmin) {\n return true;\n }\n\n // Check organisation membership using consolidated rbac_organisation_roles table\n const { data, error } = await supabase\n .from('rbac_organisation_roles')\n .select('id')\n .eq('user_id', user.id)\n .eq('organisation_id', orgId)\n .eq('status', 'active')\n .is('revoked_at', null)\n .in('role', ['org_admin', 'leader', 'member']) // Only actual members, not supporters\n .single();\n\n if (error) {\n console.error('[useOrganisationSecurity] Error validating organisation access:', error);\n return false;\n }\n\n return !!data;\n } catch (error) {\n console.error('[useOrganisationSecurity] Exception validating organisation access:', error);\n return false;\n }\n }, [user, session, supabase, superAdminContext.isSuperAdmin]);\n\n // Check if user has minimum role\n const hasMinimumRole = useCallback((minRole: string, orgId?: string): boolean => {\n // Super admin has all roles\n if (superAdminContext.isSuperAdmin) {\n return true;\n }\n\n const targetOrgId = orgId || selectedOrganisation?.id;\n if (!targetOrgId) return false;\n\n const userRole = getUserRole(targetOrgId);\n const roleHierarchy = ['supporter', 'member', 'leader', 'org_admin'];\n \n const userRoleIndex = roleHierarchy.indexOf(userRole);\n const minRoleIndex = roleHierarchy.indexOf(minRole);\n \n return userRoleIndex >= minRoleIndex;\n }, [selectedOrganisation, getUserRole, superAdminContext.isSuperAdmin]);\n\n // Check if user can access child organisations\n const canAccessChildOrganisations = useCallback((orgId?: string): boolean => {\n // Super admin can access all organisations\n if (superAdminContext.isSuperAdmin) {\n return true;\n }\n\n const targetOrgId = orgId || selectedOrganisation?.id;\n if (!targetOrgId) return false;\n\n const userRole = getUserRole(targetOrgId);\n return userRole === 'org_admin';\n }, [selectedOrganisation, getUserRole, superAdminContext.isSuperAdmin]);\n\n // Check specific permission using the new RBAC system\n const hasPermission = useCallback(async (permission: string, orgId?: string): Promise<boolean> => {\n // Super admin has all permissions\n if (superAdminContext.isSuperAdmin) {\n return true;\n }\n\n const targetOrgId = orgId || selectedOrganisation?.id;\n if (!targetOrgId || !user) return false;\n\n try {\n // Use the new RBAC system\n const { isPermitted } = await import('../rbac/api');\n \n const scope = {\n organisationId: targetOrgId,\n eventId: user.user_metadata?.eventId || user.app_metadata?.eventId,\n appId: user.user_metadata?.appId || user.app_metadata?.appId,\n };\n\n return await isPermitted({\n userId: user.id,\n scope,\n permission: permission as Permission\n });\n } catch (error) {\n console.error('[useOrganisationSecurity] Exception checking permission:', error);\n return false;\n }\n }, [selectedOrganisation, user, superAdminContext.isSuperAdmin]);\n\n // Get user's permissions for organisation using the new RBAC system\n const getUserPermissions = useCallback(async (orgId?: string): Promise<string[]> => {\n // Super admin has all permissions\n if (superAdminContext.isSuperAdmin) {\n return ['*']; // All permissions\n }\n\n const targetOrgId = orgId || selectedOrganisation?.id;\n if (!targetOrgId || !user) return [];\n\n try {\n // Use the new RBAC system\n const { getPermissionMap } = await import('../rbac/api');\n \n const scope = {\n organisationId: targetOrgId,\n eventId: user.user_metadata?.eventId || user.app_metadata?.eventId,\n appId: user.user_metadata?.appId || user.app_metadata?.appId,\n };\n\n const permissionMap = await getPermissionMap({\n userId: user.id,\n scope\n });\n \n // Flatten all permissions from all pages\n const allPermissions = Object.entries(permissionMap)\n .filter(([, allowed]) => allowed)\n .map(([permission]) => permission);\n return [...new Set(allPermissions)]; // Remove duplicates\n } catch (error) {\n console.error('[useOrganisationSecurity] Exception getting user permissions:', error);\n return [];\n }\n }, [selectedOrganisation, user, getUserRole, superAdminContext.isSuperAdmin]);\n\n // Log organisation access for audit using the new RBAC audit system\n const logOrganisationAccess = useCallback(async (action: string, details?: any): Promise<void> => {\n if (!user || !selectedOrganisation) return;\n\n try {\n // Use the new RBAC audit system - only if we have a valid organisation ID\n if (selectedOrganisation.id) {\n const { emitAuditEvent } = await import('../rbac/audit');\n \n await emitAuditEvent({\n type: 'permission_check',\n userId: user.id,\n organisationId: selectedOrganisation.id,\n permission: action,\n decision: true, // Assume access was granted if we're logging it\n source: 'api',\n duration_ms: 0, // No actual permission check performed here\n metadata: details || {}\n });\n }\n } catch (error) {\n console.error('[useOrganisationSecurity] Error logging organisation access:', error);\n }\n }, [user, selectedOrganisation]);\n\n // Ensure organisation access (throws if no access)\n const ensureOrganisationAccess = useCallback(async (orgId: string): Promise<void> => {\n const hasAccess = await validateOrganisationAccess(orgId);\n \n if (!hasAccess) {\n const error = new Error(`User does not have access to organisation ${orgId}`) as OrganisationSecurityError;\n error.name = 'OrganisationSecurityError';\n error.code = 'ACCESS_DENIED';\n error.organisationId = orgId;\n error.userId = user?.id;\n throw error;\n }\n }, [validateOrganisationAccess, user]);\n\n // Validate user access (for admin functions)\n const validateUserAccess = useCallback(async (userId: string, orgId: string): Promise<boolean> => {\n if (!supabase) return false;\n\n try {\n // Super admin can validate any user\n if (superAdminContext.isSuperAdmin) {\n return true;\n }\n\n // Regular users can only validate their own access\n if (userId !== user?.id) {\n return false;\n }\n\n return await validateOrganisationAccess(orgId);\n } catch (error) {\n console.error('[useOrganisationSecurity] Exception validating user access:', error);\n return false;\n }\n }, [supabase, superAdminContext.isSuperAdmin, user, validateOrganisationAccess]);\n\n return {\n superAdminContext,\n validateOrganisationAccess,\n hasMinimumRole,\n canAccessChildOrganisations,\n hasPermission,\n getUserPermissions,\n logOrganisationAccess,\n ensureOrganisationAccess,\n validateUserAccess\n };\n}; ","/**\n * @file useOrganisationPermissions Hook\n * @package @jmruthers/pace-core\n * @module Hooks/useOrganisationPermissions\n * @since 0.4.0\n *\n * Hook for managing organisation-specific permissions and role validation.\n * Provides secure access to user's role and permissions within organisations.\n *\n * @example\n * ```tsx\n * function OrganisationComponent() {\n * const { \n * isOrgAdmin, \n * canManageMembers,\n * userRole,\n * hasOrganisationAccess\n * } = useOrganisationPermissions();\n * \n * return (\n * <div>\n * {isOrgAdmin && <AdminPanel />}\n * {canManageMembers && <MemberManagement />}\n * <p>Your role: {userRole}</p>\n * </div>\n * );\n * }\n * \n * // For specific organisation\n * function MultiOrgComponent() {\n * const permissions = useOrganisationPermissions('org-123');\n * \n * if (!permissions.hasOrganisationAccess) {\n * return <div>No access to this organisation</div>;\n * }\n * \n * return <div>Role in org-123: {permissions.userRole}</div>;\n * }\n * ```\n *\n * @security\n * - Validates user membership in organisation\n * - Provides role-based permission checks\n * - Ensures secure access to organisation data\n * - Real-time permission validation\n */\n\nimport { useMemo } from 'react';\nimport { useOrganisations } from '../providers/OrganisationProvider';\nimport { useOrganisationSecurity } from './useOrganisationSecurity';\nimport type { OrganisationRole, OrganisationPermission } from '../types/organisation';\n\nexport interface UseOrganisationPermissionsReturn {\n /** User's role in the organisation */\n userRole: OrganisationRole | 'no_access';\n \n /** Whether user has organisation admin role */\n isOrgAdmin: boolean;\n \n /** Whether user is a super admin */\n isSuperAdmin: boolean;\n \n /** Whether user can moderate content */\n canModerate: boolean;\n \n /** Whether user can manage members */\n canManageMembers: boolean;\n \n /** Whether user can manage organisation settings */\n canManageSettings: boolean;\n \n /** Whether user can manage events */\n canManageEvents: boolean;\n \n /** Whether user has any admin privileges */\n hasAdminPrivileges: boolean;\n \n /** Whether user has access to the organisation */\n hasOrganisationAccess: boolean;\n \n /** Check if user has specific permission */\n hasPermission: (permission: OrganisationPermission) => boolean;\n \n /** Get all permissions for the user */\n getAllPermissions: () => OrganisationPermission[];\n \n /** Organisation ID being checked */\n organisationId: string;\n}\n\n/**\n * Hook to access organisation-specific permissions and roles\n * \n * @param orgId - Optional organisation ID. Defaults to currently selected organisation\n * @returns Organisation permissions and role information\n */\nexport function useOrganisationPermissions(orgId?: string): UseOrganisationPermissionsReturn {\n const { \n selectedOrganisation, \n getUserRole, \n validateOrganisationAccess,\n ensureOrganisationContext\n } = useOrganisations();\n \n // Get super admin context if available (may not be available in all contexts)\n let superAdminContext: { isSuperAdmin: boolean } = { isSuperAdmin: false };\n try {\n superAdminContext = useOrganisationSecurity().superAdminContext;\n } catch {\n // Not available in this context, default to false\n }\n\n const organisationId = useMemo(() => {\n if (orgId) {\n return orgId;\n }\n try {\n const currentOrg = ensureOrganisationContext();\n return currentOrg.id;\n } catch {\n return '';\n }\n }, [orgId, ensureOrganisationContext]);\n\n const userRole = useMemo(() => {\n if (!organisationId) return 'no_access';\n const role = getUserRole(organisationId);\n // Map to valid OrganisationRole or 'no_access'\n if (role === 'org_admin' || role === 'leader' || role === 'member' || role === 'supporter') {\n return role as OrganisationRole;\n }\n return 'no_access';\n }, [organisationId, getUserRole]);\n\n const hasOrganisationAccess = useMemo(() => {\n if (!organisationId) return false;\n return validateOrganisationAccess(organisationId);\n }, [organisationId, validateOrganisationAccess]);\n\n const permissions = useMemo(() => {\n if (!hasOrganisationAccess || userRole === 'no_access') {\n return {\n isOrgAdmin: false,\n isSuperAdmin: false,\n canModerate: false,\n canManageMembers: false,\n canManageSettings: false,\n canManageEvents: false,\n hasAdminPrivileges: false\n };\n }\n\n const isOrgAdmin = userRole === 'org_admin';\n const isLeader = userRole === 'leader';\n const isMember = userRole === 'member';\n const isSupporter = userRole === 'supporter';\n\n // Super admin status - database backed (user_metadata can be spoofed)\n // Get super admin status from the security hook\n const isSuperAdmin = superAdminContext.isSuperAdmin;\n\n return {\n isOrgAdmin,\n isSuperAdmin,\n canModerate: isSuperAdmin || isOrgAdmin || isLeader,\n canManageMembers: isSuperAdmin || isOrgAdmin || isLeader, // Leaders can manage members\n canManageSettings: isSuperAdmin || isOrgAdmin,\n canManageEvents: isSuperAdmin || isOrgAdmin || isLeader,\n hasAdminPrivileges: isSuperAdmin || isOrgAdmin || isLeader // Leaders have admin privileges\n };\n }, [hasOrganisationAccess, userRole]);\n\n const hasPermission = useMemo(() => {\n return (permission: OrganisationPermission): boolean => {\n if (!hasOrganisationAccess || userRole === 'no_access') {\n return false;\n }\n\n // Super admin has all permissions (org_admin acts as super admin within org)\n if (userRole === 'org_admin' || permission === '*') {\n return true;\n }\n\n // Map permissions to roles using the defined permissions from organisation types\n const rolePermissions: Record<OrganisationRole, OrganisationPermission[]> = {\n supporter: ['view_basic'],\n member: ['view_basic', 'view_details'],\n leader: ['view_basic', 'view_details', 'moderate_content', 'manage_events'],\n org_admin: ['view_basic', 'view_details', 'moderate_content', 'manage_events', 'manage_members', 'manage_settings']\n };\n\n const userPermissions = rolePermissions[userRole as OrganisationRole] || [];\n return userPermissions.includes(permission) || userPermissions.includes('*');\n };\n }, [hasOrganisationAccess, userRole]);\n\n const getAllPermissions = useMemo(() => {\n return (): OrganisationPermission[] => {\n if (!hasOrganisationAccess || userRole === 'no_access') {\n return [];\n }\n\n const rolePermissions: Record<OrganisationRole, OrganisationPermission[]> = {\n supporter: ['view_basic'],\n member: ['view_basic', 'view_details'],\n leader: ['view_basic', 'view_details', 'moderate_content', 'manage_events'],\n org_admin: ['view_basic', 'view_details', 'moderate_content', 'manage_events', 'manage_members', 'manage_settings']\n };\n\n return rolePermissions[userRole as OrganisationRole] || [];\n };\n }, [hasOrganisationAccess, userRole]);\n\n return useMemo(() => ({\n userRole,\n organisationId,\n hasOrganisationAccess,\n hasPermission,\n getAllPermissions,\n ...permissions\n }), [userRole, organisationId, hasOrganisationAccess, hasPermission, getAllPermissions, permissions]);\n} ","/**\n * @file Public Event Hook\n * @package @jmruthers/pace-core\n * @module Hooks/Public\n * @since 1.0.0\n *\n * A React hook for accessing public event data without authentication.\n * Provides event information by event_code for public pages.\n *\n * Features:\n * - No authentication required\n * - Caching for performance\n * - Error handling and loading states\n * - TypeScript support\n * - Automatic refetch capabilities\n *\n * @example\n * ```tsx\n * import { usePublicEvent } from '@jmruthers/pace-core';\n *\n * function PublicEventPage() {\n * const { eventCode } = usePublicRouteParams();\n * const { event, isLoading, error, refetch } = usePublicEvent(eventCode);\n *\n * if (isLoading) return <div>Loading event...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * if (!event) return <div>Event not found</div>;\n *\n * return (\n * <div>\n * <h1>{event.event_name}</h1>\n * <p>Date: {event.event_date}</p>\n * <p>Venue: {event.event_venue}</p>\n * </div>\n * );\n * }\n * ```\n *\n * @accessibility\n * - No direct accessibility concerns (hook)\n * - Enables accessible public event display\n * - Supports screen reader friendly loading states\n *\n * @security\n * - Only returns public-safe event data\n * - Validates event_code before querying\n * - No sensitive information exposed\n * - Rate limiting applied at database level\n *\n * @performance\n * - Built-in caching with TTL\n * - Minimal re-renders with stable references\n * - Lazy loading support\n * - Error boundary integration\n *\n * @dependencies\n * - React 18+ - Hooks and effects\n * - @supabase/supabase-js - Database integration\n * - Event types - Type definitions\n */\n\nimport { useState, useEffect, useCallback, useMemo } from 'react';\nimport { createClient } from '@supabase/supabase-js';\nimport type { Event } from '../../types/unified';\nimport type { Database } from '../../types/database';\nimport { usePublicPageContext } from '../../components/PublicLayout/PublicPageProvider';\n\n// Simple in-memory cache for public data\nconst publicDataCache = new Map<string, { data: any; timestamp: number; ttl: number }>();\n\nexport interface UsePublicEventReturn {\n /** The event data, null if not loaded or not found */\n event: Event | null;\n /** Whether the data is currently loading */\n isLoading: boolean;\n /** Any error that occurred during loading */\n error: Error | null;\n /** Function to manually refetch the data */\n refetch: () => Promise<void>;\n}\n\nexport interface UsePublicEventOptions {\n /** Cache TTL in milliseconds (default: 5 minutes) */\n cacheTtl?: number;\n /** Whether to enable caching (default: true) */\n enableCache?: boolean;\n}\n\n/**\n * Hook for accessing public event data by event_code\n * \n * This hook provides access to public event information without requiring\n * authentication. It includes caching, error handling, and loading states.\n * \n * @param eventCode - The event code to look up\n * @param options - Configuration options for caching and behavior\n * @returns Object containing event data, loading state, error, and refetch function\n */\nexport function usePublicEvent(\n eventCode: string,\n options: UsePublicEventOptions = {}\n): UsePublicEventReturn {\n const {\n cacheTtl = 5 * 60 * 1000, // 5 minutes\n enableCache = true\n } = options;\n\n const [event, setEvent] = useState<Event | null>(null);\n const [isLoading, setIsLoading] = useState<boolean>(true);\n const [error, setError] = useState<Error | null>(null);\n\n // Get environment variables from public page context or fallback to direct access\n let environment: { supabaseUrl: string | null; supabaseKey: string | null };\n \n try {\n environment = usePublicPageContext().environment;\n } catch {\n // Fallback to direct environment variable access if not in PublicPageProvider\n environment = {\n supabaseUrl: (import.meta as any).env?.VITE_SUPABASE_URL || (import.meta as any).env?.NEXT_PUBLIC_SUPABASE_URL || null,\n supabaseKey: (import.meta as any).env?.VITE_SUPABASE_ANON_KEY || (import.meta as any).env?.NEXT_PUBLIC_SUPABASE_ANON_KEY || null\n };\n }\n \n // Create a simple Supabase client for public access\n const supabase = useMemo(() => {\n if (typeof window === 'undefined') return null;\n \n if (!environment.supabaseUrl || !environment.supabaseKey) {\n console.warn('[usePublicEvent] Missing Supabase environment variables. Please ensure VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY are set in your environment.');\n return null;\n }\n\n return createClient<Database>(environment.supabaseUrl, environment.supabaseKey);\n }, [environment.supabaseUrl, environment.supabaseKey]);\n\n // Helper function to try refreshing schema cache\n const refreshSchemaCache = useCallback(async () => {\n try {\n // Try to trigger a schema refresh by querying a system table\n await (supabase as any).from('information_schema.routines').select('routine_name').limit(1);\n } catch (error) {\n // Ignore errors, this is just an attempt to refresh cache\n console.debug('[usePublicEvent] Schema cache refresh attempt failed:', error);\n }\n }, [supabase]);\n\n const fetchEvent = useCallback(async (): Promise<void> => {\n if (!eventCode || !supabase) {\n setError(new Error('Invalid event code or Supabase client not available'));\n setIsLoading(false);\n return;\n }\n\n // Check cache first\n const cacheKey = `public_event_${eventCode}`;\n if (enableCache) {\n const cached = publicDataCache.get(cacheKey);\n if (cached && Date.now() - cached.timestamp < cached.ttl) {\n setEvent(cached.data);\n setIsLoading(false);\n setError(null);\n return;\n }\n }\n\n try {\n setIsLoading(true);\n setError(null);\n\n let eventData: any = null;\n\n try {\n // Try to call the public event RPC function first\n const response = await (supabase as any).rpc('get_public_event_by_code', {\n event_code_param: eventCode\n });\n \n const data = response?.data;\n const rpcError = response?.error;\n\n if (rpcError) {\n // If RPC function doesn't exist or schema cache issue, try refresh first, then fallback\n if (rpcError.message?.includes('Could not find the function') || \n rpcError.message?.includes('does not exist') ||\n rpcError.message?.includes('schema cache')) {\n console.warn('[usePublicEvent] RPC function not found or schema cache issue, attempting refresh:', rpcError.message);\n \n // Try to refresh schema cache first\n await refreshSchemaCache();\n \n // Try RPC call one more time after refresh\n try {\n const retryResponse = await (supabase as any).rpc('get_public_event_by_code', {\n event_code_param: eventCode\n });\n \n const retryData = retryResponse?.data;\n const retryError = retryResponse?.error;\n \n if (!retryError && retryData && retryData.length > 0) {\n eventData = retryData[0];\n } else {\n throw new Error('RPC still failing after cache refresh');\n }\n } catch (retryError) {\n console.warn('[usePublicEvent] RPC still failing after cache refresh, falling back to direct table access');\n \n // Fallback: Direct table access with public RLS policy\n const tableResponse2 = await (supabase as any)\n .from('event')\n .select(`\n event_id,\n event_name,\n event_date,\n event_venue,\n event_participants,\n event_colours,\n organisation_id,\n event_days,\n event_typicalunit,\n event_rounddown,\n event_youthmultiplier,\n event_catering_email,\n event_news,\n event_billing,\n event_email\n `)\n .eq('event_code', eventCode)\n .eq('is_visible', true)\n .not('organisation_id', 'is', null)\n .limit(1)\n .single();\n\n const tableData = tableResponse2?.data;\n const tableError = tableResponse2?.error;\n\n if (tableError) {\n throw new Error(tableError?.message || 'Failed to fetch event from table');\n }\n\n if (!tableData) {\n setEvent(null);\n setError(new Error('Event not found'));\n return;\n }\n\n // Get event logo from file_references\n const logoResponse = await (supabase as any)\n .from('file_references')\n .select('file_path')\n .eq('table_name', 'event')\n .eq('record_id', tableData.event_id)\n .eq('is_public', true)\n .eq('file_metadata->>category', 'event_logos')\n .limit(1)\n .single();\n \n const logoData = logoResponse?.data;\n\n eventData = {\n ...tableData,\n event_logo: logoData?.file_path || null\n };\n }\n } else {\n // For RPC errors that aren't schema cache issues, throw immediately without fallback\n const errorMessage = rpcError?.message || rpcError?.toString() || 'Failed to fetch event';\n setEvent(null);\n setError(new Error(errorMessage));\n setIsLoading(false);\n return;\n }\n } else {\n if (!data || data.length === 0 || !data[0]) {\n setEvent(null);\n setError(new Error('Event not found'));\n return;\n }\n eventData = data[0];\n }\n } catch (rpcError) {\n // If RPC call fails for any reason (including schema cache issues), try direct table access\n console.warn('[usePublicEvent] RPC call failed, falling back to direct table access:', rpcError);\n \n const tableResponse = await (supabase as any)\n .from('event')\n .select(`\n event_id,\n event_name,\n event_date,\n event_venue,\n event_participants,\n event_colours,\n organisation_id,\n event_days,\n event_typicalunit,\n event_rounddown,\n event_youthmultiplier,\n event_catering_email,\n event_news,\n event_billing,\n event_email\n `)\n .eq('event_code', eventCode)\n .eq('is_visible', true)\n .not('organisation_id', 'is', null)\n .limit(1)\n .single();\n\n const tableData = tableResponse?.data;\n const tableError = tableResponse?.error;\n\n if (tableError) {\n throw new Error(tableError?.message || 'Failed to fetch event from table');\n }\n\n if (!tableData) {\n setEvent(null);\n setError(new Error('Event not found'));\n return;\n }\n\n // Get event logo from file_references\n const logoResponse = await (supabase as any)\n .from('file_references')\n .select('file_path')\n .eq('table_name', 'event')\n .eq('record_id', tableData.event_id)\n .eq('is_public', true)\n .eq('file_metadata->>category', 'event_logos')\n .limit(1)\n .single();\n \n const logoData = logoResponse?.data;\n\n eventData = {\n ...tableData,\n event_logo: logoData?.file_path || null\n };\n }\n \n // Transform to Event type\n const transformedEvent: Event = {\n id: eventData.event_id,\n event_id: eventData.event_id,\n event_name: eventData.event_name,\n event_code: eventCode,\n event_date: eventData.event_date,\n event_venue: eventData.event_venue,\n event_participants: eventData.event_participants,\n event_logo: eventData.event_logo,\n event_colours: eventData.event_colours,\n organisation_id: eventData.organisation_id,\n is_visible: true,\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n // Legacy compatibility\n name: eventData.event_name,\n start_date: eventData.event_date\n };\n\n setEvent(transformedEvent);\n\n // Cache the result\n if (enableCache) {\n publicDataCache.set(cacheKey, {\n data: transformedEvent,\n timestamp: Date.now(),\n ttl: cacheTtl\n });\n }\n\n } catch (err) {\n console.error('[usePublicEvent] Error fetching event:', err);\n const error = err instanceof Error ? err : new Error('Unknown error occurred');\n setError(error);\n setEvent(null);\n } finally {\n setIsLoading(false);\n }\n }, [eventCode, supabase, cacheTtl, enableCache]);\n\n // Fetch event when eventCode changes\n useEffect(() => {\n fetchEvent();\n }, [fetchEvent]);\n\n const refetch = useCallback(async (): Promise<void> => {\n // Clear cache for this event\n if (enableCache) {\n const cacheKey = `public_event_${eventCode}`;\n publicDataCache.delete(cacheKey);\n }\n await fetchEvent();\n }, [fetchEvent, eventCode, enableCache]);\n\n return {\n event,\n isLoading,\n error,\n refetch\n };\n}\n\n/**\n * Clear all cached public event data\n * Useful for testing or when you need to force refresh all data\n */\nexport function clearPublicEventCache(): void {\n for (const [key] of publicDataCache) {\n if (key.startsWith('public_event_')) {\n publicDataCache.delete(key);\n }\n }\n}\n\n/**\n * Get cache statistics for debugging\n */\nexport function getPublicEventCacheStats(): { size: number; keys: string[] } {\n const keys = Array.from(publicDataCache.keys()).filter(key => key.startsWith('public_event_'));\n return {\n size: keys.length,\n keys\n };\n}\n","/**\n * @file Public Route Params Hook\n * @package @jmruthers/pace-core\n * @module Hooks/Public\n * @since 1.0.0\n *\n * A React hook for extracting and validating public route parameters.\n * Provides event code extraction and validation for public pages.\n *\n * Features:\n * - URL parameter extraction\n * - Event code validation\n * - TypeScript support\n * - Error handling\n * - Route pattern support\n *\n * @example\n * ```tsx\n * import { usePublicRouteParams } from '@jmruthers/pace-core';\n *\n * function PublicEventPage() {\n * const { eventCode, eventId, event, error, isLoading } = usePublicRouteParams();\n *\n * if (isLoading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * if (!event) return <div>Event not found</div>;\n *\n * return (\n * <div>\n * <h1>{event.event_name}</h1>\n * <p>Event Code: {eventCode}</p>\n * </div>\n * );\n * }\n * ```\n *\n * @accessibility\n * - No direct accessibility concerns (hook)\n * - Enables accessible route parameter handling\n * - Supports screen reader friendly error states\n *\n * @security\n * - Validates event codes before processing\n * - Sanitizes URL parameters\n * - No sensitive information exposed\n * - Rate limiting applied at route level\n *\n * @performance\n * - Minimal re-renders with stable references\n * - Efficient parameter extraction\n * - Caching integration\n *\n * @dependencies\n * - React 18+ - Hooks and effects\n * - React Router - URL parameter extraction\n * - Event types - Type definitions\n */\n\nimport { useState, useEffect, useCallback, useMemo } from 'react';\nimport { useParams, useLocation } from 'react-router-dom';\nimport type { Event } from '../../types/unified';\nimport { usePublicEvent } from './usePublicEvent';\n\nexport interface UsePublicRouteParamsReturn {\n /** The event code from the URL */\n eventCode: string | null;\n /** The event ID (resolved from event code) */\n eventId: string | null;\n /** The full event object */\n event: Event | null;\n /** Whether the route parameters are being processed */\n isLoading: boolean;\n /** Any error that occurred during processing */\n error: Error | null;\n /** Function to manually refetch the event data */\n refetch: () => Promise<void>;\n}\n\ninterface UsePublicRouteParamsOptions {\n /** Whether to automatically fetch event data (default: true) */\n fetchEventData?: boolean;\n /** Custom event code parameter name (default: 'eventCode') */\n eventCodeParam?: string;\n /** Whether to validate event code format (default: true) */\n validateEventCode?: boolean;\n}\n\n/**\n * Validate event code format\n * Event codes should be alphanumeric with optional hyphens/underscores in the middle\n */\nfunction validateEventCodeFormat(eventCode: string): boolean {\n if (!eventCode || typeof eventCode !== 'string') return false;\n \n // Allow alphanumeric characters, hyphens, and underscores\n // Length between 3 and 50 characters\n // Must not start or end with hyphen/underscore\n const eventCodeRegex = /^[a-zA-Z0-9][a-zA-Z0-9_-]{1,48}[a-zA-Z0-9]$/;\n const matchesFormat = eventCodeRegex.test(eventCode);\n \n if (!matchesFormat) return false;\n \n // Additional check: no consecutive hyphens or underscores\n if (eventCode.includes('--') || eventCode.includes('__') || eventCode.includes('-_') || eventCode.includes('_-')) {\n return false;\n }\n \n return true;\n}\n\n/**\n * Hook for extracting and validating public route parameters\n * \n * This hook extracts event codes from URL parameters and optionally\n * fetches the corresponding event data. It provides validation and\n * error handling for public routes.\n * \n * @param options - Configuration options for behavior\n * @returns Object containing route parameters, event data, loading state, error, and refetch function\n */\nexport function usePublicRouteParams(\n options: UsePublicRouteParamsOptions = {}\n): UsePublicRouteParamsReturn {\n const {\n fetchEventData = true,\n eventCodeParam = 'eventCode',\n validateEventCode = true\n } = options;\n\n const params = useParams();\n const location = useLocation();\n \n const [error, setError] = useState<Error | null>(null);\n\n // Extract event code from URL parameters\n const eventCode = useMemo(() => {\n const code = params[eventCodeParam] as string;\n \n if (!code) {\n // Don't set error immediately - let the component handle missing eventCode gracefully\n return null;\n }\n\n // Validate event code format if requested\n if (validateEventCode && !validateEventCodeFormat(code)) {\n setError(new Error(`Invalid event code format: ${code}`));\n return null;\n }\n\n setError(null);\n return code;\n }, [params, eventCodeParam, validateEventCode]);\n\n // Use the public event hook to fetch event data\n const {\n event,\n isLoading: eventLoading,\n error: eventError,\n refetch: refetchEvent\n } = usePublicEvent(eventCode || '', {\n enableCache: true,\n cacheTtl: 5 * 60 * 1000 // 5 minutes\n });\n\n // Determine if we should show loading state\n const isLoading = useMemo(() => {\n if (!fetchEventData) return false;\n return eventLoading;\n }, [fetchEventData, eventLoading]);\n\n // Determine the final error state\n const finalError = useMemo(() => {\n if (error) return error;\n if (eventError) return eventError;\n return null;\n }, [error, eventError]);\n\n // Extract event ID from event data\n const eventId = useMemo(() => {\n if (!event) return null;\n return event.event_id || event.id;\n }, [event]);\n\n // Refetch function\n const refetch = useCallback(async (): Promise<void> => {\n if (!fetchEventData) return;\n await refetchEvent();\n }, [fetchEventData, refetchEvent]);\n\n // Log route access for debugging\n useEffect(() => {\n if (eventCode && event) {\n console.log('[usePublicRouteParams] Public route accessed:', {\n eventCode,\n eventId: event.event_id,\n eventName: event.event_name,\n path: location.pathname\n });\n }\n }, [eventCode, event, location.pathname]);\n\n return {\n eventCode,\n eventId,\n event: fetchEventData ? event : null,\n isLoading,\n error: finalError,\n refetch\n };\n}\n\n/**\n * Hook for extracting just the event code without fetching event data\n * Useful when you only need the event code and will fetch data separately\n */\nexport function usePublicEventCode(\n eventCodeParam: string = 'eventCode'\n): { eventCode: string | null; error: Error | null } {\n const params = useParams();\n \n const eventCode = useMemo(() => {\n const code = params[eventCodeParam] as string;\n \n if (!code) {\n return null;\n }\n\n // Validate event code format\n if (!validateEventCodeFormat(code)) {\n return null;\n }\n\n return code;\n }, [params, eventCodeParam]);\n\n const error = useMemo(() => {\n if (!eventCode) {\n return new Error(`Event code parameter '${eventCodeParam}' not found or invalid`);\n }\n return null;\n }, [eventCode, eventCodeParam]);\n\n return {\n eventCode,\n error\n };\n}\n\n/**\n * Utility function to generate public route paths\n */\nexport function generatePublicRoutePath(\n eventCode: string,\n pageName: string = 'index'\n): string {\n if (!eventCode || !validateEventCodeFormat(eventCode)) {\n throw new Error('Invalid event code for route generation');\n }\n \n return `/public/event/${eventCode}/${pageName}`;\n}\n\n/**\n * Utility function to extract event code from a public route path\n */\nexport function extractEventCodeFromPath(path: string): string | null {\n const match = path.match(/^\\/public\\/event\\/([a-zA-Z0-9_-]{3,50})(?:\\/.*)?$/);\n return match ? match[1] : null;\n}\n"],"mappings":"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","names":["useMemo","useMemo","useState","useEffect","useCallback","useMemo","useState","useMemo","useCallback","error","useEffect","useState","useEffect","useCallback","useMemo","useState","useMemo","useCallback","useEffect"]}
@@ -3,22 +3,22 @@ import {
3
3
  useAccessLevel,
4
4
  useCan,
5
5
  useMultiplePermissions
6
- } from "./chunk-ZPXWJA4H.js";
6
+ } from "./chunk-PHDAXDHB.js";
7
7
  import {
8
8
  OrganisationContextRequiredError,
9
9
  RBACCache,
10
10
  getRBACLogger,
11
11
  rbacCache
12
- } from "./chunk-QKIVSZ2O.js";
12
+ } from "./chunk-WP5I5GLN.js";
13
13
  import {
14
14
  useSecureDataAccess
15
- } from "./chunk-NEONKMTU.js";
15
+ } from "./chunk-XN2LYHDI.js";
16
16
  import {
17
17
  init_UnifiedAuthProvider
18
- } from "./chunk-7H75SHXZ.js";
18
+ } from "./chunk-VN3OOE35.js";
19
19
  import {
20
20
  useUnifiedAuth
21
- } from "./chunk-OO3V7W4H.js";
21
+ } from "./chunk-KA3PSVNV.js";
22
22
  import {
23
23
  getCurrentAppName
24
24
  } from "./chunk-JCQZ6LA7.js";
@@ -1539,7 +1539,7 @@ function withPermissionGuard(config, handler) {
1539
1539
  if (!userId || !organisationId) {
1540
1540
  throw new Error("User context required for permission check");
1541
1541
  }
1542
- const { isPermitted: isPermitted2 } = await import("./api-PKU4PUBO.js");
1542
+ const { isPermitted: isPermitted2 } = await import("./api-TNIBJWLM.js");
1543
1543
  const hasPermission2 = await isPermitted2({
1544
1544
  userId,
1545
1545
  scope: { organisationId, eventId, appId },
@@ -1562,7 +1562,7 @@ function withAccessLevelGuard(minLevel, handler) {
1562
1562
  if (!userId || !organisationId) {
1563
1563
  throw new Error("User context required for access level check");
1564
1564
  }
1565
- const { getAccessLevel: getAccessLevel2 } = await import("./api-PKU4PUBO.js");
1565
+ const { getAccessLevel: getAccessLevel2 } = await import("./api-TNIBJWLM.js");
1566
1566
  const accessLevel = await getAccessLevel2({
1567
1567
  userId,
1568
1568
  scope: { organisationId, eventId, appId }
@@ -1587,11 +1587,11 @@ function withRoleGuard(config, handler) {
1587
1587
  throw new Error("User context required for role check");
1588
1588
  }
1589
1589
  if (config.globalRoles && config.globalRoles.length > 0) {
1590
- const { isSuperAdmin } = await import("./api-PKU4PUBO.js");
1590
+ const { isSuperAdmin } = await import("./api-TNIBJWLM.js");
1591
1591
  const isSuper = await isSuperAdmin(userId);
1592
1592
  if (isSuper) {
1593
1593
  if (organisationId) {
1594
- const { emitAuditEvent: emitAuditEvent2 } = await import("./audit-H4YJJF7R.js");
1594
+ const { emitAuditEvent: emitAuditEvent2 } = await import("./audit-T36HM7IM.js");
1595
1595
  await emitAuditEvent2({
1596
1596
  type: "permission_check",
1597
1597
  userId,
@@ -1613,21 +1613,21 @@ function withRoleGuard(config, handler) {
1613
1613
  }
1614
1614
  }
1615
1615
  if (config.organisationRoles && config.organisationRoles.length > 0) {
1616
- const { isOrganisationAdmin } = await import("./api-PKU4PUBO.js");
1616
+ const { isOrganisationAdmin } = await import("./api-TNIBJWLM.js");
1617
1617
  const isOrgAdmin = await isOrganisationAdmin(userId, organisationId);
1618
1618
  if (!isOrgAdmin && config.requireAll !== false) {
1619
1619
  throw new Error(`Organisation admin role required`);
1620
1620
  }
1621
1621
  }
1622
1622
  if (config.eventAppRoles && config.eventAppRoles.length > 0 && eventId && appId) {
1623
- const { isEventAdmin } = await import("./api-PKU4PUBO.js");
1623
+ const { isEventAdmin } = await import("./api-TNIBJWLM.js");
1624
1624
  const isEventAdminUser = await isEventAdmin(userId, { organisationId, eventId, appId });
1625
1625
  if (!isEventAdminUser && config.requireAll !== false) {
1626
1626
  throw new Error(`Event admin role required`);
1627
1627
  }
1628
1628
  }
1629
1629
  if (organisationId) {
1630
- const { emitAuditEvent: emitAuditEvent2 } = await import("./audit-H4YJJF7R.js");
1630
+ const { emitAuditEvent: emitAuditEvent2 } = await import("./audit-T36HM7IM.js");
1631
1631
  await emitAuditEvent2({
1632
1632
  type: "permission_check",
1633
1633
  userId,
@@ -1660,7 +1660,7 @@ function createRBACMiddleware(config) {
1660
1660
  );
1661
1661
  if (protectedRoute) {
1662
1662
  try {
1663
- const { isPermitted: isPermitted2 } = await import("./api-PKU4PUBO.js");
1663
+ const { isPermitted: isPermitted2 } = await import("./api-TNIBJWLM.js");
1664
1664
  const hasPermission2 = await isPermitted2({
1665
1665
  userId,
1666
1666
  scope: { organisationId },
@@ -1687,7 +1687,7 @@ function createRBACExpressMiddleware(config) {
1687
1687
  return res.status(401).json({ error: "User context required" });
1688
1688
  }
1689
1689
  try {
1690
- const { isPermitted: isPermitted2 } = await import("./api-PKU4PUBO.js");
1690
+ const { isPermitted: isPermitted2 } = await import("./api-TNIBJWLM.js");
1691
1691
  const hasPermission2 = await isPermitted2({
1692
1692
  userId,
1693
1693
  scope: { organisationId, eventId, appId },
@@ -1860,4 +1860,4 @@ export {
1860
1860
  getPermissionsForRole,
1861
1861
  ALL_PERMISSIONS
1862
1862
  };
1863
- //# sourceMappingURL=chunk-HKWQN44G.js.map
1863
+ //# sourceMappingURL=chunk-IZXS7RZK.js.map