gazetta 0.7.0 → 0.8.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.
- package/admin-dist/assets/index-CBeq0rRb.js +693 -0
- package/admin-dist/assets/index-Dtg1dTZQ.css +1 -0
- package/admin-dist/assets/rolldown-runtime-BYbx6iT9.js +1 -0
- package/admin-dist/assets/{vendor-primevue-C0Q_YTCb.js → vendor-primevue-CBGHkaXv.js} +183 -39
- package/admin-dist/assets/{vendor-react-BipDVGow.js → vendor-react-BdW_kNCG.js} +2 -2
- package/admin-dist/assets/vendor-rjsf-lN2SztQt.js +33 -0
- package/admin-dist/assets/vendor-tiptap-C36yDquB.js +141 -0
- package/admin-dist/assets/vendor-vue-Bt5uR1VW.js +1 -0
- package/admin-dist/assets/workbox-window.prod.es5-DGMtIXHc.js +2 -0
- package/admin-dist/index.html +8 -8
- package/admin-dist/sw.js +1 -0
- package/dist/admin-api/archived-name-conflict.d.ts +31 -0
- package/dist/admin-api/archived-name-conflict.d.ts.map +1 -0
- package/dist/admin-api/archived-name-conflict.js +226 -0
- package/dist/admin-api/archived-name-conflict.js.map +1 -0
- package/dist/admin-api/cache-stats-logger.d.ts +83 -0
- package/dist/admin-api/cache-stats-logger.d.ts.map +1 -0
- package/dist/admin-api/cache-stats-logger.js +59 -0
- package/dist/admin-api/cache-stats-logger.js.map +1 -0
- package/dist/admin-api/hook-audit-emitter.d.ts +38 -0
- package/dist/admin-api/hook-audit-emitter.d.ts.map +1 -0
- package/dist/admin-api/hook-audit-emitter.js +21 -0
- package/dist/admin-api/hook-audit-emitter.js.map +1 -0
- package/dist/admin-api/index.d.ts +84 -0
- package/dist/admin-api/index.d.ts.map +1 -1
- package/dist/admin-api/index.js +254 -9
- package/dist/admin-api/index.js.map +1 -1
- package/dist/admin-api/middleware/audit.d.ts +25 -0
- package/dist/admin-api/middleware/audit.d.ts.map +1 -0
- package/dist/admin-api/middleware/audit.js +65 -0
- package/dist/admin-api/middleware/audit.js.map +1 -0
- package/dist/admin-api/middleware/capability.d.ts +8 -0
- package/dist/admin-api/middleware/capability.d.ts.map +1 -0
- package/dist/admin-api/middleware/capability.js +65 -0
- package/dist/admin-api/middleware/capability.js.map +1 -0
- package/dist/admin-api/middleware/principal.d.ts +18 -0
- package/dist/admin-api/middleware/principal.d.ts.map +1 -0
- package/dist/admin-api/middleware/principal.js +128 -0
- package/dist/admin-api/middleware/principal.js.map +1 -0
- package/dist/admin-api/routes/archive-review.d.ts +80 -0
- package/dist/admin-api/routes/archive-review.d.ts.map +1 -0
- package/dist/admin-api/routes/archive-review.js +70 -0
- package/dist/admin-api/routes/archive-review.js.map +1 -0
- package/dist/admin-api/routes/archive.d.ts +145 -0
- package/dist/admin-api/routes/archive.d.ts.map +1 -0
- package/dist/admin-api/routes/archive.js +540 -0
- package/dist/admin-api/routes/archive.js.map +1 -0
- package/dist/admin-api/routes/assets.d.ts +6 -1
- package/dist/admin-api/routes/assets.d.ts.map +1 -1
- package/dist/admin-api/routes/assets.js +167 -14
- package/dist/admin-api/routes/assets.js.map +1 -1
- package/dist/admin-api/routes/audit.d.ts +71 -0
- package/dist/admin-api/routes/audit.d.ts.map +1 -0
- package/dist/admin-api/routes/audit.js +178 -0
- package/dist/admin-api/routes/audit.js.map +1 -0
- package/dist/admin-api/routes/compare.d.ts.map +1 -1
- package/dist/admin-api/routes/compare.js +3 -2
- package/dist/admin-api/routes/compare.js.map +1 -1
- package/dist/admin-api/routes/fields.d.ts.map +1 -1
- package/dist/admin-api/routes/fields.js +2 -1
- package/dist/admin-api/routes/fields.js.map +1 -1
- package/dist/admin-api/routes/fragments.d.ts +13 -1
- package/dist/admin-api/routes/fragments.d.ts.map +1 -1
- package/dist/admin-api/routes/fragments.js +127 -92
- package/dist/admin-api/routes/fragments.js.map +1 -1
- package/dist/admin-api/routes/health.d.ts +60 -0
- package/dist/admin-api/routes/health.d.ts.map +1 -0
- package/dist/admin-api/routes/health.js +65 -0
- package/dist/admin-api/routes/health.js.map +1 -0
- package/dist/admin-api/routes/history.d.ts +2 -1
- package/dist/admin-api/routes/history.d.ts.map +1 -1
- package/dist/admin-api/routes/history.js +26 -4
- package/dist/admin-api/routes/history.js.map +1 -1
- package/dist/admin-api/routes/pages.d.ts +20 -1
- package/dist/admin-api/routes/pages.d.ts.map +1 -1
- package/dist/admin-api/routes/pages.js +157 -117
- package/dist/admin-api/routes/pages.js.map +1 -1
- package/dist/admin-api/routes/preview.d.ts.map +1 -1
- package/dist/admin-api/routes/preview.js +56 -17
- package/dist/admin-api/routes/preview.js.map +1 -1
- package/dist/admin-api/routes/publish.d.ts +19 -1
- package/dist/admin-api/routes/publish.d.ts.map +1 -1
- package/dist/admin-api/routes/publish.js +508 -92
- package/dist/admin-api/routes/publish.js.map +1 -1
- package/dist/admin-api/routes/rename.d.ts +62 -0
- package/dist/admin-api/routes/rename.d.ts.map +1 -0
- package/dist/admin-api/routes/rename.js +366 -0
- package/dist/admin-api/routes/rename.js.map +1 -0
- package/dist/admin-api/routes/site.d.ts.map +1 -1
- package/dist/admin-api/routes/site.js +6 -18
- package/dist/admin-api/routes/site.js.map +1 -1
- package/dist/admin-api/routes/system.d.ts +23 -0
- package/dist/admin-api/routes/system.d.ts.map +1 -0
- package/dist/admin-api/routes/system.js +115 -0
- package/dist/admin-api/routes/system.js.map +1 -0
- package/dist/admin-api/routes/templates.d.ts +11 -1
- package/dist/admin-api/routes/templates.d.ts.map +1 -1
- package/dist/admin-api/routes/templates.js +36 -3
- package/dist/admin-api/routes/templates.js.map +1 -1
- package/dist/admin-api/routes/validation.d.ts +47 -0
- package/dist/admin-api/routes/validation.d.ts.map +1 -0
- package/dist/admin-api/routes/validation.js +120 -0
- package/dist/admin-api/routes/validation.js.map +1 -0
- package/dist/admin-api/schemas/archive.d.ts +124 -0
- package/dist/admin-api/schemas/archive.d.ts.map +1 -0
- package/dist/admin-api/schemas/archive.js +93 -0
- package/dist/admin-api/schemas/archive.js.map +1 -0
- package/dist/admin-api/schemas/assets.d.ts +16 -0
- package/dist/admin-api/schemas/assets.d.ts.map +1 -1
- package/dist/admin-api/schemas/assets.js +15 -0
- package/dist/admin-api/schemas/assets.js.map +1 -1
- package/dist/admin-api/schemas/audit.d.ts +175 -0
- package/dist/admin-api/schemas/audit.d.ts.map +1 -0
- package/dist/admin-api/schemas/audit.js +91 -0
- package/dist/admin-api/schemas/audit.js.map +1 -0
- package/dist/admin-api/schemas/error.d.ts +94 -0
- package/dist/admin-api/schemas/error.d.ts.map +1 -0
- package/dist/admin-api/schemas/error.js +79 -0
- package/dist/admin-api/schemas/error.js.map +1 -0
- package/dist/admin-api/schemas/fragments.d.ts +2 -0
- package/dist/admin-api/schemas/fragments.d.ts.map +1 -1
- package/dist/admin-api/schemas/fragments.js +4 -0
- package/dist/admin-api/schemas/fragments.js.map +1 -1
- package/dist/admin-api/schemas/index.d.ts +8 -0
- package/dist/admin-api/schemas/index.d.ts.map +1 -1
- package/dist/admin-api/schemas/index.js +8 -0
- package/dist/admin-api/schemas/index.js.map +1 -1
- package/dist/admin-api/schemas/pages.d.ts +2 -0
- package/dist/admin-api/schemas/pages.d.ts.map +1 -1
- package/dist/admin-api/schemas/pages.js +11 -0
- package/dist/admin-api/schemas/pages.js.map +1 -1
- package/dist/admin-api/schemas/rename.d.ts +77 -0
- package/dist/admin-api/schemas/rename.d.ts.map +1 -0
- package/dist/admin-api/schemas/rename.js +75 -0
- package/dist/admin-api/schemas/rename.js.map +1 -0
- package/dist/admin-api/schemas/site.d.ts +3 -2
- package/dist/admin-api/schemas/site.d.ts.map +1 -1
- package/dist/admin-api/schemas/site.js +3 -2
- package/dist/admin-api/schemas/site.js.map +1 -1
- package/dist/admin-api/schemas/system.d.ts +28 -0
- package/dist/admin-api/schemas/system.d.ts.map +1 -0
- package/dist/admin-api/schemas/system.js +35 -0
- package/dist/admin-api/schemas/system.js.map +1 -0
- package/dist/admin-api/schemas/targets.d.ts +55 -0
- package/dist/admin-api/schemas/targets.d.ts.map +1 -1
- package/dist/admin-api/schemas/targets.js +46 -0
- package/dist/admin-api/schemas/targets.js.map +1 -1
- package/dist/admin-api/schemas/templates.d.ts +54 -0
- package/dist/admin-api/schemas/templates.d.ts.map +1 -1
- package/dist/admin-api/schemas/templates.js +21 -0
- package/dist/admin-api/schemas/templates.js.map +1 -1
- package/dist/admin-api/schemas/validation.d.ts +101 -0
- package/dist/admin-api/schemas/validation.d.ts.map +1 -0
- package/dist/admin-api/schemas/validation.js +57 -0
- package/dist/admin-api/schemas/validation.js.map +1 -0
- package/dist/admin-api/source-context.d.ts +66 -10
- package/dist/admin-api/source-context.d.ts.map +1 -1
- package/dist/admin-api/source-context.js +43 -5
- package/dist/admin-api/source-context.js.map +1 -1
- package/dist/ai/adapter-scaffold.d.ts +63 -0
- package/dist/ai/adapter-scaffold.d.ts.map +1 -0
- package/dist/ai/adapter-scaffold.js +89 -0
- package/dist/ai/adapter-scaffold.js.map +1 -0
- package/dist/ai/compose-prompt.d.ts +50 -0
- package/dist/ai/compose-prompt.d.ts.map +1 -0
- package/dist/ai/compose-prompt.js +49 -0
- package/dist/ai/compose-prompt.js.map +1 -0
- package/dist/ai/errors.d.ts +65 -0
- package/dist/ai/errors.d.ts.map +1 -0
- package/dist/ai/errors.js +59 -0
- package/dist/ai/errors.js.map +1 -0
- package/dist/ai/index.d.ts +17 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +16 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/provider.d.ts +76 -0
- package/dist/ai/provider.d.ts.map +1 -0
- package/dist/ai/provider.js +13 -0
- package/dist/ai/provider.js.map +1 -0
- package/dist/ai/refusal.d.ts +50 -0
- package/dist/ai/refusal.d.ts.map +1 -0
- package/dist/ai/refusal.js +100 -0
- package/dist/ai/refusal.js.map +1 -0
- package/dist/ai/vision-prep.d.ts +32 -0
- package/dist/ai/vision-prep.d.ts.map +1 -0
- package/dist/ai/vision-prep.js +113 -0
- package/dist/ai/vision-prep.js.map +1 -0
- package/dist/alt/adapter.d.ts +140 -0
- package/dist/alt/adapter.d.ts.map +1 -0
- package/dist/alt/adapter.js +7 -0
- package/dist/alt/adapter.js.map +1 -0
- package/dist/alt/anthropic.d.ts +63 -0
- package/dist/alt/anthropic.d.ts.map +1 -0
- package/dist/alt/anthropic.js +147 -0
- package/dist/alt/anthropic.js.map +1 -0
- package/dist/alt/config.d.ts +67 -0
- package/dist/alt/config.d.ts.map +1 -0
- package/dist/alt/config.js +41 -0
- package/dist/alt/config.js.map +1 -0
- package/dist/alt/factory.d.ts +19 -0
- package/dist/alt/factory.d.ts.map +1 -0
- package/dist/alt/factory.js +69 -0
- package/dist/alt/factory.js.map +1 -0
- package/dist/alt/null-adapter.d.ts +3 -0
- package/dist/alt/null-adapter.d.ts.map +1 -0
- package/dist/alt/null-adapter.js +43 -0
- package/dist/alt/null-adapter.js.map +1 -0
- package/dist/alt/ollama.d.ts +40 -0
- package/dist/alt/ollama.d.ts.map +1 -0
- package/dist/alt/ollama.js +139 -0
- package/dist/alt/ollama.js.map +1 -0
- package/dist/alt/openai.d.ts +46 -0
- package/dist/alt/openai.d.ts.map +1 -0
- package/dist/alt/openai.js +118 -0
- package/dist/alt/openai.js.map +1 -0
- package/dist/alt/prompt-policies.d.ts +79 -0
- package/dist/alt/prompt-policies.d.ts.map +1 -0
- package/dist/alt/prompt-policies.js +67 -0
- package/dist/alt/prompt-policies.js.map +1 -0
- package/dist/alt/route-handler.d.ts +56 -0
- package/dist/alt/route-handler.d.ts.map +1 -0
- package/dist/alt/route-handler.js +122 -0
- package/dist/alt/route-handler.js.map +1 -0
- package/dist/alt/suggester.d.ts +57 -0
- package/dist/alt/suggester.d.ts.map +1 -0
- package/dist/alt/suggester.js +133 -0
- package/dist/alt/suggester.js.map +1 -0
- package/dist/app.js +1 -1
- package/dist/app.js.map +1 -1
- package/dist/archive-aliases.d.ts +79 -0
- package/dist/archive-aliases.d.ts.map +1 -0
- package/dist/archive-aliases.js +60 -0
- package/dist/archive-aliases.js.map +1 -0
- package/dist/archive-helpers.d.ts +73 -0
- package/dist/archive-helpers.d.ts.map +1 -0
- package/dist/archive-helpers.js +94 -0
- package/dist/archive-helpers.js.map +1 -0
- package/dist/assets/find-refs.d.ts +1 -1
- package/dist/assets/find-refs.js +1 -1
- package/dist/assets/find-refs.js.map +1 -1
- package/dist/assets/rename.js +1 -1
- package/dist/assets/rename.js.map +1 -1
- package/dist/assets/replace.js +1 -1
- package/dist/assets/replace.js.map +1 -1
- package/dist/assets/resolve.js +4 -4
- package/dist/assets/resolve.js.map +1 -1
- package/dist/assets/serve-route.js +2 -2
- package/dist/assets/serve-route.js.map +1 -1
- package/dist/assets/validate.d.ts +1 -1
- package/dist/assets/validate.js +1 -1
- package/dist/audit/config.d.ts +75 -0
- package/dist/audit/config.d.ts.map +1 -0
- package/dist/audit/config.js +91 -0
- package/dist/audit/config.js.map +1 -0
- package/dist/audit/context.d.ts +98 -0
- package/dist/audit/context.d.ts.map +1 -0
- package/dist/audit/context.js +51 -0
- package/dist/audit/context.js.map +1 -0
- package/dist/audit/errors.d.ts +73 -0
- package/dist/audit/errors.d.ts.map +1 -0
- package/dist/audit/errors.js +78 -0
- package/dist/audit/errors.js.map +1 -0
- package/dist/audit/index.d.ts +16 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +10 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/provider.d.ts +73 -0
- package/dist/audit/provider.d.ts.map +1 -0
- package/dist/audit/provider.js +2 -0
- package/dist/audit/provider.js.map +1 -0
- package/dist/audit/providers/history.d.ts +66 -0
- package/dist/audit/providers/history.d.ts.map +1 -0
- package/dist/audit/providers/history.js +102 -0
- package/dist/audit/providers/history.js.map +1 -0
- package/dist/audit/pseudonymize.d.ts +26 -0
- package/dist/audit/pseudonymize.d.ts.map +1 -0
- package/dist/audit/pseudonymize.js +86 -0
- package/dist/audit/pseudonymize.js.map +1 -0
- package/dist/audit/recorder.d.ts +102 -0
- package/dist/audit/recorder.d.ts.map +1 -0
- package/dist/audit/recorder.js +55 -0
- package/dist/audit/recorder.js.map +1 -0
- package/dist/audit/retention.d.ts +83 -0
- package/dist/audit/retention.d.ts.map +1 -0
- package/dist/audit/retention.js +142 -0
- package/dist/audit/retention.js.map +1 -0
- package/dist/audit/source-ip.d.ts +32 -0
- package/dist/audit/source-ip.d.ts.map +1 -0
- package/dist/audit/source-ip.js +164 -0
- package/dist/audit/source-ip.js.map +1 -0
- package/dist/audit/types.d.ts +143 -0
- package/dist/audit/types.d.ts.map +1 -0
- package/dist/audit/types.js +33 -0
- package/dist/audit/types.js.map +1 -0
- package/dist/audit/user-agent.d.ts +28 -0
- package/dist/audit/user-agent.d.ts.map +1 -0
- package/dist/audit/user-agent.js +63 -0
- package/dist/audit/user-agent.js.map +1 -0
- package/dist/auth/capabilities.d.ts +28 -0
- package/dist/auth/capabilities.d.ts.map +1 -0
- package/dist/auth/capabilities.js +101 -0
- package/dist/auth/capabilities.js.map +1 -0
- package/dist/auth/config.d.ts +109 -0
- package/dist/auth/config.d.ts.map +1 -0
- package/dist/auth/config.js +221 -0
- package/dist/auth/config.js.map +1 -0
- package/dist/auth/errors.d.ts +72 -0
- package/dist/auth/errors.d.ts.map +1 -0
- package/dist/auth/errors.js +78 -0
- package/dist/auth/errors.js.map +1 -0
- package/dist/auth/factory.d.ts +43 -0
- package/dist/auth/factory.d.ts.map +1 -0
- package/dist/auth/factory.js +48 -0
- package/dist/auth/factory.js.map +1 -0
- package/dist/auth/index.d.ts +21 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +14 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/ip-match.d.ts +29 -0
- package/dist/auth/ip-match.d.ts.map +1 -0
- package/dist/auth/ip-match.js +162 -0
- package/dist/auth/ip-match.js.map +1 -0
- package/dist/auth/provider.d.ts +76 -0
- package/dist/auth/provider.d.ts.map +1 -0
- package/dist/auth/provider.js +2 -0
- package/dist/auth/provider.js.map +1 -0
- package/dist/auth/providers/aws-cognito.d.ts +55 -0
- package/dist/auth/providers/aws-cognito.d.ts.map +1 -0
- package/dist/auth/providers/aws-cognito.js +114 -0
- package/dist/auth/providers/aws-cognito.js.map +1 -0
- package/dist/auth/providers/azure-easy-auth.d.ts +7 -0
- package/dist/auth/providers/azure-easy-auth.d.ts.map +1 -0
- package/dist/auth/providers/azure-easy-auth.js +48 -0
- package/dist/auth/providers/azure-easy-auth.js.map +1 -0
- package/dist/auth/providers/cloudflare-access.d.ts +71 -0
- package/dist/auth/providers/cloudflare-access.d.ts.map +1 -0
- package/dist/auth/providers/cloudflare-access.js +120 -0
- package/dist/auth/providers/cloudflare-access.js.map +1 -0
- package/dist/auth/providers/forwarded-user.d.ts +31 -0
- package/dist/auth/providers/forwarded-user.d.ts.map +1 -0
- package/dist/auth/providers/forwarded-user.js +72 -0
- package/dist/auth/providers/forwarded-user.js.map +1 -0
- package/dist/auth/providers/none.d.ts +6 -0
- package/dist/auth/providers/none.d.ts.map +1 -0
- package/dist/auth/providers/none.js +19 -0
- package/dist/auth/providers/none.js.map +1 -0
- package/dist/auth/providers/tailscale.d.ts +7 -0
- package/dist/auth/providers/tailscale.d.ts.map +1 -0
- package/dist/auth/providers/tailscale.js +30 -0
- package/dist/auth/providers/tailscale.js.map +1 -0
- package/dist/auth/role-resolver.d.ts +38 -0
- package/dist/auth/role-resolver.d.ts.map +1 -0
- package/dist/auth/role-resolver.js +92 -0
- package/dist/auth/role-resolver.js.map +1 -0
- package/dist/auth/types.d.ts +150 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +60 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/cache/errors.d.ts +41 -0
- package/dist/cache/errors.d.ts.map +1 -0
- package/dist/cache/errors.js +44 -0
- package/dist/cache/errors.js.map +1 -0
- package/dist/cache/factories.d.ts +17 -0
- package/dist/cache/factories.d.ts.map +1 -0
- package/dist/cache/factories.js +17 -0
- package/dist/cache/factories.js.map +1 -0
- package/dist/cache/keys.d.ts +63 -0
- package/dist/cache/keys.d.ts.map +1 -0
- package/dist/cache/keys.js +145 -0
- package/dist/cache/keys.js.map +1 -0
- package/dist/cache/memory.d.ts +51 -0
- package/dist/cache/memory.d.ts.map +1 -0
- package/dist/cache/memory.js +204 -0
- package/dist/cache/memory.js.map +1 -0
- package/dist/cache/per-site.d.ts +22 -0
- package/dist/cache/per-site.d.ts.map +1 -0
- package/dist/cache/per-site.js +114 -0
- package/dist/cache/per-site.js.map +1 -0
- package/dist/cache/types.d.ts +142 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cache/types.js +33 -0
- package/dist/cache/types.js.map +1 -0
- package/dist/cli/archive.d.ts +44 -0
- package/dist/cli/archive.d.ts.map +1 -0
- package/dist/cli/archive.js +310 -0
- package/dist/cli/archive.js.map +1 -0
- package/dist/cli/bootstrap.d.ts +15 -8
- package/dist/cli/bootstrap.d.ts.map +1 -1
- package/dist/cli/bootstrap.js +59 -23
- package/dist/cli/bootstrap.js.map +1 -1
- package/dist/cli/dev-template-watcher.d.ts +29 -0
- package/dist/cli/dev-template-watcher.d.ts.map +1 -0
- package/dist/cli/dev-template-watcher.js +38 -0
- package/dist/cli/dev-template-watcher.js.map +1 -0
- package/dist/cli/history.d.ts.map +1 -1
- package/dist/cli/history.js +5 -3
- package/dist/cli/history.js.map +1 -1
- package/dist/cli/index.js +712 -395
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/validate-flags.d.ts +29 -0
- package/dist/cli/validate-flags.d.ts.map +1 -0
- package/dist/cli/validate-flags.js +49 -0
- package/dist/cli/validate-flags.js.map +1 -0
- package/dist/compare.d.ts +1 -1
- package/dist/compare.d.ts.map +1 -1
- package/dist/compare.js +25 -23
- package/dist/compare.js.map +1 -1
- package/dist/component-ids.d.ts +25 -0
- package/dist/component-ids.d.ts.map +1 -0
- package/dist/component-ids.js +83 -0
- package/dist/component-ids.js.map +1 -0
- package/dist/config/define.d.ts +61 -0
- package/dist/config/define.d.ts.map +1 -0
- package/dist/config/define.js +64 -0
- package/dist/config/define.js.map +1 -0
- package/dist/config/errors.d.ts +32 -0
- package/dist/config/errors.d.ts.map +1 -0
- package/dist/config/errors.js +40 -0
- package/dist/config/errors.js.map +1 -0
- package/dist/config/index.d.ts +13 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +20 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +105 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +265 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schemas.d.ts +89 -0
- package/dist/config/schemas.d.ts.map +1 -0
- package/dist/config/schemas.js +172 -0
- package/dist/config/schemas.js.map +1 -0
- package/dist/config/types.d.ts +32 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +15 -0
- package/dist/config/types.js.map +1 -0
- package/dist/deploy/cloudflare-workers.d.ts +46 -0
- package/dist/deploy/cloudflare-workers.d.ts.map +1 -0
- package/dist/deploy/cloudflare-workers.js +213 -0
- package/dist/deploy/cloudflare-workers.js.map +1 -0
- package/dist/deploy/errors.d.ts +66 -0
- package/dist/deploy/errors.d.ts.map +1 -0
- package/dist/deploy/errors.js +82 -0
- package/dist/deploy/errors.js.map +1 -0
- package/dist/deploy/index.d.ts +9 -0
- package/dist/deploy/index.d.ts.map +1 -0
- package/dist/deploy/index.js +3 -0
- package/dist/deploy/index.js.map +1 -0
- package/dist/deploy/types.d.ts +162 -0
- package/dist/deploy/types.d.ts.map +1 -0
- package/dist/deploy/types.js +2 -0
- package/dist/deploy/types.js.map +1 -0
- package/dist/fragments/create.d.ts +70 -0
- package/dist/fragments/create.d.ts.map +1 -0
- package/dist/fragments/create.js +93 -0
- package/dist/fragments/create.js.map +1 -0
- package/dist/fragments/publish.d.ts +37 -0
- package/dist/fragments/publish.d.ts.map +1 -0
- package/dist/fragments/publish.js +52 -0
- package/dist/fragments/publish.js.map +1 -0
- package/dist/fragments/save.d.ts +81 -0
- package/dist/fragments/save.d.ts.map +1 -0
- package/dist/fragments/save.js +105 -0
- package/dist/fragments/save.js.map +1 -0
- package/dist/history-recorder.d.ts +5 -5
- package/dist/history-recorder.d.ts.map +1 -1
- package/dist/history-recorder.js +4 -4
- package/dist/history-recorder.js.map +1 -1
- package/dist/history-restorer.js +2 -2
- package/dist/history-restorer.js.map +1 -1
- package/dist/history.d.ts +1 -1
- package/dist/hooks/audit-emitter.d.ts +73 -0
- package/dist/hooks/audit-emitter.d.ts.map +1 -0
- package/dist/hooks/audit-emitter.js +13 -0
- package/dist/hooks/audit-emitter.js.map +1 -0
- package/dist/hooks/context.d.ts +78 -0
- package/dist/hooks/context.d.ts.map +1 -0
- package/dist/hooks/context.js +56 -0
- package/dist/hooks/context.js.map +1 -0
- package/dist/hooks/contribution.d.ts +90 -0
- package/dist/hooks/contribution.d.ts.map +1 -0
- package/dist/hooks/contribution.js +2 -0
- package/dist/hooks/contribution.js.map +1 -0
- package/dist/hooks/dispatch.d.ts +30 -0
- package/dist/hooks/dispatch.d.ts.map +1 -0
- package/dist/hooks/dispatch.js +252 -0
- package/dist/hooks/dispatch.js.map +1 -0
- package/dist/hooks/errors.d.ts +100 -0
- package/dist/hooks/errors.d.ts.map +1 -0
- package/dist/hooks/errors.js +103 -0
- package/dist/hooks/errors.js.map +1 -0
- package/dist/hooks/index.d.ts +15 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +6 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/registry.d.ts +53 -0
- package/dist/hooks/registry.d.ts.map +1 -0
- package/dist/hooks/registry.js +139 -0
- package/dist/hooks/registry.js.map +1 -0
- package/dist/hooks/storage.d.ts +43 -0
- package/dist/hooks/storage.d.ts.map +1 -0
- package/dist/hooks/storage.js +2 -0
- package/dist/hooks/storage.js.map +1 -0
- package/dist/hooks/types.d.ts +324 -0
- package/dist/hooks/types.d.ts.map +1 -0
- package/dist/hooks/types.js +2 -0
- package/dist/hooks/types.js.map +1 -0
- package/dist/index.d.ts +26 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -5
- package/dist/index.js.map +1 -1
- package/dist/locale.d.ts +5 -1
- package/dist/locale.d.ts.map +1 -1
- package/dist/locale.js +6 -2
- package/dist/locale.js.map +1 -1
- package/dist/manifest-save.d.ts +255 -0
- package/dist/manifest-save.d.ts.map +1 -0
- package/dist/manifest-save.js +260 -0
- package/dist/manifest-save.js.map +1 -0
- package/dist/manifest.d.ts +1 -2
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +43 -44
- package/dist/manifest.js.map +1 -1
- package/dist/node-floor.d.ts +3 -0
- package/dist/node-floor.d.ts.map +1 -0
- package/dist/node-floor.js +3 -0
- package/dist/node-floor.js.map +1 -0
- package/dist/pages/create.d.ts +103 -0
- package/dist/pages/create.d.ts.map +1 -0
- package/dist/pages/create.js +117 -0
- package/dist/pages/create.js.map +1 -0
- package/dist/pages/publish.d.ts +59 -0
- package/dist/pages/publish.d.ts.map +1 -0
- package/dist/pages/publish.js +78 -0
- package/dist/pages/publish.js.map +1 -0
- package/dist/pages/save.d.ts +97 -0
- package/dist/pages/save.d.ts.map +1 -0
- package/dist/pages/save.js +138 -0
- package/dist/pages/save.js.map +1 -0
- package/dist/providers/factories.d.ts +65 -0
- package/dist/providers/factories.d.ts.map +1 -0
- package/dist/providers/factories.js +189 -0
- package/dist/providers/factories.js.map +1 -0
- package/dist/publish-item.d.ts +225 -0
- package/dist/publish-item.d.ts.map +1 -0
- package/dist/publish-item.js +210 -0
- package/dist/publish-item.js.map +1 -0
- package/dist/publish-rendered.d.ts.map +1 -1
- package/dist/publish-rendered.js +75 -6
- package/dist/publish-rendered.js.map +1 -1
- package/dist/publish-renderers.d.ts +132 -0
- package/dist/publish-renderers.d.ts.map +1 -0
- package/dist/publish-renderers.js +240 -0
- package/dist/publish-renderers.js.map +1 -0
- package/dist/publish-run.d.ts +223 -0
- package/dist/publish-run.d.ts.map +1 -0
- package/dist/publish-run.js +307 -0
- package/dist/publish-run.js.map +1 -0
- package/dist/publish.d.ts.map +1 -1
- package/dist/publish.js +1 -10
- package/dist/publish.js.map +1 -1
- package/dist/render-for-analysis.d.ts +24 -0
- package/dist/render-for-analysis.d.ts.map +1 -0
- package/dist/render-for-analysis.js +146 -0
- package/dist/render-for-analysis.js.map +1 -0
- package/dist/resolver.d.ts.map +1 -1
- package/dist/resolver.js +47 -23
- package/dist/resolver.js.map +1 -1
- package/dist/runtime/archive-marker.d.ts +62 -0
- package/dist/runtime/archive-marker.d.ts.map +1 -0
- package/dist/runtime/archive-marker.js +88 -0
- package/dist/runtime/archive-marker.js.map +1 -0
- package/dist/runtime/capability-gap-warnings.d.ts +42 -0
- package/dist/runtime/capability-gap-warnings.d.ts.map +1 -0
- package/dist/runtime/capability-gap-warnings.js +28 -0
- package/dist/runtime/capability-gap-warnings.js.map +1 -0
- package/dist/runtime/redirects-emit.d.ts +93 -0
- package/dist/runtime/redirects-emit.d.ts.map +1 -0
- package/dist/runtime/redirects-emit.js +89 -0
- package/dist/runtime/redirects-emit.js.map +1 -0
- package/dist/runtime/runtime-capabilities.d.ts +79 -0
- package/dist/runtime/runtime-capabilities.d.ts.map +1 -0
- package/dist/runtime/runtime-capabilities.js +60 -0
- package/dist/runtime/runtime-capabilities.js.map +1 -0
- package/dist/save-etag.d.ts +69 -0
- package/dist/save-etag.d.ts.map +1 -0
- package/dist/save-etag.js +118 -0
- package/dist/save-etag.js.map +1 -0
- package/dist/site-loader.d.ts +42 -4
- package/dist/site-loader.d.ts.map +1 -1
- package/dist/site-loader.js +27 -8
- package/dist/site-loader.js.map +1 -1
- package/dist/targets.d.ts +21 -12
- package/dist/targets.d.ts.map +1 -1
- package/dist/targets.js +27 -95
- package/dist/targets.js.map +1 -1
- package/dist/testing/admin-cache-contract.d.ts +52 -0
- package/dist/testing/admin-cache-contract.d.ts.map +1 -0
- package/dist/testing/admin-cache-contract.js +203 -0
- package/dist/testing/admin-cache-contract.js.map +1 -0
- package/dist/testing/index.d.ts +11 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +11 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/transforms/factories.d.ts +16 -0
- package/dist/transforms/factories.d.ts.map +1 -0
- package/dist/transforms/factories.js +18 -0
- package/dist/transforms/factories.js.map +1 -0
- package/dist/transforms/index.d.ts +10 -17
- package/dist/transforms/index.d.ts.map +1 -1
- package/dist/transforms/index.js +4 -28
- package/dist/transforms/index.js.map +1 -1
- package/dist/transforms/sharp.d.ts +15 -1
- package/dist/transforms/sharp.d.ts.map +1 -1
- package/dist/transforms/sharp.js +34 -20
- package/dist/transforms/sharp.js.map +1 -1
- package/dist/types.d.ts +379 -52
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +20 -1
- package/dist/types.js.map +1 -1
- package/dist/validation/alt-required-walker.d.ts +27 -0
- package/dist/validation/alt-required-walker.d.ts.map +1 -0
- package/dist/validation/alt-required-walker.js +108 -0
- package/dist/validation/alt-required-walker.js.map +1 -0
- package/dist/validation/default-registry.d.ts +12 -0
- package/dist/validation/default-registry.d.ts.map +1 -0
- package/dist/validation/default-registry.js +55 -0
- package/dist/validation/default-registry.js.map +1 -0
- package/dist/validation/publish-audit.d.ts +44 -0
- package/dist/validation/publish-audit.d.ts.map +1 -0
- package/dist/validation/publish-audit.js +64 -0
- package/dist/validation/publish-audit.js.map +1 -0
- package/dist/validation/registry.d.ts +23 -0
- package/dist/validation/registry.d.ts.map +1 -0
- package/dist/validation/registry.js +15 -0
- package/dist/validation/registry.js.map +1 -0
- package/dist/validation/save-delta.d.ts +46 -0
- package/dist/validation/save-delta.d.ts.map +1 -0
- package/dist/validation/save-delta.js +57 -0
- package/dist/validation/save-delta.js.map +1 -0
- package/dist/validation/scanner.d.ts +91 -0
- package/dist/validation/scanner.d.ts.map +1 -0
- package/dist/validation/scanner.js +327 -0
- package/dist/validation/scanner.js.map +1 -0
- package/dist/validation/template-impact.d.ts +52 -0
- package/dist/validation/template-impact.d.ts.map +1 -0
- package/dist/validation/template-impact.js +53 -0
- package/dist/validation/template-impact.js.map +1 -0
- package/dist/validation/types.d.ts +123 -0
- package/dist/validation/types.d.ts.map +1 -0
- package/dist/validation/types.js +7 -0
- package/dist/validation/types.js.map +1 -0
- package/dist/validation/validators/accessibility.d.ts +3 -0
- package/dist/validation/validators/accessibility.d.ts.map +1 -0
- package/dist/validation/validators/accessibility.js +106 -0
- package/dist/validation/validators/accessibility.js.map +1 -0
- package/dist/validation/validators/aliasof-points-to-archived.d.ts +40 -0
- package/dist/validation/validators/aliasof-points-to-archived.d.ts.map +1 -0
- package/dist/validation/validators/aliasof-points-to-archived.js +34 -0
- package/dist/validation/validators/aliasof-points-to-archived.js.map +1 -0
- package/dist/validation/validators/alt-required.d.ts +3 -0
- package/dist/validation/validators/alt-required.d.ts.map +1 -0
- package/dist/validation/validators/alt-required.js +118 -0
- package/dist/validation/validators/alt-required.js.map +1 -0
- package/dist/validation/validators/archive-not-supported-on-target.d.ts +3 -0
- package/dist/validation/validators/archive-not-supported-on-target.d.ts.map +1 -0
- package/dist/validation/validators/archive-not-supported-on-target.js +38 -0
- package/dist/validation/validators/archive-not-supported-on-target.js.map +1 -0
- package/dist/validation/validators/broken-links.d.ts +3 -0
- package/dist/validation/validators/broken-links.d.ts.map +1 -0
- package/dist/validation/validators/broken-links.js +190 -0
- package/dist/validation/validators/broken-links.js.map +1 -0
- package/dist/validation/validators/circular-alias.d.ts +36 -0
- package/dist/validation/validators/circular-alias.d.ts.map +1 -0
- package/dist/validation/validators/circular-alias.js +63 -0
- package/dist/validation/validators/circular-alias.js.map +1 -0
- package/dist/validation/validators/circular-fragment.d.ts +15 -0
- package/dist/validation/validators/circular-fragment.d.ts.map +1 -0
- package/dist/validation/validators/circular-fragment.js +97 -0
- package/dist/validation/validators/circular-fragment.js.map +1 -0
- package/dist/validation/validators/dangling-alias.d.ts +38 -0
- package/dist/validation/validators/dangling-alias.d.ts.map +1 -0
- package/dist/validation/validators/dangling-alias.js +31 -0
- package/dist/validation/validators/dangling-alias.js.map +1 -0
- package/dist/validation/validators/deploy-target-type-supported.d.ts +3 -0
- package/dist/validation/validators/deploy-target-type-supported.d.ts.map +1 -0
- package/dist/validation/validators/deploy-target-type-supported.js +32 -0
- package/dist/validation/validators/deploy-target-type-supported.js.map +1 -0
- package/dist/validation/validators/dynamic-route-conflict.d.ts +18 -0
- package/dist/validation/validators/dynamic-route-conflict.d.ts.map +1 -0
- package/dist/validation/validators/dynamic-route-conflict.js +80 -0
- package/dist/validation/validators/dynamic-route-conflict.js.map +1 -0
- package/dist/validation/validators/html-validity.d.ts +3 -0
- package/dist/validation/validators/html-validity.d.ts.map +1 -0
- package/dist/validation/validators/html-validity.js +89 -0
- package/dist/validation/validators/html-validity.js.map +1 -0
- package/dist/validation/validators/orphaned-locale-file.d.ts +21 -0
- package/dist/validation/validators/orphaned-locale-file.d.ts.map +1 -0
- package/dist/validation/validators/orphaned-locale-file.js +84 -0
- package/dist/validation/validators/orphaned-locale-file.js.map +1 -0
- package/dist/validation/validators/referenced-archived-without-alias.d.ts +3 -0
- package/dist/validation/validators/referenced-archived-without-alias.d.ts.map +1 -0
- package/dist/validation/validators/referenced-archived-without-alias.js +65 -0
- package/dist/validation/validators/referenced-archived-without-alias.js.map +1 -0
- package/dist/validation/validators/referenced-asset-exists.d.ts +13 -0
- package/dist/validation/validators/referenced-asset-exists.d.ts.map +1 -0
- package/dist/validation/validators/referenced-asset-exists.js +80 -0
- package/dist/validation/validators/referenced-asset-exists.js.map +1 -0
- package/dist/validation/validators/referenced-fragment-exists.d.ts +9 -0
- package/dist/validation/validators/referenced-fragment-exists.d.ts.map +1 -0
- package/dist/validation/validators/referenced-fragment-exists.js +52 -0
- package/dist/validation/validators/referenced-fragment-exists.js.map +1 -0
- package/dist/validation/validators/referenced-template-exists.d.ts +10 -0
- package/dist/validation/validators/referenced-template-exists.d.ts.map +1 -0
- package/dist/validation/validators/referenced-template-exists.js +74 -0
- package/dist/validation/validators/referenced-template-exists.js.map +1 -0
- package/dist/validation/validators/schema-conformance.d.ts +17 -0
- package/dist/validation/validators/schema-conformance.d.ts.map +1 -0
- package/dist/validation/validators/schema-conformance.js +94 -0
- package/dist/validation/validators/schema-conformance.js.map +1 -0
- package/dist/validation/validators/target-deploy-coverage.d.ts +3 -0
- package/dist/validation/validators/target-deploy-coverage.d.ts.map +1 -0
- package/dist/validation/validators/target-deploy-coverage.js +37 -0
- package/dist/validation/validators/target-deploy-coverage.js.map +1 -0
- package/dist/validation/validators/unused-fragment.d.ts +16 -0
- package/dist/validation/validators/unused-fragment.d.ts.map +1 -0
- package/dist/validation/validators/unused-fragment.js +86 -0
- package/dist/validation/validators/unused-fragment.js.map +1 -0
- package/package.json +54 -31
- package/admin-dist/assets/index-BO9-CXmW.css +0 -1
- package/admin-dist/assets/index-Ufu8zZH_.js +0 -668
- package/admin-dist/assets/rolldown-runtime-COnpUsM8.js +0 -1
- package/admin-dist/assets/vendor-rjsf-HKBAjOmQ.js +0 -32
- package/admin-dist/assets/vendor-tiptap-IyO99U4R.js +0 -142
- package/admin-dist/assets/vendor-vue-D3wBSmDf.js +0 -1
- package/dist/publish-locale.d.ts +0 -44
- package/dist/publish-locale.d.ts.map +0 -1
- package/dist/publish-locale.js +0 -103
- package/dist/publish-locale.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pseudonymize.d.ts","sourceRoot":"","sources":["../../src/audit/pseudonymize.ts"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,QAAQ,CAAA;AAElD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,CAkBxG;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAK3E"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Actor pseudonymization — opt-in privacy hardening for audit events.
|
|
3
|
+
*
|
|
4
|
+
* Per `design-audit.md`'s "Pseudonymization" section: when
|
|
5
|
+
* `admin.audit.actorPseudonym: 'sha256'` is configured, the event's
|
|
6
|
+
* `actor.id` is replaced with `sha256(sub + GAZETTA_AUDIT_ACTOR_SALT)
|
|
7
|
+
* .slice(0, 16)`. The `actor.email` field is dropped (low-entropy
|
|
8
|
+
* email gives weak pseudonymization).
|
|
9
|
+
*
|
|
10
|
+
* # When to opt in
|
|
11
|
+
*
|
|
12
|
+
* - External-sink configurations where audit events leave Gazetta's
|
|
13
|
+
* process boundary (CloudWatch, OTel, webhook) — limits PII
|
|
14
|
+
* leakage if sink storage is compromised
|
|
15
|
+
* - Regulated contexts demanding pseudonymization-by-default (some
|
|
16
|
+
* EU healthcare contexts, German telecommunications data
|
|
17
|
+
* retention)
|
|
18
|
+
* - Multi-tenant SIEM correlation with shared salt across systems
|
|
19
|
+
*
|
|
20
|
+
* # Salt management
|
|
21
|
+
*
|
|
22
|
+
* - Salt is a credential. Stored in `GAZETTA_AUDIT_ACTOR_SALT` env
|
|
23
|
+
* var per Universal Provider Requirement #3. Never in
|
|
24
|
+
* `site.config.ts`.
|
|
25
|
+
* - 16+ random bytes recommended.
|
|
26
|
+
* - Salt rotation breaks historic correlation by design — rotate
|
|
27
|
+
* per security policy (annually typical); document rotation
|
|
28
|
+
* dates so forensic queries can scope by salt-era.
|
|
29
|
+
* - Multi-instance: every instance reads the same env → deterministic
|
|
30
|
+
* hash across instances.
|
|
31
|
+
*
|
|
32
|
+
* # SOLID lenses
|
|
33
|
+
*
|
|
34
|
+
* - SRP: pseudonymization only. Doesn't dispatch, doesn't extract
|
|
35
|
+
* identity. Pure function over `(actor, mode)`.
|
|
36
|
+
* - DIP: takes the salt as a string parameter (dependency-injected
|
|
37
|
+
* by the caller); doesn't read `process.env` directly so tests
|
|
38
|
+
* can pass deterministic salts.
|
|
39
|
+
*/
|
|
40
|
+
import { createHash } from 'node:crypto';
|
|
41
|
+
/**
|
|
42
|
+
* Apply the configured pseudonymization mode to an actor snapshot.
|
|
43
|
+
*
|
|
44
|
+
* - `'none'` (default) — pass through unchanged.
|
|
45
|
+
* - `'sha256'` — replace `id` with the salted hash prefix; drop
|
|
46
|
+
* `email`.
|
|
47
|
+
*
|
|
48
|
+
* The original `actor` is never mutated; returns a new object.
|
|
49
|
+
*
|
|
50
|
+
* Throws when `mode === 'sha256'` and `salt` is empty/undefined —
|
|
51
|
+
* pseudonymization without a salt is a misconfiguration that would
|
|
52
|
+
* silently produce reversible-by-rainbow-table hashes. Caller (Cut
|
|
53
|
+
* 5's wiring) should catch this at boot via `AuditConfigurationError`
|
|
54
|
+
* when the env var is missing.
|
|
55
|
+
*/
|
|
56
|
+
export function pseudonymizeActor(actor, mode, salt) {
|
|
57
|
+
if (mode === 'none')
|
|
58
|
+
return actor;
|
|
59
|
+
// mode === 'sha256'
|
|
60
|
+
if (!salt || salt.length === 0) {
|
|
61
|
+
throw new Error('actorPseudonym: sha256 requires a non-empty salt (set GAZETTA_AUDIT_ACTOR_SALT environment variable)');
|
|
62
|
+
}
|
|
63
|
+
const hash = createHash('sha256')
|
|
64
|
+
.update(actor.id + salt)
|
|
65
|
+
.digest('hex')
|
|
66
|
+
.slice(0, 16);
|
|
67
|
+
return {
|
|
68
|
+
id: hash,
|
|
69
|
+
// email dropped — low-entropy email gives weak pseudonymization.
|
|
70
|
+
role: actor.role,
|
|
71
|
+
trustMode: actor.trustMode,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Compute the pseudonymized id for an actor — exposed for forensic
|
|
76
|
+
* queries: an operator who knows the upstream sub + salt can
|
|
77
|
+
* compute the pseudonymized id and search the audit log without
|
|
78
|
+
* the recorder being involved.
|
|
79
|
+
*/
|
|
80
|
+
export function computePseudonymizedId(rawSub, salt) {
|
|
81
|
+
return createHash('sha256')
|
|
82
|
+
.update(rawSub + salt)
|
|
83
|
+
.digest('hex')
|
|
84
|
+
.slice(0, 16);
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=pseudonymize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pseudonymize.js","sourceRoot":"","sources":["../../src/audit/pseudonymize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAKxC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAiB,EAAE,IAAwB,EAAE,IAAa;IAC1F,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,CAAA;IACjC,oBAAoB;IACpB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CACb,sGAAsG,CACvG,CAAA;IACH,CAAC;IACD,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC;SAC9B,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC;SACvB,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IACf,OAAO;QACL,EAAE,EAAE,IAAI;QACR,iEAAiE;QACjE,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAc,EAAE,IAAY;IACjE,OAAO,UAAU,CAAC,QAAQ,CAAC;SACxB,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;SACrB,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AACjB,CAAC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit-recording dispatcher. The fan-out + fail-open layer that
|
|
3
|
+
* separates recording sites (save/publish/delete/restore handlers)
|
|
4
|
+
* from individual `AuditProvider` implementations.
|
|
5
|
+
*
|
|
6
|
+
* # Locked design — synchronous fail-open, parallel fan-out
|
|
7
|
+
*
|
|
8
|
+
* Per `design-audit.md`'s "Recording timing":
|
|
9
|
+
*
|
|
10
|
+
* - **Synchronous** — operation awaits the audit attempt. If the
|
|
11
|
+
* user got a success response, the audit attempt was completed.
|
|
12
|
+
* Async queuing would lose in-flight events on process restart.
|
|
13
|
+
* - **Fail-open by default** — provider failures never block the
|
|
14
|
+
* write. Operators in compliance contexts opt into `strict: true`
|
|
15
|
+
* (any provider failure blocks the write).
|
|
16
|
+
* - **Parallel fan-out** — `Promise.allSettled` so two providers'
|
|
17
|
+
* latencies don't stack. Failures are independent.
|
|
18
|
+
*
|
|
19
|
+
* # Failure log — no payload
|
|
20
|
+
*
|
|
21
|
+
* Per Universal Provider Requirement #5: "When audit recording fails
|
|
22
|
+
* (fail-open), the failure log entry MUST NOT contain event payload."
|
|
23
|
+
* The recorder logs only `{ provider, eventId, category }` — never
|
|
24
|
+
* the actor, scope, or metadata. Prevents PII side-channels into
|
|
25
|
+
* application stderr / log shipping.
|
|
26
|
+
*
|
|
27
|
+
* # Strict mode
|
|
28
|
+
*
|
|
29
|
+
* For HIPAA / SOC 2 compliance contexts where "audit recording
|
|
30
|
+
* confirmed successful" is a hard prerequisite for the write to
|
|
31
|
+
* proceed. The recorder's caller (Cut 5's wired handlers) checks
|
|
32
|
+
* the `failed` flag in the result and aborts the write when strict
|
|
33
|
+
* mode is on.
|
|
34
|
+
*
|
|
35
|
+
* # SOLID lenses
|
|
36
|
+
*
|
|
37
|
+
* - SRP: dispatch + failure-log only. Doesn't construct providers,
|
|
38
|
+
* doesn't extract identity (Cut 4 handles privacy / source-IP
|
|
39
|
+
* extraction).
|
|
40
|
+
* - DIP: takes a `readonly AuditProvider[]` and an opaque logger
|
|
41
|
+
* callback; no coupling to specific providers or to Hono.
|
|
42
|
+
*/
|
|
43
|
+
import type { AuditEvent } from './types.js';
|
|
44
|
+
import type { AuditProvider } from './provider.js';
|
|
45
|
+
export interface AuditFailureLog {
|
|
46
|
+
/** Provider name that failed. Per design: log identifies which sink dropped. */
|
|
47
|
+
provider: string;
|
|
48
|
+
/**
|
|
49
|
+
* Categorical reason — `transport` for network/HTTP failures,
|
|
50
|
+
* `serialize` for unparseable events, `quota` for sink full.
|
|
51
|
+
* Surface to log aggregators for filtering.
|
|
52
|
+
*/
|
|
53
|
+
category: 'transport' | 'serialize' | 'quota';
|
|
54
|
+
/** Reason text for diagnostics. PII-free; never the event payload. */
|
|
55
|
+
reason: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Logger callback signature. Production wires to `pino` per
|
|
59
|
+
* `design-logging.md`; tests inject stubs to assert shape + count.
|
|
60
|
+
*
|
|
61
|
+
* Note: NEVER receives the event payload. The logger contract is
|
|
62
|
+
* narrow on purpose — operator's log-shipping pipeline can't
|
|
63
|
+
* accidentally surface PII via the audit failure path.
|
|
64
|
+
*/
|
|
65
|
+
export type AuditFailureLogger = (entry: AuditFailureLog) => void;
|
|
66
|
+
export interface RecordToAllOptions {
|
|
67
|
+
/** Providers to fan out to. Order doesn't matter (parallel). */
|
|
68
|
+
providers: ReadonlyArray<AuditProvider>;
|
|
69
|
+
/**
|
|
70
|
+
* Strict mode flag. `true` → caller blocks the write on any
|
|
71
|
+
* provider failure (per design-audit.md "Strict mode opt-in").
|
|
72
|
+
* `false` (default) → fail-open; operations always proceed.
|
|
73
|
+
*/
|
|
74
|
+
strict?: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Failure logger. Production wires `pino`. Tests inject `vi.fn()`.
|
|
77
|
+
* When undefined, failures pass silently — useful for tests that
|
|
78
|
+
* don't care about log output, but production should always wire
|
|
79
|
+
* a real logger for diagnosability.
|
|
80
|
+
*/
|
|
81
|
+
logFailure?: AuditFailureLogger;
|
|
82
|
+
}
|
|
83
|
+
export interface RecordResult {
|
|
84
|
+
/** Number of providers that successfully recorded. */
|
|
85
|
+
succeeded: number;
|
|
86
|
+
/**
|
|
87
|
+
* Number of providers that failed. Always 0 when no providers are
|
|
88
|
+
* configured. Caller uses this in strict mode to abort the write.
|
|
89
|
+
*/
|
|
90
|
+
failed: number;
|
|
91
|
+
/** Per-provider failure entries — for diagnostic surfaces. */
|
|
92
|
+
failures: ReadonlyArray<AuditFailureLog>;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Fan-out an event to every configured provider in parallel.
|
|
96
|
+
* Returns counts + per-failure entries; never throws (per Universal
|
|
97
|
+
* Provider Requirement #5). Strict-mode behavior is the caller's
|
|
98
|
+
* concern — the recorder does the dispatch + log; the caller branches
|
|
99
|
+
* on `result.failed > 0` to abort the write.
|
|
100
|
+
*/
|
|
101
|
+
export declare function recordToAll(event: AuditEvent, opts: RecordToAllOptions): Promise<RecordResult>;
|
|
102
|
+
//# sourceMappingURL=recorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/audit/recorder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAElD,MAAM,WAAW,eAAe;IAC9B,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,QAAQ,EAAE,WAAW,GAAG,WAAW,GAAG,OAAO,CAAA;IAC7C,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;AAEjE,MAAM,WAAW,kBAAkB;IACjC,gEAAgE;IAChE,SAAS,EAAE,aAAa,CAAC,aAAa,CAAC,CAAA;IACvC;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,kBAAkB,CAAA;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAA;IACd,8DAA8D;IAC9D,QAAQ,EAAE,aAAa,CAAC,eAAe,CAAC,CAAA;CACzC;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAuBpG"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fan-out an event to every configured provider in parallel.
|
|
3
|
+
* Returns counts + per-failure entries; never throws (per Universal
|
|
4
|
+
* Provider Requirement #5). Strict-mode behavior is the caller's
|
|
5
|
+
* concern — the recorder does the dispatch + log; the caller branches
|
|
6
|
+
* on `result.failed > 0` to abort the write.
|
|
7
|
+
*/
|
|
8
|
+
export async function recordToAll(event, opts) {
|
|
9
|
+
const { providers, logFailure } = opts;
|
|
10
|
+
if (providers.length === 0)
|
|
11
|
+
return { succeeded: 0, failed: 0, failures: [] };
|
|
12
|
+
const results = await Promise.allSettled(providers.map(p => p.record(event)));
|
|
13
|
+
const failures = [];
|
|
14
|
+
let succeeded = 0;
|
|
15
|
+
for (let i = 0; i < results.length; i++) {
|
|
16
|
+
const result = results[i];
|
|
17
|
+
const provider = providers[i];
|
|
18
|
+
if (result.status === 'fulfilled') {
|
|
19
|
+
succeeded++;
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
const entry = {
|
|
23
|
+
provider: provider.name,
|
|
24
|
+
category: categorizeFailure(result.reason),
|
|
25
|
+
reason: extractReason(result.reason),
|
|
26
|
+
};
|
|
27
|
+
failures.push(entry);
|
|
28
|
+
logFailure?.(entry);
|
|
29
|
+
}
|
|
30
|
+
return { succeeded, failed: failures.length, failures };
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Categorize a thrown reason into the closed-enum category. Maps
|
|
34
|
+
* `AuditTransportError.category` directly when present; falls back
|
|
35
|
+
* to `'transport'` for unknown errors (most common — provider
|
|
36
|
+
* SDKs rarely throw structured failure types).
|
|
37
|
+
*/
|
|
38
|
+
function categorizeFailure(reason) {
|
|
39
|
+
if (reason instanceof Error) {
|
|
40
|
+
// AuditTransportError carries category as a typed field.
|
|
41
|
+
const maybeCategory = reason.category;
|
|
42
|
+
if (maybeCategory === 'transport' || maybeCategory === 'serialize' || maybeCategory === 'quota') {
|
|
43
|
+
return maybeCategory;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return 'transport';
|
|
47
|
+
}
|
|
48
|
+
function extractReason(reason) {
|
|
49
|
+
if (reason instanceof Error)
|
|
50
|
+
return reason.message;
|
|
51
|
+
if (typeof reason === 'string')
|
|
52
|
+
return reason;
|
|
53
|
+
return 'unknown failure';
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../src/audit/recorder.ts"],"names":[],"mappings":"AAkGA;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAiB,EAAE,IAAwB;IAC3E,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,IAAI,CAAA;IACtC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAA;IAE5E,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAC7E,MAAM,QAAQ,GAAsB,EAAE,CAAA;IACtC,IAAI,SAAS,GAAG,CAAC,CAAA;IACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;QACzB,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAA;QAC7B,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAClC,SAAS,EAAE,CAAA;YACX,SAAQ;QACV,CAAC;QACD,MAAM,KAAK,GAAoB;YAC7B,QAAQ,EAAE,QAAQ,CAAC,IAAI;YACvB,QAAQ,EAAE,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC;YAC1C,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC;SACrC,CAAA;QACD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACpB,UAAU,EAAE,CAAC,KAAK,CAAC,CAAA;IACrB,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAA;AACzD,CAAC;AAED;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,MAAe;IACxC,IAAI,MAAM,YAAY,KAAK,EAAE,CAAC;QAC5B,yDAAyD;QACzD,MAAM,aAAa,GAAI,MAAiC,CAAC,QAAQ,CAAA;QACjE,IAAI,aAAa,KAAK,WAAW,IAAI,aAAa,KAAK,WAAW,IAAI,aAAa,KAAK,OAAO,EAAE,CAAC;YAChG,OAAO,aAAa,CAAA;QACtB,CAAC;IACH,CAAC;IACD,OAAO,WAAW,CAAA;AACpB,CAAC;AAED,SAAS,aAAa,CAAC,MAAe;IACpC,IAAI,MAAM,YAAY,KAAK;QAAE,OAAO,MAAM,CAAC,OAAO,CAAA;IAClD,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAA;IAC7C,OAAO,iBAAiB,CAAA;AAC1B,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit retention pruner.
|
|
3
|
+
*
|
|
4
|
+
* Per design-audit.md "Retention": audit retention is configurable
|
|
5
|
+
* independently from content history retention. Two dimensions:
|
|
6
|
+
*
|
|
7
|
+
* - `events` — max event count kept across all per-instance JSONL
|
|
8
|
+
* files. When exceeded, oldest events evicted (timestamp-sort
|
|
9
|
+
* ascending; drop from the head).
|
|
10
|
+
* - `maxAgeMonths` — max age in months. Events older than the
|
|
11
|
+
* cutoff evicted regardless of count.
|
|
12
|
+
*
|
|
13
|
+
* Operator sets one or both. When neither set, the pruner is a no-op
|
|
14
|
+
* (audit accumulates indefinitely until storage budget exhausted —
|
|
15
|
+
* operator's choice; documented).
|
|
16
|
+
*
|
|
17
|
+
* # JSONL storage shape
|
|
18
|
+
*
|
|
19
|
+
* Per `HistoryAuditProvider`, events live in
|
|
20
|
+
* `.gazetta/audit/events-{instance-id}.jsonl` — one file per admin
|
|
21
|
+
* instance. The pruner walks every events file, parses lines into
|
|
22
|
+
* AuditEvent objects, applies retention, and rewrites each file with
|
|
23
|
+
* the surviving lines. Per-file rewrite preserves the per-instance
|
|
24
|
+
* scoping (no cross-instance interleaving).
|
|
25
|
+
*
|
|
26
|
+
* # Multi-instance correctness
|
|
27
|
+
*
|
|
28
|
+
* Per-revision file granularity (each instance's file is independent)
|
|
29
|
+
* means concurrent pruners on the same target converge. If instance A
|
|
30
|
+
* is rewriting events-A.jsonl while instance B is rewriting
|
|
31
|
+
* events-B.jsonl, no race. If two pruners on different hosts try to
|
|
32
|
+
* rewrite the SAME events-A.jsonl simultaneously (two instances with
|
|
33
|
+
* the same hostname / K_REVISION), the storage provider's atomic
|
|
34
|
+
* write-then-rename keeps the file consistent — last-write-wins is
|
|
35
|
+
* fine because both pruners compute the same surviving set from the
|
|
36
|
+
* same input bytes.
|
|
37
|
+
*
|
|
38
|
+
* # Why JSONL-line pruning, not whole-file deletion
|
|
39
|
+
*
|
|
40
|
+
* The pruner has to handle events file-by-file because:
|
|
41
|
+
* - Different instances have different event mixes; deleting an
|
|
42
|
+
* entire instance's file would lose events newer than the cutoff
|
|
43
|
+
* - Events within one instance's file span time; some pruned, some
|
|
44
|
+
* kept — selective line removal is the right granularity
|
|
45
|
+
*
|
|
46
|
+
* # Returns: PruneResult
|
|
47
|
+
*
|
|
48
|
+
* Diagnostic info for the caller's log + metrics. `eventsKept` and
|
|
49
|
+
* `eventsEvicted` together = total events pre-prune.
|
|
50
|
+
*
|
|
51
|
+
* # SOLID lenses
|
|
52
|
+
*
|
|
53
|
+
* - SRP: retention only; doesn't construct providers, doesn't
|
|
54
|
+
* audit pruner-events itself (would create recursion).
|
|
55
|
+
* - DIP: takes a StorageProvider — works against filesystem, R2,
|
|
56
|
+
* S3, Azure Blob uniformly.
|
|
57
|
+
*/
|
|
58
|
+
import type { StorageProvider } from '../types.js';
|
|
59
|
+
export interface AuditRetentionConfig {
|
|
60
|
+
/** Max event count kept. When exceeded, oldest evicted. */
|
|
61
|
+
events?: number;
|
|
62
|
+
/** Max age in months. Events older than the cutoff evicted. */
|
|
63
|
+
maxAgeMonths?: number | null;
|
|
64
|
+
}
|
|
65
|
+
export interface PruneResult {
|
|
66
|
+
/** Number of events present before pruning. */
|
|
67
|
+
eventsBefore: number;
|
|
68
|
+
/** Number of events surviving. */
|
|
69
|
+
eventsKept: number;
|
|
70
|
+
/** Number of events evicted. */
|
|
71
|
+
eventsEvicted: number;
|
|
72
|
+
/** Files rewritten (only files with at least one eviction). */
|
|
73
|
+
filesRewritten: number;
|
|
74
|
+
/** Files inspected (every events file under .gazetta/audit/). */
|
|
75
|
+
filesInspected: number;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Walk the audit JSONL files, evict events that violate retention,
|
|
79
|
+
* rewrite each affected file. No-op when retention config has neither
|
|
80
|
+
* `events` nor `maxAgeMonths` set.
|
|
81
|
+
*/
|
|
82
|
+
export declare function pruneAuditEvents(storage: StorageProvider, config: AuditRetentionConfig): Promise<PruneResult>;
|
|
83
|
+
//# sourceMappingURL=retention.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.d.ts","sourceRoot":"","sources":["../../src/audit/retention.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAGlD,MAAM,WAAW,oBAAoB;IACnC,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,YAAY,EAAE,MAAM,CAAA;IACpB,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAA;IAClB,gCAAgC;IAChC,aAAa,EAAE,MAAM,CAAA;IACrB,+DAA+D;IAC/D,cAAc,EAAE,MAAM,CAAA;IACtB,iEAAiE;IACjE,cAAc,EAAE,MAAM,CAAA;CACvB;AAID;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC,CA0HnH"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
const AUDIT_DIR = '.gazetta/audit';
|
|
2
|
+
/**
|
|
3
|
+
* Walk the audit JSONL files, evict events that violate retention,
|
|
4
|
+
* rewrite each affected file. No-op when retention config has neither
|
|
5
|
+
* `events` nor `maxAgeMonths` set.
|
|
6
|
+
*/
|
|
7
|
+
export async function pruneAuditEvents(storage, config) {
|
|
8
|
+
// No retention configured → no-op. Operator opted out or never opted in.
|
|
9
|
+
const hasEventsCap = config.events !== undefined && config.events !== null;
|
|
10
|
+
const hasAgeCap = config.maxAgeMonths !== undefined && config.maxAgeMonths !== null && config.maxAgeMonths > 0;
|
|
11
|
+
if (!hasEventsCap && !hasAgeCap) {
|
|
12
|
+
return { eventsBefore: 0, eventsKept: 0, eventsEvicted: 0, filesRewritten: 0, filesInspected: 0 };
|
|
13
|
+
}
|
|
14
|
+
// Compute the age cutoff once so all files use the same boundary.
|
|
15
|
+
// `maxAgeMonths` is a real-month subtraction (Date.setMonth handles
|
|
16
|
+
// leap years + variable month length); ISO-8601 string compare works
|
|
17
|
+
// on the resulting timestamp.
|
|
18
|
+
const ageCutoff = hasAgeCap ? computeAgeCutoff(config.maxAgeMonths) : null;
|
|
19
|
+
// Walk the events directory. Missing dir = no events to prune.
|
|
20
|
+
let entries;
|
|
21
|
+
try {
|
|
22
|
+
entries = await storage.readDir(AUDIT_DIR);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return { eventsBefore: 0, eventsKept: 0, eventsEvicted: 0, filesRewritten: 0, filesInspected: 0 };
|
|
26
|
+
}
|
|
27
|
+
// Read every events file into memory with its source path. We need
|
|
28
|
+
// the global event count for `events` cap enforcement (oldest-across-
|
|
29
|
+
// files evicted, not per-file), so we collect all events first.
|
|
30
|
+
const filesInspected = [];
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
if (entry.isDirectory)
|
|
33
|
+
continue;
|
|
34
|
+
if (!entry.name.startsWith('events-') || !entry.name.endsWith('.jsonl'))
|
|
35
|
+
continue;
|
|
36
|
+
const path = `${AUDIT_DIR}/${entry.name}`;
|
|
37
|
+
const content = await storage.readFile(path);
|
|
38
|
+
const lines = content.split('\n');
|
|
39
|
+
const events = [];
|
|
40
|
+
let rawLineCount = 0;
|
|
41
|
+
for (const line of lines) {
|
|
42
|
+
const trimmed = line.trim();
|
|
43
|
+
if (!trimmed)
|
|
44
|
+
continue;
|
|
45
|
+
rawLineCount++;
|
|
46
|
+
try {
|
|
47
|
+
events.push(JSON.parse(trimmed));
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// Malformed line — skip + count as raw line so the rewrite
|
|
51
|
+
// doesn't accidentally include it. Same posture as the reader
|
|
52
|
+
// in HistoryAuditProvider.
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
filesInspected.push({ path, events, rawLineCount });
|
|
56
|
+
}
|
|
57
|
+
const eventsBefore = filesInspected.reduce((sum, f) => sum + f.events.length, 0);
|
|
58
|
+
if (eventsBefore === 0) {
|
|
59
|
+
return {
|
|
60
|
+
eventsBefore: 0,
|
|
61
|
+
eventsKept: 0,
|
|
62
|
+
eventsEvicted: 0,
|
|
63
|
+
filesRewritten: 0,
|
|
64
|
+
filesInspected: filesInspected.length,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
// Phase 1: age cutoff (per-file evaluation; events older than the
|
|
68
|
+
// cutoff are evicted regardless of where they sit in the global
|
|
69
|
+
// ordering).
|
|
70
|
+
for (const file of filesInspected) {
|
|
71
|
+
if (ageCutoff !== null) {
|
|
72
|
+
file.events = file.events.filter(e => e.timestamp >= ageCutoff);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Phase 2: count cap (global). Build the global ordering once:
|
|
76
|
+
// sort all surviving events by timestamp (oldest first), evict
|
|
77
|
+
// from the head until we're under the cap. The eviction set is
|
|
78
|
+
// matched back to its source file by reference identity.
|
|
79
|
+
let evictedFromCap = new Set();
|
|
80
|
+
if (hasEventsCap) {
|
|
81
|
+
const allSurviving = [];
|
|
82
|
+
for (const file of filesInspected) {
|
|
83
|
+
for (const event of file.events) {
|
|
84
|
+
allSurviving.push({ file, event });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
allSurviving.sort((a, b) => a.event.timestamp.localeCompare(b.event.timestamp));
|
|
88
|
+
const overflow = allSurviving.length - config.events;
|
|
89
|
+
if (overflow > 0) {
|
|
90
|
+
evictedFromCap = new Set(allSurviving.slice(0, overflow).map(x => x.event));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Phase 3: rewrite each file whose surviving set differs from the
|
|
94
|
+
// pre-prune set. Reasons a file rewrites:
|
|
95
|
+
// - age-cutoff already mutated `file.events`
|
|
96
|
+
// - count-cap is going to evict additional events
|
|
97
|
+
// - malformed JSONL lines on disk (rawLineCount > parsed events) —
|
|
98
|
+
// incidental hygiene; the line never made it through parse and
|
|
99
|
+
// wouldn't survive a re-read either, so we drop it during the
|
|
100
|
+
// rewrite. Doesn't count toward `eventsEvicted` (the metric
|
|
101
|
+
// reports parsed-event deltas only).
|
|
102
|
+
let filesRewritten = 0;
|
|
103
|
+
let eventsKeptTotal = 0;
|
|
104
|
+
for (const file of filesInspected) {
|
|
105
|
+
const surviving = evictedFromCap.size > 0 ? file.events.filter(e => !evictedFromCap.has(e)) : file.events;
|
|
106
|
+
eventsKeptTotal += surviving.length;
|
|
107
|
+
const parsedDelta = file.events.length - surviving.length;
|
|
108
|
+
const malformedLines = file.rawLineCount - file.events.length;
|
|
109
|
+
if (parsedDelta === 0 && malformedLines === 0)
|
|
110
|
+
continue;
|
|
111
|
+
// Rewrite. JSONL convention: one event per line + trailing newline.
|
|
112
|
+
// Empty file (all events pruned) → write an empty string so the
|
|
113
|
+
// file remains as a marker (deleting would force concurrent
|
|
114
|
+
// appenders to mkdir; safer to keep the file with a zero-line body).
|
|
115
|
+
const rewritten = surviving.map(e => JSON.stringify(e)).join('\n');
|
|
116
|
+
const final = rewritten ? rewritten + '\n' : '';
|
|
117
|
+
await storage.writeFile(file.path, final);
|
|
118
|
+
filesRewritten++;
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
eventsBefore,
|
|
122
|
+
eventsKept: eventsKeptTotal,
|
|
123
|
+
eventsEvicted: eventsBefore - eventsKeptTotal,
|
|
124
|
+
filesRewritten,
|
|
125
|
+
filesInspected: filesInspected.length,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Subtract `months` calendar months from `now` and return the ISO
|
|
130
|
+
* timestamp boundary. Events with `timestamp >= cutoff` are kept;
|
|
131
|
+
* older events evicted.
|
|
132
|
+
*
|
|
133
|
+
* Uses Date.setMonth so leap years and variable-length months are
|
|
134
|
+
* handled correctly (3 months back from 2026-05-31 is 2026-02-28,
|
|
135
|
+
* not 2026-02-31).
|
|
136
|
+
*/
|
|
137
|
+
function computeAgeCutoff(months) {
|
|
138
|
+
const cutoff = new Date();
|
|
139
|
+
cutoff.setMonth(cutoff.getMonth() - months);
|
|
140
|
+
return cutoff.toISOString();
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=retention.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.js","sourceRoot":"","sources":["../../src/audit/retention.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type SourceIpMode = 'none' | 'raw' | 'hashed' | 'truncated';
|
|
2
|
+
export interface SourceIpExtractionContext {
|
|
3
|
+
/** Trust mode determines which header carries the client IP. */
|
|
4
|
+
trustMode: string;
|
|
5
|
+
/** TCP peer IP (when available — Hono's c.req.raw.headers may not expose). */
|
|
6
|
+
peerIp?: string;
|
|
7
|
+
/** All request headers (for X-Forwarded-For / Cf-Connecting-IP / X-Real-IP lookup). */
|
|
8
|
+
headers: ReadonlyMap<string, string>;
|
|
9
|
+
/**
|
|
10
|
+
* For trust modes that read X-Forwarded-For, how many trusted
|
|
11
|
+
* proxies are between Gazetta and the client. Counts back from
|
|
12
|
+
* the rightmost; everything to the right is trusted, the
|
|
13
|
+
* resulting leftmost-of-trusted is the client.
|
|
14
|
+
*
|
|
15
|
+
* Defaults to 1 (single proxy in front of Gazetta — most common).
|
|
16
|
+
*/
|
|
17
|
+
trustedProxyCount?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Extract the client IP per the trust mode's header convention.
|
|
21
|
+
* Returns null when the configured header is missing — the caller
|
|
22
|
+
* should omit the `sourceIp` field from the event (per design:
|
|
23
|
+
* "Explicitly absent is more honest" than fake values).
|
|
24
|
+
*/
|
|
25
|
+
export declare function extractSourceIp(ctx: SourceIpExtractionContext): string | null;
|
|
26
|
+
/**
|
|
27
|
+
* Apply the configured source-IP mode. Returns null when the mode
|
|
28
|
+
* is `'none'` OR when the extracted IP is null/empty/malformed —
|
|
29
|
+
* the caller omits the field.
|
|
30
|
+
*/
|
|
31
|
+
export declare function processSourceIp(rawIp: string | null, mode: SourceIpMode, salt?: string): string | null;
|
|
32
|
+
//# sourceMappingURL=source-ip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-ip.d.ts","sourceRoot":"","sources":["../../src/audit/source-ip.ts"],"names":[],"mappings":"AAsCA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,WAAW,CAAA;AAElE,MAAM,WAAW,yBAAyB;IACxC,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAA;IACjB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,uFAAuF;IACvF,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,yBAAyB,GAAG,MAAM,GAAG,IAAI,CAqC7E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkBtG"}
|