diff --git a/_locales/de/messages.json b/_locales/de/messages.json index 195f0a389..1a43346b3 100644 --- a/_locales/de/messages.json +++ b/_locales/de/messages.json @@ -1441,9 +1441,6 @@ "displayNameEmpty": { "message": "Bitte wählen Sie einen Anzeigenamen" }, - "newClosedGroupDescription": { - "message": "Geschlossene Gruppen unterstützen bis zu 10 Mitglieder und bieten den gleichen Schutz der Privatsphäre wie Einzelgespräche." - }, "openGroupURL": { "message": "Gruppen-URL öffnen" }, @@ -1463,6 +1460,6 @@ "message": "Bitte wählen Sie mindestens zwei Gruppenmitglieder aus." }, "closedGroupMaxSize": { - "message": "Eine geschlossene Gruppe kann maximal zehn Mitglieder haben." + "message": "Eine geschlossene Gruppe kann maximal zwanzig Mitglieder haben." } } \ No newline at end of file diff --git a/_locales/en/messages.json b/_locales/en/messages.json index d4c769bfc..eae22794f 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -2124,10 +2124,6 @@ "message": "New Closed Group", "androidKey": "activity_create_closed_group_title" }, - "newClosedGroupDescription": { - "message": "Closed groups support up to 10 members and provide the same privacy protections as one-on-one sessions.", - "androidKey": "activity_create_closed_group_explanation" - }, "createClosedGroupNamePrompt": { "message": "Group Name", "androidKey": "GroupCreateActivity_group_name_hint", @@ -2178,7 +2174,7 @@ "androidKey": "activity_create_closed_group_not_enough_group_members_error" }, "closedGroupMaxSize": { - "message": "A closed group cannot have more than 10 members", + "message": "A closed group cannot have more than 20 members", "androidKey": "activity_create_closed_group_too_many_group_members_error" }, "noBlockedContacts": { diff --git a/_locales/es/messages.json b/_locales/es/messages.json index df84afe81..65a7f9e15 100644 --- a/_locales/es/messages.json +++ b/_locales/es/messages.json @@ -1378,9 +1378,6 @@ "newClosedGroup": { "message": "Nuevo grupo cerrado" }, - "newClosedGroupDescription": { - "message": "Los grupos cerrados admiten hasta 10 miembros y brindan las mismas protecciones de privacidad que las sesiones individuales." - }, "createClosedGroupNamePrompt": { "message": "Nombre Del Grupo" }, @@ -1409,6 +1406,6 @@ "message": "Por favor, elige al menos 2 miembros del grupo" }, "closedGroupMaxSize": { - "message": "Un grupo cerrado no puede tener más de 10 miembros" + "message": "Un grupo cerrado no puede tener más de 20 miembros" } } \ No newline at end of file diff --git a/_locales/fr/messages.json b/_locales/fr/messages.json index 9a3671a8f..6afa73eb3 100644 --- a/_locales/fr/messages.json +++ b/_locales/fr/messages.json @@ -1378,9 +1378,6 @@ "newClosedGroup": { "message": "Nouveau groupe privé" }, - "newClosedGroupDescription": { - "message": "Les groupes privés prennent en charge jusqu'à 10 membres et offrent le même niveau de confidentialité que les sessions individuelles." - }, "createClosedGroupNamePrompt": { "message": "Nom du groupe" }, @@ -1409,7 +1406,7 @@ "message": "Veuillez sélectionner au moins 2 membres" }, "closedGroupMaxSize": { - "message": "Un groupe privé ne peut pas avoir plus de 10 membres" + "message": "Un groupe privé ne peut pas avoir plus de 20 membres" }, "contextMenuNoSuggestions": { "message": "Pas de suggestions", diff --git a/_locales/id/messages.json b/_locales/id/messages.json index feb840cba..cc6f448be 100644 --- a/_locales/id/messages.json +++ b/_locales/id/messages.json @@ -1372,9 +1372,6 @@ "newClosedGroup": { "message": "Grup tertutup baru" }, - "newClosedGroupDescription": { - "message": "Grup tertutup maksimal berisi 10 anggota dan memiliki perlindungan privasi yang sama dengan Session antara dua pengguna" - }, "createClosedGroupNamePrompt": { "message": "Nama grup" }, @@ -1403,7 +1400,7 @@ "message": "Pilih setidaknya 2 anggota grup" }, "closedGroupMaxSize": { - "message": "Grup tertutup maksimal berisi 10 anggota" + "message": "Grup tertutup maksimal berisi 20 anggota" }, "noBlockedContacts": { "message": "Tidak ada kontak yang diblokir" diff --git a/_locales/it/messages.json b/_locales/it/messages.json index 8dcad0ac6..1f19d5d2c 100644 --- a/_locales/it/messages.json +++ b/_locales/it/messages.json @@ -1378,9 +1378,6 @@ "newClosedGroup": { "message": "Nuovo gruppo chiuso" }, - "newClosedGroupDescription": { - "message": "I gruppi chiusi supportano fino a 10 membri e forniscono le stesse protezioni per la privacy delle sessioni one-to-one." - }, "createClosedGroupNamePrompt": { "message": "Nome Del Gruppo" }, @@ -1409,6 +1406,6 @@ "message": "Scegli almeno 2 membri del gruppo" }, "closedGroupMaxSize": { - "message": "Un gruppo chiuso non può avere più di 10 membri" + "message": "Un gruppo chiuso non può avere più di 20 membri" } } \ No newline at end of file diff --git a/_locales/ja/messages.json b/_locales/ja/messages.json index c7b5def55..e5b9a9225 100644 --- a/_locales/ja/messages.json +++ b/_locales/ja/messages.json @@ -1378,9 +1378,6 @@ "newClosedGroup": { "message": "新しいクローズドグループ" }, - "newClosedGroupDescription": { - "message": "クローズドグループは最大 10 人のメンバーをサポートし、1 対 1 の Session と同じプライバシー保護を提供します。" - }, "createClosedGroupNamePrompt": { "message": "グループ名" }, @@ -1409,7 +1406,7 @@ "message": "グループメンバーを少なくとも 2 人選択してください" }, "closedGroupMaxSize": { - "message": "閉じたグループは 10 人を超えるメンバーを抱えることはできません" + "message": "閉じたグループは 20 人を超えるメンバーを抱えることはできません" }, "noBlockedContacts": { "message": "ブロックしている連絡先はありません" diff --git a/_locales/pl/messages.json b/_locales/pl/messages.json index e86d406f0..f48ccaa4b 100644 --- a/_locales/pl/messages.json +++ b/_locales/pl/messages.json @@ -1378,9 +1378,6 @@ "newClosedGroup": { "message": "Nowa grupa zamknięta" }, - "newClosedGroupDescription": { - "message": "Grupy zamknięte obsługują do 10 członków i zapewniają taką samą ochronę prywatności jak sesje jeden na jednego." - }, "createClosedGroupNamePrompt": { "message": "Nazwa grupy" }, @@ -1406,7 +1403,7 @@ "message": "Wprowadź krótszą nazwę grupy" }, "closedGroupMaxSize": { - "message": "Grupa zamknięta nie może mieć więcej niż 10 członków" + "message": "Grupa zamknięta nie może mieć więcej niż 20 członków" }, "noBlockedContacts": { "message": "Brak zablokowanych kontaktów" diff --git a/_locales/pt_BR/messages.json b/_locales/pt_BR/messages.json index e6e1df9b3..3b2d32270 100644 --- a/_locales/pt_BR/messages.json +++ b/_locales/pt_BR/messages.json @@ -1378,9 +1378,6 @@ "newClosedGroup": { "message": "Novo grupo fechado" }, - "newClosedGroupDescription": { - "message": "Grupos fechados suportam até 10 membros e fornecem as mesmas proteções de privacidade que as sessões individuais." - }, "createClosedGroupNamePrompt": { "message": "Nome Do Grupo" }, @@ -1409,6 +1406,6 @@ "message": "Escolha pelo menos 2 membros do grupo" }, "closedGroupMaxSize": { - "message": "Um grupo fechado não pode ter mais de 10 membros" + "message": "Um grupo fechado não pode ter mais de 20 membros" } } \ No newline at end of file diff --git a/_locales/ru/messages.json b/_locales/ru/messages.json index 64252ccd1..a319d95e0 100644 --- a/_locales/ru/messages.json +++ b/_locales/ru/messages.json @@ -1378,9 +1378,6 @@ "newClosedGroup": { "message": "Новая закрытая группа" }, - "newClosedGroupDescription": { - "message": "Закрытые группы поддерживают до 10 участников и обеспечивают те же меры защиты конфиденциальности, что и сессии один-на-один." - }, "createClosedGroupNamePrompt": { "message": "Название Группы" }, @@ -1409,7 +1406,7 @@ "message": "Пожалуйста, выберите как минимум 1 участников группы" }, "closedGroupMaxSize": { - "message": "В закрытой группе не может быть больше 10 участников" + "message": "В закрытой группе не может быть больше 20 участников" }, "contextMenuNoSuggestions": { "message": "No Suggestions", diff --git a/_locales/vi/messages.json b/_locales/vi/messages.json index 1a287b89f..dcd2c9cc2 100644 --- a/_locales/vi/messages.json +++ b/_locales/vi/messages.json @@ -1339,9 +1339,6 @@ "newClosedGroup": { "message": "Nhóm kín mới" }, - "newClosedGroupDescription": { - "message": "Nhóm kín hỗ trợ tối đa 10 thành viên và cung cấp dịch vụ bảo mật giống như các session một-một" - }, "createClosedGroupNamePrompt": { "message": "Tên nhóm" }, @@ -1367,6 +1364,6 @@ "message": "Vui lòng chọn ít nhất 2 thành viên trong nhóm" }, "closedGroupMaxSize": { - "message": "Một nhóm kín không thể có nhiều hơn 10 thành viên" + "message": "Một nhóm kín không thể có nhiều hơn 20 thành viên" } } \ No newline at end of file diff --git a/js/background.js b/js/background.js index 567e1d83f..b89561c0e 100644 --- a/js/background.js +++ b/js/background.js @@ -991,22 +991,21 @@ return; } - const serverAPI = await window.lokiPublicChatAPI.findOrCreateServer( - sslServerUrl - ); - if (!serverAPI) { - window.log.warn(`Could not connect to ${serverAddress}`); - return; - } - const conversation = await ConversationController.getOrCreateAndWait( conversationId, 'group' ); - - serverAPI.findOrCreateChannel(channelId, conversationId); await conversation.setPublicSource(sslServerUrl, channelId); + const channelAPI = await window.lokiPublicChatAPI.findOrCreateChannel( + sslServerUrl, + channelId, + conversationId + ); + if (!channelAPI) { + window.log.warn(`Could not connect to ${serverAddress}`); + return; + } appView.openConversation(conversationId, {}); } ); diff --git a/js/views/conversation_view.js b/js/views/conversation_view.js index 0c109e480..c2752c2bf 100644 --- a/js/views/conversation_view.js +++ b/js/views/conversation_view.js @@ -270,7 +270,6 @@ }; }; const getGroupSettingsProps = () => { - const ourPK = window.textsecure.storage.user.getNumber(); const members = this.model.get('members') || []; return { @@ -281,7 +280,7 @@ avatarPath: this.model.getAvatarPath(), isGroup: !this.model.isPrivate(), isPublic: this.model.isPublic(), - isAdmin: this.model.get('groupAdmins').includes(ourPK), + isAdmin: true, // allow closed group edits from anyone this.model.get('groupAdmins').includes(ourPK), isRss: this.model.isRss(), memberCount: members.length, amMod: this.model.isModerator( diff --git a/js/views/create_group_dialog_view.js b/js/views/create_group_dialog_view.js index fdc1b688e..6a0f5715b 100644 --- a/js/views/create_group_dialog_view.js +++ b/js/views/create_group_dialog_view.js @@ -21,9 +21,8 @@ this.members = groupConvo.get('members') || []; this.avatarPath = groupConvo.getAvatarPath(); - const ourPK = textsecure.storage.user.getNumber(); - - this.isAdmin = groupConvo.get('groupAdmins').includes(ourPK); + // any member can update a closed group name + this.isAdmin = true; // public chat settings overrides if (this.isPublic) { @@ -79,7 +78,6 @@ Whisper.UpdateGroupMembersDialogView = Whisper.View.extend({ className: 'loki-dialog modal', initialize(groupConvo) { - const ourPK = textsecure.storage.user.getNumber(); this.groupName = groupConvo.get('name'); this.close = this.close.bind(this); this.onSubmit = this.onSubmit.bind(this); @@ -99,7 +97,8 @@ this.existingMembers = []; } else { this.titleText = i18n('updateGroupDialogTitle', this.groupName); - this.isAdmin = groupConvo.get('groupAdmins').includes(ourPK); + // anybody can edit a closed group name or members + this.isAdmin = true; const convos = window.getConversations().models.filter(d => !!d); this.existingMembers = groupConvo.get('members') || []; diff --git a/js/views/invite_contacts_dialog_view.js b/js/views/invite_contacts_dialog_view.js index c21c8924c..a79adc2dc 100644 --- a/js/views/invite_contacts_dialog_view.js +++ b/js/views/invite_contacts_dialog_view.js @@ -80,12 +80,9 @@ // Do not trigger an update if there is too many members if ( newMembers.length + existingMembers.length > - window.CONSTANTS.SMALL_GROUP_SIZE_LIMIT + window.CONSTANTS.MEDIUM_GROUP_SIZE_LIMIT ) { - const msg = window.i18n( - 'closedGroupMaxSize', - window.CONSTANTS.SMALL_GROUP_SIZE_LIMIT - ); + const msg = window.i18n('closedGroupMaxSize'); window.pushToast({ title: msg, diff --git a/package.json b/package.json index f40212456..4626af6d0 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "session-messenger-desktop", "productName": "Session", "description": "Private messaging from your desktop", - "version": "1.3.1", + "version": "1.4.0", "license": "GPL-3.0", "author": { "name": "Loki Project", diff --git a/preload.js b/preload.js index ae826f80b..86eca4ccc 100644 --- a/preload.js +++ b/preload.js @@ -86,7 +86,7 @@ window.CONSTANTS = new (function() { this.MAX_CONNECTION_DURATION = 5000; this.MAX_MESSAGE_BODY_LENGTH = 64 * 1024; // Limited due to the proof-of-work requirement - this.SMALL_GROUP_SIZE_LIMIT = 10; + this.MEDIUM_GROUP_SIZE_LIMIT = 20; // Number of seconds to turn on notifications after reconnect/start of app this.NOTIFICATION_ENABLE_TIMEOUT_SECONDS = 10; this.SESSION_ID_LENGTH = 66; @@ -451,7 +451,7 @@ window.lokiFeatureFlags = { useSnodeProxy: !process.env.USE_STUBBED_NETWORK, useOnionRequests: true, useFileOnionRequests: true, - enableSenderKeys: false, + enableSenderKeys: true, onionRequestHops: 3, debugMessageLogs: process.env.ENABLE_MESSAGE_LOGS, useMultiDevice: false, @@ -490,7 +490,7 @@ if (config.environment.includes('test-integration')) { useOnionRequests: false, useFileOnionRequests: false, debugMessageLogs: true, - enableSenderKeys: false, + enableSenderKeys: true, useMultiDevice: false, }; /* eslint-disable global-require, import/no-extraneous-dependencies */ diff --git a/stylesheets/_session.scss b/stylesheets/_session.scss index 79e868d7d..10cfb00ba 100644 --- a/stylesheets/_session.scss +++ b/stylesheets/_session.scss @@ -656,6 +656,10 @@ label { } } + .group-member-list__selection { + overflow-y: auto; + } + &__centered { display: flex; flex-direction: column; @@ -1423,15 +1427,8 @@ input { text-align: center; padding: 20px; } - - // Height at which scroll bar appears on the group member list - @media (max-height: 804px) { - &__container { - overflow-y: visible; - max-height: none; - } - } } + .create-group-name-input { display: flex; justify-content: center; diff --git a/ts/components/MainViewController.tsx b/ts/components/MainViewController.tsx index 048a61231..cdc0086e6 100644 --- a/ts/components/MainViewController.tsx +++ b/ts/components/MainViewController.tsx @@ -83,7 +83,7 @@ async function createClosedGroup( }); return; - } else if (groupMembers.length >= window.CONSTANTS.SMALL_GROUP_SIZE_LIMIT) { + } else if (groupMembers.length >= window.CONSTANTS.MEDIUM_GROUP_SIZE_LIMIT) { ToastUtils.push({ title: window.i18n('closedGroupMaxSize'), type: 'error', diff --git a/ts/components/conversation/CreateGroupDialog.tsx b/ts/components/conversation/CreateGroupDialog.tsx index 9ea4baa47..2ed654fe7 100644 --- a/ts/components/conversation/CreateGroupDialog.tsx +++ b/ts/components/conversation/CreateGroupDialog.tsx @@ -8,7 +8,7 @@ import { createLegacyGroup } from '../../session/medium_group'; declare global { interface Window { Lodash: any; - SMALL_GROUP_SIZE_LIMIT: number; + MEDIUM_GROUP_SIZE_LIMIT: number; } } @@ -200,11 +200,9 @@ export class CreateGroupDialog extends React.Component { if ( updatedContacts.filter(d => d.checkmarked).length > - window.CONSTANTS.SMALL_GROUP_SIZE_LIMIT - 1 + window.CONSTANTS.MEDIUM_GROUP_SIZE_LIMIT - 1 ) { - const msg = `${this.props.i18n('closedGroupMaxSize')} ${ - window.CONSTANTS.SMALL_GROUP_SIZE_LIMIT - }`; + const msg = this.props.i18n('closedGroupMaxSize'); this.onShowError(msg); return; diff --git a/ts/components/session/SessionClosableOverlay.tsx b/ts/components/session/SessionClosableOverlay.tsx index 342859376..3c1008f81 100644 --- a/ts/components/session/SessionClosableOverlay.tsx +++ b/ts/components/session/SessionClosableOverlay.tsx @@ -151,7 +151,6 @@ export class SessionClosableOverlay extends React.Component { case 'closed-group': title = window.i18n('newClosedGroup'); buttonText = window.i18n('done'); - descriptionLong = window.i18n('newClosedGroupDescription'); subtitle = window.i18n('createClosedGroupNamePrompt'); placeholder = window.i18n('createClosedGroupPlaceholder'); break; diff --git a/ts/components/session/SessionGroupSettings.tsx b/ts/components/session/SessionGroupSettings.tsx index 2f182c9ca..e1095c55f 100644 --- a/ts/components/session/SessionGroupSettings.tsx +++ b/ts/components/session/SessionGroupSettings.tsx @@ -245,7 +245,7 @@ class SessionGroupSettings extends React.Component { const showUpdateGroupNameButton = isPublic && !isKickedFromGroup ? amMod && !isBlocked - : isAdmin && !isBlocked; + : isAdmin && !isBlocked && !isKickedFromGroup; const showUpdateGroupMembersButton = !isPublic && !isKickedFromGroup && !isBlocked && isAdmin; diff --git a/ts/receiver/groups.ts b/ts/receiver/groups.ts index 2c74f92a0..df5a70a28 100644 --- a/ts/receiver/groups.ts +++ b/ts/receiver/groups.ts @@ -85,9 +85,8 @@ export async function preprocessGroupMessage( if (newGroup) { conversation.updateGroupAdmins(group.admins); } else { - // be sure to drop a message from a non admin if it tries to change group members - // or change the group name - const fromAdmin = conversation.get('groupAdmins').includes(primarySource); + // group members and names can be changed from any member + const fromAdmin = true; if (!fromAdmin) { // Make sure the message is not removing members / renaming the group diff --git a/ts/receiver/mediumGroups.ts b/ts/receiver/mediumGroups.ts index 021bdcb31..810e6340e 100644 --- a/ts/receiver/mediumGroups.ts +++ b/ts/receiver/mediumGroups.ts @@ -308,7 +308,7 @@ async function handleMediumGroupChange( } // // Check that the sender is admin (make sure it words with multidevice) - const isAdmin = curAdmins.includes(senderIdentity); + const isAdmin = true; if (!isAdmin) { log.warn('Rejected attempt to update a group by non-admin'); @@ -317,7 +317,7 @@ async function handleMediumGroupChange( } // NOTE: right now, we don't expect admins to change - const admins = adminsBinary.map(toHex); + // const admins = adminsBinary.map(toHex); const members = membersBinary.map(toHex); const diff = SenderKeyAPI.calculateGroupDiff(convo, { name, members }); diff --git a/ts/session/messages/outgoing/content/data/ExpirationTimerUpdateMessage.ts b/ts/session/messages/outgoing/content/data/ExpirationTimerUpdateMessage.ts index 2da6fc6b3..88eb245f4 100644 --- a/ts/session/messages/outgoing/content/data/ExpirationTimerUpdateMessage.ts +++ b/ts/session/messages/outgoing/content/data/ExpirationTimerUpdateMessage.ts @@ -37,9 +37,13 @@ export class ExpirationTimerUpdateMessage extends DataMessage { if (this.groupId) { const groupMessage = new SignalService.GroupContext(); - groupMessage.id = new Uint8Array( - StringUtils.encode(this.groupId.key, 'utf8') - ); + let groupIdWithPrefix: string = this.groupId.key; + if (!this.groupId.key.startsWith(PubKey.PREFIX_GROUP_TEXTSECURE)) { + groupIdWithPrefix = PubKey.PREFIX_GROUP_TEXTSECURE + this.groupId.key; + } + const encoded = StringUtils.encode(groupIdWithPrefix, 'utf8'); + const id = new Uint8Array(encoded); + groupMessage.id = id; groupMessage.type = SignalService.GroupContext.Type.DELIVER; data.group = groupMessage; diff --git a/ts/session/snode_api/serviceNodeAPI.ts b/ts/session/snode_api/serviceNodeAPI.ts index 6b96520f9..ea7d610f3 100644 --- a/ts/session/snode_api/serviceNodeAPI.ts +++ b/ts/session/snode_api/serviceNodeAPI.ts @@ -327,6 +327,15 @@ export async function storeOnNode( return false; } else if (e instanceof textsecure.WrongDifficultyError) { const { newDifficulty } = e; + // difficulty of 100 happens when a snode restarts. We have to exit the loop and markNodeUnreachable() + if (newDifficulty === 100) { + log.warn( + 'loki_message:::storeOnNode - invalid new difficulty:100. Marking node as bad.' + ); + successiveFailures = MAX_ACCEPTABLE_FAILURES; + continue; + } + if (!Number.isNaN(newDifficulty)) { window.storage.put('PoWDifficulty', newDifficulty); }