managarten/services
Till JS c2c960121e test(mana-auth): vault service integration tests against real postgres
Closes backlog #1 from the Phase 9 audit. Adds 28 integration tests
for the EncryptionVaultService against a real Postgres so the
RLS policies, CHECK constraints and audit-row writes are exercised
as the production app actually sees them. The pure-crypto KEK tests
in kek.test.ts already covered the wrap/unwrap primitives — this
new file fills in the service-shaped gaps that need a real DB.

Test infrastructure
-------------------
- Reads TEST_DATABASE_URL from env. Whole suite is SKIPPED via
  describe.skip if unset, so unrelated CI runs and `bun test` from
  a fresh checkout don't fail on missing connection. The
  encryption-vault sub-job has to provision a Postgres explicitly.
- Schema is assumed already migrated (run `pnpm db:push` or apply
  sql/002 + sql/003 manually before invoking the suite). Tests
  insert a fresh test user per case via beforeEach so cross-test
  pollution is impossible despite the FK to auth.users.
- afterAll cleans up the user (CASCADE wipes vault + audit) and
  closes the postgres pool so bun test exits cleanly.

Coverage
--------
init (3):
  - Mints a fresh vault, wrapped_mk + wrap_iv populated, ZK off
  - Idempotent (returns same key)
  - Audit rows are written

getStatus (5):
  - vaultExists=false for unconfigured user
  - vaultExists=true after init, no recovery wrap
  - hasRecoveryWrap=true after setRecoveryWrap
  - zeroKnowledge=true after enableZK
  - Does NOT write an audit row (cheap metadata read)

setRecoveryWrap (4):
  - Stores wrap on existing vault
  - VaultNotFoundError on missing vault
  - Idempotent (replaces previous wrap)
  - Writes recovery_set audit row

clearRecoveryWrap (3):
  - Removes the wrap
  - ZeroKnowledgeActiveError when ZK is on
  - VaultNotFoundError on missing vault

enableZeroKnowledge (4):
  - Flips zero_knowledge=true and NULLs out wrapped_mk + wrap_iv
  - RecoveryWrapMissingError if no recovery wrap is set
  - Idempotent (already-on is no-op)
  - VaultNotFoundError on missing vault

disableZeroKnowledge (2):
  - Restores wrapped_mk from a client-supplied master key,
    verifies the round-trip via getMasterKey returns the same bytes
  - No-op when ZK is already off

getMasterKey (3):
  - Returns unwrapped MK in standard mode
  - Returns recovery blob with requiresRecoveryCode=true in ZK mode
  - VaultNotFoundError on missing vault

rotate (2):
  - Mints fresh MK and wipes any existing recovery wrap
  - ZeroKnowledgeRotateForbidden in ZK mode

DB-level invariants (2):
  - Setting wrapped_mk back while ZK active is rejected by
    encryption_vaults_zk_consistency
  - Setting wrap_iv to NULL while wrapped_mk is set is rejected
    by encryption_vaults_wrap_iv_pair
  Both wrap the Drizzle update in an arrow IIFE so
  expect(...).rejects.toThrow() sees a real Promise (Drizzle's
  chainable update() only executes on await/then).

Run results
-----------
With TEST_DATABASE_URL set + schema migrated:
  28 pass, 0 fail, 64 expect() calls

Without TEST_DATABASE_URL set (default):
  0 pass, 30 skip (full suite cleanly skipped)
  KEK tests in kek.test.ts still run unaffected.

Drive-by: kek.test.ts header comment updated to point at the new
sibling file instead of saying "tests will live alongside mana-sync"
(which was outdated speculation from Phase 2).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 23:39:48 +02:00
..
mana-analytics chore: complete ManaCore → Mana rename (docs, go modules, plists, images) 2026-04-07 12:26:10 +02:00
mana-api-gateway chore: complete ManaCore → Mana rename (docs, go modules, plists, images) 2026-04-07 12:26:10 +02:00
mana-auth test(mana-auth): vault service integration tests against real postgres 2026-04-07 23:39:48 +02:00
mana-crawler chore: complete ManaCore → Mana rename (docs, go modules, plists, images) 2026-04-07 12:26:10 +02:00
mana-credits chore: complete ManaCore → Mana rename (docs, go modules, plists, images) 2026-04-07 12:26:10 +02:00
mana-events feat(events): bring list (wer bringt was?) — Phase 2 2026-04-07 19:31:39 +02:00
mana-image-gen fix: resolve port conflict (mana-image-gen 3025→3026) and replace APP_URLS with internal routes 2026-04-02 12:56:37 +02:00
mana-landing-builder chore: complete ManaCore → Mana rename (docs, go modules, plists, images) 2026-04-07 12:26:10 +02:00
mana-llm feat(mana-llm): add Google Gemini fallback provider with auto-routing 2026-03-23 22:44:09 +01:00
mana-matrix-bot chore: complete ManaCore → Mana rename (docs, go modules, plists, images) 2026-04-07 12:26:10 +02:00
mana-media chore: complete ManaCore → Mana rename (docs, go modules, plists, images) 2026-04-07 12:26:10 +02:00
mana-notify chore: complete ManaCore → Mana rename (docs, go modules, plists, images) 2026-04-07 12:26:10 +02:00
mana-search chore: complete ManaCore → Mana rename (docs, go modules, plists, images) 2026-04-07 12:26:10 +02:00
mana-stt feat(memoro): voice recording → mana-stt transcription pipeline 2026-04-07 18:48:41 +02:00
mana-subscriptions chore: complete ManaCore → Mana rename (docs, go modules, plists, images) 2026-04-07 12:26:10 +02:00
mana-sync fix(mana-sync): enable row-level security on sync_changes 2026-04-07 13:07:26 +02:00
mana-tts chore: complete ManaCore → Mana rename (docs, go modules, plists, images) 2026-04-07 12:26:10 +02:00
mana-user chore: complete ManaCore → Mana rename (docs, go modules, plists, images) 2026-04-07 12:26:10 +02:00
mana-video-gen feat(mana-video-gen): add AI video generation service with LTX-Video 2026-04-02 01:17:47 +02:00
mana-voice-bot chore: complete ManaCore → Mana rename (docs, go modules, plists, images) 2026-04-07 12:26:10 +02:00