From bdbbbb7e04bcb6996a12bfabe15130e51e25f8f0 Mon Sep 17 00:00:00 2001 From: Melvin Carvalho Date: Wed, 7 Jan 2026 13:18:55 +0100 Subject: [PATCH 1/2] Fix relative URI resolution for acl:agent Resolve agent URIs against the ACL URL so that relative references like `./#me` in an ACL file correctly match the authenticated WebID. Previously, `accessTo` and `default` were resolved but `agents` were not, causing 403 Forbidden when using relative URIs for agent WebIDs. Fixes #64 --- src/wac/parser.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wac/parser.js b/src/wac/parser.js index 92faec0..b0b3727 100644 --- a/src/wac/parser.js +++ b/src/wac/parser.js @@ -144,8 +144,9 @@ function parseAuthorization(node, aclUrl) { auth.default = parseUriArray(node['acl:default'] || node['default']) .map(uri => resolveUri(uri, baseUrl)); - // Parse agents (WebIDs can be relative too) - auth.agents = parseUriArray(node['acl:agent'] || node['agent']); + // Parse agents (WebIDs can be relative too) - resolve against ACL URL + auth.agents = parseUriArray(node['acl:agent'] || node['agent']) + .map(uri => resolveUri(uri, aclUrl)); // Parse agentClass auth.agentClasses = parseUriArray(node['acl:agentClass'] || node['agentClass']); From 6aa0ad1807a4a337c8481fd19a140ea44810871b Mon Sep 17 00:00:00 2001 From: Melvin Carvalho Date: Tue, 24 Feb 2026 13:53:02 +0100 Subject: [PATCH 2/2] Add test for relative agent URI resolution Verifies that ./#me in an ACL file resolves to the correct absolute WebID when checked against the ACL URL. --- test/wac.test.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/wac.test.js b/test/wac.test.js index 81cc1a8..477ab84 100644 --- a/test/wac.test.js +++ b/test/wac.test.js @@ -187,6 +187,23 @@ describe('WAC Parser', () => { `Expected accessTo to include 'https://alice.example/other/', got: ${auths[0].accessTo}`); }); + it('should resolve relative agent URIs against ACL URL', async () => { + const acl = { + '@context': { 'acl': 'http://www.w3.org/ns/auth/acl#' }, + '@id': '#owner', + '@type': 'acl:Authorization', + 'acl:agent': { '@id': './#me' }, + 'acl:accessTo': { '@id': './' }, + 'acl:mode': [{ '@id': 'acl:Read' }] + }; + + const auths = await parseAcl(JSON.stringify(acl), 'https://alice.example/.acl'); + + assert.strictEqual(auths.length, 1); + assert.ok(auths[0].agents.includes('https://alice.example/#me'), + `Expected agents to include 'https://alice.example/#me', got: ${auths[0].agents}`); + }); + it('should keep absolute URLs unchanged', async () => { const acl = { '@context': { 'acl': 'http://www.w3.org/ns/auth/acl#' },