diff --git a/examples/bot.ts b/examples/bot.ts index ad74f6dd..a1ac99c1 100644 --- a/examples/bot.ts +++ b/examples/bot.ts @@ -1,3 +1,5 @@ +import { StoreType } from "@matrix-org/matrix-sdk-crypto-nodejs"; + import { AutojoinRoomsMixin, LogLevel, @@ -25,7 +27,7 @@ const dmTarget = creds?.['dmTarget'] ?? "@admin:localhost"; const homeserverUrl = creds?.['homeserverUrl'] ?? "http://localhost:8008"; const accessToken = creds?.['accessToken'] ?? 'YOUR_TOKEN'; const storage = new SimpleFsStorageProvider("./examples/storage/bot.json"); -const crypto = new RustSdkCryptoStorageProvider("./examples/storage/bot_sled"); +const crypto = new RustSdkCryptoStorageProvider("./examples/storage/bot_sled", StoreType.Sled); const client = new MatrixClient(homeserverUrl, accessToken, storage, crypto); AutojoinRoomsMixin.setupOnClient(client); diff --git a/examples/encryption_appservice.ts b/examples/encryption_appservice.ts index 3079f152..90c8f3f6 100644 --- a/examples/encryption_appservice.ts +++ b/examples/encryption_appservice.ts @@ -1,4 +1,5 @@ import * as fs from "fs"; +import { StoreType } from "@matrix-org/matrix-sdk-crypto-nodejs"; import { Appservice, @@ -30,7 +31,7 @@ try { const dmTarget = creds?.['dmTarget'] ?? "@admin:localhost"; const homeserverUrl = creds?.['homeserverUrl'] ?? "http://localhost:8008"; const storage = new SimpleFsStorageProvider("./examples/storage/encryption_appservice.json"); -const crypto = new RustSdkAppserviceCryptoStorageProvider("./examples/storage/encryption_appservice_sled"); +const crypto = new RustSdkAppserviceCryptoStorageProvider("./examples/storage/encryption_appservice_sled", StoreType.Sled); const worksImage = fs.readFileSync("./examples/static/it-works.png"); const registration: IAppserviceRegistration = { diff --git a/examples/encryption_bot.ts b/examples/encryption_bot.ts index 18d5dee7..011b1565 100644 --- a/examples/encryption_bot.ts +++ b/examples/encryption_bot.ts @@ -1,4 +1,5 @@ import * as fs from "fs"; +import { StoreType } from "@matrix-org/matrix-sdk-crypto-nodejs"; import { EncryptionAlgorithm, @@ -28,7 +29,7 @@ const dmTarget = creds?.['dmTarget'] ?? "@admin:localhost"; const homeserverUrl = creds?.['homeserverUrl'] ?? "http://localhost:8008"; const accessToken = creds?.['accessToken'] ?? 'YOUR_TOKEN'; const storage = new SimpleFsStorageProvider("./examples/storage/encryption_bot.json"); -const crypto = new RustSdkCryptoStorageProvider("./examples/storage/encryption_bot_sled"); +const crypto = new RustSdkCryptoStorageProvider("./examples/storage/encryption_bot_sled", StoreType.Sled); const worksImage = fs.readFileSync("./examples/static/it-works.png"); const client = new MatrixClient(homeserverUrl, accessToken, storage, crypto); diff --git a/package.json b/package.json index 72eaa776..e4998c66 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "tsconfig.json" ], "dependencies": { - "@matrix-org/matrix-sdk-crypto-nodejs": "0.1.0-beta.3", + "@matrix-org/matrix-sdk-crypto-nodejs": "0.1.0-beta.4", "@types/express": "^4.17.13", "another-json": "^0.2.0", "async-lock": "^1.3.2", @@ -76,6 +76,7 @@ "@types/async-lock": "^1.3.0", "@types/expect": "^24.3.0", "@types/jest": "^27.5.1", + "@types/lowdb": "^1.0.11", "@types/mocha": "^8", "@types/node": "^16", "@types/simple-mock": "^0.8.2", diff --git a/src/e2ee/CryptoClient.ts b/src/e2ee/CryptoClient.ts index 91cd3e9c..74ddfb50 100644 --- a/src/e2ee/CryptoClient.ts +++ b/src/e2ee/CryptoClient.ts @@ -86,7 +86,12 @@ export class CryptoClient { LogService.debug("CryptoClient", "Starting with device ID:", this.deviceId); - const machine = await OlmMachine.initialize(new UserId(await this.client.getUserId()), new DeviceId(this.deviceId), this.storage.storagePath); + const machine = await OlmMachine.initialize( + new UserId(await this.client.getUserId()), + new DeviceId(this.deviceId), + this.storage.storagePath, "", + this.storage.storageType, + ); this.engine = new RustEngine(machine, this.client); await this.engine.run(); diff --git a/src/e2ee/RustEngine.ts b/src/e2ee/RustEngine.ts index dad4a440..c9eae9c8 100644 --- a/src/e2ee/RustEngine.ts +++ b/src/e2ee/RustEngine.ts @@ -52,7 +52,7 @@ export class RustEngine { await this.processKeysClaimRequest(request); break; case RequestType.ToDevice: - await this.processToDeviceRequest(request); + await this.processToDeviceRequest(request as ToDeviceRequest); break; case RequestType.RoomMessage: throw new Error("Bindings error: Sending room messages is not supported"); diff --git a/src/storage/RustSdkCryptoStorageProvider.ts b/src/storage/RustSdkCryptoStorageProvider.ts index aedb478b..805874dd 100644 --- a/src/storage/RustSdkCryptoStorageProvider.ts +++ b/src/storage/RustSdkCryptoStorageProvider.ts @@ -4,23 +4,29 @@ import * as mkdirp from "mkdirp"; import * as path from "path"; import * as sha512 from "hash.js/lib/hash/sha/512"; import * as sha256 from "hash.js/lib/hash/sha/256"; +import { StoreType as RustSdkCryptoStoreType } from "@matrix-org/matrix-sdk-crypto-nodejs"; import { ICryptoStorageProvider } from "./ICryptoStorageProvider"; import { IAppserviceCryptoStorageProvider } from "./IAppserviceStorageProvider"; import { ICryptoRoomInformation } from "../e2ee/ICryptoRoomInformation"; +export { RustSdkCryptoStoreType }; + /** - * A crypto storage provider for the default rust-sdk store (sled, file-based). + * A crypto storage provider for the file-based rust-sdk store. * @category Storage providers */ export class RustSdkCryptoStorageProvider implements ICryptoStorageProvider { - private db: any; + private db: lowdb.LowdbSync; /** * Creates a new rust-sdk storage provider. * @param {string} storagePath The *directory* to persist database details to. */ - public constructor(public readonly storagePath: string) { + public constructor( + public readonly storagePath: string, + public readonly storageType: RustSdkCryptoStoreType = RustSdkCryptoStoreType.Sled, + ) { this.storagePath = path.resolve(this.storagePath); mkdirp.sync(storagePath); @@ -53,7 +59,7 @@ export class RustSdkCryptoStorageProvider implements ICryptoStorageProvider { } /** - * An appservice crypto storage provider for the default rust-sdk store (sled, file-based). + * An appservice crypto storage provider for the file-based rust-sdk store. * @category Storage providers */ export class RustSdkAppserviceCryptoStorageProvider extends RustSdkCryptoStorageProvider implements IAppserviceCryptoStorageProvider { @@ -61,13 +67,13 @@ export class RustSdkAppserviceCryptoStorageProvider extends RustSdkCryptoStorage * Creates a new rust-sdk storage provider. * @param {string} baseStoragePath The *directory* to persist database details to. */ - public constructor(private baseStoragePath: string) { - super(path.join(baseStoragePath, "_default")); + public constructor(private baseStoragePath: string, storageType: RustSdkCryptoStoreType = RustSdkCryptoStoreType.Sled) { + super(path.join(baseStoragePath, "_default"), storageType); } public storageForUser(userId: string): ICryptoStorageProvider { // sha256 because sha512 is a bit big for some operating systems const key = sha256().update(userId).digest('hex'); - return new RustSdkCryptoStorageProvider(path.join(this.baseStoragePath, key)); + return new RustSdkCryptoStorageProvider(path.join(this.baseStoragePath, key), this.storageType); } } diff --git a/test/DMsTest.ts b/test/DMsTest.ts index f5134892..dae6f54c 100644 --- a/test/DMsTest.ts +++ b/test/DMsTest.ts @@ -1,7 +1,7 @@ import * as simple from "simple-mock"; import { EncryptionAlgorithm } from "../src"; -import { createTestClient, TEST_DEVICE_ID } from "./TestUtils"; +import { createTestClient, testCryptoStores, TEST_DEVICE_ID } from "./TestUtils"; describe('DMs', () => { it('should update the cache when an sync requests happen', async () => { @@ -297,9 +297,9 @@ describe('DMs', () => { await flush; }); - it('should create an encrypted DM if supported', async () => { + it('should create an encrypted DM if supported', () => testCryptoStores(async (cryptoStoreType) => { const selfUserId = "@self:example.org"; - const { client, http } = createTestClient(null, selfUserId, true); + const { client, http } = createTestClient(null, selfUserId, cryptoStoreType); const dms = client.dms; const dmRoomId = "!dm:example.org"; @@ -359,11 +359,11 @@ describe('DMs', () => { expect(dms.isDm(dmRoomId)).toBe(true); await flush; - }); + })); - it('should create an unencrypted DM when the target user has no devices', async () => { + it('should create an unencrypted DM when the target user has no devices', () => testCryptoStores(async (cryptoStoreType) => { const selfUserId = "@self:example.org"; - const { client, http } = createTestClient(null, selfUserId, true); + const { client, http } = createTestClient(null, selfUserId, cryptoStoreType); const dms = client.dms; const dmRoomId = "!dm:example.org"; @@ -411,5 +411,5 @@ describe('DMs', () => { expect(dms.isDm(dmRoomId)).toBe(true); await flush; - }); + })); }); diff --git a/test/MatrixClientTest.ts b/test/MatrixClientTest.ts index f7980df9..69aa55a7 100644 --- a/test/MatrixClientTest.ts +++ b/test/MatrixClientTest.ts @@ -1,5 +1,6 @@ import * as tmp from "tmp"; import * as simple from "simple-mock"; +import { StoreType } from "@matrix-org/matrix-sdk-crypto-nodejs"; import { EventKind, @@ -21,7 +22,7 @@ import { ServerVersions, setRequestFn, } from "../src"; -import { createTestClient, expectArrayEquals, TEST_DEVICE_ID } from "./TestUtils"; +import { createTestClient, expectArrayEquals, testCryptoStores, TEST_DEVICE_ID } from "./TestUtils"; tmp.setGracefulCleanup(); @@ -51,7 +52,7 @@ describe('MatrixClient', () => { const homeserverUrl = "https://example.org"; const accessToken = "example_token"; - const client = new MatrixClient(homeserverUrl, accessToken, null, new RustSdkCryptoStorageProvider(tmp.dirSync().name)); + const client = new MatrixClient(homeserverUrl, accessToken, null, new RustSdkCryptoStorageProvider(tmp.dirSync().name, StoreType.Sled)); expect(client.crypto).toBeDefined(); }); @@ -2247,8 +2248,8 @@ describe('MatrixClient', () => { expect(eventSpy.callCount).toBe(5); }); - it('should process crypto if enabled', async () => { - const { client: realClient } = createTestClient(null, "@alice:example.org", true); + it('should process crypto if enabled', () => testCryptoStores(async (cryptoStoreType) => { + const { client: realClient } = createTestClient(null, "@alice:example.org", cryptoStoreType); const client = (realClient); const sync = { @@ -2277,7 +2278,7 @@ describe('MatrixClient', () => { await client.processSync(sync); expect(spy.callCount).toBe(1); - }); + })); }); describe('getEvent', () => { @@ -2325,8 +2326,8 @@ describe('MatrixClient', () => { expect(result["processed"]).toBeTruthy(); }); - it('should try decryption', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should try decryption', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!abc123:example.org"; const eventId = "$example:example.org"; @@ -2367,10 +2368,10 @@ describe('MatrixClient', () => { expect(processSpy.callCount).toBe(2); expect(isEncSpy.callCount).toBe(1); expect(decryptSpy.callCount).toBe(1); - }); + })); - it('should not try decryption in unencrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should not try decryption in unencrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!abc123:example.org"; const eventId = "$example:example.org"; @@ -2411,7 +2412,7 @@ describe('MatrixClient', () => { expect(processSpy.callCount).toBe(1); expect(isEncSpy.callCount).toBe(1); expect(decryptSpy.callCount).toBe(0); - }); + })); }); describe('getRawEvent', () => { @@ -2459,8 +2460,8 @@ describe('MatrixClient', () => { expect(result["processed"]).toBeTruthy(); }); - it('should not try decryption in any rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should not try decryption in any rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!abc123:example.org"; const eventId = "$example:example.org"; @@ -2501,7 +2502,7 @@ describe('MatrixClient', () => { expect(processSpy.callCount).toBe(1); expect(isEncSpy.callCount).toBe(0); expect(decryptSpy.callCount).toBe(0); - }); + })); }); describe('getRoomState', () => { @@ -3466,8 +3467,8 @@ describe('MatrixClient', () => { expect(result).toEqual(eventId); }); - it('should try to encrypt in encrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should try to encrypt in encrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -3517,10 +3518,10 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.replyText(roomId, originalEvent, replyText, replyHtml), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); - it('should not try to encrypt in unencrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should not try to encrypt in unencrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -3560,7 +3561,7 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.replyText(roomId, originalEvent, replyText, replyHtml), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); it('should use encoded plain text as the HTML component', async () => { const { client, http, hsUrl } = createTestClient(); @@ -3646,8 +3647,8 @@ describe('MatrixClient', () => { expect(result).toEqual(eventId); }); - it('should try to encrypt in encrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should try to encrypt in encrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -3697,10 +3698,10 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.replyHtmlText(roomId, originalEvent, replyHtml), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); - it('should not try to encrypt in unencrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should not try to encrypt in unencrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -3740,7 +3741,7 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.replyHtmlText(roomId, originalEvent, replyHtml), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); }); describe('replyNotice', () => { @@ -3785,8 +3786,8 @@ describe('MatrixClient', () => { expect(result).toEqual(eventId); }); - it('should try to encrypt in encrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should try to encrypt in encrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -3836,10 +3837,10 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.replyNotice(roomId, originalEvent, replyText, replyHtml), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); - it('should not try to encrypt in unencrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should not try to encrypt in unencrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -3879,7 +3880,7 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.replyNotice(roomId, originalEvent, replyText, replyHtml), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); it('should use encoded plain text as the HTML component', async () => { const { client, http, hsUrl } = createTestClient(); @@ -3965,8 +3966,8 @@ describe('MatrixClient', () => { expect(result).toEqual(eventId); }); - it('should try to encrypt in encrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should try to encrypt in encrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -4016,10 +4017,10 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.replyHtmlNotice(roomId, originalEvent, replyHtml), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); - it('should not try to encrypt in unencrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should not try to encrypt in unencrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -4059,7 +4060,7 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.replyHtmlNotice(roomId, originalEvent, replyHtml), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); }); describe('sendNotice', () => { @@ -4085,8 +4086,8 @@ describe('MatrixClient', () => { expect(result).toEqual(eventId); }); - it('should try to encrypt in encrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should try to encrypt in encrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -4118,10 +4119,10 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.sendNotice(roomId, eventContent.body), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); - it('should not try to encrypt in unencrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should not try to encrypt in unencrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -4142,7 +4143,7 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.sendNotice(roomId, eventContent.body), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); }); describe('sendHtmlNotice', () => { @@ -4170,8 +4171,8 @@ describe('MatrixClient', () => { expect(result).toEqual(eventId); }); - it('should try to encrypt in encrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should try to encrypt in encrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -4205,10 +4206,10 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.sendHtmlNotice(roomId, eventContent.formatted_body), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); - it('should not try to encrypt in unencrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should not try to encrypt in unencrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -4231,7 +4232,7 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.sendHtmlNotice(roomId, eventContent.formatted_body), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); }); describe('sendText', () => { @@ -4257,8 +4258,8 @@ describe('MatrixClient', () => { expect(result).toEqual(eventId); }); - it('should try to encrypt in encrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should try to encrypt in encrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -4290,10 +4291,10 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.sendText(roomId, eventContent.body), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); - it('should not try to encrypt in unencrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should not try to encrypt in unencrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -4314,7 +4315,7 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.sendText(roomId, eventContent.body), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); }); describe('sendHtmlText', () => { @@ -4342,8 +4343,8 @@ describe('MatrixClient', () => { expect(result).toEqual(eventId); }); - it('should try to encrypt in encrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should try to encrypt in encrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -4377,10 +4378,10 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.sendHtmlText(roomId, eventContent.formatted_body), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); - it('should not try to encrypt in unencrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should not try to encrypt in unencrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -4403,7 +4404,7 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.sendHtmlText(roomId, eventContent.formatted_body), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); }); describe('sendMessage', () => { @@ -4430,8 +4431,8 @@ describe('MatrixClient', () => { expect(result).toEqual(eventId); }); - it('should try to encrypt in encrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should try to encrypt in encrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -4464,10 +4465,10 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.sendMessage(roomId, eventPlainContent), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); - it('should not try to encrypt in unencrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should not try to encrypt in unencrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -4489,7 +4490,7 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.sendMessage(roomId, eventContent), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); }); describe('sendEvent', () => { @@ -4516,8 +4517,8 @@ describe('MatrixClient', () => { expect(result).toEqual(eventId); }); - it('should try to encrypt in encrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should try to encrypt in encrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -4551,10 +4552,10 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.sendEvent(roomId, eventType, eventPlainContent), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); - it('should not try to encrypt in unencrypted rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should not try to encrypt in unencrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -4576,7 +4577,7 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.sendEvent(roomId, eventType, eventContent), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); }); describe('sendRawEvent', () => { @@ -4603,8 +4604,8 @@ describe('MatrixClient', () => { expect(result).toEqual(eventId); }); - it('should not try to encrypt in any rooms', async () => { - const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", true); + it('should not try to encrypt in any rooms', () => testCryptoStores(async (cryptoStoreType) => { + const { client, http, hsUrl } = createTestClient(null, "@alice:example.org", cryptoStoreType); const roomId = "!testing:example.org"; const eventId = "$something:example.org"; @@ -4626,7 +4627,7 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.sendRawEvent(roomId, eventType, eventContent), http.flushAllExpected()]); expect(result).toEqual(eventId); - }); + })); }); describe('sendStateEvent', () => { @@ -6687,9 +6688,9 @@ describe('MatrixClient', () => { } }); - it('should call the right endpoint', async () => { + it('should call the right endpoint', () => testCryptoStores(async (cryptoStoreType) => { const userId = "@test:example.org"; - const { client, http } = createTestClient(null, userId, true); + const { client, http } = createTestClient(null, userId, cryptoStoreType); // @ts-ignore const keys: OTKs = { @@ -6718,7 +6719,7 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.uploadDeviceOneTimeKeys(keys), http.flushAllExpected()]); expect(result).toMatchObject(counts); - }); + })); }); describe('checkOneTimeKeyCounts', () => { @@ -6734,9 +6735,9 @@ describe('MatrixClient', () => { } }); - it('should call the right endpoint', async () => { + it('should call the right endpoint', () => testCryptoStores(async (cryptoStoreType) => { const userId = "@test:example.org"; - const { client, http } = createTestClient(null, userId, true); + const { client, http } = createTestClient(null, userId, cryptoStoreType); const counts: OTKCounts = { [OTKAlgorithm.Signed]: 12, @@ -6751,7 +6752,7 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.checkOneTimeKeyCounts(), http.flushAllExpected()]); expect(result).toMatchObject(counts); - }); + })); }); describe('getUserDevices', () => { @@ -6788,9 +6789,9 @@ describe('MatrixClient', () => { expect(result).toMatchObject(response); }); - it('should call the right endpoint with a default timeout', async () => { + it('should call the right endpoint with a default timeout', () => testCryptoStores(async (cryptoStoreType) => { const userId = "@test:example.org"; - const { client, http } = createTestClient(null, userId, true); + const { client, http } = createTestClient(null, userId, cryptoStoreType); const requestBody = { "@alice:example.org": [], @@ -6819,7 +6820,7 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.getUserDevices(Object.keys(requestBody)), http.flushAllExpected()]); expect(result).toMatchObject(response); - }); + })); }); describe('claimOneTimeKeys', () => { @@ -6835,9 +6836,9 @@ describe('MatrixClient', () => { } }); - it('should call the right endpoint', async () => { + it('should call the right endpoint', () => testCryptoStores(async (cryptoStoreType) => { const userId = "@test:example.org"; - const { client, http } = createTestClient(null, userId, true); + const { client, http } = createTestClient(null, userId, cryptoStoreType); const request = { "@alice:example.org": { @@ -6873,11 +6874,11 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.claimOneTimeKeys(request), http.flushAllExpected()]); expect(result).toMatchObject(response); - }); + })); - it('should use the timeout parameter', async () => { + it('should use the timeout parameter', () => testCryptoStores(async (cryptoStoreType) => { const userId = "@test:example.org"; - const { client, http } = createTestClient(null, userId, true); + const { client, http } = createTestClient(null, userId, cryptoStoreType); const request = { "@alice:example.org": { @@ -6915,13 +6916,13 @@ describe('MatrixClient', () => { const [result] = await Promise.all([client.claimOneTimeKeys(request, timeout), http.flushAllExpected()]); expect(result).toMatchObject(response); - }); + })); }); describe('sendToDevices', () => { - it('should call the right endpoint', async () => { + it('should call the right endpoint', () => testCryptoStores(async (cryptoStoreType) => { const userId = "@test:example.org"; - const { client, http, hsUrl } = createTestClient(null, userId, true); + const { client, http, hsUrl } = createTestClient(null, userId, cryptoStoreType); const type = "org.example.message"; const messages = { @@ -6946,13 +6947,13 @@ describe('MatrixClient', () => { }); await Promise.all([client.sendToDevices(type, messages), http.flushAllExpected()]); - }); + })); }); describe('getOwnDevices', () => { - it('should call the right endpoint', async () => { + it('should call the right endpoint', () => testCryptoStores(async (cryptoStoreType) => { const userId = "@test:example.org"; - const { client, http } = createTestClient(null, userId, true); + const { client, http } = createTestClient(null, userId, cryptoStoreType); const devices = ["schema not followed for simplicity"]; @@ -6963,7 +6964,7 @@ describe('MatrixClient', () => { const [res] = await Promise.all([client.getOwnDevices(), http.flushAllExpected()]); expect(res).toMatchObject(devices); - }); + })); }); describe('getRelationsForEvent', () => { diff --git a/test/TestUtils.ts b/test/TestUtils.ts index f62f692f..7d6f9f8d 100644 --- a/test/TestUtils.ts +++ b/test/TestUtils.ts @@ -1,5 +1,6 @@ import * as tmp from "tmp"; import HttpBackend from "matrix-mock-request"; +import { StoreType } from "@matrix-org/matrix-sdk-crypto-nodejs"; import { IStorageProvider, MatrixClient, RustSdkCryptoStorageProvider, setRequestFn } from "../src"; @@ -29,7 +30,7 @@ export function testDelay(ms: number): Promise { export function createTestClient( storage: IStorageProvider = null, userId: string = null, - crypto = false, + cryptoStoreType?: StoreType, ): { client: MatrixClient; http: HttpBackend; @@ -39,9 +40,17 @@ export function createTestClient( const http = new HttpBackend(); const hsUrl = "https://localhost"; const accessToken = "s3cret"; - const client = new MatrixClient(hsUrl, accessToken, storage, crypto ? new RustSdkCryptoStorageProvider(tmp.dirSync().name) : null); + const client = new MatrixClient(hsUrl, accessToken, storage, cryptoStoreType !== undefined ? new RustSdkCryptoStorageProvider(tmp.dirSync().name, cryptoStoreType) : null); (client).userId = userId; // private member access setRequestFn(http.requestFn); return { http, hsUrl, accessToken, client }; } + +const CRYPTO_STORE_TYPES = [StoreType.Sled, StoreType.Sqlite]; + +export async function testCryptoStores(fn: (StoreType) => Promise): Promise { + for (const st of CRYPTO_STORE_TYPES) { + await fn(st); + } +} diff --git a/test/appservice/IntentTest.ts b/test/appservice/IntentTest.ts index 3b040054..07713238 100644 --- a/test/appservice/IntentTest.ts +++ b/test/appservice/IntentTest.ts @@ -1,6 +1,7 @@ import * as simple from "simple-mock"; import HttpBackend from 'matrix-mock-request'; import * as tmp from "tmp"; +import { StoreType } from "@matrix-org/matrix-sdk-crypto-nodejs"; import { expectArrayEquals } from "../TestUtils"; import { @@ -1136,7 +1137,7 @@ describe('Intent', () => { beforeEach(() => { storage = new MemoryStorageProvider(); - cryptoStorage = new RustSdkAppserviceCryptoStorageProvider(tmp.dirSync().name); + cryptoStorage = new RustSdkAppserviceCryptoStorageProvider(tmp.dirSync().name, StoreType.Sled); options = { homeserverUrl: hsUrl, storage: storage, diff --git a/test/encryption/CryptoClientTest.ts b/test/encryption/CryptoClientTest.ts index 5f9a3d2d..bab445f6 100644 --- a/test/encryption/CryptoClientTest.ts +++ b/test/encryption/CryptoClientTest.ts @@ -2,7 +2,7 @@ import * as simple from "simple-mock"; import HttpBackend from 'matrix-mock-request'; import { EncryptedFile, MatrixClient, MembershipEvent, OTKAlgorithm, RoomEncryptionAlgorithm } from "../../src"; -import { createTestClient, TEST_DEVICE_ID } from "../TestUtils"; +import { createTestClient, testCryptoStores, TEST_DEVICE_ID } from "../TestUtils"; export function bindNullEngine(http: HttpBackend) { http.when("POST", "/keys/upload").respond(200, (path, obj) => { @@ -23,9 +23,9 @@ export function bindNullEngine(http: HttpBackend) { } describe('CryptoClient', () => { - it('should not have a device ID or be ready until prepared', async () => { + it('should not have a device ID or be ready until prepared', () => testCryptoStores(async (cryptoStoreType) => { const userId = "@alice:example.org"; - const { client, http } = createTestClient(null, userId, true); + const { client, http } = createTestClient(null, userId, cryptoStoreType); client.getWhoAmI = () => Promise.resolve({ user_id: userId, device_id: TEST_DEVICE_ID }); @@ -41,13 +41,13 @@ describe('CryptoClient', () => { expect(client.crypto.clientDeviceId).toEqual(TEST_DEVICE_ID); expect(client.crypto.isReady).toEqual(true); - }); + })); describe('prepare', () => { - it('should prepare the room tracker', async () => { + it('should prepare the room tracker', () => testCryptoStores(async (cryptoStoreType) => { const userId = "@alice:example.org"; const roomIds = ["!a:example.org", "!b:example.org"]; - const { client, http } = createTestClient(null, userId, true); + const { client, http } = createTestClient(null, userId, cryptoStoreType); client.getWhoAmI = () => Promise.resolve({ user_id: userId, device_id: TEST_DEVICE_ID }); @@ -64,11 +64,11 @@ describe('CryptoClient', () => { http.flushAllExpected(), ]); expect(prepareSpy.callCount).toEqual(1); - }); + })); - it('should use a stored device ID', async () => { + it('should use a stored device ID', () => testCryptoStores(async (cryptoStoreType) => { const userId = "@alice:example.org"; - const { client, http } = createTestClient(null, userId, true); + const { client, http } = createTestClient(null, userId, cryptoStoreType); await client.cryptoStore.setDeviceId(TEST_DEVICE_ID); @@ -82,13 +82,13 @@ describe('CryptoClient', () => { ]); expect(whoamiSpy.callCount).toEqual(0); expect(client.crypto.clientDeviceId).toEqual(TEST_DEVICE_ID); - }); + })); }); describe('isRoomEncrypted', () => { - it('should fail when the crypto has not been prepared', async () => { + it('should fail when the crypto has not been prepared', () => testCryptoStores(async (cryptoStoreType) => { const userId = "@alice:example.org"; - const { client } = createTestClient(null, userId, true); + const { client } = createTestClient(null, userId, cryptoStoreType); await client.cryptoStore.setDeviceId(TEST_DEVICE_ID); // await client.crypto.prepare([]); // deliberately commented @@ -101,11 +101,11 @@ describe('CryptoClient', () => { } catch (e) { expect(e.message).toEqual("End-to-end encryption has not initialized"); } - }); + })); - it('should return false for unknown rooms', async () => { + it('should return false for unknown rooms', () => testCryptoStores(async (cryptoStoreType) => { const userId = "@alice:example.org"; - const { client, http } = createTestClient(null, userId, true); + const { client, http } = createTestClient(null, userId, cryptoStoreType); await client.cryptoStore.setDeviceId(TEST_DEVICE_ID); client.getRoomStateEvent = () => Promise.reject(new Error("not used")); @@ -118,11 +118,11 @@ describe('CryptoClient', () => { const result = await client.crypto.isRoomEncrypted("!new:example.org"); expect(result).toEqual(false); - }); + })); - it('should return false for unencrypted rooms', async () => { + it('should return false for unencrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { const userId = "@alice:example.org"; - const { client, http } = createTestClient(null, userId, true); + const { client, http } = createTestClient(null, userId, cryptoStoreType); await client.cryptoStore.setDeviceId(TEST_DEVICE_ID); client.getRoomStateEvent = () => Promise.reject(new Error("implied 404")); @@ -135,11 +135,11 @@ describe('CryptoClient', () => { const result = await client.crypto.isRoomEncrypted("!new:example.org"); expect(result).toEqual(false); - }); + })); - it('should return true for encrypted rooms (redacted state)', async () => { + it('should return true for encrypted rooms (redacted state)', () => testCryptoStores(async (cryptoStoreType) => { const userId = "@alice:example.org"; - const { client, http } = createTestClient(null, userId, true); + const { client, http } = createTestClient(null, userId, cryptoStoreType); await client.cryptoStore.setDeviceId(TEST_DEVICE_ID); client.getRoomStateEvent = () => Promise.resolve({}); @@ -152,11 +152,11 @@ describe('CryptoClient', () => { const result = await client.crypto.isRoomEncrypted("!new:example.org"); expect(result).toEqual(true); - }); + })); - it('should return true for encrypted rooms', async () => { + it('should return true for encrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { const userId = "@alice:example.org"; - const { client, http } = createTestClient(null, userId, true); + const { client, http } = createTestClient(null, userId, cryptoStoreType); await client.cryptoStore.setDeviceId(TEST_DEVICE_ID); client.getRoomStateEvent = () => Promise.resolve({ algorithm: RoomEncryptionAlgorithm.MegolmV1AesSha2 }); @@ -169,7 +169,7 @@ describe('CryptoClient', () => { const result = await client.crypto.isRoomEncrypted("!new:example.org"); expect(result).toEqual(true); - }); + })); }); describe('sign', () => { @@ -177,15 +177,15 @@ describe('CryptoClient', () => { let client: MatrixClient; let http: HttpBackend; - beforeEach(async () => { - const { client: mclient, http: mhttp } = createTestClient(null, userId, true); + beforeEach(() => testCryptoStores(async (cryptoStoreType) => { + const { client: mclient, http: mhttp } = createTestClient(null, userId, cryptoStoreType); client = mclient; http = mhttp; await client.cryptoStore.setDeviceId(TEST_DEVICE_ID); // client crypto not prepared for the one test which wants that state - }); + })); it('should fail when the crypto has not been prepared', async () => { try { @@ -234,15 +234,15 @@ describe('CryptoClient', () => { let client: MatrixClient; let http: HttpBackend; - beforeEach(async () => { - const { client: mclient, http: mhttp } = createTestClient(null, userId, true); + beforeEach(() => testCryptoStores(async (cryptoStoreType) => { + const { client: mclient, http: mhttp } = createTestClient(null, userId, cryptoStoreType); client = mclient; http = mhttp; await client.cryptoStore.setDeviceId(TEST_DEVICE_ID); // client crypto not prepared for the one test which wants that state - }); + })); it('should fail when the crypto has not been prepared', async () => { try { @@ -284,14 +284,14 @@ describe('CryptoClient', () => { const userId = "@alice:example.org"; let client: MatrixClient; - beforeEach(async () => { - const { client: mclient } = createTestClient(null, userId, true); + beforeEach(() => testCryptoStores(async (cryptoStoreType) => { + const { client: mclient } = createTestClient(null, userId, cryptoStoreType); client = mclient; await client.cryptoStore.setDeviceId(TEST_DEVICE_ID); // client crypto not prepared for the one test which wants that state - }); + })); it('should fail when the crypto has not been prepared', async () => { try { @@ -310,15 +310,15 @@ describe('CryptoClient', () => { let client: MatrixClient; let http: HttpBackend; - beforeEach(async () => { - const { client: mclient, http: mhttp } = createTestClient(null, userId, true); + beforeEach(() => testCryptoStores(async (cryptoStoreType) => { + const { client: mclient, http: mhttp } = createTestClient(null, userId, cryptoStoreType); client = mclient; http = mhttp; await client.cryptoStore.setDeviceId(TEST_DEVICE_ID); // client crypto not prepared for the one test which wants that state - }); + })); it('should fail when the crypto has not been prepared', async () => { try { @@ -396,15 +396,15 @@ describe('CryptoClient', () => { return JSON.parse(JSON.stringify(testFile)); } - beforeEach(async () => { - const { client: mclient, http: mhttp } = createTestClient(null, userId, true); + beforeEach(() => testCryptoStores(async (cryptoStoreType) => { + const { client: mclient, http: mhttp } = createTestClient(null, userId, cryptoStoreType); client = mclient; http = mhttp; await client.cryptoStore.setDeviceId(TEST_DEVICE_ID); // client crypto not prepared for the one test which wants that state - }); + })); it('should fail when the crypto has not been prepared', async () => { try { @@ -467,8 +467,8 @@ describe('CryptoClient', () => { let client: MatrixClient; let http: HttpBackend; - beforeEach(async () => { - const { client: mclient, http: mhttp } = createTestClient(null, userId, true); + beforeEach(() => testCryptoStores(async (cryptoStoreType) => { + const { client: mclient, http: mhttp } = createTestClient(null, userId, cryptoStoreType); client = mclient; http = mhttp; @@ -478,7 +478,7 @@ describe('CryptoClient', () => { client.crypto.prepare([]), http.flushAllExpected(), ]); - }); + })); it('should update tracked users on membership changes', async () => { const targetUserIds = ["@bob:example.org", "@charlie:example.org"]; diff --git a/test/encryption/RoomTrackerTest.ts b/test/encryption/RoomTrackerTest.ts index 2dd1453e..4ce0a00c 100644 --- a/test/encryption/RoomTrackerTest.ts +++ b/test/encryption/RoomTrackerTest.ts @@ -1,7 +1,7 @@ import * as simple from "simple-mock"; import { EncryptionEventContent, MatrixClient, RoomEncryptionAlgorithm, RoomTracker } from "../../src"; -import { createTestClient, TEST_DEVICE_ID } from "../TestUtils"; +import { createTestClient, testCryptoStores, TEST_DEVICE_ID } from "../TestUtils"; import { bindNullEngine } from "./CryptoClientTest"; function prepareQueueSpies( @@ -38,10 +38,10 @@ function prepareQueueSpies( } describe('RoomTracker', () => { - it('should queue room updates when rooms are joined', async () => { + it('should queue room updates when rooms are joined', () => testCryptoStores(async (cryptoStoreType) => { const roomId = "!a:example.org"; - const { client, http } = createTestClient(null, "@user:example.org", true); + const { client, http } = createTestClient(null, "@user:example.org", cryptoStoreType); await client.cryptoStore.setDeviceId(TEST_DEVICE_ID); bindNullEngine(http); await Promise.all([ @@ -64,12 +64,12 @@ describe('RoomTracker', () => { client.emit("room.join", roomId); }); expect(queueSpy.callCount).toEqual(1); - }); + })); - it('should queue room updates when encryption events are received', async () => { + it('should queue room updates when encryption events are received', () => testCryptoStores(async (cryptoStoreType) => { const roomId = "!a:example.org"; - const { client, http } = createTestClient(null, "@user:example.org", true); + const { client, http } = createTestClient(null, "@user:example.org", cryptoStoreType); await client.cryptoStore.setDeviceId(TEST_DEVICE_ID); bindNullEngine(http); await Promise.all([ @@ -102,7 +102,7 @@ describe('RoomTracker', () => { }); await new Promise(resolve => setTimeout(() => resolve(), 250)); expect(queueSpy.callCount).toEqual(1); - }); + })); describe('prepare', () => { it('should queue updates for rooms', async () => { @@ -123,11 +123,11 @@ describe('RoomTracker', () => { }); describe('queueRoomCheck', () => { - it('should store unknown rooms', async () => { + it('should store unknown rooms', () => testCryptoStores(async (cryptoStoreType) => { const roomId = "!b:example.org"; const content = { algorithm: RoomEncryptionAlgorithm.MegolmV1AesSha2, rid: "1" }; - const { client } = createTestClient(null, "@user:example.org", true); + const { client } = createTestClient(null, "@user:example.org", cryptoStoreType); const [readSpy, stateSpy, storeSpy] = prepareQueueSpies(client, roomId, content); @@ -136,13 +136,13 @@ describe('RoomTracker', () => { expect(readSpy.callCount).toEqual(1); expect(stateSpy.callCount).toEqual(2); // m.room.encryption and m.room.history_visibility expect(storeSpy.callCount).toEqual(1); - }); + })); - it('should skip known rooms', async () => { + it('should skip known rooms', () => testCryptoStores(async (cryptoStoreType) => { const roomId = "!b:example.org"; const content = { algorithm: RoomEncryptionAlgorithm.MegolmV1AesSha2, rid: "1" }; - const { client } = createTestClient(null, "@user:example.org", true); + const { client } = createTestClient(null, "@user:example.org", cryptoStoreType); const [readSpy, stateSpy, storeSpy] = prepareQueueSpies(client, roomId, { algorithm: "no" }, content); @@ -151,13 +151,13 @@ describe('RoomTracker', () => { expect(readSpy.callCount).toEqual(1); expect(stateSpy.callCount).toEqual(0); expect(storeSpy.callCount).toEqual(0); - }); + })); - it('should not store unencrypted rooms', async () => { + it('should not store unencrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { const roomId = "!b:example.org"; const content = { algorithm: RoomEncryptionAlgorithm.MegolmV1AesSha2, rid: "1" }; - const { client } = createTestClient(null, "@user:example.org", true); + const { client } = createTestClient(null, "@user:example.org", cryptoStoreType); const [readSpy, stateSpy, storeSpy] = prepareQueueSpies(client, roomId, content); client.getRoomStateEvent = async (rid: string, et: string, sk: string) => { @@ -170,15 +170,15 @@ describe('RoomTracker', () => { expect(readSpy.callCount).toEqual(1); expect(stateSpy.callCount).toEqual(1); expect(storeSpy.callCount).toEqual(0); - }); + })); }); describe('getRoomCryptoConfig', () => { - it('should return the config as-is', async () => { + it('should return the config as-is', () => testCryptoStores(async (cryptoStoreType) => { const roomId = "!a:example.org"; const content: Partial = { algorithm: RoomEncryptionAlgorithm.MegolmV1AesSha2 }; - const { client } = createTestClient(null, "@user:example.org", true); + const { client } = createTestClient(null, "@user:example.org", cryptoStoreType); const readSpy = simple.stub().callFn((rid: string) => { expect(rid).toEqual(roomId); @@ -191,13 +191,13 @@ describe('RoomTracker', () => { const config = await tracker.getRoomCryptoConfig(roomId); expect(readSpy.callCount).toEqual(1); expect(config).toMatchObject(content); - }); + })); - it('should queue unknown rooms', async () => { + it('should queue unknown rooms', () => testCryptoStores(async (cryptoStoreType) => { const roomId = "!a:example.org"; const content: Partial = { algorithm: RoomEncryptionAlgorithm.MegolmV1AesSha2 }; - const { client } = createTestClient(null, "@user:example.org", true); + const { client } = createTestClient(null, "@user:example.org", cryptoStoreType); const readSpy = simple.stub().callFn((rid: string) => { expect(rid).toEqual(roomId); @@ -217,12 +217,12 @@ describe('RoomTracker', () => { expect(readSpy.callCount).toEqual(2); expect(queueSpy.callCount).toEqual(1); expect(config).toMatchObject(content); - }); + })); - it('should return empty for unencrypted rooms', async () => { + it('should return empty for unencrypted rooms', () => testCryptoStores(async (cryptoStoreType) => { const roomId = "!a:example.org"; - const { client } = createTestClient(null, "@user:example.org", true); + const { client } = createTestClient(null, "@user:example.org", cryptoStoreType); const readSpy = simple.stub().callFn((rid: string) => { expect(rid).toEqual(roomId); @@ -241,6 +241,6 @@ describe('RoomTracker', () => { expect(readSpy.callCount).toEqual(2); expect(queueSpy.callCount).toEqual(1); expect(config).toMatchObject({}); - }); + })); }); }); diff --git a/yarn.lock b/yarn.lock index 8b009d88..e853435b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -584,12 +584,13 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@matrix-org/matrix-sdk-crypto-nodejs@0.1.0-beta.3": - version "0.1.0-beta.3" - resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-nodejs/-/matrix-sdk-crypto-nodejs-0.1.0-beta.3.tgz#a07225dd180d9d227c24ba62bba439939446d113" - integrity sha512-jHFn6xBeNqfsY5gX60akbss7iFBHZwXycJWMw58Mjz08OwOi7AbTxeS9I2Pa4jX9/M2iinskmGZbzpqOT2fM3A== +"@matrix-org/matrix-sdk-crypto-nodejs@0.1.0-beta.4": + version "0.1.0-beta.4" + resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-nodejs/-/matrix-sdk-crypto-nodejs-0.1.0-beta.4.tgz#80456b2e2cc731982f0d3c6aece80cefa1ebb797" + integrity sha512-XjCp/tG3LRMxMj/MMZfypD5BtW3J1B6oXY2Og8Ed0SyU4uWdglalMwrBUKlDotJr0/Q/2OTspGjD+ytAzCspyw== dependencies: - node-downloader-helper "^2.1.1" + https-proxy-agent "^5.0.1" + node-downloader-helper "^2.1.5" "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -779,6 +780,18 @@ resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.2.tgz#fd2cd2edbaa7eaac7e7f3c1748b52a19143846c9" integrity sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA== +"@types/lodash@*": + version "4.14.194" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.194.tgz#b71eb6f7a0ff11bff59fc987134a093029258a76" + integrity sha512-r22s9tAS7imvBt2lyHC9B8AGwWnXaYb1tY09oyLkXDs4vArpYJzw09nj8MLx5VfciBPGIb+ZwG0ssYnEPJxn/g== + +"@types/lowdb@^1.0.11": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@types/lowdb/-/lowdb-1.0.11.tgz#d8336a635ea0dbd48a7f6f62fb9fccc5ec358ae3" + integrity sha512-h99VMxvTuz+VsXUVCCJo4dsps4vbkXwvU71TpmxDoiBU24bJ0VBygIHgmMm+UPoQIFihmV6euRik4z8J7XDJWg== + dependencies: + "@types/lodash" "*" + "@types/markdown-it@^12.2.3": version "12.2.3" resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-12.2.3.tgz#0d6f6e5e413f8daaa26522904597be3d6cd93b51" @@ -977,6 +990,13 @@ acorn@^8.7.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -1589,6 +1609,13 @@ debug@2.6.9, debug@^2.6.9: dependencies: ms "2.0.0" +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -1596,13 +1623,6 @@ debug@^3.2.7: dependencies: ms "^2.1.1" -debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - decamelize@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -2554,6 +2574,14 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +https-proxy-agent@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -3657,10 +3685,10 @@ node-dir@^0.1.10: dependencies: minimatch "^3.0.2" -node-downloader-helper@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/node-downloader-helper/-/node-downloader-helper-2.1.1.tgz#533427a3cdc163931b106d0fe6d522f83deac7ab" - integrity sha512-ouk8MGmJj1gYymbJwi1L8Mr6PdyheJLwfsmyx0KtsvyJ+7Fpf0kBBzM8Gmx8Mt/JBfRWP1PQm6dAGV6x7eNedw== +node-downloader-helper@^2.1.5: + version "2.1.6" + resolved "https://registry.yarnpkg.com/node-downloader-helper/-/node-downloader-helper-2.1.6.tgz#f73ac458e3ac8c21afd0b952a994eab99c64b879" + integrity sha512-VkOvAXIopI3xMuM/MC5UL7NqqnizQ/9QXZt28jR8FPZ6fHLQm4xe4+YXJ9FqsWwLho5BLXrF51nfOQ0QcohRkQ== node-int64@^0.4.0: version "0.4.0"