import assert from 'node:assert/strict'; import test from 'node:test'; import type { NextFunction, Request, RequestHandler } from 'express'; import { createRequest, createResponse } from 'node-mocks-http'; import { blockNonPublicRuntimeListEndpoints, sanitizePublicRuntimeListResponse, } from '../src/middlewares/runtime-public.ts'; import { setRuntimePublicRequest } from '../src/utils/request-context.ts'; function runMiddleware( middleware: RequestHandler, req: Request, ): Promise { const res = createResponse(); return new Promise((resolve, reject) => { const next: NextFunction = (error?: unknown) => { if (error) { reject( error instanceof Error ? error : new Error('Middleware returned a non-Error callback value.'), ); return; } resolve(true); }; middleware(req, res, next); if (res._isEndCalled()) { resolve(false); } }); } void test('blockNonPublicRuntimeListEndpoints blocks public runtime CSV exports', () => { const req = createRequest({ method: 'GET', url: '/?filetype=csv', query: { filetype: 'csv' }, }); setRuntimePublicRequest(req, true); const res = createResponse(); let nextCalled = false; blockNonPublicRuntimeListEndpoints('projects')(req, res, () => { nextCalled = true; }); assert.equal(nextCalled, false); assert.equal(res.statusCode, 404); assert.deepEqual(res._getData(), { message: 'Not found' }); }); void test('blockNonPublicRuntimeListEndpoints blocks non-allowed public runtime paths', () => { const req = createRequest({ method: 'GET', url: '/autocomplete', }); setRuntimePublicRequest(req, true); const res = createResponse(); let nextCalled = false; blockNonPublicRuntimeListEndpoints('projects')(req, res, () => { nextCalled = true; }); assert.equal(nextCalled, false); assert.equal(res.statusCode, 404); }); void test('blockNonPublicRuntimeListEndpoints allows configured runtime project settings path', async () => { const req = createRequest({ method: 'GET', url: '/project/094121b9-c567-469a-b256-ba221b7fd5d6/env/production', }); setRuntimePublicRequest(req, true); assert.equal( await runMiddleware( blockNonPublicRuntimeListEndpoints('project_transition_settings'), req, ), true, ); }); void test('sanitizePublicRuntimeListResponse strips non-public fields from rows and records', () => { const listReq = createRequest({ method: 'GET', url: '/', }); setRuntimePublicRequest(listReq, true); const listRes = createResponse(); sanitizePublicRuntimeListResponse('projects')(listReq, listRes, () => {}); listRes.send({ rows: [ { id: 'project-1', name: 'Lobby', slug: 'lobby', secret: 'do-not-leak', }, ], count: 1, }); assert.deepEqual(listRes._getData(), { rows: [ { id: 'project-1', name: 'Lobby', slug: 'lobby', }, ], count: 1, }); const recordReq = createRequest({ method: 'GET', url: '/', }); setRuntimePublicRequest(recordReq, true); const recordRes = createResponse(); sanitizePublicRuntimeListResponse('tour_pages')(recordReq, recordRes, () => {}); recordRes.send({ id: 'page-1', slug: 'intro', ui_schema_json: { elements: [] }, internal_note: 'do-not-leak', }); assert.deepEqual(recordRes._getData(), { id: 'page-1', slug: 'intro', ui_schema_json: { elements: [] }, }); }); void test('sanitizePublicRuntimeListResponse does not affect authenticated admin requests', () => { const req = createRequest({ method: 'GET', url: '/', }); const res = createResponse(); sanitizePublicRuntimeListResponse('projects')(req, res, () => {}); res.send({ id: 'project-1', slug: 'lobby', secret: 'visible-to-admin-path', }); assert.deepEqual(res._getData(), { id: 'project-1', slug: 'lobby', secret: 'visible-to-admin-path', }); });