From 9b6a4169018261d81a1cefc6435efd1e4ab70ec6 Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Thu, 5 Dec 2024 13:45:49 -0300 Subject: [PATCH] Test that we can decrypt history messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was previously untested. The new test in `crypto.test.js` is taken from a test Simon added in #1923, but I wanted to separate this test from all the other work that’s being done in that PR. I’ve also copied this new test to create a similar test for the modular variant of the library. Co-authored-by: Simon Woolf --- test/browser/modular.test.js | 49 ++++++++++++++++++++++++++++ test/common/modules/shared_helper.js | 9 +++++ test/realtime/crypto.test.js | 25 ++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/test/browser/modular.test.js b/test/browser/modular.test.js index 739b1becb..3b529e894 100644 --- a/test/browser/modular.test.js +++ b/test/browser/modular.test.js @@ -507,6 +507,39 @@ function registerAblyModularTests(Helper) { ); } + async function testIsAbleToDecryptHistoryMessages(helper, clientClassConfig) { + const clientOptions = helper.ablyClientOptions(); + + const client = new clientClassConfig.clientClass({ + ...clientOptions, + plugins: { + ...clientClassConfig.additionalPlugins, + FetchRequest, + Crypto, + }, + }); + + await (clientClassConfig.isRealtime ? monitorConnectionThenCloseAndFinish : async (helper, op) => await op())( + helper, + async () => { + const channelName = 'encrypted_history', + messageText = 'Test message'; + + const key = await generateRandomKey(); + + const channel = client.channels.get(channelName, { cipher: { key: key } }); + await channel.publish('event0', messageText); + let items; + await helper.waitFor(async () => { + items = (await channel.history()).items; + return items.length > 0; + }, 10_000); + expect(items[0].data).to.equal(messageText); + }, + client, + ); + } + for (const clientClassConfig of [ { clientClass: BaseRest, isRealtime: false }, { @@ -522,6 +555,22 @@ function registerAblyModularTests(Helper) { }); }); } + + for (const clientClassConfig of [ + { clientClass: BaseRest, isRealtime: false }, + { + clientClass: BaseRealtime, + additionalPlugins: { WebSocketTransport, Rest }, + isRealtime: true, + }, + ]) { + describe(clientClassConfig.clientClass.name, () => { + /** @nospec */ + it('is able to decrypt history messages', async function () { + await testIsAbleToDecryptHistoryMessages(this.test.helper, clientClassConfig); + }); + }); + } }); }); diff --git a/test/common/modules/shared_helper.js b/test/common/modules/shared_helper.js index 46c4732b0..8b059038d 100644 --- a/test/common/modules/shared_helper.js +++ b/test/common/modules/shared_helper.js @@ -483,6 +483,15 @@ define([ dumpPrivateApiUsage() { privateApiRecorder.dump(); } + + async waitFor(condition, remaining) { + const success = await condition(); + if (success || remaining <= 0) { + return success; + } + await this.setTimeoutAsync(100); + return this.waitFor(condition, remaining - 100); + } } SharedHelper.testOnAllTransports.skip = function (thisInDescribe, name, testFn) { diff --git a/test/realtime/crypto.test.js b/test/realtime/crypto.test.js index 18df2f11e..f6da97e55 100644 --- a/test/realtime/crypto.test.js +++ b/test/realtime/crypto.test.js @@ -773,6 +773,31 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, Helper, async }); }); + /** + * @spec RSL5a + */ + it('encrypted history', async function () { + if (!Crypto) { + done(new Error('Encryption not supported')); + return; + } + + const helper = this.test.helper, + rest = helper.AblyRest(), + channelName = 'encrypted_history', + messageText = 'Test message'; + + const key = await Crypto.generateRandomKey(); + const channel = rest.channels.get(channelName, { cipher: { key: key } }); + await channel.publish('event0', messageText); + let items; + await helper.waitFor(async () => { + items = (await channel.history()).items; + return items.length > 0; + }, 10_000); + expect(items[0].data).to.equal(messageText); + }); + /** * Connect twice to the service, using different cipher keys. * Publish an encrypted message on that channel using