import Database from 'better-sqlite3'; import { afterEach, describe, expect, it } from 'vitest'; import { buildControlPlaneApp } from './control-plane.js'; import { migrateDatabase } from './infrastructure/database/migrations.js'; import { UpstreamError } from './infrastructure/transport/upstream-error.js'; import { SafeInstanceTransport } from './infrastructure/transport/safe-instance-transport.js'; import { createSafeControlPlaneUpstream } from './infrastructure/transport/safe-control-plane-upstream.js'; import type { SecretStore } from './infrastructure/secrets/secret-store.js'; const dbs: Database.Database[] = []; afterEach(async () => { for (const db of dbs.splice(0)) db.close(); }); class Store implements SecretStore { async set() { return ''; } async get() { return '[REDACTED]'; } async delete() { return false; } } describe('buildControlPlaneApp', () => { it('registers the durable event route fail-closed when no authentication dependency is supplied', async () => { const db = new Database(':memory:'); db.pragma('foreign_keys=ON'); migrateDatabase(db); dbs.push(db); const app = buildControlPlaneApp({ db, store: new Store(), upstream: { get: async () => ({ status: 200, headers: {}, body: '' }), request: async () => ({ status: 200, headers: {}, body: '' }), postNetworkRegisterAuto: async () => ({ status: 200 }), }, }); const response = await app.inject({ method: 'GET', url: '/api/v1/events' }); expect(response.statusCode).toBe(401); expect(response.headers['content-type']).toContain('application/problem+json'); expect(response.json()).toMatchObject({ status: 401, code: 'UNAUTHORIZED' }); await app.close(); }); it('passes an explicit event-stream authenticator to durable cursor replay', async () => { const db = new Database(':memory:'); db.pragma('foreign_keys=ON'); migrateDatabase(db); dbs.push(db); const app = buildControlPlaneApp({ db, store: new Store(), upstream: { get: async () => ({ status: 200, headers: {}, body: '' }), request: async () => ({ status: 200, headers: {}, body: '' }), postNetworkRegisterAuto: async () => ({ status: 200 }), }, authenticateEventStream: (request) => request.headers.authorization === 'Bearer allowed', }); const response = await app.inject({ method: 'GET', url: '/api/v1/events', headers: { authorization: 'Bearer allowed', 'last-event-id': 'unknown-cursor', }, }); expect(response.statusCode).toBe(409); expect(response.headers['content-type']).toContain('application/problem+json'); expect(response.json()).toMatchObject({ status: 409, code: 'EVENT_POSITION_UNAVAILABLE', }); await app.close(); }); it('assembles instance CRUD, connection checks, login and logout without listening or reading external config', async () => { const db = new Database(':memory:'); db.pragma('foreign_keys=ON'); migrateDatabase(db); dbs.push(db); const app = buildControlPlaneApp({ db, store: new Store(), upstream: createSafeControlPlaneUpstream( new SafeInstanceTransport({ resolve: async () => [{ address: '192.168.1.10', family: 4 }], request: async (request) => ({ status: request.url.endsWith('/api/health') ? 401 : 200, headers: { 'set-cookie': 'simadmin_session=opaque' }, body: '', }), }), ), now: () => new Date('2026-07-16T12:00:00.000Z'), }); const created = await app.inject({ method: 'POST', url: '/api/v1/instances', payload: { name: 'A', origin: 'http://192.168.1.10:8080' }, }); expect(created.statusCode).toBe(201); const tested = await app.inject({ method: 'POST', url: '/api/v1/instances/' + created.json().id + '/test-connection', }); expect(tested.json()).toMatchObject({ authenticated: false }); const insecureLogin = await app.inject({ method: 'POST', url: '/api/v1/instances/' + created.json().id + '/login', payload: { password: 'never-leak-this' }, }); expect(insecureLogin.statusCode).toBe(400); expect(insecureLogin.json()).toMatchObject({ title: 'Bad Request', status: 400, code: 'UPSTREAM_INSECURE_AUTH', }); expect(insecureLogin.body).not.toContain('never-leak-this'); expect(insecureLogin.body).not.toContain('192.168.1.10'); await app.close(); }); it('maps typed upstream failures to redacted gateway Problem Details', async () => { const db = new Database(':memory:'); db.pragma('foreign_keys=ON'); migrateDatabase(db); dbs.push(db); const app = buildControlPlaneApp({ db, store: new Store(), upstream: { get: async () => { throw new UpstreamError('UPSTREAM_UNAVAILABLE', { cause: new Error('ECONNREFUSED 192.168.1.99 cookie=simadmin_session=secret'), }); }, request: async () => ({ status: 200, headers: {}, body: '' }), postNetworkRegisterAuto: async () => ({ status: 200 }), }, }); const created = await app.inject({ method: 'POST', url: '/api/v1/instances', payload: { name: 'B', origin: 'http://192.168.1.99' }, }); const response = await app.inject({ method: 'POST', url: '/api/v1/instances/' + created.json().id + '/test-connection', }); expect(response.statusCode).toBe(502); expect(response.headers['content-type']).toContain('application/problem+json'); expect(response.json()).toMatchObject({ title: 'Bad Gateway', status: 502, code: 'UPSTREAM_UNAVAILABLE', }); expect(response.body).not.toContain('ECONNREFUSED'); expect(response.body).not.toContain('192.168.1.99'); expect(response.body).not.toContain('simadmin_session'); await app.close(); }); });