From a35dfa85a955331b462f6f0e760d54f913272d8e Mon Sep 17 00:00:00 2001 From: Simon Woolf Date: Thu, 5 Dec 2024 18:25:28 +0000 Subject: [PATCH] Add decryption-capable versions of modular presencemessage decode functions --- modular.d.ts | 4 ++ scripts/moduleReport.ts | 2 + src/platform/web/modular/presencemessage.ts | 9 +++++ test/browser/modular.test.js | 45 +++++++++++++++++++++ 4 files changed, 60 insertions(+) diff --git a/modular.d.ts b/modular.d.ts index 6dac14d39..94f0ba27f 100644 --- a/modular.d.ts +++ b/modular.d.ts @@ -16,6 +16,8 @@ * | `MessageStatic.fromEncodedArray()` | [`decodeMessages()`](../functions/modular.decodeMessages.html) | * | `MessageStatic.fromEncodedArray()` | [`decodeEncryptedMessages()`](../functions/modular.decodeEncryptedMessages.html) | * | `PresenceMessageStatic.fromEncoded()` | [`decodePresenceMessage()`](../functions/modular.decodePresenceMessage.html) | + * | `PresenceMessageStatic.fromEncoded()` | [`decodeEncryptedPresenceMessage()`](../functions/modular.decodeEncryptedPresenceMessage.html) | + * | `PresenceMessageStatic.fromEncodedArray()` | [`decodeEncryptedPresenceMessages()`](../functions/modular.decodeEncryptedPresenceMessages.html) | * | `PresenceMessageStatic.fromEncodedArray()` | [`decodePresenceMessages()`](../functions/modular.decodePresenceMessages.html) | * | `PresenceMessageStatic.fromValues()` | [`constructPresenceMessage()`](../functions/modular.constructPresenceMessage.html) | * @@ -60,6 +62,8 @@ export declare const decodeMessages: MessageStatic['fromEncodedArray']; export declare const decodeEncryptedMessages: MessageStatic['fromEncodedArray']; export declare const decodePresenceMessage: PresenceMessageStatic['fromEncoded']; export declare const decodePresenceMessages: PresenceMessageStatic['fromEncodedArray']; +export declare const decodeEncryptedPresenceMessage: PresenceMessageStatic['fromEncoded']; +export declare const decodeEncryptedPresenceMessages: PresenceMessageStatic['fromEncodedArray']; export declare const constructPresenceMessage: PresenceMessageStatic['fromValues']; /** diff --git a/scripts/moduleReport.ts b/scripts/moduleReport.ts index aacec5a00..8117950a4 100644 --- a/scripts/moduleReport.ts +++ b/scripts/moduleReport.ts @@ -34,6 +34,8 @@ const functions = [ { name: 'decodeEncryptedMessages', transitiveImports: ['Crypto'] }, { name: 'decodePresenceMessage', transitiveImports: [] }, { name: 'decodePresenceMessages', transitiveImports: [] }, + { name: 'decodeEncryptedPresenceMessage', transitiveImports: ['Crypto'] }, + { name: 'decodeEncryptedPresenceMessages', transitiveImports: ['Crypto'] }, { name: 'constructPresenceMessage', transitiveImports: [] }, ]; diff --git a/src/platform/web/modular/presencemessage.ts b/src/platform/web/modular/presencemessage.ts index 0ebf5f8be..40e90830e 100644 --- a/src/platform/web/modular/presencemessage.ts +++ b/src/platform/web/modular/presencemessage.ts @@ -1,5 +1,6 @@ import * as API from '../../../../ably'; import { fromEncoded, fromEncodedArray, fromValues } from '../../../common/lib/types/presencemessage'; +import { Crypto } from './crypto'; import Logger from '../../../common/lib/util/logger'; // The type assertions for the functions below are due to https://github.com/ably/ably-js/issues/1421 @@ -8,8 +9,16 @@ export const decodePresenceMessage = ((obj, options) => { return fromEncoded(Logger.defaultLogger, null, obj, options); }) as API.PresenceMessageStatic['fromEncoded']; +export const decodeEncryptedPresenceMessage = ((obj, options) => { + return fromEncoded(Logger.defaultLogger, Crypto, obj, options); +}) as API.PresenceMessageStatic['fromEncoded']; + export const decodePresenceMessages = ((obj, options) => { return fromEncodedArray(Logger.defaultLogger, null, obj, options); }) as API.PresenceMessageStatic['fromEncodedArray']; +export const decodeEncryptedPresenceMessages = ((obj, options) => { + return fromEncodedArray(Logger.defaultLogger, Crypto, obj, options); +}) as API.PresenceMessageStatic['fromEncodedArray']; + export const constructPresenceMessage = fromValues as API.PresenceMessageStatic['fromValues']; diff --git a/test/browser/modular.test.js b/test/browser/modular.test.js index 739b1becb..6834223cb 100644 --- a/test/browser/modular.test.js +++ b/test/browser/modular.test.js @@ -8,6 +8,8 @@ import { decodeEncryptedMessage, decodeMessages, decodeEncryptedMessages, + decodeEncryptedPresenceMessage, + decodeEncryptedPresenceMessages, Crypto, MsgPack, RealtimePresence, @@ -348,6 +350,26 @@ function registerAblyModularTests(Helper) { }); }); + describe('decodeEncryptedPresenceMessage', async () => { + /** @nospec */ + it('decrypts a presence message', async function () { + const helper = this.test.helper; + const testData = await loadTestData(helper, helper.testResourcesPath + 'crypto-data-128.json'); + + const key = BufferUtils.base64Decode(testData.key); + const iv = BufferUtils.base64Decode(testData.iv); + + for (const item of testData.items) { + const [decodedFromEncoded, decodedFromEncrypted] = await Promise.all([ + decodePresenceMessage(item.encoded), + decodeEncryptedPresenceMessage(item.encrypted, { cipher: { key, iv } }), + ]); + + this.test.helper.testMessageEquality(decodedFromEncoded, decodedFromEncrypted); + } + }); + }); + async function testDecodesMessagesData(helper, functionUnderTest) { const testData = await loadTestData(helper, helper.testResourcesPath + 'crypto-data-128.json'); @@ -418,6 +440,29 @@ function registerAblyModularTests(Helper) { } }); }); + + describe('decodeEncryptedPresenceMessages', () => { + /** @nospec */ + it('decrypts messages', async function () { + const helper = this.test.helper; + const testData = await loadTestData(helper, helper.testResourcesPath + 'crypto-data-128.json'); + + const key = BufferUtils.base64Decode(testData.key); + const iv = BufferUtils.base64Decode(testData.iv); + + const [decodedFromEncoded, decodedFromEncrypted] = await Promise.all([ + decodePresenceMessages(testData.items.map((item) => item.encoded)), + decodeEncryptedPresenceMessages( + testData.items.map((item) => item.encrypted), + { cipher: { key, iv } }, + ), + ]); + + for (let i = 0; i < decodedFromEncoded.length; i++) { + this.test.helper.testMessageEquality(decodedFromEncoded[i], decodedFromEncrypted[i]); + } + }); + }); }); describe('Crypto', () => {