fix(federation): harness CRIT bugs — admin bootstrap auth + peer FK + boot deadline (review remediation)
CRIT-1: Replace nonexistent x-admin-key header with Authorization: Bearer <token>; add bootstrapAdmin() to call POST /api/bootstrap/setup on each pristine gateway before any admin-guarded endpoint is used. CRIT-2: Fix cross-gateway peer FK violation — peer keypair is now created on Server B first (so the grant FK resolves against B's own federation_peers table), then Server A creates its own keypair and redeems the enrollment token at B. HIGH-3: waitForStack() now polls both gateways in parallel via Promise.all, each with an independent deadline, so a slow gateway-a cannot starve gateway-b's budget. MED-4: seed() throws immediately with a clear error if scenario !== 'all'; per-variant narrowing deferred to M3-11 with explicit JSDoc note. Also: remove ADMIN_API_KEY (no such path in AdminGuard) from compose, replace with ADMIN_BOOTSTRAP_PASSWORD; add BETTER_AUTH_URL production-code limitation as a TODO in the README. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -87,7 +87,8 @@ afterAll(async () => {
|
||||
});
|
||||
|
||||
test('variant A: list tasks returns personal tasks', async () => {
|
||||
const seedResult = await seed(handle, 'variantA');
|
||||
// NOTE: Only 'all' is supported for now — per-variant narrowing is M3-11.
|
||||
const seedResult = await seed(handle, 'all');
|
||||
const a = serverA(handle);
|
||||
|
||||
const res = await fetch(`${a.baseUrl}/api/federation/tasks`, {
|
||||
@@ -97,6 +98,11 @@ test('variant A: list tasks returns personal tasks', async () => {
|
||||
});
|
||||
```
|
||||
|
||||
> **Note:** `seed()` bootstraps a fresh admin user on each gateway via
|
||||
> `POST /api/bootstrap/setup`. Both gateways must have zero users (pristine DB).
|
||||
> If either gateway already has users, `seed()` throws with a clear error.
|
||||
> Reset state with `docker compose down -v`.
|
||||
|
||||
The `bootHarness()` function is **idempotent**: if both gateways are already
|
||||
healthy, it reuses the running stack and returns `ownedStack: false`. Tests
|
||||
should not call `tearDownHarness` when `ownedStack` is false unless they
|
||||
@@ -207,6 +213,25 @@ The gateway image is pinned to `sha256:1069117740e00ccfeba357cae38c43f3729fe5ae7
|
||||
tag is forbidden per Mosaic image policy. When a new gateway build is promoted,
|
||||
update the digest in `docker-compose.two-gateways.yml` and in this file.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
### BETTER_AUTH_URL enrollment URL bug (production code — not fixed here)
|
||||
|
||||
`apps/gateway/src/federation/federation.controller.ts:145` constructs the
|
||||
enrollment URL using `process.env['BETTER_AUTH_URL'] ?? 'http://localhost:14242'`.
|
||||
In non-harness deployments (where `BETTER_AUTH_URL` is not set or points to the
|
||||
web origin rather than the gateway's own base URL) this produces an incorrect
|
||||
enrollment URL that points to the wrong host or port.
|
||||
|
||||
The harness works around this by explicitly setting
|
||||
`BETTER_AUTH_URL: 'http://gateway-b:3000'` in the compose file so the enrollment
|
||||
URL correctly references gateway-b's internal Docker hostname.
|
||||
|
||||
**TODO:** Fix `federation.controller.ts` to derive the enrollment URL from its own
|
||||
listening address (e.g. `GATEWAY_BASE_URL` env var or a dedicated
|
||||
`FEDERATION_ENROLLMENT_BASE_URL` env var) rather than reusing `BETTER_AUTH_URL`.
|
||||
Tracked as a follow-up to PR #505 — do not bundle with harness changes.
|
||||
|
||||
## Permanent Infrastructure
|
||||
|
||||
This harness is designed to outlive M3 and be reused by M4+ milestone tests.
|
||||
|
||||
Reference in New Issue
Block a user