diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index 916bfda27..21ce72678 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -19,6 +19,8 @@
"editMenuPaste": "Paste",
"editMenuPasteAndMatchStyle": "Paste and Match Style",
"editMenuDelete": "Delete",
+ "editMenuDeleteContact": "Delete Contact",
+ "editMenuDeleteGroup": "Delete Group",
"editMenuSelectAll": "Select all",
"windowMenuClose": "Close Window",
"windowMenuMinimize": "Minimize",
diff --git a/package.json b/package.json
index ae5d8b26d..1e42bd38c 100644
--- a/package.json
+++ b/package.json
@@ -179,7 +179,7 @@
"chai-bytes": "^0.1.2",
"css-loader": "^3.6.0",
"dashdash": "1.14.1",
- "electron": "^13.1.9",
+ "electron": "^13.6.2",
"electron-builder": "22.8.0",
"electron-notarize": "^0.2.0",
"eslint": "4.14.0",
diff --git a/ts/components/basic/SessionIdEditable.tsx b/ts/components/basic/SessionIdEditable.tsx
index b43d8d526..7571ba419 100644
--- a/ts/components/basic/SessionIdEditable.tsx
+++ b/ts/components/basic/SessionIdEditable.tsx
@@ -11,10 +11,21 @@ type Props = {
onPressEnter?: any;
maxLength?: number;
isGroup?: boolean;
+ dataTestId?: string;
};
export const SessionIdEditable = (props: Props) => {
- const { placeholder, onPressEnter, onChange, editable, text, value, maxLength, isGroup } = props;
+ const {
+ placeholder,
+ onPressEnter,
+ onChange,
+ editable,
+ text,
+ value,
+ maxLength,
+ isGroup,
+ dataTestId,
+ } = props;
const inputRef = useRef(null);
useFocusMount(inputRef, editable);
@@ -48,6 +59,7 @@ export const SessionIdEditable = (props: Props) => {
onBlur={handleChange}
value={value || text}
maxLength={maxLength}
+ data-testid={dataTestId}
/>
);
diff --git a/ts/components/conversation/Timestamp.tsx b/ts/components/conversation/Timestamp.tsx
index e277062f8..589593340 100644
--- a/ts/components/conversation/Timestamp.tsx
+++ b/ts/components/conversation/Timestamp.tsx
@@ -13,8 +13,6 @@ type Props = {
isConversationListItem?: boolean;
};
-const UPDATE_FREQUENCY = 60 * 1000;
-
const TimestampContainerListItem = styled.div`
flex-shrink: 0;
margin-inline-start: 6px;
@@ -28,6 +26,8 @@ const TimestampContainerListItem = styled.div`
color: var(--color-text);
`;
+const UPDATE_FREQUENCY = 60 * 1000;
+
const TimestampContainerNotListItem = styled.div`
font-size: 11px;
line-height: 16px;
diff --git a/ts/components/dialog/SessionSeedModal.tsx b/ts/components/dialog/SessionSeedModal.tsx
index 43bafc71d..bba69097a 100644
--- a/ts/components/dialog/SessionSeedModal.tsx
+++ b/ts/components/dialog/SessionSeedModal.tsx
@@ -107,7 +107,7 @@ const Seed = (props: SeedProps) => {
{i18n('recoveryPhraseSavePromptMain')}
-
+
{recoveryPhrase}
diff --git a/ts/components/leftpane/conversation-list-item/ConversationListItem.tsx b/ts/components/leftpane/conversation-list-item/ConversationListItem.tsx
index bbbd100a3..065ae17c4 100644
--- a/ts/components/leftpane/conversation-list-item/ConversationListItem.tsx
+++ b/ts/components/leftpane/conversation-list-item/ConversationListItem.tsx
@@ -19,7 +19,7 @@ import {
useIsPrivate,
} from '../../../hooks/useParamSelector';
import { MemoConversationListItemContextMenu } from '../../menu/ConversationListItemContextMenu';
-import { HeaderItem } from './HeaderItem';
+import { ConversationListItemHeaderItem } from './HeaderItem';
import { MessageItem } from './MessageItem';
// tslint:disable-next-line: no-empty-interface
@@ -127,7 +127,7 @@ const ConversationListItem = (props: Props) => {
>
-
+
diff --git a/ts/components/leftpane/conversation-list-item/HeaderItem.tsx b/ts/components/leftpane/conversation-list-item/HeaderItem.tsx
index c8e69fc72..a50260e5b 100644
--- a/ts/components/leftpane/conversation-list-item/HeaderItem.tsx
+++ b/ts/components/leftpane/conversation-list-item/HeaderItem.tsx
@@ -73,7 +73,7 @@ const ListItemIcons = () => {
);
};
-export const HeaderItem = () => {
+export const ConversationListItemHeaderItem = () => {
const conversationId = useContext(ContextConversationId);
const convoProps = useHeaderItemProps(conversationId);
diff --git a/ts/components/menu/Menu.tsx b/ts/components/menu/Menu.tsx
index f148a6b5c..5dafc5445 100644
--- a/ts/components/menu/Menu.tsx
+++ b/ts/components/menu/Menu.tsx
@@ -196,7 +196,9 @@ export function getDeleteContactMenuItem(
if (isPublic) {
menuItemText = window.i18n('leaveGroup');
} else {
- menuItemText = window.i18n('delete');
+ menuItemText = isGroup
+ ? window.i18n('editMenuDeleteGroup')
+ : window.i18n('editMenuDeleteContact');
}
const onClickClose = () => {
diff --git a/ts/components/registration/SignUpTab.tsx b/ts/components/registration/SignUpTab.tsx
index 7bbb8f3dd..178104b77 100644
--- a/ts/components/registration/SignUpTab.tsx
+++ b/ts/components/registration/SignUpTab.tsx
@@ -70,7 +70,7 @@ const SignUpSessionIDShown = (props: { continueSignUp: () => void }) => {
{window.i18n('yourUniqueSessionID')}
-
+
{window.i18n('allUsersAreRandomly...')}
diff --git a/ts/receiver/dataMessage.ts b/ts/receiver/dataMessage.ts
index 1be4dafac..739ca67c4 100644
--- a/ts/receiver/dataMessage.ts
+++ b/ts/receiver/dataMessage.ts
@@ -362,29 +362,28 @@ export async function isMessageDuplicate({
serverTimestamp,
}: MessageId) {
const { Errors } = window.Signal.Types;
- // serverId is only used for opengroupv2
+ // serverTimestamp is only used for opengroupv2
try {
let result;
if (serverTimestamp) {
// first try to find a duplicate with the same serverTimestamp from this sender
- if (serverTimestamp) {
- result = await getMessageBySenderAndServerTimestamp({
- source,
- serverTimestamp,
- });
- }
+
+ result = await getMessageBySenderAndServerTimestamp({
+ source,
+ serverTimestamp,
+ });
+
// if we have a result, it means a specific user sent two messages either with the same serverTimestamp.
// no need to do anything else, those messages must be the same
// Note: this test is not based on which conversation the user sent the message
// but we consider that a user sending two messages with the same serverTimestamp is unlikely
return Boolean(result);
- } else {
- result = await getMessageBySender({
- source,
- sourceDevice,
- sentAt: timestamp,
- });
}
+ result = await getMessageBySender({
+ source,
+ sourceDevice,
+ sentAt: timestamp,
+ });
if (!result) {
return false;
diff --git a/ts/receiver/hashDuplicateFilter.ts b/ts/receiver/hashDuplicateFilter.ts
deleted file mode 100644
index b7680cc41..000000000
--- a/ts/receiver/hashDuplicateFilter.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import _ from 'lodash';
-import { SignalService } from '../protobuf';
-import { sha256 } from '../session/crypto';
-
-const recentHashByConvo = new Map>();
-
-const maxHashToKeepPerConvo = 10;
-
-export function isDuplicateBasedOnHash(
- dataMessage: SignalService.DataMessage,
- conversationId: string,
- sender: string
-): boolean {
- const toUseForHash = {
- ..._.omit(
- SignalService.DataMessage.toObject(dataMessage),
- 'timestamp',
- 'profile',
- 'preview',
- 'profileKey'
- ),
- conversationId,
- sender,
- };
-
- if (!recentHashByConvo.has(conversationId)) {
- recentHashByConvo.set(conversationId, new Array());
- }
- const newHash = sha256(JSON.stringify(toUseForHash));
-
- // this can only be set based on the .set above()
- let recentHashForConvo = recentHashByConvo.get(conversationId) as Array;
-
- // this hash already exists for this convo
- if (recentHashForConvo.some(n => n === newHash)) {
- return true;
- }
- // push the new hash at the end
- recentHashForConvo.push(newHash);
- if (recentHashForConvo.length > maxHashToKeepPerConvo) {
- // slice the last maxHashToKeepPerConvo hashes
- recentHashForConvo = recentHashForConvo?.slice(-maxHashToKeepPerConvo);
- }
- recentHashByConvo.set(conversationId, recentHashForConvo);
- return false;
-}
-
-// build a hash of the data and check against recent messages
diff --git a/ts/receiver/receiver.ts b/ts/receiver/receiver.ts
index abb9c2f93..0e2212ce1 100644
--- a/ts/receiver/receiver.ts
+++ b/ts/receiver/receiver.ts
@@ -26,7 +26,6 @@ import { OpenGroupRequestCommonType } from '../session/apis/open_group_api/openg
import { handleMessageJob } from './queuedJob';
import { fromBase64ToArray } from '../session/utils/String';
import { removeMessagePadding } from '../session/crypto/BufferPadding';
-import { isDuplicateBasedOnHash } from './hashDuplicateFilter';
import { createTaskWithTimeout } from '../session/utils/TaskWithTimeout';
import { perfEnd, perfStart } from '../session/utils/Performance';
@@ -317,7 +316,7 @@ export async function handleOpenGroupV2Message(
source: sender,
message: dataMessage,
};
- // WARNING this is very important that the isMessageDuplicate is made in the conversation.queueJob
+ // WARNING this is important that the isMessageDuplicate is made in the conversation.queueJob
const isDuplicate = await isMessageDuplicate(messageCreationData);
if (isDuplicate) {
@@ -325,10 +324,6 @@ export async function handleOpenGroupV2Message(
return;
}
- if (isDuplicateBasedOnHash(dataMessage, conversationId, sender)) {
- window?.log?.info('Received duplicate message based on hash. Dropping it.');
- return;
- }
// this line just create an empty message with some basic stuff set.
// the whole decoding of data is happening in handleMessageJob()
const msg = createMessage(messageCreationData, !isMe);
diff --git a/ts/session/apis/open_group_api/opengroupV2/ApiAuth.ts b/ts/session/apis/open_group_api/opengroupV2/ApiAuth.ts
index 9226720e2..86a17a2f4 100644
--- a/ts/session/apis/open_group_api/opengroupV2/ApiAuth.ts
+++ b/ts/session/apis/open_group_api/opengroupV2/ApiAuth.ts
@@ -84,35 +84,6 @@ export async function getAuthToken({
return oneAtATimeGetAuth({ roomId, serverUrl });
}
-export type DeleteAuthTokenRequest = OpenGroupRequestCommonType & { token: string };
-export const deleteAuthToken = async ({
- serverUrl,
- roomId,
- token,
-}: DeleteAuthTokenRequest): Promise => {
- const request: OpenGroupV2Request = {
- method: 'DELETE',
- room: roomId,
- server: serverUrl,
- isAuthRequired: true,
- endpoint: 'auth_token',
- forcedTokenToUse: token,
- };
- try {
- const result = await sendApiV2Request(request);
- const statusCode = parseStatusCodeFromOnionRequest(result);
- if (statusCode !== 200) {
- // FIXME not yet sure why this call always return 401
- // window?.log?.warn(`Could not deleteAuthToken, status code: ${statusCode}`);
- return;
- }
- return;
- } catch (e) {
- window?.log?.error('deleteAuthToken failed:', e);
- return;
- }
-};
-
// tslint:disable: member-ordering
export async function requestNewAuthToken({
serverUrl,
diff --git a/ts/session/apis/open_group_api/opengroupV2/OpenGroupManagerV2.ts b/ts/session/apis/open_group_api/opengroupV2/OpenGroupManagerV2.ts
index 3519b0fa7..d2e279d7f 100644
--- a/ts/session/apis/open_group_api/opengroupV2/OpenGroupManagerV2.ts
+++ b/ts/session/apis/open_group_api/opengroupV2/OpenGroupManagerV2.ts
@@ -14,7 +14,6 @@ import { openGroupV2GetRoomInfo } from './OpenGroupAPIV2';
import { OpenGroupServerPoller } from './OpenGroupServerPoller';
import _ from 'lodash';
-import { deleteAuthToken, DeleteAuthTokenRequest } from './ApiAuth';
import autoBind from 'auto-bind';
let instance: OpenGroupManagerV2 | undefined;
@@ -129,13 +128,6 @@ export class OpenGroupManagerV2 {
try {
const roomConvoId = getOpenGroupV2ConversationId(infos.serverUrl, infos.roomId);
if (!allConvos.get(roomConvoId)) {
- // leave the group on the remote server
- // this request doesn't throw
- if (infos.token) {
- await deleteAuthToken(
- _.pick(infos, 'serverUrl', 'roomId', 'token') as DeleteAuthTokenRequest
- );
- }
// remove the roomInfos locally for this open group room
await removeV2OpenGroupRoom(roomConvoId);
getOpenGroupManager().removeRoomFromPolledRooms(infos);
diff --git a/ts/session/conversations/ConversationController.ts b/ts/session/conversations/ConversationController.ts
index bbcf83f12..e35ce9f96 100644
--- a/ts/session/conversations/ConversationController.ts
+++ b/ts/session/conversations/ConversationController.ts
@@ -12,10 +12,7 @@ import { actions as conversationActions } from '../../state/ducks/conversations'
import { getV2OpenGroupRoom, removeV2OpenGroupRoom } from '../../data/opengroups';
import _ from 'lodash';
import { getOpenGroupManager } from '../apis/open_group_api/opengroupV2/OpenGroupManagerV2';
-import {
- deleteAuthToken,
- DeleteAuthTokenRequest,
-} from '../apis/open_group_api/opengroupV2/ApiAuth';
+
import { deleteAllMessagesByConvoIdNoConfirmation } from '../../interactions/conversationInteractions';
let instance: ConversationController | null;
@@ -201,12 +198,6 @@ export class ConversationController {
window?.log?.info('leaving open group v2', conversation.id);
const roomInfos = await getV2OpenGroupRoom(conversation.id);
if (roomInfos) {
- if (roomInfos.token) {
- // leave the group on the remote server
- await deleteAuthToken(
- _.pick(roomInfos, 'serverUrl', 'roomId', 'token') as DeleteAuthTokenRequest
- );
- }
getOpenGroupManager().removeRoomFromPolledRooms(roomInfos);
// remove the roomInfos locally for this open group room
diff --git a/ts/types/LocalizerKeys.ts b/ts/types/LocalizerKeys.ts
index 218956f2a..da5b86cbc 100644
--- a/ts/types/LocalizerKeys.ts
+++ b/ts/types/LocalizerKeys.ts
@@ -214,6 +214,7 @@ export type LocalizerKeys =
| 'groupNamePlaceholder'
| 'stagedPreviewThumbnail'
| 'helpUsTranslateSession'
+ | 'editMenuDeleteGroup'
| 'unreadMessages'
| 'documents'
| 'audioPermissionNeededTitle'
@@ -250,6 +251,7 @@ export type LocalizerKeys =
| 'previewThumbnail'
| 'photo'
| 'setPassword'
+ | 'editMenuDeleteContact'
| 'hideMenuBarTitle'
| 'imageCaptionIconAlt'
| 'blockAll'
diff --git a/yarn.lock b/yarn.lock
index 235351d23..381f87435 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3687,10 +3687,10 @@ electron-updater@^4.2.2:
pako "^1.0.11"
semver "^7.1.3"
-electron@^13.1.9:
- version "13.1.9"
- resolved "https://registry.yarnpkg.com/electron/-/electron-13.1.9.tgz#668e2632b81e9fa21edfd32876282d3e2ff7fd76"
- integrity sha512-By4Zb72XNQLrPb70BXdIW3NtEHFwybP5DIQjohnCxOYONq5vojuHjNcTuWnBgMvwQ2qwykk6Tw5EwF2Pt0CWjA==
+electron@^13.6.2:
+ version "13.6.3"
+ resolved "https://registry.yarnpkg.com/electron/-/electron-13.6.3.tgz#c0217178807d3e0b2175c49dbe33ea8dac447e73"
+ integrity sha512-kevgR6/RuEhchJQbgCKhHle9HvJhi2dOJlicFZJqbbqa9BVpZARqqFDlwTSatYxmUPUJwu09FvyMwJG2DMQIng==
dependencies:
"@electron/get" "^1.0.1"
"@types/node" "^14.6.2"