From 38a26c2ce1fccea86fbaa8b589cf8865fe7cafd0 Mon Sep 17 00:00:00 2001 From: chick Date: Sun, 19 Jul 2026 00:56:03 +0800 Subject: [PATCH] fix(transport): allow passwordless resource reads --- .../transport/safe-upstream-gateway.test.ts | 17 +++++++++++++++++ .../transport/safe-upstream-gateway.ts | 5 +++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/apps/api/src/infrastructure/transport/safe-upstream-gateway.test.ts b/apps/api/src/infrastructure/transport/safe-upstream-gateway.test.ts index cf1a83d..b8f5918 100644 --- a/apps/api/src/infrastructure/transport/safe-upstream-gateway.test.ts +++ b/apps/api/src/infrastructure/transport/safe-upstream-gateway.test.ts @@ -81,6 +81,23 @@ describe('SafeUpstreamGateway', () => { ).rejects.toThrow('UPSTREAM_INSECURE_AUTH'); }); + it('allows audited resource GETs without a cookie for passwordless instances', async () => { + const get = vi.fn(async () => ({ status: 200, headers: {}, body: '{}' })); + const gateway = new SafeUpstreamGateway({ + transport: { get, post: async () => ({ status: 200, headers: {}, body: '' }) }, + }); + await expect( + gateway.request({ + url: 'http://192.168.1.20:8080/api/stats', + method: 'GET', + headers: { accept: 'application/json' }, + }), + ).resolves.toMatchObject({ status: 200 }); + expect(get).toHaveBeenCalledWith('http://192.168.1.20:8080/api/stats', { + accept: 'application/json', + }); + }); + it('does not allow a supplied redacted body marker to become a network request body', async () => { const gateway = new SafeUpstreamGateway({ transport: { diff --git a/apps/api/src/infrastructure/transport/safe-upstream-gateway.ts b/apps/api/src/infrastructure/transport/safe-upstream-gateway.ts index 5bc55a9..6718f85 100644 --- a/apps/api/src/infrastructure/transport/safe-upstream-gateway.ts +++ b/apps/api/src/infrastructure/transport/safe-upstream-gateway.ts @@ -55,8 +55,9 @@ export class SafeUpstreamGateway { url.hash || url.username || url.password || - typeof request.headers.cookie !== 'string' || - !/^simadmin_session=[^;\s,]+$/.test(request.headers.cookie) + (request.headers.cookie !== undefined && + (typeof request.headers.cookie !== 'string' || + !/^simadmin_session=[^;\s,]+$/.test(request.headers.cookie))) ) throw new UpstreamError('UPSTREAM_REQUEST_INVALID'); return this.options.transport.get(request.url, request.headers);