enable explicit group updates on the sending side

This commit is contained in:
Audric Ackermann 2021-02-08 14:04:34 +11:00
parent 9400ec9e1c
commit aede96b69b
No known key found for this signature in database
GPG key ID: 999F434D76324AD4
4 changed files with 9 additions and 128 deletions

View file

@ -448,7 +448,6 @@ window.lokiFeatureFlags = {
useFileOnionRequests: true,
useFileOnionRequestsV2: true, // more compact encoding of files in response
onionRequestHops: 3,
useExplicitGroupUpdatesSending: false,
};
// eslint-disable-next-line no-extend-native,func-names
@ -482,7 +481,6 @@ if (config.environment.includes('test-integration')) {
useOnionRequests: false,
useFileOnionRequests: false,
useOnionRequestsV2: false,
useExplicitGroupUpdatesSending: false,
};
/* eslint-disable global-require, import/no-extraneous-dependencies */
window.sinon = require('sinon');

View file

@ -473,6 +473,9 @@ async function performIfValid(
}
if (groupUpdate.type === Type.UPDATE) {
window.log.warn(
'Received a groupUpdate non explicit. This should not happen anymore.'
);
await handleUpdateClosedGroup(envelope, groupUpdate, convo);
} else if (groupUpdate.type === Type.NAME_CHANGE) {
await handleClosedGroupNameChanged(envelope, groupUpdate, convo);

View file

@ -122,111 +122,6 @@ export async function initiateGroupUpdate(
expireTimer: convo.get('expireTimer'),
};
if (!window.lokiFeatureFlags.useExplicitGroupUpdatesSending) {
// we still don't send any explicit group updates for now - only the receiving side is enabled
const dbMessageAdded = await addUpdateMessage(convo, diff, 'outgoing');
window.getMessageController().register(dbMessageAdded.id, dbMessageAdded);
// Check preconditions
const hexEncryptionKeyPair = await Data.getLatestClosedGroupEncryptionKeyPair(
groupId
);
if (!hexEncryptionKeyPair) {
throw new Error("Couldn't get key pair for closed group");
}
const encryptionKeyPair = ECKeyPair.fromHexKeyPair(hexEncryptionKeyPair);
const removedMembers = diff.leavingMembers || [];
const newMembers = diff.joiningMembers || []; // joining members
const wasAnyUserRemoved = removedMembers.length > 0;
const ourPrimary = await UserUtils.getOurNumber();
const isUserLeaving = removedMembers.includes(ourPrimary.key);
const isCurrentUserAdmin = convo
.get('groupAdmins')
?.includes(ourPrimary.key);
const expireTimerToShare = groupDetails.expireTimer || 0;
const admins = convo.get('groupAdmins') || [];
if (removedMembers.includes(admins[0]) && newMembers.length !== 0) {
throw new Error(
"Can't remove admin from closed group without removing everyone."
); // Error.invalidClosedGroupUpdate
}
if (isUserLeaving && newMembers.length !== 0) {
if (removedMembers.length !== 1 || newMembers.length !== 0) {
throw new Error(
"Can't remove self and add or remove others simultaneously."
);
}
}
// Send the update to the group
const mainClosedGroupUpdate = new ClosedGroupUpdateMessage({
timestamp: Date.now(),
groupId,
name: groupName,
members,
identifier: dbMessageAdded.id || uuid(),
expireTimer: expireTimerToShare,
});
if (isUserLeaving) {
window.log.info(
`We are leaving the group ${groupId}. Sending our leaving message.`
);
// sent the message to the group and once done, remove everything related to this group
window.SwarmPolling.removePubkey(groupId);
await getMessageQueue().sendToGroup(mainClosedGroupUpdate, async () => {
window.log.info(
`Leaving message sent ${groupId}. Removing everything related to this group.`
);
await Data.removeAllClosedGroupEncryptionKeyPairs(groupId);
});
} else {
// Send the group update, and only once sent, generate and distribute a new encryption key pair if needed
await getMessageQueue().sendToGroup(mainClosedGroupUpdate, async () => {
if (wasAnyUserRemoved && isCurrentUserAdmin) {
// we send the new encryption key only to members already here before the update
const membersNotNew = members.filter(m => !newMembers.includes(m));
window.log.info(
`Sending group update: A user was removed from ${groupId} and we are the admin. Generating and sending a new EncryptionKeyPair`
);
await generateAndSendNewEncryptionKeyPair(groupId, membersNotNew);
}
});
if (newMembers.length) {
// Send closed group update messages to any new members individually
const newClosedGroupUpdate = new ClosedGroupNewMessage({
timestamp: Date.now(),
name: groupName,
groupId,
admins,
members,
keypair: encryptionKeyPair,
identifier: dbMessageAdded.id || uuid(),
expireTimer: expireTimerToShare,
});
const promises = newMembers.map(async m => {
await ConversationController.getInstance().getOrCreateAndWait(
m,
'private'
);
const memberPubKey = PubKey.cast(m);
await getMessageQueue().sendToPubKey(
memberPubKey,
newClosedGroupUpdate
);
});
await Promise.all(promises);
}
}
return;
}
if (diff.newName?.length) {
const nameOnlyDiff: GroupDiff = { newName: diff.newName };
const dbMessageName = await addUpdateMessage(
@ -452,26 +347,12 @@ export async function leaveClosedGroup(groupId: string) {
window.getMessageController().register(dbMessage.id, dbMessage);
const existingExpireTimer = convo.get('expireTimer') || 0;
// Send the update to the group
let ourLeavingMessage;
if (window.lokiFeatureFlags.useExplicitGroupUpdatesSending) {
ourLeavingMessage = new ClosedGroupMemberLeftMessage({
timestamp: Date.now(),
groupId,
identifier: dbMessage.id,
expireTimer: existingExpireTimer,
});
} else {
const ourPubkey = await UserUtils.getOurNumber();
ourLeavingMessage = new ClosedGroupUpdateMessage({
timestamp: Date.now(),
groupId,
identifier: dbMessage.id,
expireTimer: existingExpireTimer,
name: convo.get('name'),
members: convo.get('members').filter(m => m !== ourPubkey.key),
});
}
const ourLeavingMessage = new ClosedGroupMemberLeftMessage({
timestamp: Date.now(),
groupId,
identifier: dbMessage.id,
expireTimer: existingExpireTimer,
});
window.log.info(
`We are leaving the group ${groupId}. Sending our leaving message.`

1
ts/window.d.ts vendored
View file

@ -63,7 +63,6 @@ declare global {
useOnionRequestsV2: boolean;
useFileOnionRequests: boolean;
useFileOnionRequestsV2: boolean;
useExplicitGroupUpdatesSending: boolean;
onionRequestHops: number;
};
lokiFileServerAPI: LokiFileServerInstance;