test(integration): end-to-end auth flow test with Mailpit + CI gating

Adds a 13-step integration test that exercises register → email
verification → login → JWT validation → /me/data → encryption-vault
init/key → logout against a real stack of postgres + redis + mailpit +
mana-auth + mana-notify in docker compose.

Verified locally that this catches every regression we hit on
2026-04-08 in well under a second:

  - missing nanoid dependency → register endpoint 500
  - missing MANA_AUTH_KEK env passthrough → mana-auth never starts
  - missing encryption-vault SQL migrations → vault endpoints 500
  - wrong cookie name in /api/v1/auth/login → no accessToken in response
  - mana-notify SMTP misconfigured → mailpit poll times out

Files:

- docker-compose.test.yml — minimal isolated stack on alt ports
  (postgres 5443, redis 6390, mailpit 1026/8026, mana-auth 3091,
  mana-notify 3092). Runs alongside the dev stack without collision.
  Postgres healthcheck runs a real query rather than just pg_isready
  to avoid the race where pg_isready reports healthy while the docker
  init scripts are still running on a unix socket.

- tests/integration/auth-flow.test.ts — bun test that drives the full
  flow via fetch + mailpit's REST API. Cleans up its test user from
  postgres in afterAll. Self-contained, no extra deps.

- tests/integration/README.md — what's covered, why it exists, how
  to run locally + extend.

- scripts/run-integration-tests.sh — orchestrator. Brings up the
  stack, pushes the @mana/auth Drizzle schema, applies the
  encryption-vault SQL migrations (002, 003), restarts mana-auth so
  it sees the fresh tables, runs the test, tears down on exit.
  KEEP_STACK=1 to leave it up for manual mailpit inspection.

- docker-compose.dev.yml — also adds Mailpit as a regular dev service
  (ports 1025/8025) so local development can have a working email
  capture without spinning up the test stack.

- .github/workflows/ci.yml — new auth-integration job that runs on
  every PR. Calls run-integration-tests.sh; on failure dumps
  mana-auth + mana-notify logs and the mailpit message queue. Marked
  as a required check via the existing PR validation pipeline.

Reproduced 3 clean runs and 1 negative-control run (removed nanoid
from package.json → mana-auth container exits → script aborts with
non-zero) before committing. Full happy path runs in ~22s on a warm
Docker cache.
This commit is contained in:
Till JS 2026-04-08 17:14:02 +02:00
parent 3b41b39a32
commit 5af4ddab3c
7 changed files with 612 additions and 0 deletions

View file

@ -472,6 +472,58 @@ jobs:
echo "::warning::Potentially vulnerable axios version detected"
fi
# ===========================================
# Auth flow integration test
# ===========================================
# Spins up postgres + redis + mailpit + mana-auth + mana-notify via
# docker-compose.test.yml and runs tests/integration/auth-flow.test.ts.
# Catches register/verify/login/JWT/encryption-vault regressions before
# they can be merged. Required check — never bypass.
auth-integration:
name: Auth flow integration test
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: ${{ env.PNPM_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run auth flow integration test
run: ./scripts/run-integration-tests.sh
- name: Dump test stack logs on failure
if: failure()
run: |
echo "::group::mana-auth logs"
docker logs mana-test-mana-auth 2>&1 | tail -200 || true
echo "::endgroup::"
echo "::group::mana-notify logs"
docker logs mana-test-mana-notify 2>&1 | tail -200 || true
echo "::endgroup::"
echo "::group::mailpit messages"
curl -s http://localhost:8026/api/v1/messages | head -100 || true
echo "::endgroup::"
# ===========================================
# Build Docker images - only changed services
# ===========================================