From 840b95ccd763ec894dd6cc5284a43af65889f42f Mon Sep 17 00:00:00 2001 From: Viljami Kuosmanen Date: Sat, 15 Aug 2026 06:55:52 +0300 Subject: [PATCH 1/2] fix: reject error-key authorization results --- src/backend.test.ts | 6 +++--- src/backend.ts | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/backend.test.ts b/src/backend.test.ts index 407108fe..4b54ddda 100644 --- a/src/backend.test.ts +++ b/src/backend.test.ts @@ -565,13 +565,13 @@ describe('OpenAPIBackend', () => { expect(context.security?.authorized).toBe(false); }); - test('sets context.security.authorized=true if handler returns an object with a falsy error', async () => { + test('sets context.security.authorized=false if handler returns an object with a falsy error', async () => { const api = new OpenAPIBackend({ definition }); let context: Partial = {}; api.register('notImplemented', (c) => { context = c; }); - // a falsy `error` (e.g. the "no error, here's the user" success pattern) is not a rejection + // an error key is interpreted as failed auth, even when its value is falsy api.registerSecurityHandler('basicAuth', () => ({ error: null, user: { id: 1 } })); await api.init(); @@ -583,7 +583,7 @@ describe('OpenAPIBackend', () => { }; await api.handleRequest(request); - expect(context.security?.authorized).toBe(true); + expect(context.security?.authorized).toBe(false); }); test('does not call operation handler if handler returns a multi-key error object', async () => { diff --git a/src/backend.ts b/src/backend.ts index 6533b5f7..a2bb9ff5 100644 --- a/src/backend.ts +++ b/src/backend.ts @@ -402,13 +402,12 @@ export class OpenAPIBackend { } // handle error object passed earlier - // any object carrying a truthy `error` property is treated as a failed - // auth, regardless of whatever other properties it carries. A falsy - // `error` (e.g. `{ error: null, user }`) is not a rejection. + // any object carrying an `error` key is treated as failed auth, + // regardless of its value or any additional properties. if ( requirementResult && typeof requirementResult === 'object' && - (requirementResult as { error?: unknown }).error + Object.prototype.hasOwnProperty.call(requirementResult, 'error') ) { return false; } From 0298d1105c5029b62fb91e6a8d0a4dee0adcdbde Mon Sep 17 00:00:00 2001 From: Viljami Kuosmanen Date: Sat, 15 Aug 2026 06:59:45 +0300 Subject: [PATCH 2/2] fix: preserve falsy auth result semantics --- src/backend.test.ts | 6 +++--- src/backend.ts | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/backend.test.ts b/src/backend.test.ts index 4b54ddda..407108fe 100644 --- a/src/backend.test.ts +++ b/src/backend.test.ts @@ -565,13 +565,13 @@ describe('OpenAPIBackend', () => { expect(context.security?.authorized).toBe(false); }); - test('sets context.security.authorized=false if handler returns an object with a falsy error', async () => { + test('sets context.security.authorized=true if handler returns an object with a falsy error', async () => { const api = new OpenAPIBackend({ definition }); let context: Partial = {}; api.register('notImplemented', (c) => { context = c; }); - // an error key is interpreted as failed auth, even when its value is falsy + // a falsy `error` (e.g. the "no error, here's the user" success pattern) is not a rejection api.registerSecurityHandler('basicAuth', () => ({ error: null, user: { id: 1 } })); await api.init(); @@ -583,7 +583,7 @@ describe('OpenAPIBackend', () => { }; await api.handleRequest(request); - expect(context.security?.authorized).toBe(false); + expect(context.security?.authorized).toBe(true); }); test('does not call operation handler if handler returns a multi-key error object', async () => { diff --git a/src/backend.ts b/src/backend.ts index a2bb9ff5..6533b5f7 100644 --- a/src/backend.ts +++ b/src/backend.ts @@ -402,12 +402,13 @@ export class OpenAPIBackend { } // handle error object passed earlier - // any object carrying an `error` key is treated as failed auth, - // regardless of its value or any additional properties. + // any object carrying a truthy `error` property is treated as a failed + // auth, regardless of whatever other properties it carries. A falsy + // `error` (e.g. `{ error: null, user }`) is not a rejection. if ( requirementResult && typeof requirementResult === 'object' && - Object.prototype.hasOwnProperty.call(requirementResult, 'error') + (requirementResult as { error?: unknown }).error ) { return false; }