@revealui/core 0.2.0 → 0.3.0

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 (341) hide show
  1. package/README.md +137 -30
  2. package/dist/api/compression.d.ts.map +1 -1
  3. package/dist/api/payload-optimization.d.ts.map +1 -1
  4. package/dist/api/rate-limit.d.ts +30 -29
  5. package/dist/api/rate-limit.d.ts.map +1 -1
  6. package/dist/api/rate-limit.js +79 -4
  7. package/dist/api/response-cache.d.ts.map +1 -1
  8. package/dist/api/response-cache.js +1 -1
  9. package/dist/api/rest.d.ts.map +1 -1
  10. package/dist/api/rest.js +5 -4
  11. package/dist/auth/access.d.ts.map +1 -1
  12. package/dist/auth/index.d.ts.map +1 -1
  13. package/dist/cache/query-cache.d.ts +12 -10
  14. package/dist/cache/query-cache.d.ts.map +1 -1
  15. package/dist/cache/query-cache.js +38 -42
  16. package/dist/caching/app-cache.d.ts +5 -0
  17. package/dist/caching/app-cache.d.ts.map +1 -1
  18. package/dist/caching/app-cache.js +9 -1
  19. package/dist/caching/cdn-config.d.ts +2 -2
  20. package/dist/caching/cdn-config.d.ts.map +1 -1
  21. package/dist/caching/cdn-config.js +5 -15
  22. package/dist/caching/edge-cache.d.ts +1 -1
  23. package/dist/caching/edge-cache.d.ts.map +1 -1
  24. package/dist/caching/edge-cache.js +44 -11
  25. package/dist/caching/index.d.ts +6 -0
  26. package/dist/caching/index.d.ts.map +1 -0
  27. package/dist/caching/index.js +5 -0
  28. package/dist/caching/service-worker.d.ts +10 -18
  29. package/dist/caching/service-worker.d.ts.map +1 -1
  30. package/dist/caching/service-worker.js +5 -4
  31. package/dist/client/admin/RichText.d.ts +1 -1
  32. package/dist/client/admin/RichText.d.ts.map +1 -1
  33. package/dist/client/admin/components/AdminDashboard.d.ts.map +1 -1
  34. package/dist/client/admin/components/AdminDashboard.js +178 -205
  35. package/dist/client/admin/components/CollectionList.d.ts.map +1 -1
  36. package/dist/client/admin/components/DocumentForm.d.ts.map +1 -1
  37. package/dist/client/admin/components/DocumentForm.js +130 -6
  38. package/dist/client/admin/components/GlobalForm.d.ts.map +1 -1
  39. package/dist/client/admin/context/ServerFunctionContext.d.ts +8 -0
  40. package/dist/client/admin/context/ServerFunctionContext.d.ts.map +1 -0
  41. package/dist/client/admin/context/ServerFunctionContext.js +15 -0
  42. package/dist/client/admin/i18n/en.d.ts.map +1 -1
  43. package/dist/client/admin/index.d.ts +1 -0
  44. package/dist/client/admin/index.d.ts.map +1 -1
  45. package/dist/client/admin/index.js +1 -0
  46. package/dist/client/admin/layout.d.ts +1 -1
  47. package/dist/client/admin/layout.d.ts.map +1 -1
  48. package/dist/client/admin/layout.js +3 -2
  49. package/dist/client/admin/page.d.ts.map +1 -1
  50. package/dist/client/admin/utils/apiClient.d.ts.map +1 -1
  51. package/dist/client/admin/utils/apiClient.js +0 -4
  52. package/dist/client/admin/utils/auth.d.ts +0 -4
  53. package/dist/client/admin/utils/auth.d.ts.map +1 -1
  54. package/dist/client/admin/utils/auth.js +0 -6
  55. package/dist/client/admin/utils/index.d.ts +0 -1
  56. package/dist/client/admin/utils/index.d.ts.map +1 -1
  57. package/dist/client/admin/utils/index.js +0 -1
  58. package/dist/client/admin/utils/serializeConfig.d.ts.map +1 -1
  59. package/dist/client/hooks.d.ts.map +1 -1
  60. package/dist/client/index.d.ts +0 -1
  61. package/dist/client/index.d.ts.map +1 -1
  62. package/dist/client/index.js +0 -2
  63. package/dist/client/richtext/RichTextEditor.d.ts.map +1 -1
  64. package/dist/client/richtext/components/ImageNodeComponent.d.ts.map +1 -1
  65. package/dist/client/richtext/components/ImageNodeComponent.js +0 -1
  66. package/dist/client/richtext/components/ImageUploadButton.d.ts +2 -0
  67. package/dist/client/richtext/components/ImageUploadButton.d.ts.map +1 -1
  68. package/dist/client/richtext/components/ImageUploadButton.js +30 -15
  69. package/dist/client/richtext/index.d.ts.map +1 -1
  70. package/dist/client/richtext/nodes/DecoratorBlockNode.d.ts.map +1 -1
  71. package/dist/client/richtext/nodes/ImageNode.d.ts.map +1 -1
  72. package/dist/client/richtext/plugins/CollaborationPlugin.d.ts.map +1 -1
  73. package/dist/client/richtext/plugins/CursorsOverlayPlugin.d.ts.map +1 -1
  74. package/dist/client/richtext/plugins/FloatingToolbarPlugin.d.ts.map +1 -1
  75. package/dist/client/richtext/plugins/ImagePlugin.d.ts.map +1 -1
  76. package/dist/client/richtext/plugins/ToolbarPlugin.d.ts.map +1 -1
  77. package/dist/client/ui/index.d.ts.map +1 -1
  78. package/dist/client/ui/index.js +1 -1
  79. package/dist/collections/CollectionOperations.d.ts +7 -7
  80. package/dist/collections/CollectionOperations.d.ts.map +1 -1
  81. package/dist/collections/CollectionOperations.js +15 -1
  82. package/dist/collections/hooks.d.ts.map +1 -1
  83. package/dist/collections/index.d.ts.map +1 -1
  84. package/dist/collections/operations/create.d.ts +2 -4
  85. package/dist/collections/operations/create.d.ts.map +1 -1
  86. package/dist/collections/operations/create.js +9 -7
  87. package/dist/collections/operations/createMany.d.ts +12 -0
  88. package/dist/collections/operations/createMany.d.ts.map +1 -0
  89. package/dist/collections/operations/createMany.js +43 -0
  90. package/dist/collections/operations/delete.d.ts +1 -1
  91. package/dist/collections/operations/delete.d.ts.map +1 -1
  92. package/dist/collections/operations/delete.js +31 -2
  93. package/dist/collections/operations/deleteMany.d.ts +11 -0
  94. package/dist/collections/operations/deleteMany.d.ts.map +1 -0
  95. package/dist/collections/operations/deleteMany.js +50 -0
  96. package/dist/collections/operations/fieldHooks.d.ts +2 -2
  97. package/dist/collections/operations/fieldHooks.d.ts.map +1 -1
  98. package/dist/collections/operations/fieldHooks.js +4 -4
  99. package/dist/collections/operations/find.d.ts +2 -4
  100. package/dist/collections/operations/find.d.ts.map +1 -1
  101. package/dist/collections/operations/find.js +115 -8
  102. package/dist/collections/operations/findById.d.ts +3 -4
  103. package/dist/collections/operations/findById.d.ts.map +1 -1
  104. package/dist/collections/operations/findById.js +53 -1
  105. package/dist/collections/operations/sqlAdapter.d.ts +23 -0
  106. package/dist/collections/operations/sqlAdapter.d.ts.map +1 -0
  107. package/dist/collections/operations/sqlAdapter.js +76 -0
  108. package/dist/collections/operations/update.d.ts +3 -5
  109. package/dist/collections/operations/update.d.ts.map +1 -1
  110. package/dist/collections/operations/update.js +103 -11
  111. package/dist/collections/operations/updateMany.d.ts +11 -0
  112. package/dist/collections/operations/updateMany.d.ts.map +1 -0
  113. package/dist/collections/operations/updateMany.js +52 -0
  114. package/dist/collections/registry.d.ts +12 -0
  115. package/dist/collections/registry.d.ts.map +1 -0
  116. package/dist/collections/registry.js +38 -0
  117. package/dist/config/index.d.ts.map +1 -1
  118. package/dist/config/runtime.d.ts.map +1 -1
  119. package/dist/config/utils.d.ts +0 -10
  120. package/dist/config/utils.d.ts.map +1 -1
  121. package/dist/config/utils.js +18 -17
  122. package/dist/database/index.d.ts +3 -0
  123. package/dist/database/index.d.ts.map +1 -1
  124. package/dist/database/index.js +1 -5
  125. package/dist/database/safe-parse.d.ts +26 -0
  126. package/dist/database/safe-parse.d.ts.map +1 -0
  127. package/dist/database/safe-parse.js +42 -0
  128. package/dist/database/ssl-config.d.ts.map +1 -1
  129. package/dist/database/type-adapter.d.ts.map +1 -1
  130. package/dist/database/universal-postgres.d.ts.map +1 -1
  131. package/dist/database/universal-postgres.js +18 -13
  132. package/dist/dataloader.d.ts.map +1 -1
  133. package/dist/dataloader.js +16 -2
  134. package/dist/error-handling/circuit-breaker.d.ts +1 -1
  135. package/dist/error-handling/circuit-breaker.d.ts.map +1 -1
  136. package/dist/error-handling/circuit-breaker.js +11 -3
  137. package/dist/error-handling/error-boundary.d.ts.map +1 -1
  138. package/dist/error-handling/error-reporter.d.ts +6 -5
  139. package/dist/error-handling/error-reporter.d.ts.map +1 -1
  140. package/dist/error-handling/error-reporter.js +26 -41
  141. package/dist/error-handling/fallback-components.d.ts.map +1 -1
  142. package/dist/error-handling/fallback-components.js +1 -1
  143. package/dist/error-handling/index.d.ts +3 -5
  144. package/dist/error-handling/index.d.ts.map +1 -1
  145. package/dist/error-handling/index.js +2 -5
  146. package/dist/error-handling/retry.d.ts.map +1 -1
  147. package/dist/error-handling/retry.js +13 -8
  148. package/dist/factories/builders.d.ts.map +1 -1
  149. package/dist/factories/index.d.ts.map +1 -1
  150. package/dist/features.d.ts +5 -5
  151. package/dist/features.d.ts.map +1 -1
  152. package/dist/features.js +6 -5
  153. package/dist/fieldTraversal.d.ts.map +1 -1
  154. package/dist/fields/config/types.d.ts.map +1 -1
  155. package/dist/fields/getDefaultValue.d.ts.map +1 -1
  156. package/dist/fields/getFieldPaths.d.ts.map +1 -1
  157. package/dist/fields/hooks/afterRead/index.d.ts.map +1 -1
  158. package/dist/fields/hooks/afterRead/promise.d.ts.map +1 -1
  159. package/dist/fields/hooks/afterRead/traverseFields.d.ts.map +1 -1
  160. package/dist/generated/types/cms.d.ts.map +1 -1
  161. package/dist/generated/types/cms.js +0 -1
  162. package/dist/generated/types/index.d.ts +0 -3
  163. package/dist/generated/types/index.d.ts.map +1 -1
  164. package/dist/generated/types/index.js +0 -7
  165. package/dist/generated/types/neon.d.ts.map +1 -1
  166. package/dist/generated/types/neon.js +4 -2
  167. package/dist/globals/GlobalOperations.d.ts.map +1 -1
  168. package/dist/globals/GlobalOperations.js +4 -2
  169. package/dist/globals/index.d.ts.map +1 -1
  170. package/dist/index.d.ts +4 -4
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js +4 -6
  173. package/dist/instance/RevealUIInstance.d.ts.map +1 -1
  174. package/dist/instance/RevealUIInstance.js +50 -69
  175. package/dist/instance/index.d.ts.map +1 -1
  176. package/dist/instance/logger.d.ts.map +1 -1
  177. package/dist/instance/methods/create.d.ts.map +1 -1
  178. package/dist/instance/methods/create.js +4 -4
  179. package/dist/instance/methods/delete.d.ts.map +1 -1
  180. package/dist/instance/methods/delete.js +5 -5
  181. package/dist/instance/methods/find.d.ts.map +1 -1
  182. package/dist/instance/methods/find.js +0 -3
  183. package/dist/instance/methods/findById.d.ts.map +1 -1
  184. package/dist/instance/methods/findById.js +0 -3
  185. package/dist/instance/methods/hooks.d.ts.map +1 -1
  186. package/dist/instance/methods/hooks.js +3 -1
  187. package/dist/instance/methods/update.d.ts.map +1 -1
  188. package/dist/instance/methods/update.js +4 -4
  189. package/dist/jobs/index.d.ts +16 -0
  190. package/dist/jobs/index.d.ts.map +1 -0
  191. package/dist/jobs/index.js +14 -0
  192. package/dist/jobs/queue.d.ts +57 -0
  193. package/dist/jobs/queue.d.ts.map +1 -0
  194. package/dist/jobs/queue.js +134 -0
  195. package/dist/license-encryption.d.ts +21 -0
  196. package/dist/license-encryption.d.ts.map +1 -0
  197. package/dist/license-encryption.js +74 -0
  198. package/dist/license.d.ts +33 -7
  199. package/dist/license.d.ts.map +1 -1
  200. package/dist/license.js +119 -16
  201. package/dist/monitoring/alerts.d.ts.map +1 -1
  202. package/dist/monitoring/cleanup-manager.d.ts.map +1 -1
  203. package/dist/monitoring/health-monitor.d.ts.map +1 -1
  204. package/dist/monitoring/index.d.ts.map +1 -1
  205. package/dist/monitoring/process-registry.d.ts.map +1 -1
  206. package/dist/monitoring/query-monitor.d.ts.map +1 -1
  207. package/dist/monitoring/types.d.ts.map +1 -1
  208. package/dist/monitoring/zombie-detector.d.ts.map +1 -1
  209. package/dist/monitoring/zombie-detector.js +5 -0
  210. package/dist/nextjs/index.d.ts.map +1 -1
  211. package/dist/nextjs/utilities.d.ts.map +1 -1
  212. package/dist/nextjs/withRevealUI.d.ts.map +1 -1
  213. package/dist/observability/alerts.d.ts.map +1 -1
  214. package/dist/observability/alerts.js +1 -2
  215. package/dist/observability/health-check.d.ts +1 -5
  216. package/dist/observability/health-check.d.ts.map +1 -1
  217. package/dist/observability/health-check.js +37 -43
  218. package/dist/observability/index.d.ts.map +1 -1
  219. package/dist/observability/logger.d.ts.map +1 -1
  220. package/dist/observability/logger.js +1 -1
  221. package/dist/observability/metrics.d.ts.map +1 -1
  222. package/dist/observability/tracing.d.ts.map +1 -1
  223. package/dist/observability/tracing.js +0 -1
  224. package/dist/optimization/asset-optimizer.d.ts +6 -2
  225. package/dist/optimization/asset-optimizer.d.ts.map +1 -1
  226. package/dist/optimization/asset-optimizer.js +31 -7
  227. package/dist/optimization/bundle-analyzer.d.ts +1 -1
  228. package/dist/optimization/bundle-analyzer.d.ts.map +1 -1
  229. package/dist/optimization/bundle-analyzer.js +29 -5
  230. package/dist/optimization/code-splitting.d.ts +0 -23
  231. package/dist/optimization/code-splitting.d.ts.map +1 -1
  232. package/dist/optimization/code-splitting.js +0 -29
  233. package/dist/plugins/form-builder.d.ts.map +1 -1
  234. package/dist/plugins/index.d.ts.map +1 -1
  235. package/dist/plugins/nested-docs.d.ts +4 -0
  236. package/dist/plugins/nested-docs.d.ts.map +1 -1
  237. package/dist/plugins/nested-docs.js +50 -5
  238. package/dist/plugins/redirects.d.ts.map +1 -1
  239. package/dist/queries/index.d.ts.map +1 -1
  240. package/dist/queries/queryBuilder.d.ts.map +1 -1
  241. package/dist/queries/queryBuilder.js +15 -5
  242. package/dist/relationships/analyzer.d.ts.map +1 -1
  243. package/dist/relationships/analyzer.js +8 -0
  244. package/dist/relationships/index.d.ts.map +1 -1
  245. package/dist/relationships/populate-core.d.ts +57 -0
  246. package/dist/relationships/populate-core.d.ts.map +1 -0
  247. package/dist/relationships/populate-core.js +116 -0
  248. package/dist/relationships/populate-helpers.d.ts +5 -51
  249. package/dist/relationships/populate-helpers.d.ts.map +1 -1
  250. package/dist/relationships/populate-helpers.js +4 -109
  251. package/dist/relationships/population.d.ts +1 -9
  252. package/dist/relationships/population.d.ts.map +1 -1
  253. package/dist/relationships/population.js +8 -3
  254. package/dist/revealui.d.ts.map +1 -1
  255. package/dist/richtext/exports/client/rcc.d.ts.map +1 -1
  256. package/dist/richtext/exports/client/rcc.js +1 -1
  257. package/dist/richtext/exports/server/rsc.d.ts +17 -0
  258. package/dist/richtext/exports/server/rsc.d.ts.map +1 -1
  259. package/dist/richtext/exports/server/rsc.js +61 -5
  260. package/dist/richtext/index.d.ts.map +1 -1
  261. package/dist/richtext/lexical.d.ts.map +1 -1
  262. package/dist/security/audit.d.ts +1 -1
  263. package/dist/security/audit.d.ts.map +1 -1
  264. package/dist/security/audit.js +4 -2
  265. package/dist/security/auth.d.ts +29 -160
  266. package/dist/security/auth.d.ts.map +1 -1
  267. package/dist/security/auth.js +150 -367
  268. package/dist/security/authorization.d.ts +7 -31
  269. package/dist/security/authorization.d.ts.map +1 -1
  270. package/dist/security/authorization.js +72 -14
  271. package/dist/security/encryption.d.ts +56 -44
  272. package/dist/security/encryption.d.ts.map +1 -1
  273. package/dist/security/encryption.js +128 -100
  274. package/dist/security/gdpr-storage.d.ts +102 -0
  275. package/dist/security/gdpr-storage.d.ts.map +1 -0
  276. package/dist/security/gdpr-storage.js +65 -0
  277. package/dist/security/gdpr.d.ts +57 -37
  278. package/dist/security/gdpr.d.ts.map +1 -1
  279. package/dist/security/gdpr.js +155 -94
  280. package/dist/security/headers.d.ts +4 -2
  281. package/dist/security/headers.d.ts.map +1 -1
  282. package/dist/security/headers.js +35 -17
  283. package/dist/security/index.d.ts +3 -16
  284. package/dist/security/index.d.ts.map +1 -1
  285. package/dist/security/index.js +3 -16
  286. package/dist/server/index.d.ts.map +1 -1
  287. package/dist/server/renderPage.d.ts.map +1 -1
  288. package/dist/storage/index.d.ts +1 -0
  289. package/dist/storage/index.d.ts.map +1 -1
  290. package/dist/storage/index.js +2 -4
  291. package/dist/storage/vercel-blob.d.ts.map +1 -1
  292. package/dist/translations/index.d.ts.map +1 -1
  293. package/dist/types/access.d.ts.map +1 -1
  294. package/dist/types/api.d.ts.map +1 -1
  295. package/dist/types/cms.d.ts.map +1 -1
  296. package/dist/types/config.d.ts.map +1 -1
  297. package/dist/types/core.d.ts.map +1 -1
  298. package/dist/types/extensions.d.ts.map +1 -1
  299. package/dist/types/frontend.d.ts.map +1 -1
  300. package/dist/types/generated.d.ts +0 -2
  301. package/dist/types/generated.d.ts.map +1 -1
  302. package/dist/types/generated.js +0 -1
  303. package/dist/types/hooks.d.ts.map +1 -1
  304. package/dist/types/index.d.ts +1 -1
  305. package/dist/types/index.d.ts.map +1 -1
  306. package/dist/types/interfaces/app.d.ts.map +1 -1
  307. package/dist/types/jobs.d.ts.map +1 -1
  308. package/dist/types/legacy.d.ts.map +1 -1
  309. package/dist/types/plugins.d.ts.map +1 -1
  310. package/dist/types/query.d.ts.map +1 -1
  311. package/dist/types/request.d.ts.map +1 -1
  312. package/dist/types/richtext.d.ts.map +1 -1
  313. package/dist/types/runtime.d.ts +59 -1
  314. package/dist/types/runtime.d.ts.map +1 -1
  315. package/dist/types/schema.d.ts.map +1 -1
  316. package/dist/types/user.d.ts.map +1 -1
  317. package/dist/utils/access-conversion.d.ts.map +1 -1
  318. package/dist/utils/api-wrapper.d.ts.map +1 -1
  319. package/dist/utils/api-wrapper.js +1 -1
  320. package/dist/utils/block-conversion.d.ts.map +1 -1
  321. package/dist/utils/cache.d.ts.map +1 -1
  322. package/dist/utils/deep-clone.js +0 -1
  323. package/dist/utils/error-responses.d.ts.map +1 -1
  324. package/dist/utils/errors.d.ts +36 -0
  325. package/dist/utils/errors.d.ts.map +1 -1
  326. package/dist/utils/errors.js +103 -0
  327. package/dist/utils/field-conversion.d.ts +1 -1
  328. package/dist/utils/field-conversion.d.ts.map +1 -1
  329. package/dist/utils/flattenResult.d.ts.map +1 -1
  330. package/dist/utils/flattenResult.js +0 -1
  331. package/dist/utils/getBlockSelect.d.ts.map +1 -1
  332. package/dist/utils/getSelectMode.d.ts.map +1 -1
  333. package/dist/utils/isValidID.d.ts.map +1 -1
  334. package/dist/utils/json-parsing.d.ts.map +1 -1
  335. package/dist/utils/logger-client.d.ts.map +1 -1
  336. package/dist/utils/logger-server.d.ts.map +1 -1
  337. package/dist/utils/logger.d.ts.map +1 -1
  338. package/dist/utils/request-context.d.ts.map +1 -1
  339. package/dist/utils/stripUnselectedFields.d.ts.map +1 -1
  340. package/dist/utils/type-guards.d.ts.map +1 -1
  341. package/package.json +39 -16
