From 8f1e650b9351a7719025a9b367096a5c7bd7be7a Mon Sep 17 00:00:00 2001 From: Jaapjan Tinbergen Date: Thu, 12 Jun 2025 18:37:35 +0200 Subject: [PATCH] Add support for custom denied access reason --- src/gatehouse.ts | 32 ++++++++++++++++++-------------- tests/index.test.ts | 19 +++++++++++++++++++ 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/gatehouse.ts b/src/gatehouse.ts index 1cbf084..8d4f3be 100644 --- a/src/gatehouse.ts +++ b/src/gatehouse.ts @@ -715,24 +715,28 @@ function buildAbacPolicy( action, context, }): Promise => { - const conditionMet: boolean = await condition({ - subject, - resource, - action, - context, - }); + try { + const conditionMet: boolean = await condition({ + subject, + resource, + action, + context, + }); - if (conditionMet) { - return new GrantedAccessResult({ + if (conditionMet) { + return new GrantedAccessResult({ + policyType, + reason: 'Condition evaluated to true', + }); + } + + throw new Error('Condition evaluated to false'); + } catch (error) { + return new DeniedAccessResult({ policyType, - reason: 'Condition evaluated to true', + reason: (error as Error)?.message || "Condition evaluated to false", }); } - - return new DeniedAccessResult({ - policyType, - reason: 'Condition evaluated to false', - }); }; return Object.freeze({ name: policyType, evaluateAccess, condition }); diff --git a/tests/index.test.ts b/tests/index.test.ts index 48e85ad..326d63f 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -898,3 +898,22 @@ describe("PermissionChecker", () => { expect(result.isGranted()).toBe(false); }); }); + +describe("Custom denied reasons", () => { + test("should return custom denied reason when access is denied", async () => { + const abacPolicy = buildAbacPolicy({ + condition: () => { + throw new Error("Access denied: A detailed reason for denial"); + }, + }); + + const result = await abacPolicy.evaluateAccess({ + subject: {}, + resource: {}, + action: {}, + context: {}, + }); + expect(result.isGranted()).toBe(false); + expect(result.reason).toBe("Access denied: A detailed reason for denial"); + }); +});