diff --git a/README.md b/README.md index d6dd3be81..eabe24163 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ # Decentralized Web Node (DWN) SDK Code Coverage -![Statements](https://img.shields.io/badge/statements-94.91%25-brightgreen.svg?style=flat) ![Branches](https://img.shields.io/badge/branches-92.93%25-brightgreen.svg?style=flat) ![Functions](https://img.shields.io/badge/functions-93.27%25-brightgreen.svg?style=flat) ![Lines](https://img.shields.io/badge/lines-94.91%25-brightgreen.svg?style=flat) +![Statements](https://img.shields.io/badge/statements-94.93%25-brightgreen.svg?style=flat) ![Branches](https://img.shields.io/badge/branches-92.92%25-brightgreen.svg?style=flat) ![Functions](https://img.shields.io/badge/functions-93.27%25-brightgreen.svg?style=flat) ![Lines](https://img.shields.io/badge/lines-94.93%25-brightgreen.svg?style=flat) ## Introduction diff --git a/src/core/dwn-constant.ts b/src/core/dwn-constant.ts new file mode 100644 index 000000000..a9b1d5dc6 --- /dev/null +++ b/src/core/dwn-constant.ts @@ -0,0 +1,6 @@ +export class DwnConstant { + /** + * The maximum size of raw data that will be returned as `encodedData`. + */ + public static readonly maxDataSizeAllowedToBeEncoded = 10_000; +} \ No newline at end of file diff --git a/src/core/message-reply.ts b/src/core/message-reply.ts index b95e71194..586de36c1 100644 --- a/src/core/message-reply.ts +++ b/src/core/message-reply.ts @@ -1,4 +1,5 @@ -import { Descriptor } from './types.js'; +import type { QueryResultEntry } from './types.js'; + import { Readable } from 'readable-stream'; type Status = { @@ -8,7 +9,7 @@ type Status = { type MessageReplyOptions = { status: Status, - entries?: { descriptor: Descriptor }[]; + entries?: QueryResultEntry[]; data? : Readable; }; @@ -20,7 +21,7 @@ export class MessageReply { * e.g. the resulting messages from a RecordsQuery * Mutually exclusive with `data`. */ - entries?: { descriptor: Descriptor }[]; + entries?: QueryResultEntry[]; /** * Data corresponding to the message received if applicable (e.g. RecordsRead). diff --git a/src/core/message.ts b/src/core/message.ts index 9950f6664..7462144cf 100644 --- a/src/core/message.ts +++ b/src/core/message.ts @@ -71,15 +71,11 @@ export abstract class Message { * Gets the CID of the given message. */ public static async getCid(message: BaseMessage): Promise { - const messageCopy = { ...message }; - - // TODO: Once #219 (https://github.com/TBD54566975/dwn-sdk-js/issues/219) is implemented, - // `encodedData` will likely not exist directly as part of the message - if (messageCopy['encodedData'] !== undefined) { - delete (messageCopy as any).encodedData; - } - - const cid = await computeCid(messageCopy); + // NOTE: we wrap the `computeCid()` here in case that + // the message will contain properties that should not be part of the CID computation + // and we need to strip them out (like `encodedData` that we historically had for a long time), + // but we can remove this method entirely if the code becomes stable and it is apparent that the wrapper is not needed + const cid = await computeCid(message); return cid; } diff --git a/src/core/types.ts b/src/core/types.ts index f3edb5492..de3b487a0 100644 --- a/src/core/types.ts +++ b/src/core/types.ts @@ -35,22 +35,34 @@ export type TimestampedMessage = BaseMessage & { }; /** - * Message that references `dataCid`. + * Message returned in a query result. + * NOTE: the message structure is a modified version of the message received, the most notable differences are: + * 1. does not contain `authorization` + * 2. may include encoded data */ -export type DataReferencingMessage = { - descriptor: { - dataCid: string; - }; - - encodedData: string; +export type QueryResultEntry = { + descriptor: Descriptor; + encodedData?: string; }; export type EqualFilter = string | number | boolean; export type OneOfFilter = EqualFilter[]; -type GT = ({ gt: string } & { gte?: never }) | ({ gt?: never } & { gte: string }); -type LT = ({ lt: string } & { lte?: never }) | ({ lt?: never } & { lte: string }); + +/** + * "greater than" or "greater than or equal to" range condition. `gt` and `gte` are mutually exclusive. + */ +export type GT = ({ gt: string } & { gte?: never }) | ({ gt?: never } & { gte: string }); + +/** + * "less than" or "less than or equal to" range condition. `lt`, `lte` are mutually exclusive. + */ +export type LT = ({ lt: string } & { lte?: never }) | ({ lt?: never } & { lte: string }); + +/** + * Ranger filter. 1 condition is required. + */ export type RangeFilter = (GT | LT) & Partial & Partial; export type Filter = { diff --git a/src/index.ts b/src/index.ts index 14ed6bb62..a97ad4090 100644 --- a/src/index.ts +++ b/src/index.ts @@ -24,6 +24,7 @@ export { DidKeyResolver } from './did/did-key-resolver.js'; export { DidIonResolver } from './did/did-ion-resolver.js'; export { DidResolver, DidMethodResolver } from './did/did-resolver.js'; export { Dwn } from './dwn.js'; +export { DwnConstant } from './core/dwn-constant.js'; export { DwnInterfaceName, DwnMethodName } from './core/message.js'; export { Encoder } from './utils/encoder.js'; export { HooksWrite, HooksWriteOptions } from './interfaces/hooks/messages/hooks-write.js'; diff --git a/src/interfaces/protocols/handlers/protocols-query.ts b/src/interfaces/protocols/handlers/protocols-query.ts index 7fd2f1393..0211eda6e 100644 --- a/src/interfaces/protocols/handlers/protocols-query.ts +++ b/src/interfaces/protocols/handlers/protocols-query.ts @@ -1,5 +1,6 @@ import type { MethodHandler } from '../../types.js'; import type { ProtocolsQueryMessage } from '../types.js'; +import type { QueryResultEntry } from '../../../core/types.js'; import { canonicalAuth } from '../../../core/auth.js'; import { MessageReply } from '../../../core/message-reply.js'; @@ -43,7 +44,14 @@ export class ProtocolsQueryHandler implements MethodHandler { }; removeUndefinedProperties(query); - const entries = await this.messageStore.query(tenant, query); + const records = await this.messageStore.query(tenant, query); + + // strip away `authorization` property for each record before responding + const entries: QueryResultEntry[] = []; + for (const record of records) { + const { authorization: _, ...objectWithRemainingProperties } = record; // a trick to stripping away `authorization` + entries.push(objectWithRemainingProperties); + } return new MessageReply({ status: { code: 200, detail: 'OK' }, diff --git a/src/interfaces/records/handlers/records-query.ts b/src/interfaces/records/handlers/records-query.ts index 299db63ff..35a237795 100644 --- a/src/interfaces/records/handlers/records-query.ts +++ b/src/interfaces/records/handlers/records-query.ts @@ -1,8 +1,8 @@ import type { MethodHandler } from '../../types.js'; +import type { BaseMessage, QueryResultEntry } from '../../../core/types.js'; import type { RecordsQueryMessage, RecordsWriteMessage } from '../types.js'; import { authenticate } from '../../../core/auth.js'; -import { BaseMessage } from '../../../core/types.js'; import { lexicographicalCompare } from '../../../utils/string.js'; import { MessageReply } from '../../../core/message-reply.js'; import { StorageController } from '../../../store/storage-controller.js'; @@ -50,11 +50,10 @@ export class RecordsQueryHandler implements MethodHandler { } // strip away `authorization` property for each record before responding - const entries = []; + const entries: QueryResultEntry[] = []; for (const record of records) { - const recordDuplicate = { ...record }; - delete recordDuplicate.authorization; - entries.push(recordDuplicate); + const { authorization: _, ...objectWithRemainingProperties } = record; // a trick to stripping away `authorization` + entries.push(objectWithRemainingProperties); } return new MessageReply({ diff --git a/src/store/blockstore-level.ts b/src/store/blockstore-level.ts index ba61f342c..fbce2aac4 100644 --- a/src/store/blockstore-level.ts +++ b/src/store/blockstore-level.ts @@ -11,6 +11,11 @@ import { sleep } from '../utils/time.js'; // FreeBSD, including any future Node.js and Electron release thanks to Node-API, including ARM // platforms like Raspberry Pi and Android, as well as in Chrome, Firefox, Edge, Safari, iOS Safari // and Chrome for Android. + +/** + * Blockstore implementation using LevelDB for storing the actual messages (in the case of MessageStore) + * or the data associated with messages (in the case of a DataStore). + */ export class BlockstoreLevel implements Blockstore { config: BlockstoreLevelConfig; diff --git a/src/store/index-level.ts b/src/store/index-level.ts index 7aa5cd6d9..c097b1818 100644 --- a/src/store/index-level.ts +++ b/src/store/index-level.ts @@ -15,6 +15,9 @@ export interface IndexLevelOptions { signal?: AbortSignal; } +/** + * A LevelDB implementation for indexing the messages stored in the DWN. + */ export class IndexLevel { config: IndexLevelConfig; diff --git a/src/store/storage-controller.ts b/src/store/storage-controller.ts index 89d6d2829..58214e7c3 100644 --- a/src/store/storage-controller.ts +++ b/src/store/storage-controller.ts @@ -1,8 +1,9 @@ import { DataStore } from './data-store.js'; +import { DwnConstant } from '../core/dwn-constant.js'; import { MessageStore } from './message-store.js'; import { Readable } from 'readable-stream'; -import { BaseMessage, Filter } from '../core/types.js'; +import { BaseMessage, Filter } from '../core/types.js'; import { DataStream, Encoder } from '../index.js'; import { DwnError, DwnErrorCode } from '../core/dwn-error.js'; @@ -84,12 +85,11 @@ export class StorageController { const messages = await messageStore.query(tenant, filter); + // for every message, only include the data as `encodedData` if the data size is equal or smaller than the size threshold for (const message of messages) { const dataCid = message.descriptor.dataCid; - if (dataCid !== undefined) { - // TODO: #219 (https://github.com/TBD54566975/dwn-sdk-js/issues/219) - // temporary placeholder for keeping status-quo of returning data in `encodedData` - // once #219 is implemented, `encodedData` may or may not exist directly as part of the returned message here + const dataSize = message.descriptor.dataSize; + if (dataCid !== undefined && dataSize! <= DwnConstant.maxDataSizeAllowedToBeEncoded) { const readableStream = await dataStore.get(tenant, 'not used yet', dataCid); const dataBytes = await DataStream.toBytes(readableStream); diff --git a/tests/interfaces/records/handlers/records-delete.spec.ts b/tests/interfaces/records/handlers/records-delete.spec.ts index b0fea4943..cea743e15 100644 --- a/tests/interfaces/records/handlers/records-delete.spec.ts +++ b/tests/interfaces/records/handlers/records-delete.spec.ts @@ -118,7 +118,7 @@ describe('RecordsDeleteHandler.handle()', () => { const reply = await dwn.processMessage(alice.did, queryData.message); expect(reply.status.code).to.equal(200); expect(reply.entries?.length).to.equal(1); - expect((reply.entries[0] as any).encodedData).to.equal(expectedEncodedData); + expect(reply.entries[0].encodedData).to.equal(expectedEncodedData); }); }); diff --git a/tests/interfaces/records/handlers/records-query.spec.ts b/tests/interfaces/records/handlers/records-query.spec.ts index d84ada036..564ee39f2 100644 --- a/tests/interfaces/records/handlers/records-query.spec.ts +++ b/tests/interfaces/records/handlers/records-query.spec.ts @@ -4,6 +4,7 @@ import chai, { expect } from 'chai'; import { DataStoreLevel } from '../../../../src/store/data-store-level.js'; import { DidKeyResolver } from '../../../../src/did/did-key-resolver.js'; +import { DwnConstant } from '../../../../src/core/dwn-constant.js'; import { Encoder } from '../../../../src/utils/encoder.js'; import { Jws } from '../../../../src/utils/jws.js'; import { MessageStoreLevel } from '../../../../src/store/message-store-level.js'; @@ -98,6 +99,38 @@ describe('RecordsQueryHandler.handle()', () => { expect(reply2.entries?.length).to.equal(1); // only 1 entry should match the query }); + it('should return `encodedData` if data size is within the spec threshold', async () => { + const data = TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded); // within/on threshold + const alice = await DidKeyResolver.generate(); + const write= await TestDataGenerator.generateRecordsWrite({ requester: alice, data }); + + const writeReply = await dwn.processMessage(alice.did, write.message, write.dataStream); + expect(writeReply.status.code).to.equal(202); + + const messageData = await TestDataGenerator.generateRecordsQuery({ requester: alice, filter: { recordId: write.message.recordId } }); + const reply = await dwn.processMessage(alice.did, messageData.message); + + expect(reply.status.code).to.equal(200); + expect(reply.entries?.length).to.equal(1); + expect(reply.entries[0].encodedData).to.equal(Encoder.bytesToBase64Url(data)); + }); + + it('should not return `encodedData` if data size is greater then spec threshold', async () => { + const data = TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded + 1); // exceeding threshold + const alice = await DidKeyResolver.generate(); + const write= await TestDataGenerator.generateRecordsWrite({ requester: alice, data }); + + const writeReply = await dwn.processMessage(alice.did, write.message, write.dataStream); + expect(writeReply.status.code).to.equal(202); + + const messageData = await TestDataGenerator.generateRecordsQuery({ requester: alice, filter: { recordId: write.message.recordId } }); + const reply = await dwn.processMessage(alice.did, messageData.message); + + expect(reply.status.code).to.equal(200); + expect(reply.entries?.length).to.equal(1); + expect(reply.entries[0].encodedData).to.be.undefined; + }); + it('should be able to query by attester', async () => { // scenario: 2 records authored by alice, 1st attested by alice, 2nd attested by bob const alice = await DidKeyResolver.generate(); @@ -162,8 +195,8 @@ describe('RecordsQueryHandler.handle()', () => { }); const reply1 = await dwn.processMessage(alice.did, recordsQuery1.message); expect(reply1.entries?.length).to.equal(2); - expect((reply1.entries[0] as any).encodedData).to.equal(Encoder.bytesToBase64Url(write2.dataBytes)); - expect((reply1.entries[1] as any).encodedData).to.equal(Encoder.bytesToBase64Url(write3.dataBytes)); + expect(reply1.entries[0].encodedData).to.equal(Encoder.bytesToBase64Url(write2.dataBytes)); + expect(reply1.entries[1].encodedData).to.equal(Encoder.bytesToBase64Url(write3.dataBytes)); // testing `to` range const lastDayOf2022 = Temporal.PlainDateTime.from({ year: 2022, month: 12, day: 31 }).toString({ smallestUnit: 'microseconds' }); @@ -174,8 +207,8 @@ describe('RecordsQueryHandler.handle()', () => { }); const reply2 = await dwn.processMessage(alice.did, recordsQuery2.message); expect(reply2.entries?.length).to.equal(2); - expect((reply2.entries[0] as any).encodedData).to.equal(Encoder.bytesToBase64Url(write1.dataBytes)); - expect((reply2.entries[1] as any).encodedData).to.equal(Encoder.bytesToBase64Url(write2.dataBytes)); + expect(reply2.entries[0].encodedData).to.equal(Encoder.bytesToBase64Url(write1.dataBytes)); + expect(reply2.entries[1].encodedData).to.equal(Encoder.bytesToBase64Url(write2.dataBytes)); // testing `from` and `to` range const lastDayOf2023 = Temporal.PlainDateTime.from({ year: 2023, month: 12, day: 31 }).toString({ smallestUnit: 'microseconds' }); @@ -186,7 +219,7 @@ describe('RecordsQueryHandler.handle()', () => { }); const reply3 = await dwn.processMessage(alice.did, recordsQuery3.message); expect(reply3.entries?.length).to.equal(1); - expect((reply3.entries[0] as any).encodedData).to.equal(Encoder.bytesToBase64Url(write3.dataBytes)); + expect(reply3.entries[0].encodedData).to.equal(Encoder.bytesToBase64Url(write3.dataBytes)); // testing edge case where value equals `from` and `to` const recordsQuery4 = await TestDataGenerator.generateRecordsQuery({ @@ -196,7 +229,7 @@ describe('RecordsQueryHandler.handle()', () => { }); const reply4 = await dwn.processMessage(alice.did, recordsQuery4.message); expect(reply4.entries?.length).to.equal(1); - expect((reply4.entries[0] as any).encodedData).to.equal(Encoder.bytesToBase64Url(write2.dataBytes)); + expect(reply4.entries[0].encodedData).to.equal(Encoder.bytesToBase64Url(write2.dataBytes)); }); it('should be able use range and exact match queries at the same time', async () => { @@ -237,7 +270,7 @@ describe('RecordsQueryHandler.handle()', () => { }); const reply = await dwn.processMessage(alice.did, recordsQuery5.message); expect(reply.entries?.length).to.equal(1); - expect((reply.entries[0] as any).encodedData).to.equal(Encoder.bytesToBase64Url(write2.dataBytes)); + expect(reply.entries[0].encodedData).to.equal(Encoder.bytesToBase64Url(write2.dataBytes)); }); it('should not include `authorization` in returned records', async () => { @@ -441,9 +474,9 @@ describe('RecordsQueryHandler.handle()', () => { expect(replyToBob.status.code).to.equal(200); expect(replyToBob.entries?.length).to.equal(3); // expect 3 records - const privateRecordsForBob = replyToBob.entries.filter(message => (message as any).encodedData === Encoder.stringToBase64Url('2')); - const privateRecordsFromBob = replyToBob.entries.filter(message => (message as any).encodedData === Encoder.stringToBase64Url('3')); - const publicRecords = replyToBob.entries.filter(message => (message as any).encodedData === Encoder.stringToBase64Url('4')); + const privateRecordsForBob = replyToBob.entries.filter(message => message.encodedData === Encoder.stringToBase64Url('2')); + const privateRecordsFromBob = replyToBob.entries.filter(message => message.encodedData === Encoder.stringToBase64Url('3')); + const publicRecords = replyToBob.entries.filter(message => message.encodedData === Encoder.stringToBase64Url('4')); expect(privateRecordsForBob.length).to.equal(1); expect(privateRecordsFromBob.length).to.equal(1); expect(publicRecords.length).to.equal(1); diff --git a/tests/interfaces/records/handlers/records-write.spec.ts b/tests/interfaces/records/handlers/records-write.spec.ts index 407bc633d..6130ebbc8 100644 --- a/tests/interfaces/records/handlers/records-write.spec.ts +++ b/tests/interfaces/records/handlers/records-write.spec.ts @@ -16,6 +16,7 @@ import { GeneralJwsSigner } from '../../../../src/jose/jws/general/signer.js'; import { getCurrentTimeInHighPrecision } from '../../../../src/utils/time.js'; import { Message } from '../../../../src/core/message.js'; import { MessageStoreLevel } from '../../../../src/store/message-store-level.js'; +import { QueryResultEntry } from '../../../../src/core/types.js'; import { RecordsWriteHandler } from '../../../../src/interfaces/records/handlers/records-write.js'; import { RecordsWriteMessage } from '../../../../src/interfaces/records/types.js'; import { StorageController } from '../../../../src/store/storage-controller.js'; @@ -82,7 +83,7 @@ describe('RecordsWriteHandler.handle()', () => { const recordsQueryReply = await dwn.processMessage(tenant, recordsQueryMessageData.message); expect(recordsQueryReply.status.code).to.equal(200); expect(recordsQueryReply.entries?.length).to.equal(1); - expect((recordsQueryReply.entries![0] as any).encodedData).to.equal(base64url.baseEncode(data1)); + expect(recordsQueryReply.entries![0].encodedData).to.equal(base64url.baseEncode(data1)); // generate and write a new RecordsWrite to overwrite the existing record // a new RecordsWrite by default will have a later `dateModified` @@ -105,7 +106,7 @@ describe('RecordsWriteHandler.handle()', () => { expect(newRecordsQueryReply.status.code).to.equal(200); expect(newRecordsQueryReply.entries?.length).to.equal(1); - expect((newRecordsQueryReply.entries![0] as any).encodedData).to.equal(newDataEncoded); + expect(newRecordsQueryReply.entries![0].encodedData).to.equal(newDataEncoded); // try to write the older message to store again and verify that it is not accepted const thirdRecordsWriteReply = await dwn.processMessage(tenant, recordsWriteMessageData.message, recordsWriteMessageData.dataStream); @@ -115,7 +116,7 @@ describe('RecordsWriteHandler.handle()', () => { const thirdRecordsQueryReply = await dwn.processMessage(tenant, recordsQueryMessageData.message); expect(thirdRecordsQueryReply.status.code).to.equal(200); expect(thirdRecordsQueryReply.entries?.length).to.equal(1); - expect((thirdRecordsQueryReply.entries![0] as any).encodedData).to.equal(newDataEncoded); + expect(thirdRecordsQueryReply.entries![0].encodedData).to.equal(newDataEncoded); }); it('should only be able to overwrite existing record if new message CID is larger when `dateModified` value is the same', async () => { @@ -337,7 +338,7 @@ describe('RecordsWriteHandler.handle()', () => { expect((recordsQueryReply.entries![0] as RecordsWriteMessage).descriptor.published).to.equal(true); // very importantly verify the original data is still returned - expect((recordsQueryReply.entries![0] as any).encodedData).to.equal(Encoder.bytesToBase64Url(dataBytes)); + expect(recordsQueryReply.entries![0].encodedData).to.equal(Encoder.bytesToBase64Url(dataBytes)); }); it('should inherit parent published state when using createFrom() to create RecordsWrite', async () => { @@ -374,7 +375,7 @@ describe('RecordsWriteHandler.handle()', () => { expect(recordsQueryReply.entries?.length).to.equal(1); const recordsWriteReturned = recordsQueryReply.entries![0] as RecordsWriteMessage; - expect((recordsWriteReturned as any).encodedData).to.equal(Encoder.bytesToBase64Url(newData)); + expect((recordsWriteReturned as QueryResultEntry).encodedData).to.equal(Encoder.bytesToBase64Url(newData)); expect(recordsWriteReturned.descriptor.published).to.equal(true); expect(recordsWriteReturned.descriptor.datePublished).to.equal(message.descriptor.datePublished); }); @@ -485,7 +486,7 @@ describe('RecordsWriteHandler.handle()', () => { const bobRecordQueryReply = await dwn.processMessage(alice.did, messageDataForQueryingBobsWrite.message); expect(bobRecordQueryReply.status.code).to.equal(200); expect(bobRecordQueryReply.entries?.length).to.equal(1); - expect((bobRecordQueryReply.entries![0] as any).encodedData).to.equal(base64url.baseEncode(bobData)); + expect(bobRecordQueryReply.entries![0].encodedData).to.equal(base64url.baseEncode(bobData)); }); it('should allow write with recipient rule', async () => { @@ -550,7 +551,7 @@ describe('RecordsWriteHandler.handle()', () => { const applicationResponseQueryReply = await dwn.processMessage(alice.did, messageDataForQueryingCredentialResponse.message); expect(applicationResponseQueryReply.status.code).to.equal(200); expect(applicationResponseQueryReply.entries?.length).to.equal(1); - expect((applicationResponseQueryReply.entries![0] as any).encodedData) + expect(applicationResponseQueryReply.entries![0].encodedData) .to.equal(base64url.baseEncode(encodedCredentialResponse)); }); @@ -614,7 +615,7 @@ describe('RecordsWriteHandler.handle()', () => { const bobRecordQueryReply = await dwn.processMessage(alice.did, messageDataForQueryingBobsWrite.message); expect(bobRecordQueryReply.status.code).to.equal(200); expect(bobRecordQueryReply.entries?.length).to.equal(1); - expect((bobRecordQueryReply.entries![0] as any).encodedData).to.equal(base64url.baseEncode(bobData)); + expect(bobRecordQueryReply.entries![0].encodedData).to.equal(base64url.baseEncode(bobData)); // generate a new message from bob updating the existing notes const newNotesBytes = Encoder.stringToBytes('new data from bob'); @@ -631,7 +632,7 @@ describe('RecordsWriteHandler.handle()', () => { const newRecordQueryReply = await dwn.processMessage(alice.did, messageDataForQueryingBobsWrite.message); expect(newRecordQueryReply.status.code).to.equal(200); expect(newRecordQueryReply.entries?.length).to.equal(1); - expect((newRecordQueryReply.entries![0] as any).encodedData).to.equal(Encoder.bytesToBase64Url(newNotesBytes)); + expect(newRecordQueryReply.entries![0].encodedData).to.equal(Encoder.bytesToBase64Url(newNotesBytes)); }); it('should disallow overwriting existing records by a different author', async () => { @@ -695,7 +696,7 @@ describe('RecordsWriteHandler.handle()', () => { const bobRecordQueryReply = await dwn.processMessage(alice.did, messageDataForQueryingBobsWrite.message); expect(bobRecordQueryReply.status.code).to.equal(200); expect(bobRecordQueryReply.entries?.length).to.equal(1); - expect((bobRecordQueryReply.entries![0] as any).encodedData).to.equal(base64url.baseEncode(bobData)); + expect(bobRecordQueryReply.entries![0].encodedData).to.equal(base64url.baseEncode(bobData)); // generate a new message from carol updating the existing notes, which should not be allowed/accepted const newNotesData = new TextEncoder().encode('different data by carol'); @@ -777,7 +778,7 @@ describe('RecordsWriteHandler.handle()', () => { const bobRecordQueryReply = await dwn.processMessage(alice.did, messageDataForQueryingBobsWrite.message); expect(bobRecordQueryReply.status.code).to.equal(200); expect(bobRecordQueryReply.entries?.length).to.equal(1); - expect((bobRecordQueryReply.entries![0] as any).encodedData).to.equal(base64url.baseEncode(bobData)); + expect(bobRecordQueryReply.entries![0].encodedData).to.equal(base64url.baseEncode(bobData)); // generate a new message from bob changing immutable recipientDid const newNotesFromBob = await TestDataGenerator.generateRecordsWrite( diff --git a/tests/interfaces/records/messages/records-write.spec.ts b/tests/interfaces/records/messages/records-write.spec.ts index fe01f0bc3..c3dc4cf93 100644 --- a/tests/interfaces/records/messages/records-write.spec.ts +++ b/tests/interfaces/records/messages/records-write.spec.ts @@ -3,7 +3,6 @@ import sinon from 'sinon'; import chai, { expect } from 'chai'; import { Jws } from '../../../../src/index.js'; -import { Message } from '../../../../src/core/message.js'; import { MessageStoreLevel } from '../../../../src/store/message-store-level.js'; import { RecordsWrite } from '../../../../src/interfaces/records/messages/records-write.js'; import { RecordsWriteMessage } from '../../../../src/interfaces/records/types.js'; @@ -164,20 +163,6 @@ describe('RecordsWrite', () => { }); }); - describe('getCid', () => { - it('should return the same value with or without `encodedData`', async () => { - const messageData = await TestDataGenerator.generateRecordsWrite(); - - const messageWithEncodedData = { ...messageData.message }; - messageWithEncodedData['encodedData'] = 'dW51c2Vk'; - - const cidOfMessageWithoutEncodedData = await Message.getCid(messageData.message); - const cidOfMessageWithEncodedData = await Message.getCid(messageWithEncodedData); - - expect(cidOfMessageWithoutEncodedData).to.equal(cidOfMessageWithEncodedData); - }); - }); - describe('isInitialWrite', () => { it('should return false if given message is not a RecordsWrite', async () => { const { message }= await TestDataGenerator.generateRecordsQuery();