@urateam/core 0.1.4 → 0.1.9
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/dist/__tests__/agent-profiles.test.d.ts +2 -0
- package/dist/__tests__/agent-profiles.test.d.ts.map +1 -0
- package/dist/__tests__/agent-profiles.test.js +120 -0
- package/dist/__tests__/agent-profiles.test.js.map +1 -0
- package/dist/__tests__/audit/audit-e2e.test.d.ts +2 -0
- package/dist/__tests__/audit/audit-e2e.test.d.ts.map +1 -0
- package/dist/__tests__/audit/audit-e2e.test.js +56 -0
- package/dist/__tests__/audit/audit-e2e.test.js.map +1 -0
- package/dist/__tests__/audit/csv.test.d.ts +2 -0
- package/dist/__tests__/audit/csv.test.d.ts.map +1 -0
- package/dist/__tests__/audit/csv.test.js +134 -0
- package/dist/__tests__/audit/csv.test.js.map +1 -0
- package/dist/__tests__/audit/events.test.d.ts +2 -0
- package/dist/__tests__/audit/events.test.d.ts.map +1 -0
- package/dist/__tests__/audit/events.test.js +45 -0
- package/dist/__tests__/audit/events.test.js.map +1 -0
- package/dist/__tests__/audit/policy-events.test.d.ts +2 -0
- package/dist/__tests__/audit/policy-events.test.d.ts.map +1 -0
- package/dist/__tests__/audit/policy-events.test.js +49 -0
- package/dist/__tests__/audit/policy-events.test.js.map +1 -0
- package/dist/__tests__/audit/projection.test.d.ts +2 -0
- package/dist/__tests__/audit/projection.test.d.ts.map +1 -0
- package/dist/__tests__/audit/projection.test.js +76 -0
- package/dist/__tests__/audit/projection.test.js.map +1 -0
- package/dist/__tests__/audit/rbac-events.test.d.ts +2 -0
- package/dist/__tests__/audit/rbac-events.test.d.ts.map +1 -0
- package/dist/__tests__/audit/rbac-events.test.js +56 -0
- package/dist/__tests__/audit/rbac-events.test.js.map +1 -0
- package/dist/__tests__/audit/reader.test.d.ts +2 -0
- package/dist/__tests__/audit/reader.test.d.ts.map +1 -0
- package/dist/__tests__/audit/reader.test.js +133 -0
- package/dist/__tests__/audit/reader.test.js.map +1 -0
- package/dist/__tests__/audit/retention.test.d.ts +2 -0
- package/dist/__tests__/audit/retention.test.d.ts.map +1 -0
- package/dist/__tests__/audit/retention.test.js +48 -0
- package/dist/__tests__/audit/retention.test.js.map +1 -0
- package/dist/__tests__/audit/sso-events.test.d.ts +2 -0
- package/dist/__tests__/audit/sso-events.test.d.ts.map +1 -0
- package/dist/__tests__/audit/sso-events.test.js +49 -0
- package/dist/__tests__/audit/sso-events.test.js.map +1 -0
- package/dist/__tests__/audit/writer.test.d.ts +2 -0
- package/dist/__tests__/audit/writer.test.d.ts.map +1 -0
- package/dist/__tests__/audit/writer.test.js +67 -0
- package/dist/__tests__/audit/writer.test.js.map +1 -0
- package/dist/__tests__/audit-immutability.test.d.ts +2 -0
- package/dist/__tests__/audit-immutability.test.d.ts.map +1 -0
- package/dist/__tests__/audit-immutability.test.js +61 -0
- package/dist/__tests__/audit-immutability.test.js.map +1 -0
- package/dist/__tests__/audit-types.test.d.ts +2 -0
- package/dist/__tests__/audit-types.test.d.ts.map +1 -0
- package/dist/__tests__/audit-types.test.js +35 -0
- package/dist/__tests__/audit-types.test.js.map +1 -0
- package/dist/__tests__/auth/session-store.test.d.ts +2 -0
- package/dist/__tests__/auth/session-store.test.d.ts.map +1 -0
- package/dist/__tests__/auth/session-store.test.js +65 -0
- package/dist/__tests__/auth/session-store.test.js.map +1 -0
- package/dist/__tests__/auth/sso-config.test.d.ts +2 -0
- package/dist/__tests__/auth/sso-config.test.d.ts.map +1 -0
- package/dist/__tests__/auth/sso-config.test.js +75 -0
- package/dist/__tests__/auth/sso-config.test.js.map +1 -0
- package/dist/__tests__/auth/sso-feature-flag.test.d.ts +2 -0
- package/dist/__tests__/auth/sso-feature-flag.test.d.ts.map +1 -0
- package/dist/__tests__/auth/sso-feature-flag.test.js +33 -0
- package/dist/__tests__/auth/sso-feature-flag.test.js.map +1 -0
- package/dist/__tests__/auth/user-role-round-trip.test.d.ts +2 -0
- package/dist/__tests__/auth/user-role-round-trip.test.d.ts.map +1 -0
- package/dist/__tests__/auth/user-role-round-trip.test.js +30 -0
- package/dist/__tests__/auth/user-role-round-trip.test.js.map +1 -0
- package/dist/__tests__/auth/user-store.test.d.ts +2 -0
- package/dist/__tests__/auth/user-store.test.d.ts.map +1 -0
- package/dist/__tests__/auth/user-store.test.js +119 -0
- package/dist/__tests__/auth/user-store.test.js.map +1 -0
- package/dist/__tests__/auth/workos-client.test.d.ts +2 -0
- package/dist/__tests__/auth/workos-client.test.d.ts.map +1 -0
- package/dist/__tests__/auth/workos-client.test.js +17 -0
- package/dist/__tests__/auth/workos-client.test.js.map +1 -0
- package/dist/__tests__/auto-merge.test.js +2 -1
- package/dist/__tests__/auto-merge.test.js.map +1 -1
- package/dist/__tests__/cost/aggregate.test.d.ts +2 -0
- package/dist/__tests__/cost/aggregate.test.d.ts.map +1 -0
- package/dist/__tests__/cost/aggregate.test.js +358 -0
- package/dist/__tests__/cost/aggregate.test.js.map +1 -0
- package/dist/__tests__/cost/csv.test.d.ts +2 -0
- package/dist/__tests__/cost/csv.test.d.ts.map +1 -0
- package/dist/__tests__/cost/csv.test.js +109 -0
- package/dist/__tests__/cost/csv.test.js.map +1 -0
- package/dist/__tests__/cost/per-run.test.d.ts +2 -0
- package/dist/__tests__/cost/per-run.test.d.ts.map +1 -0
- package/dist/__tests__/cost/per-run.test.js +64 -0
- package/dist/__tests__/cost/per-run.test.js.map +1 -0
- package/dist/__tests__/cost/rates.test.d.ts +2 -0
- package/dist/__tests__/cost/rates.test.d.ts.map +1 -0
- package/dist/__tests__/cost/rates.test.js +47 -0
- package/dist/__tests__/cost/rates.test.js.map +1 -0
- package/dist/__tests__/cost/rollup.test.d.ts +2 -0
- package/dist/__tests__/cost/rollup.test.d.ts.map +1 -0
- package/dist/__tests__/cost/rollup.test.js +187 -0
- package/dist/__tests__/cost/rollup.test.js.map +1 -0
- package/dist/__tests__/cost-defensive.test.d.ts +2 -0
- package/dist/__tests__/cost-defensive.test.d.ts.map +1 -0
- package/dist/__tests__/cost-defensive.test.js +123 -0
- package/dist/__tests__/cost-defensive.test.js.map +1 -0
- package/dist/__tests__/cost-integration.test.d.ts +2 -0
- package/dist/__tests__/cost-integration.test.d.ts.map +1 -0
- package/dist/__tests__/cost-integration.test.js +80 -0
- package/dist/__tests__/cost-integration.test.js.map +1 -0
- package/dist/__tests__/cost-license.test.d.ts +2 -0
- package/dist/__tests__/cost-license.test.d.ts.map +1 -0
- package/dist/__tests__/cost-license.test.js +23 -0
- package/dist/__tests__/cost-license.test.js.map +1 -0
- package/dist/__tests__/cost-types.test.d.ts +2 -0
- package/dist/__tests__/cost-types.test.d.ts.map +1 -0
- package/dist/__tests__/cost-types.test.js +65 -0
- package/dist/__tests__/cost-types.test.js.map +1 -0
- package/dist/__tests__/db-audit-schema.test.d.ts +2 -0
- package/dist/__tests__/db-audit-schema.test.d.ts.map +1 -0
- package/dist/__tests__/db-audit-schema.test.js +35 -0
- package/dist/__tests__/db-audit-schema.test.js.map +1 -0
- package/dist/__tests__/db-cost-rollups-schema.test.d.ts +2 -0
- package/dist/__tests__/db-cost-rollups-schema.test.d.ts.map +1 -0
- package/dist/__tests__/db-cost-rollups-schema.test.js +28 -0
- package/dist/__tests__/db-cost-rollups-schema.test.js.map +1 -0
- package/dist/__tests__/db-rbac-schema.test.d.ts +2 -0
- package/dist/__tests__/db-rbac-schema.test.d.ts.map +1 -0
- package/dist/__tests__/db-rbac-schema.test.js +32 -0
- package/dist/__tests__/db-rbac-schema.test.js.map +1 -0
- package/dist/__tests__/db-sso-schema.test.d.ts +2 -0
- package/dist/__tests__/db-sso-schema.test.d.ts.map +1 -0
- package/dist/__tests__/db-sso-schema.test.js +48 -0
- package/dist/__tests__/db-sso-schema.test.js.map +1 -0
- package/dist/__tests__/executor.test.js +3 -1
- package/dist/__tests__/executor.test.js.map +1 -1
- package/dist/__tests__/extract-handoff.test.js +109 -0
- package/dist/__tests__/extract-handoff.test.js.map +1 -1
- package/dist/__tests__/helpers/license.d.ts +3 -0
- package/dist/__tests__/helpers/license.d.ts.map +1 -0
- package/dist/__tests__/helpers/license.js +74 -0
- package/dist/__tests__/helpers/license.js.map +1 -0
- package/dist/__tests__/license-audit-event.test.d.ts +2 -0
- package/dist/__tests__/license-audit-event.test.d.ts.map +1 -0
- package/dist/__tests__/license-audit-event.test.js +60 -0
- package/dist/__tests__/license-audit-event.test.js.map +1 -0
- package/dist/__tests__/license-end-to-end.test.d.ts +2 -0
- package/dist/__tests__/license-end-to-end.test.d.ts.map +1 -0
- package/dist/__tests__/license-end-to-end.test.js +75 -0
- package/dist/__tests__/license-end-to-end.test.js.map +1 -0
- package/dist/__tests__/license-public-key.test.d.ts +2 -0
- package/dist/__tests__/license-public-key.test.d.ts.map +1 -0
- package/dist/__tests__/license-public-key.test.js +18 -0
- package/dist/__tests__/license-public-key.test.js.map +1 -0
- package/dist/__tests__/license.test.js +195 -32
- package/dist/__tests__/license.test.js.map +1 -1
- package/dist/__tests__/pm-action-audit-events.test.d.ts +2 -0
- package/dist/__tests__/pm-action-audit-events.test.d.ts.map +1 -0
- package/dist/__tests__/pm-action-audit-events.test.js +185 -0
- package/dist/__tests__/pm-action-audit-events.test.js.map +1 -0
- package/dist/__tests__/pm-approvals.test.js +1 -1
- package/dist/__tests__/pm-approvals.test.js.map +1 -1
- package/dist/__tests__/pm-audit-retention-step.test.d.ts +2 -0
- package/dist/__tests__/pm-audit-retention-step.test.d.ts.map +1 -0
- package/dist/__tests__/pm-audit-retention-step.test.js +126 -0
- package/dist/__tests__/pm-audit-retention-step.test.js.map +1 -0
- package/dist/__tests__/pm-budget-alerts.test.d.ts +2 -0
- package/dist/__tests__/pm-budget-alerts.test.d.ts.map +1 -0
- package/dist/__tests__/pm-budget-alerts.test.js +128 -0
- package/dist/__tests__/pm-budget-alerts.test.js.map +1 -0
- package/dist/__tests__/pm-budget-refused-event.test.d.ts +2 -0
- package/dist/__tests__/pm-budget-refused-event.test.d.ts.map +1 -0
- package/dist/__tests__/pm-budget-refused-event.test.js +141 -0
- package/dist/__tests__/pm-budget-refused-event.test.js.map +1 -0
- package/dist/__tests__/pm-budget.test.js +138 -42
- package/dist/__tests__/pm-budget.test.js.map +1 -1
- package/dist/__tests__/pm-cost-rollup-step.test.d.ts +2 -0
- package/dist/__tests__/pm-cost-rollup-step.test.d.ts.map +1 -0
- package/dist/__tests__/pm-cost-rollup-step.test.js +113 -0
- package/dist/__tests__/pm-cost-rollup-step.test.js.map +1 -0
- package/dist/__tests__/pm-scheduler.test.js +48 -21
- package/dist/__tests__/pm-scheduler.test.js.map +1 -1
- package/dist/__tests__/pm-slack.test.js +37 -0
- package/dist/__tests__/pm-slack.test.js.map +1 -1
- package/dist/__tests__/pm-sso-prune-step.test.d.ts +2 -0
- package/dist/__tests__/pm-sso-prune-step.test.d.ts.map +1 -0
- package/dist/__tests__/pm-sso-prune-step.test.js +103 -0
- package/dist/__tests__/pm-sso-prune-step.test.js.map +1 -0
- package/dist/__tests__/pm-types.test.js +130 -1
- package/dist/__tests__/pm-types.test.js.map +1 -1
- package/dist/__tests__/policy/auto-merge-reviewer-gate.test.d.ts +2 -0
- package/dist/__tests__/policy/auto-merge-reviewer-gate.test.d.ts.map +1 -0
- package/dist/__tests__/policy/auto-merge-reviewer-gate.test.js +50 -0
- package/dist/__tests__/policy/auto-merge-reviewer-gate.test.js.map +1 -0
- package/dist/__tests__/policy/cost-gate.test.d.ts +2 -0
- package/dist/__tests__/policy/cost-gate.test.d.ts.map +1 -0
- package/dist/__tests__/policy/cost-gate.test.js +27 -0
- package/dist/__tests__/policy/cost-gate.test.js.map +1 -0
- package/dist/__tests__/policy/evaluate.test.d.ts +2 -0
- package/dist/__tests__/policy/evaluate.test.d.ts.map +1 -0
- package/dist/__tests__/policy/evaluate.test.js +105 -0
- package/dist/__tests__/policy/evaluate.test.js.map +1 -0
- package/dist/__tests__/policy/override.test.d.ts +2 -0
- package/dist/__tests__/policy/override.test.d.ts.map +1 -0
- package/dist/__tests__/policy/override.test.js +26 -0
- package/dist/__tests__/policy/override.test.js.map +1 -0
- package/dist/__tests__/policy/path-gate.test.d.ts +2 -0
- package/dist/__tests__/policy/path-gate.test.d.ts.map +1 -0
- package/dist/__tests__/policy/path-gate.test.js +31 -0
- package/dist/__tests__/policy/path-gate.test.js.map +1 -0
- package/dist/__tests__/policy/pr-reviewer-wiring.test.d.ts +2 -0
- package/dist/__tests__/policy/pr-reviewer-wiring.test.d.ts.map +1 -0
- package/dist/__tests__/policy/pr-reviewer-wiring.test.js +24 -0
- package/dist/__tests__/policy/pr-reviewer-wiring.test.js.map +1 -0
- package/dist/__tests__/policy/reviewer-gate.test.d.ts +2 -0
- package/dist/__tests__/policy/reviewer-gate.test.d.ts.map +1 -0
- package/dist/__tests__/policy/reviewer-gate.test.js +125 -0
- package/dist/__tests__/policy/reviewer-gate.test.js.map +1 -0
- package/dist/__tests__/policy-license.test.d.ts +2 -0
- package/dist/__tests__/policy-license.test.d.ts.map +1 -0
- package/dist/__tests__/policy-license.test.js +31 -0
- package/dist/__tests__/policy-license.test.js.map +1 -0
- package/dist/__tests__/policy-types.test.d.ts +2 -0
- package/dist/__tests__/policy-types.test.d.ts.map +1 -0
- package/dist/__tests__/policy-types.test.js +49 -0
- package/dist/__tests__/policy-types.test.js.map +1 -0
- package/dist/__tests__/ralph-gate.test.js +6 -4
- package/dist/__tests__/ralph-gate.test.js.map +1 -1
- package/dist/__tests__/rbac/bootstrap.test.d.ts +2 -0
- package/dist/__tests__/rbac/bootstrap.test.d.ts.map +1 -0
- package/dist/__tests__/rbac/bootstrap.test.js +62 -0
- package/dist/__tests__/rbac/bootstrap.test.js.map +1 -0
- package/dist/__tests__/rbac/matrix.test.d.ts +2 -0
- package/dist/__tests__/rbac/matrix.test.d.ts.map +1 -0
- package/dist/__tests__/rbac/matrix.test.js +62 -0
- package/dist/__tests__/rbac/matrix.test.js.map +1 -0
- package/dist/__tests__/rbac/user-role-store.test.d.ts +2 -0
- package/dist/__tests__/rbac/user-role-store.test.d.ts.map +1 -0
- package/dist/__tests__/rbac/user-role-store.test.js +78 -0
- package/dist/__tests__/rbac/user-role-store.test.js.map +1 -0
- package/dist/__tests__/rbac-defensive.test.d.ts +2 -0
- package/dist/__tests__/rbac-defensive.test.d.ts.map +1 -0
- package/dist/__tests__/rbac-defensive.test.js +29 -0
- package/dist/__tests__/rbac-defensive.test.js.map +1 -0
- package/dist/__tests__/rbac-integration.test.d.ts +2 -0
- package/dist/__tests__/rbac-integration.test.d.ts.map +1 -0
- package/dist/__tests__/rbac-integration.test.js +58 -0
- package/dist/__tests__/rbac-integration.test.js.map +1 -0
- package/dist/__tests__/rbac-license.test.d.ts +2 -0
- package/dist/__tests__/rbac-license.test.d.ts.map +1 -0
- package/dist/__tests__/rbac-license.test.js +27 -0
- package/dist/__tests__/rbac-license.test.js.map +1 -0
- package/dist/__tests__/reproduce-bec113-pagination-warning.test.js +14 -2
- package/dist/__tests__/reproduce-bec113-pagination-warning.test.js.map +1 -1
- package/dist/__tests__/reproduce-bec62.test.js +10 -3
- package/dist/__tests__/reproduce-bec62.test.js.map +1 -1
- package/dist/__tests__/reproduce-bec91-stuck-in-progress.test.js +24 -4
- package/dist/__tests__/reproduce-bec91-stuck-in-progress.test.js.map +1 -1
- package/dist/__tests__/server.test.js +46 -2
- package/dist/__tests__/server.test.js.map +1 -1
- package/dist/__tests__/sso-license.test.d.ts +2 -0
- package/dist/__tests__/sso-license.test.d.ts.map +1 -0
- package/dist/__tests__/sso-license.test.js +49 -0
- package/dist/__tests__/sso-license.test.js.map +1 -0
- package/dist/__tests__/stage-models.test.js.map +1 -1
- package/dist/__tests__/start-todo.test.js +5 -0
- package/dist/__tests__/start-todo.test.js.map +1 -1
- package/dist/__tests__/webhook-handler.test.js +138 -0
- package/dist/__tests__/webhook-handler.test.js.map +1 -1
- package/dist/audit/config-fingerprint.d.ts +10 -0
- package/dist/audit/config-fingerprint.d.ts.map +1 -0
- package/dist/audit/config-fingerprint.js +20 -0
- package/dist/audit/config-fingerprint.js.map +1 -0
- package/dist/audit/csv.d.ts +8 -0
- package/dist/audit/csv.d.ts.map +1 -0
- package/dist/audit/csv.js +56 -0
- package/dist/audit/csv.js.map +1 -0
- package/dist/audit/events.d.ts +107 -0
- package/dist/audit/events.d.ts.map +1 -0
- package/dist/audit/events.js +221 -0
- package/dist/audit/events.js.map +1 -0
- package/dist/audit/index.d.ts +7 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +7 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/projection.d.ts +38 -0
- package/dist/audit/projection.d.ts.map +1 -0
- package/dist/audit/projection.js +109 -0
- package/dist/audit/projection.js.map +1 -0
- package/dist/audit/reader.d.ts +42 -0
- package/dist/audit/reader.d.ts.map +1 -0
- package/dist/audit/reader.js +243 -0
- package/dist/audit/reader.js.map +1 -0
- package/dist/audit/retention.d.ts +12 -0
- package/dist/audit/retention.d.ts.map +1 -0
- package/dist/audit/retention.js +23 -0
- package/dist/audit/retention.js.map +1 -0
- package/dist/audit/writer.d.ts +26 -0
- package/dist/audit/writer.d.ts.map +1 -0
- package/dist/audit/writer.js +54 -0
- package/dist/audit/writer.js.map +1 -0
- package/dist/auth/index.d.ts +5 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +5 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/session-store.d.ts +17 -0
- package/dist/auth/session-store.d.ts.map +1 -0
- package/dist/auth/session-store.js +59 -0
- package/dist/auth/session-store.js.map +1 -0
- package/dist/auth/sso-config.d.ts +14 -0
- package/dist/auth/sso-config.d.ts.map +1 -0
- package/dist/auth/sso-config.js +50 -0
- package/dist/auth/sso-config.js.map +1 -0
- package/dist/auth/user-store.d.ts +33 -0
- package/dist/auth/user-store.d.ts.map +1 -0
- package/dist/auth/user-store.js +71 -0
- package/dist/auth/user-store.js.map +1 -0
- package/dist/auth/workos-client.d.ts +46 -0
- package/dist/auth/workos-client.d.ts.map +1 -0
- package/dist/auth/workos-client.js +66 -0
- package/dist/auth/workos-client.js.map +1 -0
- package/dist/cost/aggregate.d.ts +49 -0
- package/dist/cost/aggregate.d.ts.map +1 -0
- package/dist/cost/aggregate.js +364 -0
- package/dist/cost/aggregate.js.map +1 -0
- package/dist/cost/csv.d.ts +12 -0
- package/dist/cost/csv.d.ts.map +1 -0
- package/dist/cost/csv.js +79 -0
- package/dist/cost/csv.js.map +1 -0
- package/dist/cost/index.d.ts +7 -0
- package/dist/cost/index.d.ts.map +1 -0
- package/dist/cost/index.js +7 -0
- package/dist/cost/index.js.map +1 -0
- package/dist/cost/per-run.d.ts +31 -0
- package/dist/cost/per-run.d.ts.map +1 -0
- package/dist/cost/per-run.js +35 -0
- package/dist/cost/per-run.js.map +1 -0
- package/dist/cost/rates.d.ts +27 -0
- package/dist/cost/rates.d.ts.map +1 -0
- package/dist/cost/rates.js +26 -0
- package/dist/cost/rates.js.map +1 -0
- package/dist/cost/rollup.d.ts +17 -0
- package/dist/cost/rollup.d.ts.map +1 -0
- package/dist/cost/rollup.js +164 -0
- package/dist/cost/rollup.js.map +1 -0
- package/dist/cost/types.d.ts +54 -0
- package/dist/cost/types.d.ts.map +1 -0
- package/dist/cost/types.js +2 -0
- package/dist/cost/types.js.map +1 -0
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +79 -1
- package/dist/db/client.js.map +1 -1
- package/dist/db/migrations/postgres/006_spend_caps.sql +14 -0
- package/dist/db/migrations/postgres/007_audit_events.sql +19 -0
- package/dist/db/migrations/postgres/008_cost_rollups.sql +19 -0
- package/dist/db/migrations/postgres/008_sso.sql +20 -0
- package/dist/db/migrations/sqlite/005_spend_caps.sql +16 -0
- package/dist/db/migrations/sqlite/006_audit_events.sql +19 -0
- package/dist/db/migrations/sqlite/007_cost_rollups.sql +19 -0
- package/dist/db/migrations/sqlite/007_sso.sql +20 -0
- package/dist/db/schema.d.ts +802 -0
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +80 -1
- package/dist/db/schema.js.map +1 -1
- package/dist/executor/executor.js +2 -2
- package/dist/executor/executor.js.map +1 -1
- package/dist/executor/extract-handoff.d.ts +7 -1
- package/dist/executor/extract-handoff.d.ts.map +1 -1
- package/dist/executor/extract-handoff.js +51 -11
- package/dist/executor/extract-handoff.js.map +1 -1
- package/dist/executor/handoff.d.ts.map +1 -1
- package/dist/executor/handoff.js +6 -0
- package/dist/executor/handoff.js.map +1 -1
- package/dist/executor/index.d.ts +1 -1
- package/dist/executor/index.d.ts.map +1 -1
- package/dist/executor/index.js +1 -1
- package/dist/executor/index.js.map +1 -1
- package/dist/executor/profiles.d.ts +42 -0
- package/dist/executor/profiles.d.ts.map +1 -1
- package/dist/executor/profiles.js +147 -2
- package/dist/executor/profiles.js.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/license-public-key.d.ts +15 -0
- package/dist/license-public-key.d.ts.map +1 -0
- package/dist/license-public-key.js +15 -0
- package/dist/license-public-key.js.map +1 -0
- package/dist/license.d.ts +30 -5
- package/dist/license.d.ts.map +1 -1
- package/dist/license.js +142 -12
- package/dist/license.js.map +1 -1
- package/dist/pipeline/runner.d.ts +1 -7
- package/dist/pipeline/runner.d.ts.map +1 -1
- package/dist/pipeline/runner.js +168 -21
- package/dist/pipeline/runner.js.map +1 -1
- package/dist/pm/actions/promote.d.ts +3 -0
- package/dist/pm/actions/promote.d.ts.map +1 -1
- package/dist/pm/actions/promote.js +12 -0
- package/dist/pm/actions/promote.js.map +1 -1
- package/dist/pm/actions/resolve-approvals.d.ts.map +1 -1
- package/dist/pm/actions/resolve-approvals.js +16 -0
- package/dist/pm/actions/resolve-approvals.js.map +1 -1
- package/dist/pm/actions/start-todo.d.ts +3 -0
- package/dist/pm/actions/start-todo.d.ts.map +1 -1
- package/dist/pm/actions/start-todo.js +5 -1
- package/dist/pm/actions/start-todo.js.map +1 -1
- package/dist/pm/actions/triage.d.ts +3 -0
- package/dist/pm/actions/triage.d.ts.map +1 -1
- package/dist/pm/actions/triage.js +8 -0
- package/dist/pm/actions/triage.js.map +1 -1
- package/dist/pm/budget-alerts.d.ts +18 -0
- package/dist/pm/budget-alerts.d.ts.map +1 -0
- package/dist/pm/budget-alerts.js +100 -0
- package/dist/pm/budget-alerts.js.map +1 -0
- package/dist/pm/budget.d.ts +28 -5
- package/dist/pm/budget.d.ts.map +1 -1
- package/dist/pm/budget.js +115 -39
- package/dist/pm/budget.js.map +1 -1
- package/dist/pm/scheduler.d.ts +8 -4
- package/dist/pm/scheduler.d.ts.map +1 -1
- package/dist/pm/scheduler.js +128 -5
- package/dist/pm/scheduler.js.map +1 -1
- package/dist/pm/slack.d.ts.map +1 -1
- package/dist/pm/slack.js +11 -0
- package/dist/pm/slack.js.map +1 -1
- package/dist/pm/types.d.ts +36 -0
- package/dist/pm/types.d.ts.map +1 -1
- package/dist/pm/types.js +12 -0
- package/dist/pm/types.js.map +1 -1
- package/dist/policy/cost-gate.d.ts +3 -0
- package/dist/policy/cost-gate.d.ts.map +1 -0
- package/dist/policy/cost-gate.js +11 -0
- package/dist/policy/cost-gate.js.map +1 -0
- package/dist/policy/evaluate.d.ts +32 -0
- package/dist/policy/evaluate.d.ts.map +1 -0
- package/dist/policy/evaluate.js +61 -0
- package/dist/policy/evaluate.js.map +1 -0
- package/dist/policy/index.d.ts +7 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +7 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/override.d.ts +23 -0
- package/dist/policy/override.d.ts.map +1 -0
- package/dist/policy/override.js +26 -0
- package/dist/policy/override.js.map +1 -0
- package/dist/policy/path-gate.d.ts +3 -0
- package/dist/policy/path-gate.d.ts.map +1 -0
- package/dist/policy/path-gate.js +20 -0
- package/dist/policy/path-gate.js.map +1 -0
- package/dist/policy/reviewer-gate.d.ts +45 -0
- package/dist/policy/reviewer-gate.d.ts.map +1 -0
- package/dist/policy/reviewer-gate.js +77 -0
- package/dist/policy/reviewer-gate.js.map +1 -0
- package/dist/policy/types.d.ts +7 -0
- package/dist/policy/types.d.ts.map +1 -0
- package/dist/policy/types.js +2 -0
- package/dist/policy/types.js.map +1 -0
- package/dist/rbac/errors.d.ts +7 -0
- package/dist/rbac/errors.d.ts.map +1 -0
- package/dist/rbac/errors.js +13 -0
- package/dist/rbac/errors.js.map +1 -0
- package/dist/rbac/index.d.ts +5 -0
- package/dist/rbac/index.d.ts.map +1 -0
- package/dist/rbac/index.js +5 -0
- package/dist/rbac/index.js.map +1 -0
- package/dist/rbac/matrix.d.ts +35 -0
- package/dist/rbac/matrix.d.ts.map +1 -0
- package/dist/rbac/matrix.js +42 -0
- package/dist/rbac/matrix.js.map +1 -0
- package/dist/rbac/types.d.ts +2 -0
- package/dist/rbac/types.d.ts.map +1 -0
- package/dist/rbac/types.js +2 -0
- package/dist/rbac/types.js.map +1 -0
- package/dist/rbac/user-role-store.d.ts +27 -0
- package/dist/rbac/user-role-store.d.ts.map +1 -0
- package/dist/rbac/user-role-store.js +148 -0
- package/dist/rbac/user-role-store.js.map +1 -0
- package/dist/repo/git.d.ts +9 -0
- package/dist/repo/git.d.ts.map +1 -1
- package/dist/repo/git.js +11 -0
- package/dist/repo/git.js.map +1 -1
- package/dist/repo/github.d.ts +4 -0
- package/dist/repo/github.d.ts.map +1 -1
- package/dist/repo/github.js +27 -0
- package/dist/repo/github.js.map +1 -1
- package/dist/repo/gitlab.d.ts +4 -0
- package/dist/repo/gitlab.d.ts.map +1 -1
- package/dist/repo/gitlab.js +7 -0
- package/dist/repo/gitlab.js.map +1 -1
- package/dist/server.d.ts +6 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +16 -10
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +155 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +83 -0
- package/dist/types.js.map +1 -1
- package/dist/util/glob.d.ts +7 -0
- package/dist/util/glob.d.ts.map +1 -0
- package/dist/util/glob.js +20 -0
- package/dist/util/glob.js.map +1 -0
- package/dist/webhook/handler.d.ts +3 -0
- package/dist/webhook/handler.d.ts.map +1 -1
- package/dist/webhook/handler.js +36 -2
- package/dist/webhook/handler.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { and, desc, eq, gte, inArray, lte } from "drizzle-orm";
|
|
2
|
+
import { auditEvents, pipelineRuns, pmApprovals, budgetAlerts } from "../db/schema.js";
|
|
3
|
+
import { projectPipelineRun, projectPmApproval, projectBudgetAlert } from "./projection.js";
|
|
4
|
+
function encodeCursor(c) {
|
|
5
|
+
return Buffer.from(JSON.stringify(c), "utf8").toString("base64url");
|
|
6
|
+
}
|
|
7
|
+
function decodeCursor(s) {
|
|
8
|
+
return JSON.parse(Buffer.from(s, "base64url").toString("utf8"));
|
|
9
|
+
}
|
|
10
|
+
function parseNativeRow(row) {
|
|
11
|
+
return {
|
|
12
|
+
id: row.id,
|
|
13
|
+
timestamp: row.timestamp,
|
|
14
|
+
eventType: row.eventType,
|
|
15
|
+
actor: row.actor,
|
|
16
|
+
actorType: row.actorType,
|
|
17
|
+
scope: row.scope ?? null,
|
|
18
|
+
runId: row.runId ?? null,
|
|
19
|
+
issueId: row.issueId ?? null,
|
|
20
|
+
inputTokens: row.inputTokens ?? 0,
|
|
21
|
+
outputTokens: row.outputTokens ?? 0,
|
|
22
|
+
payload: (() => {
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(row.payload ?? "{}");
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return {};
|
|
28
|
+
}
|
|
29
|
+
})(),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Lists audit events by merging native `audit_events` rows with events
|
|
34
|
+
* projected from `pipeline_runs`, `pm_approvals`, and `budget_alerts`.
|
|
35
|
+
*
|
|
36
|
+
* Supports filtering by time window, scope, event type, actor prefix, run/issue id,
|
|
37
|
+
* and full-text search on payload/actor. Paginates via opaque cursor, sorted desc
|
|
38
|
+
* by (timestamp, id).
|
|
39
|
+
*/
|
|
40
|
+
export async function listAuditEvents(db, filters = {}) {
|
|
41
|
+
const limit = Math.min(filters.limit ?? 50, 500);
|
|
42
|
+
const cursor = filters.cursor ? decodeCursor(filters.cursor) : null;
|
|
43
|
+
const cursorTs = cursor ? new Date(cursor.ts) : null;
|
|
44
|
+
// Native audit_events query
|
|
45
|
+
const nativeConditions = [];
|
|
46
|
+
if (filters.from)
|
|
47
|
+
nativeConditions.push(gte(auditEvents.timestamp, filters.from));
|
|
48
|
+
if (filters.to)
|
|
49
|
+
nativeConditions.push(lte(auditEvents.timestamp, filters.to));
|
|
50
|
+
if (filters.scope)
|
|
51
|
+
nativeConditions.push(eq(auditEvents.scope, filters.scope));
|
|
52
|
+
if (filters.eventTypes?.length)
|
|
53
|
+
nativeConditions.push(inArray(auditEvents.eventType, filters.eventTypes));
|
|
54
|
+
if (filters.runId)
|
|
55
|
+
nativeConditions.push(eq(auditEvents.runId, filters.runId));
|
|
56
|
+
if (filters.issueId)
|
|
57
|
+
nativeConditions.push(eq(auditEvents.issueId, filters.issueId));
|
|
58
|
+
if (cursorTs)
|
|
59
|
+
nativeConditions.push(lte(auditEvents.timestamp, cursorTs));
|
|
60
|
+
const nativeRows = await db
|
|
61
|
+
.select()
|
|
62
|
+
.from(auditEvents)
|
|
63
|
+
.where(nativeConditions.length ? and(...nativeConditions) : undefined)
|
|
64
|
+
.orderBy(desc(auditEvents.timestamp))
|
|
65
|
+
.limit(limit * 4);
|
|
66
|
+
// Projected: pipeline_runs
|
|
67
|
+
const runConditions = [];
|
|
68
|
+
if (filters.from)
|
|
69
|
+
runConditions.push(gte(pipelineRuns.startedAt, filters.from));
|
|
70
|
+
if (filters.to)
|
|
71
|
+
runConditions.push(lte(pipelineRuns.startedAt, filters.to));
|
|
72
|
+
if (filters.runId)
|
|
73
|
+
runConditions.push(eq(pipelineRuns.id, filters.runId));
|
|
74
|
+
if (filters.issueId)
|
|
75
|
+
runConditions.push(eq(pipelineRuns.issueId, filters.issueId));
|
|
76
|
+
if (cursorTs)
|
|
77
|
+
runConditions.push(lte(pipelineRuns.startedAt, cursorTs));
|
|
78
|
+
const runRows = await db
|
|
79
|
+
.select()
|
|
80
|
+
.from(pipelineRuns)
|
|
81
|
+
.where(runConditions.length ? and(...runConditions) : undefined)
|
|
82
|
+
.orderBy(desc(pipelineRuns.startedAt))
|
|
83
|
+
.limit(limit * 4);
|
|
84
|
+
// Projected: pm_approvals (filter by createdAt)
|
|
85
|
+
// Projected pm_approvals always have scope=null, so skip the query entirely
|
|
86
|
+
// when a scope filter is set — avoids an unbounded fetch.
|
|
87
|
+
let apprRows = [];
|
|
88
|
+
if (!filters.scope) {
|
|
89
|
+
const apprConditions = [];
|
|
90
|
+
if (filters.from)
|
|
91
|
+
apprConditions.push(gte(pmApprovals.createdAt, filters.from));
|
|
92
|
+
if (filters.to)
|
|
93
|
+
apprConditions.push(lte(pmApprovals.createdAt, filters.to));
|
|
94
|
+
if (cursorTs)
|
|
95
|
+
apprConditions.push(lte(pmApprovals.createdAt, cursorTs));
|
|
96
|
+
apprRows = await db
|
|
97
|
+
.select()
|
|
98
|
+
.from(pmApprovals)
|
|
99
|
+
.where(apprConditions.length ? and(...apprConditions) : undefined)
|
|
100
|
+
.orderBy(desc(pmApprovals.createdAt))
|
|
101
|
+
.limit(limit * 4);
|
|
102
|
+
}
|
|
103
|
+
// Projected: budget_alerts (filter by firedAt)
|
|
104
|
+
const alertConditions = [];
|
|
105
|
+
if (filters.from)
|
|
106
|
+
alertConditions.push(gte(budgetAlerts.firedAt, filters.from));
|
|
107
|
+
if (filters.to)
|
|
108
|
+
alertConditions.push(lte(budgetAlerts.firedAt, filters.to));
|
|
109
|
+
if (filters.scope)
|
|
110
|
+
alertConditions.push(eq(budgetAlerts.scope, filters.scope));
|
|
111
|
+
if (cursorTs)
|
|
112
|
+
alertConditions.push(lte(budgetAlerts.firedAt, cursorTs));
|
|
113
|
+
const alertRows = await db
|
|
114
|
+
.select()
|
|
115
|
+
.from(budgetAlerts)
|
|
116
|
+
.where(alertConditions.length ? and(...alertConditions) : undefined)
|
|
117
|
+
.orderBy(desc(budgetAlerts.firedAt))
|
|
118
|
+
.limit(limit * 4);
|
|
119
|
+
const merged = [
|
|
120
|
+
...nativeRows.map(parseNativeRow),
|
|
121
|
+
...runRows.flatMap((r) => projectPipelineRun(r)),
|
|
122
|
+
...apprRows.flatMap((r) => projectPmApproval(r)),
|
|
123
|
+
...alertRows.map((r) => projectBudgetAlert(r)),
|
|
124
|
+
];
|
|
125
|
+
// Apply filters that weren't pushed to SQL (actor prefix, q, eventType on projected,
|
|
126
|
+
// scope on projected, and the cursor tiebreak).
|
|
127
|
+
const filtered = merged.filter((e) => {
|
|
128
|
+
if (filters.from && e.timestamp < filters.from)
|
|
129
|
+
return false;
|
|
130
|
+
if (filters.to && e.timestamp > filters.to)
|
|
131
|
+
return false;
|
|
132
|
+
if (filters.scope && e.scope !== filters.scope)
|
|
133
|
+
return false;
|
|
134
|
+
if (filters.eventTypes?.length && !filters.eventTypes.includes(e.eventType))
|
|
135
|
+
return false;
|
|
136
|
+
if (filters.actor && !e.actor.startsWith(filters.actor))
|
|
137
|
+
return false;
|
|
138
|
+
if (filters.runId && e.runId !== filters.runId)
|
|
139
|
+
return false;
|
|
140
|
+
if (filters.issueId && e.issueId !== filters.issueId)
|
|
141
|
+
return false;
|
|
142
|
+
if (filters.q) {
|
|
143
|
+
const hay = JSON.stringify(e.payload) + " " + e.actor;
|
|
144
|
+
if (!hay.toLowerCase().includes(filters.q.toLowerCase()))
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
if (cursor) {
|
|
148
|
+
const cTs = new Date(cursor.ts).getTime();
|
|
149
|
+
if (e.timestamp.getTime() > cTs)
|
|
150
|
+
return false;
|
|
151
|
+
if (e.timestamp.getTime() === cTs && e.id >= cursor.id)
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
return true;
|
|
155
|
+
});
|
|
156
|
+
// Sort desc by (timestamp, id)
|
|
157
|
+
filtered.sort((a, b) => {
|
|
158
|
+
const d = b.timestamp.getTime() - a.timestamp.getTime();
|
|
159
|
+
return d !== 0 ? d : b.id > a.id ? 1 : -1;
|
|
160
|
+
});
|
|
161
|
+
const page = filtered.slice(0, limit);
|
|
162
|
+
const nextCursor = filtered.length > limit
|
|
163
|
+
? encodeCursor({
|
|
164
|
+
ts: page[page.length - 1].timestamp.toISOString(),
|
|
165
|
+
id: page[page.length - 1].id,
|
|
166
|
+
})
|
|
167
|
+
: null;
|
|
168
|
+
return { events: page, nextCursor };
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Finds a single audit event by ID. Supports both native audit_events rows
|
|
172
|
+
* (looked up directly) and projected events (IDs with `proj_` prefix resolved
|
|
173
|
+
* by querying the source table and re-projecting).
|
|
174
|
+
*
|
|
175
|
+
* Returns null if no matching event is found.
|
|
176
|
+
*
|
|
177
|
+
* Projected ID formats:
|
|
178
|
+
* - `proj_run_started_<runId>`, `proj_run_completed_<runId>`, `proj_run_failed_<runId>`,
|
|
179
|
+
* `proj_run_auto_merged_<runId>`, `proj_run_auto_merge_skipped_<runId>` → pipeline_runs
|
|
180
|
+
* - `proj_approval_requested_<approvalId>`, `proj_approval_resolved_<approvalId>` → pm_approvals
|
|
181
|
+
* - `proj_budget_alert_<alertId>` → budget_alerts
|
|
182
|
+
*/
|
|
183
|
+
export async function findAuditEventById(db, id) {
|
|
184
|
+
if (!id.startsWith("proj_")) {
|
|
185
|
+
const rows = await db
|
|
186
|
+
.select()
|
|
187
|
+
.from(auditEvents)
|
|
188
|
+
.where(eq(auditEvents.id, id))
|
|
189
|
+
.limit(1);
|
|
190
|
+
return rows.length > 0 ? parseNativeRow(rows[0]) : null;
|
|
191
|
+
}
|
|
192
|
+
// Parse projected ID prefixes. Listed in the order they appear in projection.ts;
|
|
193
|
+
// no prefix is a strict prefix of another, so matching order is defensive only.
|
|
194
|
+
const runPrefixes = [
|
|
195
|
+
"proj_run_auto_merge_skipped_",
|
|
196
|
+
"proj_run_auto_merged_",
|
|
197
|
+
"proj_run_started_",
|
|
198
|
+
"proj_run_completed_",
|
|
199
|
+
"proj_run_failed_",
|
|
200
|
+
];
|
|
201
|
+
for (const prefix of runPrefixes) {
|
|
202
|
+
if (id.startsWith(prefix)) {
|
|
203
|
+
const runId = id.slice(prefix.length);
|
|
204
|
+
const rows = await db
|
|
205
|
+
.select()
|
|
206
|
+
.from(pipelineRuns)
|
|
207
|
+
.where(eq(pipelineRuns.id, runId))
|
|
208
|
+
.limit(1);
|
|
209
|
+
if (rows.length === 0)
|
|
210
|
+
return null;
|
|
211
|
+
const projected = projectPipelineRun(rows[0]);
|
|
212
|
+
return projected.find((e) => e.id === id) ?? null;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const approvalPrefixes = ["proj_approval_requested_", "proj_approval_resolved_"];
|
|
216
|
+
for (const prefix of approvalPrefixes) {
|
|
217
|
+
if (id.startsWith(prefix)) {
|
|
218
|
+
const approvalId = id.slice(prefix.length);
|
|
219
|
+
const rows = await db
|
|
220
|
+
.select()
|
|
221
|
+
.from(pmApprovals)
|
|
222
|
+
.where(eq(pmApprovals.id, approvalId))
|
|
223
|
+
.limit(1);
|
|
224
|
+
if (rows.length === 0)
|
|
225
|
+
return null;
|
|
226
|
+
const projected = projectPmApproval(rows[0]);
|
|
227
|
+
return projected.find((e) => e.id === id) ?? null;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (id.startsWith("proj_budget_alert_")) {
|
|
231
|
+
const alertId = id.slice("proj_budget_alert_".length);
|
|
232
|
+
const rows = await db
|
|
233
|
+
.select()
|
|
234
|
+
.from(budgetAlerts)
|
|
235
|
+
.where(eq(budgetAlerts.id, alertId))
|
|
236
|
+
.limit(1);
|
|
237
|
+
if (rows.length === 0)
|
|
238
|
+
return null;
|
|
239
|
+
return projectBudgetAlert(rows[0]);
|
|
240
|
+
}
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../../src/audit/reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AnyDb } from "../db/client.js";
|
|
2
|
+
/**
|
|
3
|
+
* Deletes audit_events rows older than `retentionDays`.
|
|
4
|
+
*
|
|
5
|
+
* This is the SOLE authorized mutation on the audit_events table. The
|
|
6
|
+
* audit-immutability lint test grep-checks that no other file in the
|
|
7
|
+
* codebase calls `update(auditEvents)` or `delete(auditEvents)`.
|
|
8
|
+
*
|
|
9
|
+
* Returns the number of rows deleted.
|
|
10
|
+
*/
|
|
11
|
+
export declare function pruneAuditLog(db: AnyDb, retentionDays: number): Promise<number>;
|
|
12
|
+
//# sourceMappingURL=retention.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.d.ts","sourceRoot":"","sources":["../../src/audit/retention.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAM7C;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,EAAE,EAAE,KAAK,EACT,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC,CAYjB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { lt } from "drizzle-orm";
|
|
2
|
+
import { auditEvents } from "../db/schema.js";
|
|
3
|
+
import { createLogger } from "../logger.js";
|
|
4
|
+
const log = createLogger({ component: "audit.retention" });
|
|
5
|
+
/**
|
|
6
|
+
* Deletes audit_events rows older than `retentionDays`.
|
|
7
|
+
*
|
|
8
|
+
* This is the SOLE authorized mutation on the audit_events table. The
|
|
9
|
+
* audit-immutability lint test grep-checks that no other file in the
|
|
10
|
+
* codebase calls `update(auditEvents)` or `delete(auditEvents)`.
|
|
11
|
+
*
|
|
12
|
+
* Returns the number of rows deleted.
|
|
13
|
+
*/
|
|
14
|
+
export async function pruneAuditLog(db, retentionDays) {
|
|
15
|
+
const cutoff = new Date(Date.now() - retentionDays * 86400_000);
|
|
16
|
+
const result = await db
|
|
17
|
+
.delete(auditEvents)
|
|
18
|
+
.where(lt(auditEvents.timestamp, cutoff));
|
|
19
|
+
const n = result?.changes ?? result?.rowCount ?? 0;
|
|
20
|
+
log.info({ retentionDays, cutoff, deleted: n }, "audit log pruned");
|
|
21
|
+
return n;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=retention.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retention.js","sourceRoot":"","sources":["../../src/audit/retention.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAEjC,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC,CAAC;AAE3D;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,EAAS,EACT,aAAqB;IAErB,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,GAAG,SAAS,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,MAAO,EAAU;SAC7B,MAAM,CAAC,WAAW,CAAC;SACnB,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,MAAM,CAAC,GACJ,MAAc,EAAE,OAAO,IAAK,MAAc,EAAE,QAAQ,IAAI,CAAC,CAAC;IAC7D,GAAG,CAAC,IAAI,CACN,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,EACrC,kBAAkB,CACnB,CAAC;IACF,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AnyDb } from "../db/client.js";
|
|
2
|
+
import type { AuditEvent } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Fire-and-forget insert of an audit event. Write failures are logged but
|
|
5
|
+
* never propagated — audit writes must not crash the caller.
|
|
6
|
+
*
|
|
7
|
+
* Gated on the `audit-log` enterprise feature (spec §8): when unlicensed,
|
|
8
|
+
* this is a no-op so OSS/Pro deployments do not accumulate audit_events rows
|
|
9
|
+
* indefinitely (retention sweep is also gated).
|
|
10
|
+
*
|
|
11
|
+
* Uses a dynamic import of `../license.js` to avoid a circular-import cycle
|
|
12
|
+
* (license.ts calls into this module to record license-validation failures
|
|
13
|
+
* via `logAuditEventUnchecked`).
|
|
14
|
+
*
|
|
15
|
+
* Callers should use `void logAuditEvent(...)` when they don't await.
|
|
16
|
+
*/
|
|
17
|
+
export declare function logAuditEvent(db: AnyDb, event: AuditEvent): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Unchecked writer used by the license-validation failure path itself.
|
|
20
|
+
* Bypasses the `audit-log` feature gate because (a) recording why a license
|
|
21
|
+
* was rejected must not depend on that license being valid, and (b) the
|
|
22
|
+
* event is emitted at most once per process (license status is cached).
|
|
23
|
+
* Do not use this from other call sites.
|
|
24
|
+
*/
|
|
25
|
+
export declare function logAuditEventUnchecked(db: AnyDb, event: AuditEvent): Promise<void>;
|
|
26
|
+
//# sourceMappingURL=writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/audit/writer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAG7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA2B9C;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CACjC,EAAE,EAAE,KAAK,EACT,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,KAAK,EACT,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,IAAI,CAAC,CAEf"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { auditEvents } from "../db/schema.js";
|
|
2
|
+
import { createLogger } from "../logger.js";
|
|
3
|
+
const log = createLogger({ component: "audit.writer" });
|
|
4
|
+
async function insertAuditEvent(db, event) {
|
|
5
|
+
try {
|
|
6
|
+
await db.insert(auditEvents).values({
|
|
7
|
+
id: event.id,
|
|
8
|
+
timestamp: event.timestamp,
|
|
9
|
+
eventType: event.eventType,
|
|
10
|
+
actor: event.actor,
|
|
11
|
+
actorType: event.actorType,
|
|
12
|
+
scope: event.scope,
|
|
13
|
+
runId: event.runId,
|
|
14
|
+
issueId: event.issueId,
|
|
15
|
+
inputTokens: event.inputTokens,
|
|
16
|
+
outputTokens: event.outputTokens,
|
|
17
|
+
payload: JSON.stringify(event.payload ?? {}),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
log.warn({ err, eventType: event.eventType, id: event.id }, "audit event write failed");
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Fire-and-forget insert of an audit event. Write failures are logged but
|
|
26
|
+
* never propagated — audit writes must not crash the caller.
|
|
27
|
+
*
|
|
28
|
+
* Gated on the `audit-log` enterprise feature (spec §8): when unlicensed,
|
|
29
|
+
* this is a no-op so OSS/Pro deployments do not accumulate audit_events rows
|
|
30
|
+
* indefinitely (retention sweep is also gated).
|
|
31
|
+
*
|
|
32
|
+
* Uses a dynamic import of `../license.js` to avoid a circular-import cycle
|
|
33
|
+
* (license.ts calls into this module to record license-validation failures
|
|
34
|
+
* via `logAuditEventUnchecked`).
|
|
35
|
+
*
|
|
36
|
+
* Callers should use `void logAuditEvent(...)` when they don't await.
|
|
37
|
+
*/
|
|
38
|
+
export async function logAuditEvent(db, event) {
|
|
39
|
+
const { isFeatureLicensed } = await import("../license.js");
|
|
40
|
+
if (!isFeatureLicensed("audit-log"))
|
|
41
|
+
return;
|
|
42
|
+
await insertAuditEvent(db, event);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Unchecked writer used by the license-validation failure path itself.
|
|
46
|
+
* Bypasses the `audit-log` feature gate because (a) recording why a license
|
|
47
|
+
* was rejected must not depend on that license being valid, and (b) the
|
|
48
|
+
* event is emitted at most once per process (license status is cached).
|
|
49
|
+
* Do not use this from other call sites.
|
|
50
|
+
*/
|
|
51
|
+
export async function logAuditEventUnchecked(db, event) {
|
|
52
|
+
await insertAuditEvent(db, event);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/audit/writer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC,CAAC;AAExD,KAAK,UAAU,gBAAgB,CAAC,EAAS,EAAE,KAAiB;IAC1D,IAAI,CAAC;QACH,MAAO,EAAU,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC;YAC3C,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;SAC7C,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CACN,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,EACjD,0BAA0B,CAC3B,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,EAAS,EACT,KAAiB;IAEjB,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;IAC5D,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC;QAAE,OAAO;IAC5C,MAAM,gBAAgB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,EAAS,EACT,KAAiB;IAEjB,MAAM,gBAAgB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AnyDb } from "../db/client.js";
|
|
2
|
+
export interface DashboardSession {
|
|
3
|
+
id: string;
|
|
4
|
+
userId: string;
|
|
5
|
+
createdAt: Date;
|
|
6
|
+
expiresAt: Date;
|
|
7
|
+
lastSeenAt: Date;
|
|
8
|
+
}
|
|
9
|
+
export declare function createSession(db: AnyDb, args: {
|
|
10
|
+
userId: string;
|
|
11
|
+
durationHours: number;
|
|
12
|
+
}): Promise<string>;
|
|
13
|
+
export declare function getSession(db: AnyDb, id: string): Promise<DashboardSession | null>;
|
|
14
|
+
export declare function deleteSession(db: AnyDb, id: string): Promise<void>;
|
|
15
|
+
export declare function pruneExpiredSessions(db: AnyDb): Promise<number>;
|
|
16
|
+
export declare function touchSessionLastSeen(db: AnyDb, id: string): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=session-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../../src/auth/session-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAM7C,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,IAAI,CAAC;CAClB;AAED,wBAAsB,aAAa,CACjC,EAAE,EAAE,KAAK,EACT,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC9C,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED,wBAAsB,UAAU,CAC9B,EAAE,EAAE,KAAK,EACT,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAmBlC;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAExE;AAED,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAUrE;AAED,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,KAAK,EACT,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,IAAI,CAAC,CAcf"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { and, eq, gt, lt } from "drizzle-orm";
|
|
3
|
+
import { dashboardSessions } from "../db/schema.js";
|
|
4
|
+
import { createLogger } from "../logger.js";
|
|
5
|
+
const log = createLogger({ component: "auth.session" });
|
|
6
|
+
export async function createSession(db, args) {
|
|
7
|
+
const id = randomBytes(32).toString("base64url");
|
|
8
|
+
const expiresAt = new Date(Date.now() + args.durationHours * 3600_000);
|
|
9
|
+
await db.insert(dashboardSessions).values({
|
|
10
|
+
id,
|
|
11
|
+
userId: args.userId,
|
|
12
|
+
expiresAt,
|
|
13
|
+
lastSeenAt: new Date(),
|
|
14
|
+
});
|
|
15
|
+
return id;
|
|
16
|
+
}
|
|
17
|
+
export async function getSession(db, id) {
|
|
18
|
+
const rows = await db
|
|
19
|
+
.select()
|
|
20
|
+
.from(dashboardSessions)
|
|
21
|
+
.where(and(eq(dashboardSessions.id, id), gt(dashboardSessions.expiresAt, new Date())));
|
|
22
|
+
if (rows.length === 0)
|
|
23
|
+
return null;
|
|
24
|
+
const r = rows[0];
|
|
25
|
+
return {
|
|
26
|
+
id: r.id,
|
|
27
|
+
userId: r.userId,
|
|
28
|
+
createdAt: r.createdAt,
|
|
29
|
+
expiresAt: r.expiresAt,
|
|
30
|
+
lastSeenAt: r.lastSeenAt,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export async function deleteSession(db, id) {
|
|
34
|
+
await db.delete(dashboardSessions).where(eq(dashboardSessions.id, id));
|
|
35
|
+
}
|
|
36
|
+
export async function pruneExpiredSessions(db) {
|
|
37
|
+
const result = await db
|
|
38
|
+
.delete(dashboardSessions)
|
|
39
|
+
.where(lt(dashboardSessions.expiresAt, new Date()));
|
|
40
|
+
const n = result?.changes ??
|
|
41
|
+
result?.rowCount ??
|
|
42
|
+
0;
|
|
43
|
+
log.info({ deleted: n }, "expired sessions pruned");
|
|
44
|
+
return n;
|
|
45
|
+
}
|
|
46
|
+
export async function touchSessionLastSeen(db, id) {
|
|
47
|
+
try {
|
|
48
|
+
await db
|
|
49
|
+
.update(dashboardSessions)
|
|
50
|
+
.set({ lastSeenAt: new Date() })
|
|
51
|
+
.where(eq(dashboardSessions.id, id));
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
// Session IDs are bearer credentials — never log them in full. Log a
|
|
55
|
+
// short prefix for correlation only.
|
|
56
|
+
log.warn({ err, idPrefix: id.slice(0, 8) + "…" }, "touchSessionLastSeen failed");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=session-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-store.js","sourceRoot":"","sources":["../../src/auth/session-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface StatePayload {
|
|
2
|
+
next: string;
|
|
3
|
+
nonce: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function signState(payload: StatePayload, secret: string): string;
|
|
6
|
+
export declare function verifyState(signed: string, secret: string): StatePayload | null;
|
|
7
|
+
/**
|
|
8
|
+
* Validate that `next` is a same-origin absolute path. Reject scheme-relative
|
|
9
|
+
* (`//evil.com`), absolute (`https://evil.com`), and backslash variants.
|
|
10
|
+
* Falls back to "/" on any rejection.
|
|
11
|
+
*/
|
|
12
|
+
export declare function validateNextPath(next: string | undefined | null): string;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=sso-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sso-config.d.ts","sourceRoot":"","sources":["../../src/auth/sso-config.ts"],"names":[],"mappings":"AAEA,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAKvE;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAmB/E;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAMxE"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
2
|
+
export function signState(payload, secret) {
|
|
3
|
+
const json = JSON.stringify(payload);
|
|
4
|
+
const b64 = Buffer.from(json, "utf8").toString("base64url");
|
|
5
|
+
const hmac = createHmac("sha256", secret).update(b64).digest("base64url");
|
|
6
|
+
return `${b64}.${hmac}`;
|
|
7
|
+
}
|
|
8
|
+
export function verifyState(signed, secret) {
|
|
9
|
+
if (!signed || typeof signed !== "string")
|
|
10
|
+
return null;
|
|
11
|
+
const idx = signed.lastIndexOf(".");
|
|
12
|
+
if (idx <= 0 || idx === signed.length - 1)
|
|
13
|
+
return null;
|
|
14
|
+
const b64 = signed.slice(0, idx);
|
|
15
|
+
const sig = signed.slice(idx + 1);
|
|
16
|
+
const expected = createHmac("sha256", secret).update(b64).digest("base64url");
|
|
17
|
+
const sigBuf = Buffer.from(sig, "base64url");
|
|
18
|
+
const expBuf = Buffer.from(expected, "base64url");
|
|
19
|
+
if (sigBuf.length !== expBuf.length)
|
|
20
|
+
return null;
|
|
21
|
+
if (!timingSafeEqual(sigBuf, expBuf))
|
|
22
|
+
return null;
|
|
23
|
+
try {
|
|
24
|
+
const json = Buffer.from(b64, "base64url").toString("utf8");
|
|
25
|
+
const parsed = JSON.parse(json);
|
|
26
|
+
if (typeof parsed?.next !== "string" || typeof parsed?.nonce !== "string")
|
|
27
|
+
return null;
|
|
28
|
+
return parsed;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Validate that `next` is a same-origin absolute path. Reject scheme-relative
|
|
36
|
+
* (`//evil.com`), absolute (`https://evil.com`), and backslash variants.
|
|
37
|
+
* Falls back to "/" on any rejection.
|
|
38
|
+
*/
|
|
39
|
+
export function validateNextPath(next) {
|
|
40
|
+
if (!next || typeof next !== "string")
|
|
41
|
+
return "/";
|
|
42
|
+
if (!next.startsWith("/"))
|
|
43
|
+
return "/";
|
|
44
|
+
if (next.startsWith("//"))
|
|
45
|
+
return "/";
|
|
46
|
+
if (next.startsWith("/\\") || next.includes("\\"))
|
|
47
|
+
return "/";
|
|
48
|
+
return next;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=sso-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sso-config.js","sourceRoot":"","sources":["../../src/auth/sso-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAO1D,MAAM,UAAU,SAAS,CAAC,OAAqB,EAAE,MAAc;IAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC5D,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC1E,OAAO,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,MAAc;IACxD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvD,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,KAAK,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACvD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACjC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC9E,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAClD,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAClD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,OAAO,MAAM,EAAE,IAAI,KAAK,QAAQ,IAAI,OAAO,MAAM,EAAE,KAAK,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACvF,OAAO,MAAsB,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAA+B;IAC9D,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IAClD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IACtC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC;IACtC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC;IAC9D,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { AnyDb } from "../db/client.js";
|
|
2
|
+
import type { Role } from "../rbac/types.js";
|
|
3
|
+
export interface DashboardUser {
|
|
4
|
+
id: string;
|
|
5
|
+
email: string;
|
|
6
|
+
name: string | null;
|
|
7
|
+
workosUserId: string | null;
|
|
8
|
+
createdAt: Date;
|
|
9
|
+
lastLoginAt: Date | null;
|
|
10
|
+
role: Role;
|
|
11
|
+
}
|
|
12
|
+
export interface UpsertUserInput {
|
|
13
|
+
email: string;
|
|
14
|
+
name: string | null;
|
|
15
|
+
workosUserId: string | null;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Insert or update a dashboard user by normalized email. Returns the
|
|
19
|
+
* canonical user id. On update, `name`, `workosUserId`, and `lastLoginAt`
|
|
20
|
+
* are refreshed; `id` and `createdAt` are preserved.
|
|
21
|
+
*
|
|
22
|
+
* Implemented as an atomic upsert (`onConflictDoUpdate` on the unique
|
|
23
|
+
* `email` column) so that two concurrent `/auth/callback` requests for the
|
|
24
|
+
* same email cannot both see `existing.length === 0` and race on INSERT.
|
|
25
|
+
* The generated `id` is only used if no row exists; on conflict we read
|
|
26
|
+
* back the canonical id from the surviving row.
|
|
27
|
+
*/
|
|
28
|
+
export declare function upsertUser(db: AnyDb, input: UpsertUserInput): Promise<string>;
|
|
29
|
+
/**
|
|
30
|
+
* Look up a dashboard user by id. Returns `null` when not found.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getUserById(db: AnyDb, id: string): Promise<DashboardUser | null>;
|
|
33
|
+
//# sourceMappingURL=user-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-store.d.ts","sourceRoot":"","sources":["../../src/auth/user-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,IAAI,CAAC;IAChB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAMD;;;;;;;;;;GAUG;AACH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,KAAK,EACT,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,MAAM,CAAC,CAgCjB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,EAAE,EAAE,KAAK,EACT,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAiB/B"}
|