From 2ddb4042fee59e6b667057f6e82c711fa9e318ee Mon Sep 17 00:00:00 2001 From: Vicente Olmedo Date: Fri, 28 Feb 2025 12:09:34 +0100 Subject: [PATCH] fix: dedupe proofs (#1635) closes https://github.com/storacha/w3up/issues/1633 backporting here this fix: https://github.com/storacha/upload-service/pull/143 --- packages/access-client/src/agent.js | 13 +++++++------ packages/access-client/test/agent.test.js | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/packages/access-client/src/agent.js b/packages/access-client/src/agent.js index bde24a61c..cf4203957 100644 --- a/packages/access-client/src/agent.js +++ b/packages/access-client/src/agent.js @@ -265,25 +265,26 @@ export class Agent { * @param {API.DID} [options.sessionProofIssuer] - only include session proofs for this issuer */ proofs(caps, options) { - const authorizations = [] + /** @type {Map>} */ + const authorizations = new Map() for (const { delegation } of this.#delegations(caps)) { if (delegation.audience.did() === this.issuer.did()) { - authorizations.push(delegation) + authorizations.set(delegation.cid.toString(), delegation) } } // now let's add any session proofs that refer to those authorizations const sessions = getSessionProofs(this.#data) - for (const proof of authorizations) { + for (const proof of [...authorizations.values()]) { const proofsByIssuer = sessions[proof.asCID.toString()] ?? {} const sessionProofs = options?.sessionProofIssuer ? proofsByIssuer[options.sessionProofIssuer] ?? [] : Object.values(proofsByIssuer).flat() - if (sessionProofs.length) { - authorizations.push(...sessionProofs) + for (const sessionProof of sessionProofs) { + authorizations.set(sessionProof.cid.toString(), sessionProof) } } - return authorizations + return [...authorizations.values()] } /** diff --git a/packages/access-client/test/agent.test.js b/packages/access-client/test/agent.test.js index 2849ccb85..eeebd1cfc 100644 --- a/packages/access-client/test/agent.test.js +++ b/packages/access-client/test/agent.test.js @@ -571,6 +571,25 @@ describe('Agent', function () { 'invocation for serviceBWeb does not have sessionProof from serviceAWeb' ) }) + + it('should dedupe proofs', async function () { + const agent = await Agent.create() + const space = await agent.createSpace('test-add') + const authorization = await space.createAuthorization(agent, { + access: { '*': {} }, + expiration: Infinity, + }) + + await agent.importSpaceFromDelegation(authorization) + const proofs = agent.proofs([ + { can: 'space/blob/add', with: space.did() }, + { can: 'space/index/add', with: space.did() }, + ]) + + // the same proof proves both capabilities + assert.equal(proofs.length, 1) + assert.equal(proofs[0].cid.toString(), authorization.cid.toString()) + }) }) /**