diff --git a/ts/session/protocols/MultiDeviceProtocol.ts b/ts/session/protocols/MultiDeviceProtocol.ts index ab28ad5b2..0b8b33e5c 100644 --- a/ts/session/protocols/MultiDeviceProtocol.ts +++ b/ts/session/protocols/MultiDeviceProtocol.ts @@ -31,27 +31,37 @@ export class MultiDeviceProtocol { // This return here stops an infinite loop when we get all our other devices const ourKey = await UserUtil.getCurrentDevicePubKey(); if (!ourKey || device.key === ourKey) { + console.log(`[vince] 1 GUARD`); + console.log('[vince] ourKey:', ourKey); + console.log('[vince] device:', device); + return; } // We always prefer our local pairing over the one on the server const isOurDevice = await this.isOurDevice(device); if (isOurDevice) { + console.log(`[vince] 2 GUARD`); return; } // Only fetch if we hit the refresh delay const lastFetchTime = this.lastFetch[device.key]; if (lastFetchTime && lastFetchTime + this.refreshDelay > Date.now()) { + console.log(`[vince] 3 GUARD`); return; } + this.lastFetch[device.key] = Date.now(); + console.log(`[vince] 4 GUARD`); try { + console.log(`[vince] 5 GUARD`); const authorisations = await this.fetchPairingAuthorisations(device); await Promise.all(authorisations.map(this.savePairingAuthorisation)); } catch (e) { + console.log(`[vince] 6 GUARD`); // Something went wrong, let it re-try another time this.lastFetch[device.key] = lastFetchTime; } diff --git a/ts/test/session/protocols/MultiDeviceProtocol_test.ts b/ts/test/session/protocols/MultiDeviceProtocol_test.ts index b92d0305a..e176de3a7 100644 --- a/ts/test/session/protocols/MultiDeviceProtocol_test.ts +++ b/ts/test/session/protocols/MultiDeviceProtocol_test.ts @@ -42,7 +42,7 @@ describe('MultiDeviceProtocol', () => { 'getPairingAuthorisationsFor' ).resolves([]); await MultiDeviceProtocol.getPairingAuthorisations( - TestUtils.generateFakePubkey() + TestUtils.generateFakePubKey() ); expect(fetchPairingStub.called).to.equal(true, 'Pairing is not fetched.'); expect(fetchPairingStub.calledBefore(dataStub)).to.equal( @@ -52,8 +52,8 @@ describe('MultiDeviceProtocol', () => { }); it('should return the authorisations from the database', async () => { - const device1 = TestUtils.generateFakePubkey(); - const device2 = TestUtils.generateFakePubkey(); + const device1 = TestUtils.generateFakePubKey(); + const device2 = TestUtils.generateFakePubKey(); const pairing: PairingAuthorisation = { primaryDevicePubKey: device1.key, secondaryDevicePubKey: device2.key, @@ -74,7 +74,7 @@ describe('MultiDeviceProtocol', () => { TestUtils.stubWindow('lokiFileServerAPI', undefined); expect( MultiDeviceProtocol.fetchPairingAuthorisations( - TestUtils.generateFakePubkey() + TestUtils.generateFakePubKey() ) ).to.be.rejectedWith('lokiFileServerAPI is not initialised.'); }); @@ -100,7 +100,7 @@ describe('MultiDeviceProtocol', () => { }); const authorisations = await MultiDeviceProtocol.fetchPairingAuthorisations( - TestUtils.generateFakePubkey() + TestUtils.generateFakePubKey() ); expect(authorisations.length).to.equal(1); @@ -139,8 +139,8 @@ describe('MultiDeviceProtocol', () => { fetchPairingAuthorisationStub = sandbox .stub(MultiDeviceProtocol, 'fetchPairingAuthorisations') .resolves([]); - currentDevice = TestUtils.generateFakePubkey(); - device = TestUtils.generateFakePubkey(); + currentDevice = TestUtils.generateFakePubKey(); + device = TestUtils.generateFakePubKey(); sandbox .stub(UserUtil, 'getCurrentDevicePubKey') .resolves(currentDevice.key); @@ -235,7 +235,7 @@ describe('MultiDeviceProtocol', () => { describe('getAllDevices', () => { it('should return all devices', async () => { - const primary = TestUtils.generateFakePubkey(); + const primary = TestUtils.generateFakePubKey(); const otherDevices = TestUtils.generateFakePubKeys(2); const authorisations = generateFakeAuthorisations(primary, otherDevices); sandbox @@ -253,7 +253,7 @@ describe('MultiDeviceProtocol', () => { describe('getPrimaryDevice', () => { it('should return the primary device', async () => { - const primary = TestUtils.generateFakePubkey(); + const primary = TestUtils.generateFakePubKey(); const otherDevices = TestUtils.generateFakePubKeys(2); const authorisations = generateFakeAuthorisations(primary, otherDevices); sandbox @@ -270,7 +270,7 @@ describe('MultiDeviceProtocol', () => { describe('getSecondaryDevices', () => { it('should return the secondary devices', async () => { - const primary = TestUtils.generateFakePubkey(); + const primary = TestUtils.generateFakePubKey(); const otherDevices = TestUtils.generateFakePubKeys(2); const authorisations = generateFakeAuthorisations(primary, otherDevices); sandbox diff --git a/ts/test/session/sending/MessageQueue_test.ts b/ts/test/session/sending/MessageQueue_test.ts index 2831c9b26..a86c91ef5 100644 --- a/ts/test/session/sending/MessageQueue_test.ts +++ b/ts/test/session/sending/MessageQueue_test.ts @@ -1,5 +1,6 @@ import { expect } from 'chai'; import * as sinon from 'sinon'; +import * as _ from 'lodash'; import { GroupUtils, SyncMessageUtils } from '../../../session/utils'; import { Stubs, TestUtils } from '../../../test/test-utils'; import { MessageQueue } from '../../../session/sending/MessageQueue'; @@ -36,9 +37,9 @@ describe('MessageQueue', () => { // Initialize new stubbed cache let data: StorageItem; const sandbox = sinon.createSandbox(); - const ourDevice = TestUtils.generateFakePubkey(); + const ourDevice = TestUtils.generateFakePubKey(); const ourNumber = ourDevice.key; - const pairedDevices = TestUtils.generateMemberList(2); + const pairedDevices = TestUtils.generateFakePubKeys(2); // Initialize new stubbed queue let messageQueueStub: MessageQueue; @@ -106,7 +107,7 @@ describe('MessageQueue', () => { sandbox.stub(GroupUtils, 'isMediumGroup').returns(false); groupMembersStub = sandbox .stub(GroupUtils, 'getGroupMembers' as any) - .resolves(TestUtils.generateMemberList(10)); + .resolves(TestUtils.generateFakePubKeys(10)); // Session Protocol Stubs sandbox.stub(SessionProtocol, 'sendSessionRequest').resolves(); @@ -121,7 +122,7 @@ describe('MessageQueue', () => { TestUtils.generateChatMessage ); const rawMessage = toRawMessage( - TestUtils.generateFakePubkey(), + TestUtils.generateFakePubKey(), TestUtils.generateChatMessage() ); @@ -129,11 +130,11 @@ describe('MessageQueue', () => { sandbox.stub(PendingMessageCache.prototype, 'remove').resolves(); sandbox .stub(PendingMessageCache.prototype, 'getDevices') - .returns(TestUtils.generateMemberList(10)); + .returns(TestUtils.generateFakePubKeys(10)); sandbox .stub(PendingMessageCache.prototype, 'getForDevice') .returns( - chatMessages.map(m => toRawMessage(TestUtils.generateFakePubkey(), m)) + chatMessages.map(m => toRawMessage(TestUtils.generateFakePubKey(), m)) ); // Spies @@ -155,7 +156,7 @@ describe('MessageQueue', () => { describe('send', () => { it('can send to a single device', async () => { - const device = TestUtils.generateFakePubkey(); + const device = TestUtils.generateFakePubKey(); const message = TestUtils.generateChatMessage(); const promise = messageQueueStub.send(device, message); @@ -163,7 +164,7 @@ describe('MessageQueue', () => { }); it('can send sync message', async () => { - const devices = TestUtils.generateMemberList(3); + const devices = TestUtils.generateFakePubKeys(3); const message = TestUtils.generateChatMessage(); const promise = messageQueueStub.sendSyncMessage(message, devices); @@ -175,7 +176,7 @@ describe('MessageQueue', () => { it('will send session request message if no session', async () => { hasSessionStub.resolves(false); - const device = TestUtils.generateFakePubkey(); + const device = TestUtils.generateFakePubKey(); const promise = messageQueueStub.processPending(device); await expect(promise).to.be.fulfilled; @@ -183,7 +184,7 @@ describe('MessageQueue', () => { }); it('will send message if session exists', async () => { - const device = TestUtils.generateFakePubkey(); + const device = TestUtils.generateFakePubKey(); const hasSession = await hasSessionStub(device); const promise = messageQueueStub.processPending(device); @@ -196,7 +197,7 @@ describe('MessageQueue', () => { describe('sendUsingMultiDevice', () => { it('can send using multidevice', async () => { - const device = TestUtils.generateFakePubkey(); + const device = TestUtils.generateFakePubKey(); const message = TestUtils.generateChatMessage(); const promise = messageQueueStub.sendUsingMultiDevice(device, message); @@ -238,7 +239,7 @@ describe('MessageQueue', () => { describe('sendMessageToDevices', () => { it('can send to many devices', async () => { - const devices = TestUtils.generateMemberList(10); + const devices = TestUtils.generateFakePubKeys(10); const message = TestUtils.generateChatMessage(); const promise = messageQueueStub.sendMessageToDevices(devices, message); @@ -248,10 +249,9 @@ describe('MessageQueue', () => { it('can send sync message and confirm canSync is valid', async () => { canSyncStub.returns(true); - const devices = TestUtils.generateMemberList(3); + const devices = TestUtils.generateFakePubKeys(3); const message = TestUtils.generateChatMessage(); const pairedDeviceKeys = pairedDevices.map(device => device.key); - const ourDeviceKeys = [...pairedDeviceKeys, ourNumber].sort(); const promise = messageQueueStub.sendMessageToDevices(devices, message); await expect(promise).to.be.fulfilled; @@ -267,7 +267,7 @@ describe('MessageQueue', () => { expect(previousArgs).to.have.length(2); const argsChatMessage = previousArgs[0]; - const argsPairedKeys = [...previousArgs[1]].map(d => d.key).sort(); + const argsPairedKeys = [...previousArgs[1]].map(d => d.key); expect(argsChatMessage instanceof ChatMessage).to.equal( true, @@ -278,9 +278,9 @@ describe('MessageQueue', () => { 'message passed into sendMessageToDevices has been mutated' ); - argsPairedKeys.forEach((argsPaired: string, index: number) => { - expect(argsPaired).to.equal(ourDeviceKeys[index]); - }); + // argsPairedKeys and pairedDeviceKeys should contain the same values + const keyArgsValid = _.isEmpty(_.xor(argsPairedKeys, pairedDeviceKeys)); + expect(keyArgsValid).to.equal(true, 'devices passed into sendSyncMessage were invalid'); }); }); @@ -334,7 +334,7 @@ describe('MessageQueue', () => { }); it('wont send message to empty closed group', async () => { - groupMembersStub.resolves(TestUtils.generateMemberList(0)); + groupMembersStub.resolves(TestUtils.generateFakePubKeys(0)); const message = TestUtils.generateClosedGroupMessage(); const response = await messageQueueStub.sendToGroup(message); @@ -358,7 +358,7 @@ describe('MessageQueue', () => { const successSpy = sandbox.spy(); messageQueueStub.events.on('success', successSpy); - const device = TestUtils.generateFakePubkey(); + const device = TestUtils.generateFakePubKey(); const promise = messageQueueStub.processPending(device); await expect(promise).to.be.fulfilled; @@ -372,7 +372,7 @@ describe('MessageQueue', () => { const failureSpy = sandbox.spy(); messageQueueStub.events.on('fail', failureSpy); - const device = TestUtils.generateFakePubkey(); + const device = TestUtils.generateFakePubKey(); const promise = messageQueueStub.processPending(device); await expect(promise).to.be.fulfilled; diff --git a/ts/test/session/sending/PendingMessageCache_test.ts b/ts/test/session/sending/PendingMessageCache_test.ts index 05b2d7b87..5ed1e211e 100644 --- a/ts/test/session/sending/PendingMessageCache_test.ts +++ b/ts/test/session/sending/PendingMessageCache_test.ts @@ -52,7 +52,7 @@ describe('PendingMessageCache', () => { }); it('can add to cache', async () => { - const device = TestUtils.generateFakePubkey(); + const device = TestUtils.generateFakePubKey(); const message = TestUtils.generateChatMessage(); const rawMessage = MessageUtils.toRawMessage(device, message); @@ -69,7 +69,7 @@ describe('PendingMessageCache', () => { }); it('can remove from cache', async () => { - const device = TestUtils.generateFakePubkey(); + const device = TestUtils.generateFakePubKey(); const message = TestUtils.generateChatMessage(); const rawMessage = MessageUtils.toRawMessage(device, message); @@ -90,15 +90,15 @@ describe('PendingMessageCache', () => { it('can get devices', async () => { const cacheItems = [ { - device: TestUtils.generateFakePubkey(), + device: TestUtils.generateFakePubKey(), message: TestUtils.generateChatMessage(), }, { - device: TestUtils.generateFakePubkey(), + device: TestUtils.generateFakePubKey(), message: TestUtils.generateChatMessage(), }, { - device: TestUtils.generateFakePubkey(), + device: TestUtils.generateFakePubKey(), message: TestUtils.generateChatMessage(), }, ]; @@ -122,11 +122,11 @@ describe('PendingMessageCache', () => { it('can get pending for device', async () => { const cacheItems = [ { - device: TestUtils.generateFakePubkey(), + device: TestUtils.generateFakePubKey(), message: TestUtils.generateChatMessage(), }, { - device: TestUtils.generateFakePubkey(), + device: TestUtils.generateFakePubKey(), message: TestUtils.generateChatMessage(), }, ]; @@ -149,7 +149,7 @@ describe('PendingMessageCache', () => { }); it('can find nothing when empty', async () => { - const device = TestUtils.generateFakePubkey(); + const device = TestUtils.generateFakePubKey(); const message = TestUtils.generateChatMessage(); const rawMessage = MessageUtils.toRawMessage(device, message); @@ -158,7 +158,7 @@ describe('PendingMessageCache', () => { }); it('can find message in cache', async () => { - const device = TestUtils.generateFakePubkey(); + const device = TestUtils.generateFakePubKey(); const message = TestUtils.generateChatMessage(); const rawMessage = MessageUtils.toRawMessage(device, message); @@ -175,15 +175,15 @@ describe('PendingMessageCache', () => { it('can clear cache', async () => { const cacheItems = [ { - device: TestUtils.generateFakePubkey(), + device: TestUtils.generateFakePubKey(), message: TestUtils.generateChatMessage(), }, { - device: TestUtils.generateFakePubkey(), + device: TestUtils.generateFakePubKey(), message: TestUtils.generateChatMessage(), }, { - device: TestUtils.generateFakePubkey(), + device: TestUtils.generateFakePubKey(), message: TestUtils.generateChatMessage(), }, ]; @@ -205,15 +205,15 @@ describe('PendingMessageCache', () => { it('can restore from db', async () => { const cacheItems = [ { - device: TestUtils.generateFakePubkey(), + device: TestUtils.generateFakePubKey(), message: TestUtils.generateChatMessage(), }, { - device: TestUtils.generateFakePubkey(), + device: TestUtils.generateFakePubKey(), message: TestUtils.generateChatMessage(), }, { - device: TestUtils.generateFakePubkey(), + device: TestUtils.generateFakePubKey(), message: TestUtils.generateChatMessage(), }, ]; diff --git a/ts/test/test-utils/testUtils.ts b/ts/test/test-utils/testUtils.ts index 68e63a1a0..737b3690f 100644 --- a/ts/test/test-utils/testUtils.ts +++ b/ts/test/test-utils/testUtils.ts @@ -69,7 +69,7 @@ export function restoreStubs() { sandbox.restore(); } -export function generateFakePubkey(): PubKey { +export function generateFakePubKey(): PubKey { // Generates a mock pubkey for testing const numBytes = PubKey.PUBKEY_LEN / 2 - 1; const hexBuffer = crypto.randomBytes(numBytes).toString('hex'); @@ -79,8 +79,12 @@ export function generateFakePubkey(): PubKey { } export function generateFakePubKeys(amount: number): Array { + const numPubKeys = amount > 0 + ? Math.floor(amount) + : 0; + // tslint:disable-next-line: no-unnecessary-callback-wrapper - return new Array(amount).fill(0).map(() => generateFakePubkey()); + return new Array(numPubKeys).fill(0).map(() => generateFakePubKey()); } export function generateChatMessage(): ChatMessage { @@ -118,15 +122,8 @@ export function generateClosedGroupMessage( ): ClosedGroupChatMessage { return new ClosedGroupChatMessage({ identifier: uuid(), - groupId: groupId ?? generateFakePubkey().key, + groupId: groupId ?? generateFakePubKey().key, chatMessage: generateChatMessage(), }); } -export function generateMemberList(size: number): Array { - const numMembers = Math.floor(size); - - return numMembers > 0 - ? Array.from({ length: numMembers }, generateFakePubkey) - : []; -}