Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RecordsQuery & RecordsSubscribe supports an array for author and recipient #777

Merged
merged 8 commits into from
Aug 20, 2024
18 changes: 16 additions & 2 deletions json-schemas/interface-methods/records-filter.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,27 @@
"type": "string"
},
"author": {
"$ref": "https://identity.foundation/dwn/json-schemas/defs.json#/$defs/did"
"oneOf": [{
"$ref": "https://identity.foundation/dwn/json-schemas/defs.json#/$defs/did"
},{
"type": "array",
"items": {
"$ref": "https://identity.foundation/dwn/json-schemas/defs.json#/$defs/did"
}
}]
},
"attester": {
"$ref": "https://identity.foundation/dwn/json-schemas/defs.json#/$defs/did"
},
"recipient": {
"$ref": "https://identity.foundation/dwn/json-schemas/defs.json#/$defs/did"
"oneOf": [{
"$ref": "https://identity.foundation/dwn/json-schemas/defs.json#/$defs/did"
},{
"type": "array",
"items": {
"$ref": "https://identity.foundation/dwn/json-schemas/defs.json#/$defs/did"
}
}]
},
"contextId": {
"type": "string"
Expand Down
11 changes: 6 additions & 5 deletions src/handlers/records-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,16 +151,17 @@ export class RecordsQueryHandler implements MethodHandler {
}

if (Records.filterIncludesUnpublishedRecords(filter)) {
filters.push(RecordsQueryHandler.buildUnpublishedRecordsByQueryAuthorFilter(recordsQuery));

const recipientFilter = recordsQuery.message.descriptor.filter.recipient;
if (recipientFilter === undefined || recipientFilter === recordsQuery.author) {
filters.push(RecordsQueryHandler.buildUnpublishedRecordsForQueryAuthorFilter(recordsQuery));
if (Records.shouldBuildUnpublishedAuthorFilter(filter, recordsQuery.author!)) {
filters.push(RecordsQueryHandler.buildUnpublishedRecordsByQueryAuthorFilter(recordsQuery));
}

if (Records.shouldProtocolAuthorize(recordsQuery.signaturePayload!)) {
filters.push(RecordsQueryHandler.buildUnpublishedProtocolAuthorizedRecordsFilter(recordsQuery));
}

if (Records.shouldBuildUnpublishedRecipientFilter(filter, recordsQuery.author!)) {
filters.push(RecordsQueryHandler.buildUnpublishedRecordsForQueryAuthorFilter(recordsQuery));
}
}

const messageSort = this.convertDateSort(dateSort);
Expand Down
11 changes: 6 additions & 5 deletions src/handlers/records-subscribe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,16 +127,17 @@ export class RecordsSubscribeHandler implements MethodHandler {
}

if (Records.filterIncludesUnpublishedRecords(filter)) {
filters.push(RecordsSubscribeHandler.buildUnpublishedRecordsBySubscribeAuthorFilter(recordsSubscribe));

const recipientFilter = recordsSubscribe.message.descriptor.filter.recipient;
if (recipientFilter === undefined || recipientFilter === recordsSubscribe.author) {
filters.push(RecordsSubscribeHandler.buildUnpublishedRecordsForSubscribeAuthorFilter(recordsSubscribe));
if (Records.shouldBuildUnpublishedAuthorFilter(filter, recordsSubscribe.author!)) {
filters.push(RecordsSubscribeHandler.buildUnpublishedRecordsBySubscribeAuthorFilter(recordsSubscribe));
}

if (Records.shouldProtocolAuthorize(recordsSubscribe.signaturePayload!)) {
filters.push(RecordsSubscribeHandler.buildUnpublishedProtocolAuthorizedRecordsFilter(recordsSubscribe));
}

if (Records.shouldBuildUnpublishedRecipientFilter(filter, recordsSubscribe.author!)) {
filters.push(RecordsSubscribeHandler.buildUnpublishedRecordsForSubscribeAuthorFilter(recordsSubscribe));
}
}
return filters;
}
Expand Down
4 changes: 2 additions & 2 deletions src/types/records-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ export type RecordsFilter = {
/**
* The logical author of the record
*/
author?: string;
author?: string | string[];
attester?: string;
recipient?: string;
recipient?: string | string[];
protocol?: string;
protocolPath?: string;
published?: boolean;
Expand Down
40 changes: 40 additions & 0 deletions src/utils/records.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,16 @@ export class Records {
filterCopy.contextId = contextIdPrefixFilter;
}

// if the author filter is an array and it's empty, we should remove it from the filter as it will always return no results.
if (Array.isArray(filterCopy.author) && filterCopy.author.length === 0) {
delete filterCopy.author;
}

// if the recipient filter is an array and it's empty, we should remove it from the filter as it will always return no results.
if (Array.isArray(filterCopy.recipient) && filterCopy.recipient.length === 0) {
delete filterCopy.recipient;
}

return filterCopy as Filter;
}

Expand Down Expand Up @@ -531,4 +541,34 @@ export class Records {

return true;
}

/**
* Checks whether or not the incoming records query filter should build an unpublished recipient MessageStore filter.
*
* @param filter The incoming RecordsFilter to evaluate against.
* @param recipient The recipient to check against the filter, typically the query/subscribe message author.
* @returns {boolean} True if the filter contains the recipient, or if the recipient filter is undefined/empty.
*/
static shouldBuildUnpublishedRecipientFilter(filter: RecordsFilter, recipient: string): boolean {
const { recipient: recipientFilter } = filter;

return Array.isArray(recipientFilter) ?
recipientFilter.length === 0 || recipientFilter.includes(recipient) :
recipientFilter === undefined || recipientFilter === recipient;
}

/**
* Checks whether or not the incoming records query filter should build an unpublished author MessageStore filter.
*
* @param filter The incoming RecordsFilter to evaluate against.
* @param author The author to check against the filter, typically the query/subscribe message author.
* @returns {boolean} True if the filter contains the author, or if the author filter is undefined/empty.
*/
static shouldBuildUnpublishedAuthorFilter(filter: RecordsFilter, author: string): boolean {
const { author: authorFilter } = filter;

return Array.isArray(authorFilter) ?
authorFilter.length === 0 || authorFilter.includes(author) :
authorFilter === undefined || authorFilter === author;
}
}
Loading