Skip to content

Commit 36a4631

Browse files
committed
fix(cmc): readOffer must omit streams filter — :_cmc:_internal:offer is not a real parent
After the previous `streamIds → streams` fix, readOffer still fails against any real api-server with `unknown-referenced-resource`: the api-server validates that streams referenced in events.get actually exist, and `:_cmc:_internal:offer` is NOT auto-provisioned on every user account — only the per-capability children `:_cmc:_internal:offer:<capId>` are minted by capabilityMintHook. The accepter doesn't know <capId> from the capabilityUrl alone, so a specific-stream filter isn't possible either. The plugin's own implementation of the same read (`readOfferViaCapability` in acceptOrchestration.ts:71-78) handles this correctly: omit the streams filter entirely and rely on the capability access's permissions to narrow the response to the single offer event this token can read. Mirror that approach. Keep the `types: [ET_REQUEST]` filter as defense in case future plugin revisions place additional event types on the offer stream. Verified end-to-end on demo: readOffer now returns the offer with `requestedPermissions`, `consent`, etc. No new tests in this PR — the existing cmc.test.js mocks Connection.apiOne, so neither the field-name bug nor this parent- stream-doesn't-exist bug is caught at unit-test time. Both surface only against a real api-server.
1 parent 38bf4e6 commit 36a4631

1 file changed

Lines changed: 13 additions & 5 deletions

File tree

components/pryv-cmc/src/index.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -550,12 +550,20 @@ async function requestScopeUpdate (conn, params) {
550550
async function readOffer (capabilityUrl, opts) {
551551
const pryv = (opts && opts.pryv) || require('pryv');
552552
const cap = new pryv.Connection(capabilityUrl);
553-
// `events.get` takes `streams` (recursive read filter), not `streamIds`
554-
// (which is the events.create write target). Mirror the field used by
555-
// the other events.get callers in this file (listInvites, waitForAccept,
556-
// listAcceptedRelationships).
553+
// The capability access has `read` on a single per-capability stream
554+
// (`:_cmc:_internal:offer:<capId>`) but the accepter doesn't know
555+
// <capId> from the capabilityUrl alone. The parent `:_cmc:_internal:offer`
556+
// is NOT a reserved stream that auto-exists on every user account — only
557+
// the per-capability children do — so a `streams: [':_cmc:_internal:offer']`
558+
// filter resolves to `unknown-referenced-resource`.
559+
//
560+
// Mirror the plugin's own readOfferViaCapability (acceptOrchestration.ts):
561+
// omit the streams filter entirely and rely on the cap access's
562+
// permissions to narrow the response to the single offer event this
563+
// token can read. The `types` filter is defensive in case the offer
564+
// stream ever holds more than one event in future revisions.
557565
const events = await cap.apiOne('events.get', {
558-
streams: [NS_INTERNAL + ':offer'],
566+
types: [ET_REQUEST],
559567
limit: 1
560568
}, 'events');
561569
if (events.length === 0) {

0 commit comments

Comments
 (0)