test(12-06): add failing tests for vapid public-key equality assertion (gap 2)
- mismatched submitted key (BH123) → 400, no VAPID_PRIVATE_KEY leak - absent app_config.vapid_public_key row → 400 - happy path seeds matching app_config row
This commit is contained in:
@@ -345,6 +345,12 @@ describe('POST /api/setup/validate/vapid', () => {
|
||||
it('returns 200 { ok: true } for a valid VAPID key pair from generate-secrets', async () => {
|
||||
process.env.VAPID_PUBLIC_KEY = VAPID_PUBLIC_KEY;
|
||||
process.env.VAPID_PRIVATE_KEY = VAPID_PRIVATE_KEY;
|
||||
// Gap 2: the operator-submitted public key (app_config.vapid_public_key) must equal
|
||||
// process.env.VAPID_PUBLIC_KEY for the happy path. Seed the matching row.
|
||||
await db
|
||||
.insert(appConfig)
|
||||
.values({ key: 'vapid_public_key', value: VAPID_PUBLIC_KEY })
|
||||
.onDuplicateKeyUpdate({ set: { value: VAPID_PUBLIC_KEY } });
|
||||
|
||||
const app = await getApp();
|
||||
const res = await app.fetch(jsonRequest('POST', '/api/setup/validate/vapid'));
|
||||
@@ -353,6 +359,43 @@ describe('POST /api/setup/validate/vapid', () => {
|
||||
expect(body.ok).toBe(true);
|
||||
});
|
||||
|
||||
// Gap 2 (major): a wrong wizard-entered public key (e.g. "BH123") must fail the row.
|
||||
// The env VAPID pair is valid, but the submitted key in app_config does not match
|
||||
// process.env.VAPID_PUBLIC_KEY → 400. The response must NEVER contain VAPID_PRIVATE_KEY (T-12-06).
|
||||
it('returns 400 when submitted vapid_public_key does not match process.env.VAPID_PUBLIC_KEY (gap 2)', async () => {
|
||||
process.env.VAPID_PUBLIC_KEY = VAPID_PUBLIC_KEY;
|
||||
process.env.VAPID_PRIVATE_KEY = VAPID_PRIVATE_KEY;
|
||||
// Operator typed a clearly-wrong key — env pair is still structurally valid.
|
||||
await db
|
||||
.insert(appConfig)
|
||||
.values({ key: 'vapid_public_key', value: 'BH123' })
|
||||
.onDuplicateKeyUpdate({ set: { value: 'BH123' } });
|
||||
|
||||
const app = await getApp();
|
||||
const res = await app.fetch(jsonRequest('POST', '/api/setup/validate/vapid'));
|
||||
expect(res.status).toBe(400);
|
||||
const bodyText = await res.text();
|
||||
const body = JSON.parse(bodyText) as { ok: boolean };
|
||||
expect(body.ok).toBe(false);
|
||||
// T-12-06: VAPID_PRIVATE_KEY must never leak into any response.
|
||||
expect(bodyText).not.toContain(VAPID_PRIVATE_KEY);
|
||||
});
|
||||
|
||||
// Gap 2: without an operator-submitted key there is nothing to compare → 400.
|
||||
it('returns 400 when app_config.vapid_public_key row is absent (no submitted key)', async () => {
|
||||
process.env.VAPID_PUBLIC_KEY = VAPID_PUBLIC_KEY;
|
||||
process.env.VAPID_PRIVATE_KEY = VAPID_PRIVATE_KEY;
|
||||
// No vapid_public_key seeded in app_config (cleaned in afterEach).
|
||||
|
||||
const app = await getApp();
|
||||
const res = await app.fetch(jsonRequest('POST', '/api/setup/validate/vapid'));
|
||||
expect(res.status).toBe(400);
|
||||
const bodyText = await res.text();
|
||||
const body = JSON.parse(bodyText) as { ok: boolean };
|
||||
expect(body.ok).toBe(false);
|
||||
expect(bodyText).not.toContain(VAPID_PRIVATE_KEY);
|
||||
});
|
||||
|
||||
it('returns 400 { ok: false } when VAPID env vars are missing', async () => {
|
||||
// VAPID env vars not set (cleared in beforeEach)
|
||||
const app = await getApp();
|
||||
|
||||
Reference in New Issue
Block a user