From a0105eb80ef6a9c133b4fc861cd2fc0aea71afc5 Mon Sep 17 00:00:00 2001 From: Lawrence Forooghian Date: Thu, 22 Jun 2023 10:49:19 -0300 Subject: [PATCH] Change Crypto.generateRandomKey API to use Promises MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds the missing Promise-based version of this method. Since we’re going to be removing the callbacks API in #1199 anyway, I’ve just replaced the callbacks version of the method. Resolves #1345. --- ably.d.ts | 4 +-- src/platform/nodejs/lib/util/crypto.ts | 23 ++++++++--------- src/platform/web/lib/util/crypto.ts | 24 ++++++++---------- test/realtime/crypto.test.js | 34 +++++++++++++------------- 4 files changed, 39 insertions(+), 46 deletions(-) diff --git a/ably.d.ts b/ably.d.ts index 0a85fd2602..f3f4a028d7 100644 --- a/ably.d.ts +++ b/ably.d.ts @@ -2963,9 +2963,9 @@ declare namespace Types { * Generates a random key to be used in the encryption of the channel. If the language cryptographic randomness primitives are blocking or async, a callback is used. The callback returns a generated binary key. * * @param keyLength - The length of the key, in bits, to be generated. If not specified, this is equal to the default `keyLength` of the default algorithm: for AES this is 256 bits. - * @param callback - A function which, upon success, will be called with the generated key as a binary, for example, a byte array. Upon failure, the function will be called with information about the error. + * @returns A promise which, upon success, will be fulfilled with the generated key as a binary, for example, a byte array. Upon failure, the promise will be rejected with an {@link Types.ErrorInfo} object which explains the error. */ - generateRandomKey(keyLength?: number, callback?: Types.StandardCallback): void; + generateRandomKey(keyLength?: number): Promise; /** * Returns a {@link CipherParams} object, using the default values for any fields not supplied by the {@link CipherParamOptions} object. * diff --git a/src/platform/nodejs/lib/util/crypto.ts b/src/platform/nodejs/lib/util/crypto.ts index 3a19dc93fe..1d99b060af 100644 --- a/src/platform/nodejs/lib/util/crypto.ts +++ b/src/platform/nodejs/lib/util/crypto.ts @@ -190,19 +190,16 @@ var CryptoFactory = function (bufferUtils: typeof BufferUtils) { * @param keyLength (optional) the required keyLength in bits * @param callback (optional) (err, key) */ - static generateRandomKey(keyLength?: number, callback?: API.Types.StandardCallback) { - if (arguments.length == 1 && typeof keyLength == 'function') { - callback = keyLength; - keyLength = undefined; - } - - generateRandom((keyLength || DEFAULT_KEYLENGTH) / 8, function (err, buf) { - if (callback !== undefined) { - const errorInfo = err - ? new ErrorInfo('Failed to generate random key: ' + err.message, 500, 50000, err) - : null; - callback(errorInfo, buf); - } + static async generateRandomKey(keyLength?: number): Promise { + return new Promise((resolve, reject) => { + generateRandom((keyLength || DEFAULT_KEYLENGTH) / 8, function (err, buf) { + if (err) { + const errorInfo = new ErrorInfo('Failed to generate random key: ' + err.message, 500, 50000, err); + reject(errorInfo); + } else { + resolve(buf!); + } + }); }); } diff --git a/src/platform/web/lib/util/crypto.ts b/src/platform/web/lib/util/crypto.ts index 92168b5801..23c572d9dd 100644 --- a/src/platform/web/lib/util/crypto.ts +++ b/src/platform/web/lib/util/crypto.ts @@ -181,21 +181,17 @@ var CryptoFactory = function (config: IPlatformConfig, bufferUtils: typeof Buffe * Generate a random encryption key from the supplied keylength (or the * default keyLength if none supplied) as an ArrayBuffer * @param keyLength (optional) the required keyLength in bits - * @param callback (optional) (err, key) */ - static generateRandomKey(keyLength?: number, callback?: API.Types.StandardCallback) { - if (arguments.length == 1 && typeof keyLength == 'function') { - callback = keyLength; - keyLength = undefined; - } - - generateRandom((keyLength || DEFAULT_KEYLENGTH) / 8, function (err, buf) { - if (callback !== undefined) { - const errorInfo = err - ? new ErrorInfo('Failed to generate random key: ' + err.message, 400, 50000, err) - : null; - callback(errorInfo, buf ?? undefined); - } + static async generateRandomKey(keyLength?: number): Promise { + return new Promise((resolve, reject) => { + generateRandom((keyLength || DEFAULT_KEYLENGTH) / 8, function (err, buf) { + if (err) { + const errorInfo = new ErrorInfo('Failed to generate random key: ' + err.message, 400, 50000, err); + reject(errorInfo); + } else { + resolve(buf!); + } + }); }); } diff --git a/test/realtime/crypto.test.js b/test/realtime/crypto.test.js index ba8f8d13bb..8952bcf71e 100644 --- a/test/realtime/crypto.test.js +++ b/test/realtime/crypto.test.js @@ -119,7 +119,7 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, helper, async /* generateRandomKey with an explicit keyLength */ it('generateRandomKey0', function (done) { - Crypto.generateRandomKey(64, function (err, key) { + whenPromiseSettles(Crypto.generateRandomKey(64), function (err, key) { if (err) { done(err); return; @@ -136,7 +136,7 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, helper, async /* generateRandomKey with no keyLength should generate 256-bit keys */ it('generateRandomKey1', function (done) { - Crypto.generateRandomKey(function (err, key) { + whenPromiseSettles(Crypto.generateRandomKey(), function (err, key) { if (err) { done(err); return; @@ -151,7 +151,7 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, helper, async }); it('getDefaultParams_withResultOfGenerateRandomKey', function (done) { - Crypto.generateRandomKey(function (err, key) { + whenPromiseSettles(Crypto.generateRandomKey(), function (err, key) { if (err) { done(err); } @@ -168,7 +168,7 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, helper, async }); it('getDefaultParams_ArrayBuffer_key', function (done) { - Crypto.generateRandomKey(function (err, key) { + whenPromiseSettles(Crypto.generateRandomKey(), function (err, key) { if (err) { done(err); } @@ -184,7 +184,7 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, helper, async }); it('getDefaultParams_base64_key', function (done) { - Crypto.generateRandomKey(function (err, key) { + whenPromiseSettles(Crypto.generateRandomKey(), function (err, key) { if (err) { done(err); return; @@ -201,7 +201,7 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, helper, async }); it('getDefaultParams_check_keylength', function (done) { - Crypto.generateRandomKey(64, function (err, key) { + whenPromiseSettles(Crypto.generateRandomKey(64), function (err, key) { if (err) { done(err); return; @@ -216,7 +216,7 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, helper, async }); it('getDefaultParams_preserves_custom_algorithms', function (done) { - Crypto.generateRandomKey(64, function (err, key) { + whenPromiseSettles(Crypto.generateRandomKey(64), function (err, key) { if (err) { done(err); return; @@ -401,7 +401,7 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, helper, async return; } - Crypto.generateRandomKey(keyLength, function (err, key) { + whenPromiseSettles(Crypto.generateRandomKey(keyLength), function (err, key) { if (err) { closeAndFinish(done, realtime, err); return; @@ -464,7 +464,7 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, helper, async channel = realtime.channels.get(channelName), messageText = 'Test message (' + channelName + ')'; - Crypto.generateRandomKey(128, function (err, key) { + whenPromiseSettles(Crypto.generateRandomKey(128), function (err, key) { channel.setOptions({ cipher: { key: key } }); try { expect(channel.channelOptions.cipher.algorithm).to.equal('aes'); @@ -534,7 +534,7 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, helper, async txChannel = txRealtime.channels.get(channelName), rxChannel = rxRealtime.channels.get(channelName); - Crypto.generateRandomKey(function (err, key) { + whenPromiseSettles(Crypto.generateRandomKey(), function (err, key) { if (err) { closeAndFinish(done, realtime, err); return; @@ -608,7 +608,7 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, helper, async channelName = 'publish_immediately', messageText = 'Test message'; - Crypto.generateRandomKey(function (err, key) { + whenPromiseSettles(Crypto.generateRandomKey(), function (err, key) { if (err) { closeAndFinish(done, [txRealtime, rxRealtime], err); return; @@ -655,10 +655,10 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, helper, async async.parallel( [ function (cb) { - Crypto.generateRandomKey(cb); + whenPromiseSettles(Crypto.generateRandomKey(), cb); }, function (cb) { - Crypto.generateRandomKey(cb); + whenPromiseSettles(Crypto.generateRandomKey(), cb); }, function (cb) { attachChannels([txChannel, rxChannel], cb); @@ -723,7 +723,7 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, helper, async closeAndFinish(done, [txRealtime, rxRealtime], err); return; } - Crypto.generateRandomKey(function (err, rxKey) { + whenPromiseSettles(Crypto.generateRandomKey(), function (err, rxKey) { if (err) { closeAndFinish(done, [txRealtime, rxRealtime], err); return; @@ -766,7 +766,7 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, helper, async closeAndFinish(done, [txRealtime, rxRealtime], err); return; } - Crypto.generateRandomKey(function (err, txKey) { + whenPromiseSettles(Crypto.generateRandomKey(), function (err, txKey) { if (err) { closeAndFinish(done, [txRealtime, rxRealtime], err); return; @@ -811,7 +811,7 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, helper, async attachChannels([txChannel, rxChannel], cb); }; var setInitialOptions = function (cb) { - Crypto.generateRandomKey(function (err, key) { + whenPromiseSettles(Crypto.generateRandomKey(), function (err, key) { if (err) { closeAndFinish(done, [txRealtime, rxRealtime], err); return; @@ -844,7 +844,7 @@ define(['ably', 'shared_helper', 'async', 'chai'], function (Ably, helper, async }; var createSecondKey = function (cb) { - Crypto.generateRandomKey(function (err, key) { + whenPromiseSettles(Crypto.generateRandomKey(), function (err, key) { if (err) { closeAndFinish(done, [txRealtime, rxRealtime], err); return;