var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import chaiAsPromised from 'chai-as-promised';
import emailProtocolDefinition from '../../../vectors/protocol-definitions/email.json' assert { type: 'json' };
import sinon from 'sinon';
import socialMediaProtocolDefinition from '../../../vectors/protocol-definitions/social-media.json' assert { type: 'json' };
import chai, { expect } from 'chai';
import { ArrayUtility } from '../../../../src/utils/array.js';
import { DataStoreLevel } from '../../../../src/store/data-store-level.js';
import { DidKeyResolver } from '../../../../src/did/did-key-resolver.js';
import { DwnErrorCode } from '../../../../src/core/dwn-error.js';
import { Encryption } from '../../../../src/utils/encryption.js';
import { EventLogLevel } from '../../../../src/event-log/event-log-level.js';
import { HdKey } from '../../../../src/utils/hd-key.js';
import { KeyDerivationScheme } from '../../../../src/utils/hd-key.js';
import { MessageStoreLevel } from '../../../../src/store/message-store-level.js';
import { RecordsReadHandler } from '../../../../src/interfaces/records/handlers/records-read.js';
import { TestDataGenerator } from '../../../utils/test-data-generator.js';
import { TestStubGenerator } from '../../../utils/test-stub-generator.js';
import { DataStream, DidResolver, Dwn, Encoder, Jws, Records, RecordsDelete, RecordsRead } from '../../../../src/index.js';
chai.use(chaiAsPromised);
describe('RecordsReadHandler.handle()', () => {
    if (process.env.TESTSOFF === 'true') {
        return;
    }
    let didResolver;
    let messageStore;
    let dataStore;
    let eventLog;
    let dwn;
    describe('functional tests', () => {
        before(() => __awaiter(void 0, void 0, void 0, function* () {
            didResolver = new DidResolver([new DidKeyResolver()]);
            // important to follow this pattern to initialize and clean the message and data store in tests
            // so that different suites can reuse the same block store and index location for testing
            messageStore = new MessageStoreLevel({
                blockstoreLocation: 'tests/data/TEST-MESSAGESTORE',
                indexLocation: 'tests/data/TEST-INDEX'
            });
            dataStore = new DataStoreLevel({
                blockstoreLocation: 'tests/data/TEST-DATASTORE'
            });
            eventLog = new EventLogLevel({
                location: 'tests/data/TEST-EVENTLOG'
            });
            dwn = yield Dwn.create({ didResolver, messageStore, dataStore, eventLog });
        }));
        beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
            sinon.restore(); // wipe all previous stubs/spies/mocks/fakes
            // clean up before each test rather than after so that a test does not depend on other tests to do the clean up
            yield messageStore.clear();
            yield dataStore.clear();
            yield eventLog.clear();
        }));
        after(() => __awaiter(void 0, void 0, void 0, function* () {
            yield dwn.close();
        }));
        it('should allow tenant to RecordsRead their own record', () => __awaiter(void 0, void 0, void 0, function* () {
            var _a;
            const alice = yield DidKeyResolver.generate();
            // insert data
            const { message, dataStream, dataBytes } = yield TestDataGenerator.generateRecordsWrite({ author: alice });
            const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
            expect(writeReply.status.code).to.equal(202);
            // testing RecordsRead
            const recordsRead = yield RecordsRead.create({
                recordId: message.recordId,
                authorizationSignatureInput: Jws.createSignatureInput(alice)
            });
            const readReply = yield dwn.handleRecordsRead(alice.did, recordsRead.message);
            expect(readReply.status.code).to.equal(200);
            expect(readReply.record).to.exist;
            expect((_a = readReply.record) === null || _a === void 0 ? void 0 : _a.descriptor).to.exist;
            const dataFetched = yield DataStream.toBytes(readReply.record.data);
            expect(ArrayUtility.byteArraysEqual(dataFetched, dataBytes)).to.be.true;
        }));
        it('should not allow non-tenant to RecordsRead their a record data', () => __awaiter(void 0, void 0, void 0, function* () {
            const alice = yield DidKeyResolver.generate();
            // insert data
            const { message, dataStream } = yield TestDataGenerator.generateRecordsWrite({ author: alice });
            const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
            expect(writeReply.status.code).to.equal(202);
            // testing RecordsRead
            const bob = yield DidKeyResolver.generate();
            const recordsRead = yield RecordsRead.create({
                recordId: message.recordId,
                authorizationSignatureInput: Jws.createSignatureInput(bob)
            });
            const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
            expect(readReply.status.code).to.equal(401);
        }));
        it('should allow reading of data that is published without `authorization`', () => __awaiter(void 0, void 0, void 0, function* () {
            const alice = yield DidKeyResolver.generate();
            // insert public data
            const { message, dataStream, dataBytes } = yield TestDataGenerator.generateRecordsWrite({ author: alice, published: true });
            const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
            expect(writeReply.status.code).to.equal(202);
            // testing public RecordsRead
            const recordsRead = yield RecordsRead.create({
                recordId: message.recordId
            });
            expect(recordsRead.author).to.be.undefined; // making sure no author/authorization is created
            const readReply = yield dwn.handleRecordsRead(alice.did, recordsRead.message);
            expect(readReply.status.code).to.equal(200);
            const dataFetched = yield DataStream.toBytes(readReply.record.data);
            expect(ArrayUtility.byteArraysEqual(dataFetched, dataBytes)).to.be.true;
        }));
        it('should allow an authenticated user to RecordRead data that is published', () => __awaiter(void 0, void 0, void 0, function* () {
            const alice = yield DidKeyResolver.generate();
            // insert public data
            const { message, dataStream, dataBytes } = yield TestDataGenerator.generateRecordsWrite({ author: alice, published: true });
            const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
            expect(writeReply.status.code).to.equal(202);
            // testing public RecordsRead
            const bob = yield DidKeyResolver.generate();
            const recordsRead = yield RecordsRead.create({
                recordId: message.recordId,
                authorizationSignatureInput: Jws.createSignatureInput(bob)
            });
            const readReply = yield dwn.handleRecordsRead(alice.did, recordsRead.message);
            expect(readReply.status.code).to.equal(200);
            const dataFetched = yield DataStream.toBytes(readReply.record.data);
            expect(ArrayUtility.byteArraysEqual(dataFetched, dataBytes)).to.be.true;
        }));
        describe('protocol based reads', () => {
            it('should allow read with allow-anyone rule', () => __awaiter(void 0, void 0, void 0, function* () {
                // scenario: Alice writes an image to her DWN, then Bob reads the image because he is "anyone".
                const alice = yield DidKeyResolver.generate();
                const bob = yield DidKeyResolver.generate();
                const protocolDefinition = socialMediaProtocolDefinition;
                // Install social-media protocol on Alice's DWN
                const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
                    author: alice,
                    protocolDefinition
                });
                const protocolWriteReply = yield dwn.processMessage(alice.did, protocolsConfig.message, protocolsConfig.dataStream);
                expect(protocolWriteReply.status.code).to.equal(202);
                // Alice writes image to her DWN
                const encodedImage = new TextEncoder().encode('cafe-aesthetic.jpg');
                const imageRecordsWrite = yield TestDataGenerator.generateRecordsWrite({
                    author: alice,
                    protocol: protocolDefinition.protocol,
                    protocolPath: 'image',
                    schema: protocolDefinition.types.image.schema,
                    dataFormat: 'image/jpeg',
                    data: encodedImage,
                    recipient: alice.did
                });
                const imageReply = yield dwn.processMessage(alice.did, imageRecordsWrite.message, imageRecordsWrite.dataStream);
                expect(imageReply.status.code).to.equal(202);
                // Bob (anyone) reads the image that Alice wrote
                const imageRecordsRead = yield RecordsRead.create({
                    recordId: imageRecordsWrite.message.recordId,
                    authorizationSignatureInput: Jws.createSignatureInput(bob)
                });
                const imageReadReply = yield dwn.processMessage(alice.did, imageRecordsRead.message);
                expect(imageReadReply.status.code).to.equal(200);
            }));
            it('should allow read with recipient rule', () => __awaiter(void 0, void 0, void 0, function* () {
                // scenario: Alice sends an email to Bob, then Bob reads the email.
                //           ImposterBob tries and fails to read the email.
                const alice = yield DidKeyResolver.generate();
                const bob = yield DidKeyResolver.generate();
                const imposterBob = yield DidKeyResolver.generate();
                const protocolDefinition = emailProtocolDefinition;
                // Install email protocol on Alice's DWN
                const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
                    author: alice,
                    protocolDefinition
                });
                const protocolWriteReply = yield dwn.processMessage(alice.did, protocolsConfig.message, protocolsConfig.dataStream);
                expect(protocolWriteReply.status.code).to.equal(202);
                // Alice writes an email with Bob as recipient
                const encodedEmail = new TextEncoder().encode('Dear Bob, hello!');
                const emailRecordsWrite = yield TestDataGenerator.generateRecordsWrite({
                    author: alice,
                    protocol: protocolDefinition.protocol,
                    protocolPath: 'email',
                    schema: protocolDefinition.types.email.schema,
                    dataFormat: protocolDefinition.types.email.dataFormats[0],
                    data: encodedEmail,
                    recipient: bob.did
                });
                const imageReply = yield dwn.processMessage(alice.did, emailRecordsWrite.message, emailRecordsWrite.dataStream);
                expect(imageReply.status.code).to.equal(202);
                // Bob reads Alice's email
                const bobRecordsRead = yield RecordsRead.create({
                    recordId: emailRecordsWrite.message.recordId,
                    authorizationSignatureInput: Jws.createSignatureInput(bob)
                });
                const bobReadReply = yield dwn.processMessage(alice.did, bobRecordsRead.message);
                expect(bobReadReply.status.code).to.equal(200);
                // ImposterBob is not able to read Alice's email
                const imposterRecordsRead = yield RecordsRead.create({
                    recordId: emailRecordsWrite.message.recordId,
                    authorizationSignatureInput: Jws.createSignatureInput(imposterBob)
                });
                const imposterReadReply = yield dwn.processMessage(alice.did, imposterRecordsRead.message);
                expect(imposterReadReply.status.code).to.equal(401);
                expect(imposterReadReply.status.detail).to.include(DwnErrorCode.ProtocolAuthorizationActionNotAllowed);
            }));
            it('should allow read with author rule', () => __awaiter(void 0, void 0, void 0, function* () {
                // scenario: Bob sends an email to Alice, then Bob reads the email.
                //           ImposterBob tries and fails to read the email.
                const alice = yield DidKeyResolver.generate();
                const bob = yield DidKeyResolver.generate();
                const imposterBob = yield DidKeyResolver.generate();
                const protocolDefinition = emailProtocolDefinition;
                // Install email protocol on Alice's DWN
                const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
                    author: alice,
                    protocolDefinition
                });
                const protocolWriteReply = yield dwn.processMessage(alice.did, protocolsConfig.message, protocolsConfig.dataStream);
                expect(protocolWriteReply.status.code).to.equal(202);
                // Alice writes an email with Bob as recipient
                const encodedEmail = new TextEncoder().encode('Dear Alice, hello!');
                const emailRecordsWrite = yield TestDataGenerator.generateRecordsWrite({
                    author: bob,
                    protocol: protocolDefinition.protocol,
                    protocolPath: 'email',
                    schema: protocolDefinition.types.email.schema,
                    dataFormat: protocolDefinition.types.email.dataFormats[0],
                    data: encodedEmail,
                    recipient: alice.did
                });
                const imageReply = yield dwn.processMessage(alice.did, emailRecordsWrite.message, emailRecordsWrite.dataStream);
                expect(imageReply.status.code).to.equal(202);
                // Bob reads the email he just sent
                const bobRecordsRead = yield RecordsRead.create({
                    recordId: emailRecordsWrite.message.recordId,
                    authorizationSignatureInput: Jws.createSignatureInput(bob)
                });
                const bobReadReply = yield dwn.processMessage(alice.did, bobRecordsRead.message);
                expect(bobReadReply.status.code).to.equal(200);
                // ImposterBob is not able to read the email
                const imposterRecordsRead = yield RecordsRead.create({
                    recordId: emailRecordsWrite.message.recordId,
                    authorizationSignatureInput: Jws.createSignatureInput(imposterBob)
                });
                const imposterReadReply = yield dwn.processMessage(alice.did, imposterRecordsRead.message);
                expect(imposterReadReply.status.code).to.equal(401);
                expect(imposterReadReply.status.detail).to.include(DwnErrorCode.ProtocolAuthorizationActionNotAllowed);
            }));
        });
        it('should return 404 RecordRead if data does not exist', () => __awaiter(void 0, void 0, void 0, function* () {
            const alice = yield DidKeyResolver.generate();
            const recordsRead = yield RecordsRead.create({
                recordId: `non-existent-record-id`,
                authorizationSignatureInput: Jws.createSignatureInput(alice)
            });
            const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
            expect(readReply.status.code).to.equal(404);
        }));
        it('should return 404 RecordRead if data has been deleted', () => __awaiter(void 0, void 0, void 0, function* () {
            var _b;
            const alice = yield DidKeyResolver.generate();
            // insert public data
            const { message, dataStream } = yield TestDataGenerator.generateRecordsWrite({ author: alice, published: true });
            const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
            expect(writeReply.status.code).to.equal(202);
            // ensure data is inserted
            const queryData = yield TestDataGenerator.generateRecordsQuery({
                author: alice,
                filter: { recordId: message.recordId }
            });
            const reply = yield dwn.processMessage(alice.did, queryData.message);
            expect(reply.status.code).to.equal(200);
            expect((_b = reply.entries) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
            // RecordsDelete
            const recordsDelete = yield RecordsDelete.create({
                recordId: message.recordId,
                authorizationSignatureInput: Jws.createSignatureInput(alice)
            });
            const deleteReply = yield dwn.processMessage(alice.did, recordsDelete.message);
            expect(deleteReply.status.code).to.equal(202);
            // RecordsRead
            const recordsRead = yield RecordsRead.create({
                recordId: message.recordId,
                authorizationSignatureInput: Jws.createSignatureInput(alice)
            });
            const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
            expect(readReply.status.code).to.equal(404);
        }));
        it('should return 404 underlying data store cannot locate the data', () => __awaiter(void 0, void 0, void 0, function* () {
            const alice = yield DidKeyResolver.generate();
            sinon.stub(dataStore, 'get').resolves(undefined);
            // insert data
            const { message, dataStream } = yield TestDataGenerator.generateRecordsWrite({ author: alice });
            const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
            expect(writeReply.status.code).to.equal(202);
            // testing RecordsRead
            const recordsRead = yield RecordsRead.create({
                recordId: message.recordId,
                authorizationSignatureInput: Jws.createSignatureInput(alice)
            });
            const readReply = yield dwn.processMessage(alice.did, recordsRead.message);
            expect(readReply.status.code).to.equal(404);
        }));
        describe('encryption scenarios', () => {
            it('should only be able to decrypt record with a correct derived private key - `dataFormats` derivation scheme', () => __awaiter(void 0, void 0, void 0, function* () {
                // scenario: Alice writes into her own DWN an encrypted record using a `dataFormats` derived key and she is able to decrypt it
                const alice = yield TestDataGenerator.generatePersona();
                TestStubGenerator.stubDidResolver(didResolver, [alice]);
                // encrypt Alice's record
                const originalData = TestDataGenerator.randomBytes(1000);
                const originalDataStream = DataStream.fromBytes(originalData);
                const dataEncryptionInitializationVector = TestDataGenerator.randomBytes(16);
                const dataEncryptionKey = TestDataGenerator.randomBytes(32);
                const encryptedDataStream = yield Encryption.aes256CtrEncrypt(dataEncryptionKey, dataEncryptionInitializationVector, originalDataStream);
                const encryptedDataBytes = yield DataStream.toBytes(encryptedDataStream);
                const encryptionInput = {
                    initializationVector: dataEncryptionInitializationVector,
                    key: dataEncryptionKey,
                    keyEncryptionInputs: [{
                            publicKeyId: alice.keyId,
                            publicKey: alice.keyPair.publicJwk,
                            derivationScheme: KeyDerivationScheme.DataFormats
                        }]
                };
                const { message, dataStream } = yield TestDataGenerator.generateRecordsWrite({
                    author: alice,
                    data: encryptedDataBytes,
                    encryptionInput
                });
                const writeReply = yield dwn.processMessage(alice.did, message, dataStream);
                expect(writeReply.status.code).to.equal(202);
                const recordsRead = yield RecordsRead.create({
                    recordId: message.recordId,
                    authorizationSignatureInput: Jws.createSignatureInput(alice)
                });
                const readReply = yield dwn.handleRecordsRead(alice.did, recordsRead.message);
                expect(readReply.status.code).to.equal(200);
                const unsignedRecordsWrite = readReply.record;
                const cipherStream = readReply.record.data;
                // test able to decrypt the message using the root key
                const rootPrivateKey = {
                    rootKeyId: alice.keyId,
                    derivationScheme: KeyDerivationScheme.DataFormats,
                    derivedPrivateKey: alice.keyPair.privateJwk
                };
                const plaintextDataStream = yield Records.decrypt(unsignedRecordsWrite, rootPrivateKey, cipherStream);
                const plaintextBytes = yield DataStream.toBytes(plaintextDataStream);
                expect(ArrayUtility.byteArraysEqual(plaintextBytes, originalData)).to.be.true;
                // test able to decrypt the message using a derived key
                const readReply2 = yield dwn.handleRecordsRead(alice.did, recordsRead.message); // process the same read message to get a new cipher stream
                expect(readReply.status.code).to.equal(200);
                const cipherStream2 = readReply2.record.data;
                const derivationPath = [KeyDerivationScheme.DataFormats, message.descriptor.dataFormat];
                const derivedPrivateKey = yield HdKey.derivePrivateKey(rootPrivateKey, derivationPath);
                const plaintextDataStream2 = yield Records.decrypt(unsignedRecordsWrite, derivedPrivateKey, cipherStream2);
                const plaintextBytes2 = yield DataStream.toBytes(plaintextDataStream2);
                expect(ArrayUtility.byteArraysEqual(plaintextBytes2, originalData)).to.be.true;
                // test unable to decrypt the message if derived key has an unexpected path
                const readReply3 = yield dwn.handleRecordsRead(alice.did, recordsRead.message); // process the same read message to get a new cipher stream
                expect(readReply.status.code).to.equal(200);
                const cipherStream3 = readReply3.record.data;
                const invalidDerivationPath = [KeyDerivationScheme.DataFormats, 'invalidDataFormat'];
                const inValidDescendantPrivateKey = yield HdKey.derivePrivateKey(rootPrivateKey, invalidDerivationPath);
                yield expect(Records.decrypt(unsignedRecordsWrite, inValidDescendantPrivateKey, cipherStream3)).to.be.rejectedWith(DwnErrorCode.RecordsInvalidAncestorKeyDerivationSegment);
            }));
            it('should only be able to decrypt record with a correct derived private key  - `protocols` derivation scheme', () => __awaiter(void 0, void 0, void 0, function* () {
                // scenario, Bob writes into Alice's DWN an encrypted "email", alice is able to decrypt it
                // creating Alice and Bob persona and setting up a stub DID resolver
                const alice = yield TestDataGenerator.generatePersona();
                const bob = yield TestDataGenerator.generatePersona();
                TestStubGenerator.stubDidResolver(didResolver, [alice, bob]);
                // configure protocol
                const protocolDefinition = emailProtocolDefinition;
                const protocolsConfig = yield TestDataGenerator.generateProtocolsConfigure({
                    author: alice,
                    protocolDefinition
                });
                const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfig.message, protocolsConfig.dataStream);
                expect(protocolsConfigureReply.status.code).to.equal(202);
                // encrypt bob's message
                const bobMessageBytes = Encoder.stringToBytes('message from bob');
                const bobMessageStream = DataStream.fromBytes(bobMessageBytes);
                const dataEncryptionInitializationVector = TestDataGenerator.randomBytes(16);
                const dataEncryptionKey = TestDataGenerator.randomBytes(32);
                const bobMessageEncryptedStream = yield Encryption.aes256CtrEncrypt(dataEncryptionKey, dataEncryptionInitializationVector, bobMessageStream);
                const bobMessageEncryptedBytes = yield DataStream.toBytes(bobMessageEncryptedStream);
                // generate a `RecordsWrite` message from bob allowed by anyone
                const encryptionInput = {
                    initializationVector: dataEncryptionInitializationVector,
                    key: dataEncryptionKey,
                    keyEncryptionInputs: [{
                            publicKeyId: alice.keyId,
                            publicKey: alice.keyPair.publicJwk,
                            derivationScheme: KeyDerivationScheme.Protocols
                        }]
                };
                const { message, dataStream } = yield TestDataGenerator.generateRecordsWrite({
                    author: bob,
                    protocol: protocolDefinition.protocol,
                    protocolPath: 'email',
                    schema: protocolDefinition.types.email.schema,
                    dataFormat: protocolDefinition.types.email.dataFormats[0],
                    data: bobMessageEncryptedBytes,
                    encryptionInput
                });
                const bobWriteReply = yield dwn.processMessage(alice.did, message, dataStream);
                expect(bobWriteReply.status.code).to.equal(202);
                const recordsRead = yield RecordsRead.create({
                    recordId: message.recordId,
                    authorizationSignatureInput: Jws.createSignatureInput(alice)
                });
                const readReply = yield dwn.handleRecordsRead(alice.did, recordsRead.message);
                expect(readReply.status.code).to.equal(200);
                // test able to decrypt the message using a derived key
                const rootPrivateKey = {
                    rootKeyId: alice.keyId,
                    derivationScheme: KeyDerivationScheme.Protocols,
                    derivedPrivateKey: alice.keyPair.privateJwk
                };
                const relativeDescendantDerivationPath = Records.constructKeyDerivationPath(KeyDerivationScheme.Protocols, message.recordId, message.contextId, message.descriptor);
                const descendantPrivateKey = yield HdKey.derivePrivateKey(rootPrivateKey, relativeDescendantDerivationPath);
                const unsignedRecordsWrite = readReply.record;
                const cipherStream = readReply.record.data;
                const plaintextDataStream = yield Records.decrypt(unsignedRecordsWrite, descendantPrivateKey, cipherStream);
                const plaintextBytes = yield DataStream.toBytes(plaintextDataStream);
                expect(ArrayUtility.byteArraysEqual(plaintextBytes, bobMessageBytes)).to.be.true;
                // test unable to decrypt the message if derived key has an unexpected path
                const invalidDerivationPath = [KeyDerivationScheme.Protocols, protocolDefinition.protocol, 'invalidContextId'];
                const inValidDescendantPrivateKey = yield HdKey.derivePrivateKey(rootPrivateKey, invalidDerivationPath);
                yield expect(Records.decrypt(unsignedRecordsWrite, inValidDescendantPrivateKey, cipherStream)).to.be.rejectedWith(DwnErrorCode.RecordsInvalidAncestorKeyDerivationSegment);
                // test unable to decrypt the message if no derivation scheme used by the message matches the scheme used by the given private key
                const privateKeyWithMismatchingDerivationScheme = {
                    rootKeyId: alice.keyId,
                    derivationScheme: 'scheme-that-is-not-protocol-context',
                    derivedPrivateKey: alice.keyPair.privateJwk
                };
                yield expect(Records.decrypt(unsignedRecordsWrite, privateKeyWithMismatchingDerivationScheme, cipherStream)).to.be.rejectedWith(DwnErrorCode.RecordsDecryptNoMatchingKeyEncryptedFound);
                // test unable to decrypt the message if public key ID does not match the derived private key
                const privateKeyWithMismatchingKeyId = {
                    rootKeyId: 'mismatchingKeyId',
                    derivationScheme: KeyDerivationScheme.Protocols,
                    derivedPrivateKey: alice.keyPair.privateJwk
                };
                yield expect(Records.decrypt(unsignedRecordsWrite, privateKeyWithMismatchingKeyId, cipherStream)).to.be.rejectedWith(DwnErrorCode.RecordsDecryptNoMatchingKeyEncryptedFound);
            }));
        });
    });
    it('should return 401 if signature check fails', () => __awaiter(void 0, void 0, void 0, function* () {
        const alice = yield DidKeyResolver.generate();
        const recordsRead = yield RecordsRead.create({
            recordId: 'any-id',
            authorizationSignatureInput: Jws.createSignatureInput(alice)
        });
        // setting up a stub did resolver & message store
        // intentionally not supplying the public key so a different public key is generated to simulate invalid signature
        const mismatchingPersona = yield TestDataGenerator.generatePersona({ did: alice.did, keyId: alice.keyId });
        const didResolver = TestStubGenerator.createDidResolverStub(mismatchingPersona);
        const messageStore = sinon.createStubInstance(MessageStoreLevel);
        const dataStore = sinon.createStubInstance(DataStoreLevel);
        const recordsReadHandler = new RecordsReadHandler(didResolver, messageStore, dataStore);
        const reply = yield recordsReadHandler.handle({ tenant: alice.did, message: recordsRead.message });
        expect(reply.status.code).to.equal(401);
    }));
    it('should return 400 if fail parsing the message', () => __awaiter(void 0, void 0, void 0, function* () {
        const alice = yield DidKeyResolver.generate();
        const recordsRead = yield RecordsRead.create({
            recordId: 'any-id',
            authorizationSignatureInput: Jws.createSignatureInput(alice)
        });
        // setting up a stub method resolver & message store
        const messageStore = sinon.createStubInstance(MessageStoreLevel);
        const dataStore = sinon.createStubInstance(DataStoreLevel);
        const recordsReadHandler = new RecordsReadHandler(didResolver, messageStore, dataStore);
        // stub the `parse()` function to throw an error
        sinon.stub(RecordsRead, 'parse').throws('anyError');
        const reply = yield recordsReadHandler.handle({ tenant: alice.did, message: recordsRead.message });
        expect(reply.status.code).to.equal(400);
    }));
});
//# sourceMappingURL=records-read.spec.js.map