diff --git a/app/sql.js b/app/sql.js index 276746a25..7b5fa4363 100644 --- a/app/sql.js +++ b/app/sql.js @@ -171,6 +171,7 @@ module.exports = { getSenderKeys, createOrUpdateSenderKeys, + removeAllClosedGroupRatchets, }; function generateUUID() { @@ -923,6 +924,12 @@ async function createOrUpdateSenderKeys(data) { ); } +async function removeAllClosedGroupRatchets(groupId) { + await db.run(`DELETE FROM ${SENDER_KEYS_TABLE} WHERE groupId = $groupId;`, { + $groupId: groupId, + }); +} + async function updateToLokiSchemaVersion4(currentVersion, instance) { if (currentVersion >= 4) { return; diff --git a/js/modules/data.d.ts b/js/modules/data.d.ts index 0b344b121..b19fb4c5a 100644 --- a/js/modules/data.d.ts +++ b/js/modules/data.d.ts @@ -412,3 +412,4 @@ export function getMessagesWithFileAttachments( // Sender Keys export function getSenderKeys(groupId: any, senderIdentity: any): Promise; export function createOrUpdateSenderKeys(data: any): Promise; +export function removeAllClosedGroupRatchets(groupId: string): Promise; diff --git a/js/modules/data.js b/js/modules/data.js index 8111770f5..c135bf44c 100644 --- a/js/modules/data.js +++ b/js/modules/data.js @@ -196,6 +196,7 @@ module.exports = { getSenderKeys, createOrUpdateSenderKeys, + removeAllClosedGroupRatchets, }; function init() { @@ -704,6 +705,10 @@ async function createOrUpdateSenderKeys(data) { await channels.createOrUpdateSenderKeys(data); } +async function removeAllClosedGroupRatchets(groupId) { + await channels.removeAllClosedGroupRatchets(groupId); +} + // Sessions async function createOrUpdateSession(data) { diff --git a/ts/components/session/LeftPaneMessageSection.tsx b/ts/components/session/LeftPaneMessageSection.tsx index 2e3d525e2..e426099a1 100644 --- a/ts/components/session/LeftPaneMessageSection.tsx +++ b/ts/components/session/LeftPaneMessageSection.tsx @@ -307,12 +307,7 @@ export class LeftPaneMessageSection extends React.Component { onButtonClick={async ( groupName: string, groupMembers: Array - ) => - this.onCreateClosedGroup( - groupName, - groupMembers - ) - } + ) => this.onCreateClosedGroup(groupName, groupMembers)} searchTerm={searchTerm} updateSearch={this.updateSearchBound} showSpinner={loading} @@ -497,13 +492,9 @@ export class LeftPaneMessageSection extends React.Component { groupName: string, groupMembers: Array ) { - await MainViewController.createClosedGroup( - groupName, - groupMembers, - () => { - this.handleToggleOverlay(undefined); - } - ); + await MainViewController.createClosedGroup(groupName, groupMembers, () => { + this.handleToggleOverlay(undefined); + }); } private handleNewSessionButtonClick() { diff --git a/ts/receiver/contentMessage.ts b/ts/receiver/contentMessage.ts index b32505438..5a6a61ca4 100644 --- a/ts/receiver/contentMessage.ts +++ b/ts/receiver/contentMessage.ts @@ -19,7 +19,6 @@ import { BlockedNumberController } from '../util/blockedNumberController'; import { decryptWithSenderKey } from '../session/medium_group/ratchet'; import { StringUtils } from '../session/utils'; import { UserUtil } from '../util'; -import { getMessageQueue } from '../session'; export async function handleContentMessage(envelope: EnvelopePlus) { try { @@ -310,7 +309,7 @@ async function decrypt( const requestKeysMessage = new MediumGroupRequestKeysMessage(params); const sender = new PubKey(senderIdentity); - void getMessageQueue().send(sender, requestKeysMessage); + void libsession.getMessageQueue().send(sender, requestKeysMessage); return; } diff --git a/ts/receiver/dataMessage.ts b/ts/receiver/dataMessage.ts index 31f3f7cbf..ea8049a71 100644 --- a/ts/receiver/dataMessage.ts +++ b/ts/receiver/dataMessage.ts @@ -279,10 +279,7 @@ export async function handleDataMessage( envelope: EnvelopePlus, dataMessage: SignalService.IDataMessage ): Promise { - window.log.info( - 'data message from', - getEnvelopeId(envelope) - ); + window.log.info('data message from', getEnvelopeId(envelope)); if (dataMessage.mediumGroupUpdate) { await handleMediumGroupUpdate(envelope, dataMessage.mediumGroupUpdate); diff --git a/ts/receiver/mediumGroups.ts b/ts/receiver/mediumGroups.ts index db6dd0d1d..5c1cffd52 100644 --- a/ts/receiver/mediumGroups.ts +++ b/ts/receiver/mediumGroups.ts @@ -13,7 +13,10 @@ import { BufferType } from '../session/utils/String'; import { MultiDeviceProtocol } from '../session/protocols'; import { ConversationModel } from '../../js/models/conversations'; import { UserUtil } from '../util'; -import { RatchetState } from '../session/medium_group/senderKeys'; +import { + createSenderKeyForGroup, + RatchetState, +} from '../session/medium_group/senderKeys'; const toHex = (d: BufferType) => StringUtils.decode(d, 'hex'); const fromHex = (d: string) => StringUtils.encode(d, 'hex'); @@ -344,6 +347,18 @@ async function handleMediumGroupChange( await convo.commit(); + if (diff.leavingMembers && diff.leavingMembers.length > 0) { + // Send out the user's new ratchet to all members (minus the removed ones) using established channels + const userSenderKey = await createSenderKeyForGroup(groupId, primary); + window.log.warn( + 'Sharing our new senderKey with remainingMembers via message', + members, + userSenderKey + ); + + await shareSenderKeys(groupId, members, userSenderKey); + } + await removeFromCache(envelope); } diff --git a/ts/session/medium_group/index.ts b/ts/session/medium_group/index.ts index 0d899a9fe..5a79c84b2 100644 --- a/ts/session/medium_group/index.ts +++ b/ts/session/medium_group/index.ts @@ -641,7 +641,8 @@ async function sendGroupUpdateForMedium( getMessageQueue().events.addListener('success', async message => { if (message.identifier === params.identifier) { // console.log('Our first message encrypted with old sk is sent.'); - // TODO Delete all ratchets (it's important that this happens * after * sending out the update) + // Delete all ratchets (it's important that this happens * after * sending out the update) + await Data.removeAllClosedGroupRatchets(groupId); if (isUserLeaving) { // nothing to do on desktop } else { diff --git a/ts/session/medium_group/ratchet.ts b/ts/session/medium_group/ratchet.ts index e64fd5ffd..4b3c35dbd 100644 --- a/ts/session/medium_group/ratchet.ts +++ b/ts/session/medium_group/ratchet.ts @@ -20,7 +20,8 @@ async function queueJobForNumber(number: string, runJob: any) { // tslint:disable-next-line no-dynamic-delete delete jobQueue[number]; } - }).catch((e: any) => { + }) + .catch((e: any) => { window.log.error('queueJobForNumber() Caught error', e); }); return runCurrent;