diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 53145bd93..aaf4829d1 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -327,6 +327,7 @@ "leaveGroupConfirmationAdmin": "As you are the admin of this group, if you leave it it will be removed for every current members. Are you sure you want to leave this group?", "cannotRemoveCreatorFromGroup": "Cannot remove this user", "cannotRemoveCreatorFromGroupDesc": "You cannot remove this user as they are the creator of the group.", + "cannotRemoveAdminFromGroup": "Admins cannot be removed", "noContactsForGroup": "You don't have any contacts yet", "failedToAddAsModerator": "Failed to add user as admin", "failedToRemoveFromModerator": "Failed to remove user from the admin list", diff --git a/ts/components/dialog/UpdateGroupMembersDialog.tsx b/ts/components/dialog/UpdateGroupMembersDialog.tsx index 1fdad5c58..6e88916ef 100644 --- a/ts/components/dialog/UpdateGroupMembersDialog.tsx +++ b/ts/components/dialog/UpdateGroupMembersDialog.tsx @@ -249,6 +249,11 @@ export const UpdateGroupMembersDialog = (props: Props) => { return; } if (groupAdmins?.includes(member)) { + if (PubKey.is03Pubkey(conversationId)) { + ToastUtils.pushCannotRemoveAdminFromGroup(); + window?.log?.warn(`User ${member} cannot be removed as they are adn admin.`); + return; + } ToastUtils.pushCannotRemoveCreatorFromGroup(); window?.log?.warn( `User ${member} cannot be removed as they are the creator of the closed group.` diff --git a/ts/session/messages/outgoing/controlMessage/group_v2/to_group/GroupUpdateMemberChangeMessage.ts b/ts/session/messages/outgoing/controlMessage/group_v2/to_group/GroupUpdateMemberChangeMessage.ts index dbb4f3370..f3d6692c4 100644 --- a/ts/session/messages/outgoing/controlMessage/group_v2/to_group/GroupUpdateMemberChangeMessage.ts +++ b/ts/session/messages/outgoing/controlMessage/group_v2/to_group/GroupUpdateMemberChangeMessage.ts @@ -95,16 +95,18 @@ export class GroupUpdateMemberChangeMessage extends GroupUpdateMessage { public dataProto(): SignalService.DataMessage { const { Type } = SignalService.GroupUpdateMemberChangeMessage; + const type: SignalService.GroupUpdateMemberChangeMessage.Type = + this.typeOfChange === 'added' || this.typeOfChange === 'addedWithHistory' + ? Type.ADDED + : this.typeOfChange === 'removed' + ? Type.REMOVED + : Type.PROMOTED; + const memberChangeMessage = new SignalService.GroupUpdateMemberChangeMessage({ - type: - this.typeOfChange === 'added' || this.typeOfChange === 'addedWithHistory' - ? Type.ADDED - : this.typeOfChange === 'removed' - ? Type.REMOVED - : Type.PROMOTED, + type, memberSessionIds: this.memberSessionIds, adminSignature: this.sodium.crypto_sign_detached( - stringToUint8Array(`MEMBER_CHANGE${this.typeOfChange}${this.createAtNetworkTimestamp}`), + stringToUint8Array(`MEMBER_CHANGE${type}${this.createAtNetworkTimestamp}`), this.secretKey ), }); diff --git a/ts/session/sending/MessageSender.ts b/ts/session/sending/MessageSender.ts index ab495712a..6931ba8b2 100644 --- a/ts/session/sending/MessageSender.ts +++ b/ts/session/sending/MessageSender.ts @@ -493,6 +493,8 @@ async function encryptMessageAndWrap( return encryptForGroupV2(params); } + // can only be legacy group or 1o1 chats here + const recipient = PubKey.cast(destination); const { envelopeType, cipherText } = await MessageEncrypter.encrypt( diff --git a/ts/session/utils/Toast.tsx b/ts/session/utils/Toast.tsx index fbaef4056..748d79371 100644 --- a/ts/session/utils/Toast.tsx +++ b/ts/session/utils/Toast.tsx @@ -194,6 +194,10 @@ export function pushCannotRemoveCreatorFromGroup() { pushToastWarning('cannotRemoveCreatorFromGroup', window.i18n('cannotRemoveCreatorFromGroupDesc')); } +export function pushCannotRemoveAdminFromGroup() { + pushToastWarning('cannotRemoveAdminFromGroup', window.i18n('cannotRemoveAdminFromGroup')); +} + export function pushOnlyAdminCanRemove() { pushToastInfo('onlyAdminCanRemoveMembers', window.i18n('onlyAdminCanRemoveMembersDesc')); } diff --git a/ts/state/ducks/metaGroups.ts b/ts/state/ducks/metaGroups.ts index 7d5e0947c..02bb6cf98 100644 --- a/ts/state/ducks/metaGroups.ts +++ b/ts/state/ducks/metaGroups.ts @@ -11,6 +11,7 @@ import { } from 'libsession_util_nodejs'; import { base64_variants, from_base64 } from 'libsodium-wrappers-sumo'; import { intersection, isEmpty, uniq } from 'lodash'; +import { v4 } from 'uuid'; import { ConfigDumpData } from '../../data/configDump/configDump'; import { ConversationModel } from '../../models/conversation'; import { ConversationTypeEnum } from '../../models/conversationAttributes'; @@ -630,6 +631,7 @@ async function getUpdateMessagesToPush({ if (withoutHistory.length) { updateMessages.push( new GroupUpdateMemberChangeMessage({ + identifier: v4(), added: withoutHistory, groupPk, typeOfChange: 'added', @@ -643,6 +645,7 @@ async function getUpdateMessagesToPush({ if (withHistory.length) { updateMessages.push( new GroupUpdateMemberChangeMessage({ + identifier: v4(), added: withHistory, groupPk, typeOfChange: 'addedWithHistory', @@ -656,6 +659,7 @@ async function getUpdateMessagesToPush({ if (removed.length) { updateMessages.push( new GroupUpdateMemberChangeMessage({ + identifier: v4(), removed, groupPk, typeOfChange: 'removed', diff --git a/ts/types/LocalizerKeys.ts b/ts/types/LocalizerKeys.ts index 61e390416..131b88d8b 100644 --- a/ts/types/LocalizerKeys.ts +++ b/ts/types/LocalizerKeys.ts @@ -52,6 +52,7 @@ export type LocalizerKeys = | 'cameraPermissionNeeded' | 'cancel' | 'cannotMixImageAndNonImageAttachments' + | 'cannotRemoveAdminFromGroup' | 'cannotRemoveCreatorFromGroup' | 'cannotRemoveCreatorFromGroupDesc' | 'cannotUpdate'