@@ -192,35 +192,73 @@ export class AuthorizationSystem {
192
192
  */
193
193
  export const authorization = new AuthorizationSystem();
194
194
  /**
195
- * Common roles
195
+ * Common roles — aligned with DB schema (`users.role` column)
196
+ * and `UserRoleSchema` in @revealui/contracts.
197
+ *
198
+ * Values: owner | admin | editor | viewer | agent | contributor
196
199
  */
197
200
  export const CommonRoles = {
201
+ owner: {
202
+ id: 'owner',
203
+ name: 'Owner',
204
+ description: 'Full control — inherits admin',
205
+ permissions: [{ resource: '*', action: '*' }],
206
+ inherits: ['admin'],
207
+ },
198
208
  admin: {
199
209
  id: 'admin',
200
210
  name: 'Administrator',
201
211
  description: 'Full system access',
202
212
  permissions: [{ resource: '*', action: '*' }],
203
213
  },
204
- user: {
205
- id: 'user',
206
- name: 'User',
207
- description: 'Standard user access',
214
+ editor: {
215
+ id: 'editor',
216
+ name: 'Editor',
217
+ description: 'Can read and modify content',
208
218
  permissions: [
219
+ { resource: 'content', action: 'read' },
220
+ { resource: 'content', action: 'create' },
221
+ { resource: 'content', action: 'update' },
209
222
  { resource: 'profile', action: 'read' },
210
223
  { resource: 'profile', action: 'update' },
211
- { resource: 'posts', action: 'read' },
212
- { resource: 'posts', action: 'create' },
224
+ { resource: 'sites', action: 'read' },
225
+ { resource: 'marketplace', action: 'read' },
213
226
  ],
214
227
  },
215
- guest: {
216
- id: 'guest',
217
- name: 'Guest',
218
- description: 'Public access',
228
+ viewer: {
229
+ id: 'viewer',
230
+ name: 'Viewer',
231
+ description: 'Read-only access',
219
232
  permissions: [
220
- { resource: 'posts', action: 'read' },
233
+ { resource: 'content', action: 'read' },
234
+ { resource: 'profile', action: 'read' },
235
+ { resource: 'sites', action: 'read' },
221
236
  { resource: 'public', action: 'read' },
222
237
  ],
223
238
  },
239
+ agent: {
240
+ id: 'agent',
241
+ name: 'AI Agent',
242
+ description: 'Can execute tasks and read content',
243
+ permissions: [
244
+ { resource: 'tasks', action: 'create' },
245
+ { resource: 'tasks', action: 'read' },
246
+ { resource: 'content', action: 'read' },
247
+ { resource: 'rag', action: 'read' },
248
+ { resource: 'rag', action: 'create' },
249
+ ],
250
+ },
251
+ contributor: {
252
+ id: 'contributor',
253
+ name: 'Contributor',
254
+ description: 'Can suggest changes — create drafts but not publish or delete',
255
+ permissions: [
256
+ { resource: 'content', action: 'read' },
257
+ { resource: 'content', action: 'create' },
258
+ { resource: 'profile', action: 'read' },
259
+ { resource: 'profile', action: 'update' },
260
+ ],
261
+ },
224
262
  };
225
263
  /**
226
264
  * Permission builder
@@ -375,9 +413,11 @@ export function checkAttributeAccess(context, resource, action, requiredAttribut
375
413
  export class PermissionCache {
376
414
  cache = new Map();
377
415
  ttl;
378
- constructor(ttl = 300000) {
379
- // 5 minutes default
416
+ maxEntries;
417
+ constructor(ttl = 300000, maxEntries = 10_000) {
418
+ // 5 minutes default, 10k max entries
380
419
  this.ttl = ttl;
420
+ this.maxEntries = maxEntries;
381
421
  }
382
422
  /**
383
423
  * Get cached permission
@@ -400,6 +440,24 @@ export class PermissionCache {
400
440
  */
401
441
  set(userId, resource, action, allowed) {
402
442
  const key = this.getCacheKey(userId, resource, action);
443
+ // Evict expired entries when approaching max size
444
+ if (this.cache.size >= this.maxEntries) {
445
+ const now = Date.now();
446
+ for (const [k, v] of this.cache) {
447
+ if (now > v.expiresAt)
448
+ this.cache.delete(k);
449
+ }
450
+ // If still over limit after purge, drop oldest entries (FIFO via Map insertion order)
451
+ if (this.cache.size >= this.maxEntries) {
452
+ const excess = this.cache.size - this.maxEntries + 1;
453
+ const keys = this.cache.keys();
454
+ for (let i = 0; i < excess; i++) {
455
+ const next = keys.next();
456
+ if (!next.done)
457
+ this.cache.delete(next.value);
458
+ }
459
+ }
460
+ }
403
461
  this.cache.set(key, {
404
462
  allowed,
405
463
  expiresAt: Date.now() + this.ttl,
@@ -4,7 +4,7 @@
4
4
  * Data encryption for at-rest and in-transit protection
5
5
  */
6
6
  export interface EncryptionConfig {
7
- algorithm: 'AES-GCM' | 'AES-CBC' | 'AES-CTR';
7
+ algorithm: 'AES-GCM' | 'AES-CTR';
8
8
  keySize: 128 | 192 | 256;
9
9
  ivSize?: number;
10
10
  }
@@ -125,6 +125,7 @@ export declare class KeyRotationManager {
125
125
  private encryption;
126
126
  private currentKeyId;
127
127
  private oldKeys;
128
+ private keyCreationDates;
128
129
  constructor(encryption: EncryptionSystem, initialKeyId: string);
129
130
  /**
130
131
  * Rotate to new key
@@ -139,9 +140,10 @@ export declare class KeyRotationManager {
139
140
  */
140
141
  getCurrentKeyId(): string;
141
142
  /**
142
- * Clean up old keys
143
+ * Clean up old keys created before the specified date.
144
+ * Never removes the current active key.
143
145
  */
144
- cleanupOldKeys(_olderThan: Date): void;
146
+ cleanupOldKeys(olderThan: Date): void;
145
147
  }
146
148
  /**
147
149
  * Envelope encryption for large data
@@ -167,48 +169,58 @@ export declare class EnvelopeEncryption {
167
169
  /**
168
170
  * Data masking utilities
169
171
  */
170
- export declare class DataMasking {
171
- /**
172
- * Mask email
173
- */
174
- static maskEmail(email: string): string;
175
- /**
176
- * Mask phone number
177
- */
178
- static maskPhone(phone: string): string;
179
- /**
180
- * Mask credit card
181
- */
182
- static maskCreditCard(card: string): string;
183
- /**
184
- * Mask SSN
185
- */
186
- static maskSSN(ssn: string): string;
187
- /**
188
- * Mask string (keep first and last character)
189
- */
190
- static maskString(str: string, keepChars?: number): string;
191
- }
172
+ /**
173
+ * Mask email
174
+ */
175
+ declare function maskEmail(email: string): string;
176
+ /**
177
+ * Mask phone number
178
+ */
179
+ declare function maskPhone(phone: string): string;
180
+ /**
181
+ * Mask credit card
182
+ */
183
+ declare function maskCreditCard(card: string): string;
184
+ /**
185
+ * Mask SSN
186
+ */
187
+ declare function maskSSN(ssn: string): string;
188
+ /**
189
+ * Mask string (keep first and last character)
190
+ */
191
+ declare function maskString(str: string, keepChars?: number): string;
192
+ export declare const DataMasking: {
193
+ readonly maskEmail: typeof maskEmail;
194
+ readonly maskPhone: typeof maskPhone;
195
+ readonly maskCreditCard: typeof maskCreditCard;
196
+ readonly maskSSN: typeof maskSSN;
197
+ readonly maskString: typeof maskString;
198
+ };
192
199
  /**
193
200
  * Secure random token generator
194
201
  */
195
- export declare class TokenGenerator {
196
- /**
197
- * Generate secure token. `length` is the number of random bytes;
198
- * the returned string is hex-encoded, so it will be `length * 2` characters.
199
- */
200
- static generate(length?: number): string;
201
- /**
202
- * Generate UUID v4
203
- */
204
- static generateUUID(): string;
205
- /**
206
- * Generate API key
207
- */
208
- static generateAPIKey(prefix?: string): string;
209
- /**
210
- * Generate session ID
211
- */
212
- static generateSessionID(): string;
213
- }
202
+ /**
203
+ * Generate secure token. `length` is the number of random bytes;
204
+ * the returned string is hex-encoded, so it will be `length * 2` characters.
205
+ */
206
+ declare function generateToken(length?: number): string;
207
+ /**
208
+ * Generate UUID v4
209
+ */
210
+ declare function generateUUID(): string;
211
+ /**
212
+ * Generate API key
213
+ */
214
+ declare function generateAPIKey(prefix?: string): string;
215
+ /**
216
+ * Generate session ID
217
+ */
218
+ declare function generateSessionID(): string;
219
+ export declare const TokenGenerator: {
220
+ readonly generate: typeof generateToken;
221
+ readonly generateUUID: typeof generateUUID;
222
+ readonly generateAPIKey: typeof generateAPIKey;
223
+ readonly generateSessionID: typeof generateSessionID;
224
+ };
225
+ export {};
214
226
  //# sourceMappingURL=encryption.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../../src/security/encryption.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../../src/security/encryption.ts"],"names":[],"mappings":"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"}
@@ -160,10 +160,21 @@ export class EncryptionSystem {
160
160
  * Generate random string
161
161
  */
162
162
  randomString(length, charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') {
163
- const bytes = this.randomBytes(length);
164
- return Array.from(bytes)
165
- .map((byte) => charset[byte % charset.length])
166
- .join('');
163
+ // Rejection sampling to avoid modulo bias:
164
+ // Only accept bytes below the largest multiple of charset.length that fits in a byte.
165
+ const maxValid = 256 - (256 % charset.length);
166
+ const result = [];
167
+ while (result.length < length) {
168
+ const bytes = this.randomBytes(length - result.length + 16);
169
+ for (const byte of bytes) {
170
+ if (byte < maxValid) {
171
+ result.push(charset[byte % charset.length]);
172
+ if (result.length === length)
173
+ break;
174
+ }
175
+ }
176
+ }
177
+ return result.join('');
167
178
  }
168
179
  /**
169
180
  * Convert ArrayBuffer to base64
@@ -304,9 +315,11 @@ export class KeyRotationManager {
304
315
  encryption;
305
316
  currentKeyId;
306
317
  oldKeys = new Map();
318
+ keyCreationDates = new Map();
307
319
  constructor(encryption, initialKeyId) {
308
320
  this.encryption = encryption;
309
321
  this.currentKeyId = initialKeyId;
322
+ this.keyCreationDates.set(initialKeyId, new Date());
310
323
  }
311
324
  /**
312
325
  * Rotate to new key
@@ -320,6 +333,7 @@ export class KeyRotationManager {
320
333
  // Set new key
321
334
  this.encryption.storeKey(newKeyId, newKey);
322
335
  this.currentKeyId = newKeyId;
336
+ this.keyCreationDates.set(newKeyId, new Date());
323
337
  }
324
338
  /**
325
339
  * Re-encrypt data with new key
@@ -343,12 +357,17 @@ export class KeyRotationManager {
343
357
  return this.currentKeyId;
344
358
  }
345
359
  /**
346
- * Clean up old keys
360
+ * Clean up old keys created before the specified date.
361
+ * Never removes the current active key.
347
362
  */
348
- cleanupOldKeys(_olderThan) {
349
- // In a real implementation, you'd track key creation dates
350
- // and remove keys older than the specified date
351
- this.oldKeys.clear();
363
+ cleanupOldKeys(olderThan) {
364
+ for (const [keyId, createdAt] of this.keyCreationDates.entries()) {
365
+ if (keyId !== this.currentKeyId && createdAt < olderThan) {
366
+ this.oldKeys.delete(keyId);
367
+ this.encryption.removeKey(keyId);
368
+ this.keyCreationDates.delete(keyId);
369
+ }
370
+ }
352
371
  }
353
372
  }
354
373
  /**
@@ -407,100 +426,109 @@ export class EnvelopeEncryption {
407
426
  /**
408
427
  * Data masking utilities
409
428
  */
410
- export class DataMasking {
411
- /**
412
- * Mask email
413
- */
414
- static maskEmail(email) {
415
- const [local, domain] = email.split('@');
416
- if (!(local && domain))
417
- return email;
418
- const maskedLocal = local.length > 2
419
- ? local[0] + '*'.repeat(local.length - 2) + local[local.length - 1]
420
- : `${local[0]}*`;
421
- return `${maskedLocal}@${domain}`;
422
- }
423
- /**
424
- * Mask phone number
425
- */
426
- static maskPhone(phone) {
427
- const digits = phone.replace(/\D/g, '');
428
- if (digits.length < 4)
429
- return phone;
430
- const lastFour = digits.slice(-4);
431
- const masked = '*'.repeat(digits.length - 4) + lastFour;
432
- return phone.replace(/\d/g, (char, index) => {
433
- const digitIndex = phone.slice(0, index + 1).replace(/\D/g, '').length - 1;
434
- return masked[digitIndex] || char;
435
- });
436
- }
437
- /**
438
- * Mask credit card
439
- */
440
- static maskCreditCard(card) {
441
- const digits = card.replace(/\D/g, '');
442
- if (digits.length < 4)
443
- return card;
444
- const lastFour = digits.slice(-4);
445
- return `****-****-****-${lastFour}`;
446
- }
447
- /**
448
- * Mask SSN
449
- */
450
- static maskSSN(ssn) {
451
- const digits = ssn.replace(/\D/g, '');
452
- if (digits.length !== 9)
453
- return ssn;
454
- return `***-**-${digits.slice(-4)}`;
455
- }
456
- /**
457
- * Mask string (keep first and last character)
458
- */
459
- static maskString(str, keepChars = 1) {
460
- if (str.length <= keepChars * 2) {
461
- return '*'.repeat(str.length);
462
- }
463
- const prefix = str.slice(0, keepChars);
464
- const suffix = str.slice(-keepChars);
465
- const masked = '*'.repeat(str.length - keepChars * 2);
466
- return `${prefix}${masked}${suffix}`;
467
- }
429
+ /**
430
+ * Mask email
431
+ */
432
+ function maskEmail(email) {
433
+ const [local, domain] = email.split('@');
434
+ if (!(local && domain))
435
+ return email;
436
+ const maskedLocal = local.length > 2
437
+ ? local[0] + '*'.repeat(local.length - 2) + local[local.length - 1]
438
+ : `${local[0]}*`;
439
+ return `${maskedLocal}@${domain}`;
440
+ }
441
+ /**
442
+ * Mask phone number
443
+ */
444
+ function maskPhone(phone) {
445
+ const digits = phone.replace(/\D/g, '');
446
+ if (digits.length < 4)
447
+ return phone;
448
+ const lastFour = digits.slice(-4);
449
+ const masked = '*'.repeat(digits.length - 4) + lastFour;
450
+ return phone.replace(/\d/g, (char, index) => {
451
+ const digitIndex = phone.slice(0, index + 1).replace(/\D/g, '').length - 1;
452
+ return masked[digitIndex] || char;
453
+ });
454
+ }
455
+ /**
456
+ * Mask credit card
457
+ */
458
+ function maskCreditCard(card) {
459
+ const digits = card.replace(/\D/g, '');
460
+ if (digits.length < 4)
461
+ return card;
462
+ const lastFour = digits.slice(-4);
463
+ return `****-****-****-${lastFour}`;
464
+ }
465
+ /**
466
+ * Mask SSN
467
+ */
468
+ function maskSSN(ssn) {
469
+ const digits = ssn.replace(/\D/g, '');
470
+ if (digits.length !== 9)
471
+ return ssn;
472
+ return `***-**-${digits.slice(-4)}`;
468
473
  }
474
+ /**
475
+ * Mask string (keep first and last character)
476
+ */
477
+ function maskString(str, keepChars = 1) {
478
+ if (str.length <= keepChars * 2) {
479
+ return '*'.repeat(str.length);
480
+ }
481
+ const prefix = str.slice(0, keepChars);
482
+ const suffix = str.slice(-keepChars);
483
+ const masked = '*'.repeat(str.length - keepChars * 2);
484
+ return `${prefix}${masked}${suffix}`;
485
+ }
486
+ export const DataMasking = {
487
+ maskEmail,
488
+ maskPhone,
489
+ maskCreditCard,
490
+ maskSSN,
491
+ maskString,
492
+ };
469
493
  /**
470
494
  * Secure random token generator
471
495
  */
472
- export class TokenGenerator {
473
- /**
474
- * Generate secure token. `length` is the number of random bytes;
475
- * the returned string is hex-encoded, so it will be `length * 2` characters.
476
- */
477
- static generate(length = 32) {
478
- const bytes = encryption.randomBytes(length);
479
- return Array.from(bytes)
480
- .map((b) => b.toString(16).padStart(2, '0'))
481
- .join('');
482
- }
483
- /**
484
- * Generate UUID v4
485
- */
486
- static generateUUID() {
487
- const crypto = globalThis.crypto;
488
- if (!crypto) {
489
- throw new Error('Crypto API not available');
490
- }
491
- return crypto.randomUUID();
492
- }
493
- /**
494
- * Generate API key
495
- */
496
- static generateAPIKey(prefix = 'sk') {
497
- const token = TokenGenerator.generate(32);
498
- return `${prefix}_${token}`;
499
- }
500
- /**
501
- * Generate session ID
502
- */
503
- static generateSessionID() {
504
- return TokenGenerator.generate(64);
496
+ /**
497
+ * Generate secure token. `length` is the number of random bytes;
498
+ * the returned string is hex-encoded, so it will be `length * 2` characters.
499
+ */
500
+ function generateToken(length = 32) {
501
+ const bytes = encryption.randomBytes(length);
502
+ return Array.from(bytes)
503
+ .map((b) => b.toString(16).padStart(2, '0'))
504
+ .join('');
505
+ }
506
+ /**
507
+ * Generate UUID v4
508
+ */
509
+ function generateUUID() {
510
+ const crypto = globalThis.crypto;
511
+ if (!crypto) {
512
+ throw new Error('Crypto API not available');
505
513
  }
514
+ return crypto.randomUUID();
506
515
  }
516
+ /**
517
+ * Generate API key
518
+ */
519
+ function generateAPIKey(prefix = 'sk') {
520
+ const token = generateToken(32);
521
+ return `${prefix}_${token}`;
522
+ }
523
+ /**
524
+ * Generate session ID
525
+ */
526
+ function generateSessionID() {
527
+ return generateToken(64);
528
+ }
529
+ export const TokenGenerator = {
530
+ generate: generateToken,
531
+ generateUUID,
532
+ generateAPIKey,
533
+ generateSessionID,
534
+ };
@@ -0,0 +1,102 @@
1
+ /**
2
+ * GDPR Storage Abstraction
3
+ *
4
+ * Record-oriented storage interface for GDPR compliance data.
5
+ * Provides a clean seam for replacing the default in-memory implementation
6
+ * with a database-backed store in production.
7
+ */
8
+ import type { ConsentRecord, ConsentType, DataBreach, DataDeletionRequest } from './gdpr.js';
9
+ /**
10
+ * Storage interface for GDPR consent records and deletion requests.
11
+ *
12
+ * All methods are async to support database-backed implementations.
13
+ * The default `InMemoryGDPRStorage` is suitable for testing and development
14
+ * but must be replaced with a persistent store for production use.
15
+ */
16
+ export interface GDPRStorage {
17
+ /**
18
+ * Store or update a consent record, keyed by `userId:consentType`.
19
+ */
20
+ setConsent(userId: string, type: ConsentType, record: ConsentRecord): Promise<void>;
21
+ /**
22
+ * Retrieve a consent record by user and type. Returns `undefined` if not found.
23
+ */
24
+ getConsent(userId: string, type: ConsentType): Promise<ConsentRecord | undefined>;
25
+ /**
26
+ * Retrieve all consent records for a given user.
27
+ */
28
+ getConsentsByUser(userId: string): Promise<ConsentRecord[]>;
29
+ /**
30
+ * Retrieve every consent record in storage (used for aggregate statistics).
31
+ */
32
+ getAllConsents(): Promise<ConsentRecord[]>;
33
+ /**
34
+ * Store a deletion request, keyed by its `id`.
35
+ */
36
+ setDeletionRequest(request: DataDeletionRequest): Promise<void>;
37
+ /**
38
+ * Retrieve a deletion request by ID. Returns `undefined` if not found.
39
+ */
40
+ getDeletionRequest(requestId: string): Promise<DataDeletionRequest | undefined>;
41
+ /**
42
+ * Retrieve all deletion requests for a given user.
43
+ */
44
+ getDeletionRequestsByUser(userId: string): Promise<DataDeletionRequest[]>;
45
+ }
46
+ /**
47
+ * Storage interface for data breach records.
48
+ *
49
+ * All methods are async to support database-backed implementations.
50
+ * The default `InMemoryBreachStorage` is suitable for testing and development
51
+ * but must be replaced with a persistent store for production GDPR compliance.
52
+ */
53
+ export interface BreachStorage {
54
+ /**
55
+ * Store a data breach record.
56
+ */
57
+ setBreach(breach: DataBreach): Promise<void>;
58
+ /**
59
+ * Retrieve a breach by ID. Returns `undefined` if not found.
60
+ */
61
+ getBreach(id: string): Promise<DataBreach | undefined>;
62
+ /**
63
+ * Retrieve all breach records.
64
+ */
65
+ getAllBreaches(): Promise<DataBreach[]>;
66
+ /**
67
+ * Update an existing breach record (e.g., status change, add mitigation).
68
+ */
69
+ updateBreach(id: string, updates: Partial<DataBreach>): Promise<void>;
70
+ }
71
+ /**
72
+ * In-memory implementation of `BreachStorage`.
73
+ *
74
+ * WARNING: All data is lost on process restart or serverless cold start.
75
+ * GDPR requires breach records be retained — use database-backed storage in production.
76
+ */
77
+ export declare class InMemoryBreachStorage implements BreachStorage {
78
+ private breaches;
79
+ setBreach(breach: DataBreach): Promise<void>;
80
+ getBreach(id: string): Promise<DataBreach | undefined>;
81
+ getAllBreaches(): Promise<DataBreach[]>;
82
+ updateBreach(id: string, updates: Partial<DataBreach>): Promise<void>;
83
+ }
84
+ /**
85
+ * In-memory implementation of `GDPRStorage`.
86
+ *
87
+ * WARNING: All data is lost on process restart or serverless cold start.
88
+ * Use this only for development, testing, or as a reference implementation.
89
+ * Production deployments MUST supply a database-backed `GDPRStorage`.
90
+ */
91
+ export declare class InMemoryGDPRStorage implements GDPRStorage {
92
+ private consents;
93
+ private deletionRequests;
94
+ setConsent(userId: string, type: ConsentType, record: ConsentRecord): Promise<void>;
95
+ getConsent(userId: string, type: ConsentType): Promise<ConsentRecord | undefined>;
96
+ getConsentsByUser(userId: string): Promise<ConsentRecord[]>;
97
+ getAllConsents(): Promise<ConsentRecord[]>;
98
+ setDeletionRequest(request: DataDeletionRequest): Promise<void>;
99
+ getDeletionRequest(requestId: string): Promise<DataDeletionRequest | undefined>;
100
+ getDeletionRequestsByUser(userId: string): Promise<DataDeletionRequest[]>;
101
+ }
102
+ //# sourceMappingURL=gdpr-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gdpr-storage.d.ts","sourceRoot":"","sources":["../../src/security/gdpr-storage.ts"],"names":[],"mappings":"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"}