mirror of
https://github.com/oxen-io/session-desktop.git
synced 2023-12-14 02:12:57 +01:00
Merge branch 'clearnet' into global-search-off-clearnet
This commit is contained in:
commit
3f4db67c1b
17 changed files with 46 additions and 128 deletions
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -107,7 +107,7 @@ const Seed = (props: SeedProps) => {
|
|||
<p className="session-modal__description">{i18n('recoveryPhraseSavePromptMain')}</p>
|
||||
<SpacerXS />
|
||||
|
||||
<i data-test-id="recovery-phrase-seed-modal" className="session-modal__text-highlight">
|
||||
<i data-testid="recovery-phrase-seed-modal" className="session-modal__text-highlight">
|
||||
{recoveryPhrase}
|
||||
</i>
|
||||
</div>
|
||||
|
|
|
@ -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) => {
|
|||
>
|
||||
<AvatarItem />
|
||||
<div className="module-conversation-list-item__content">
|
||||
<HeaderItem />
|
||||
<ConversationListItemHeaderItem />
|
||||
<MessageItem isMessageRequest={Boolean(isMessageRequest)} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -73,7 +73,7 @@ const ListItemIcons = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export const HeaderItem = () => {
|
||||
export const ConversationListItemHeaderItem = () => {
|
||||
const conversationId = useContext(ContextConversationId);
|
||||
|
||||
const convoProps = useHeaderItemProps(conversationId);
|
||||
|
|
|
@ -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 = () => {
|
||||
|
|
|
@ -70,7 +70,7 @@ const SignUpSessionIDShown = (props: { continueSignUp: () => void }) => {
|
|||
{window.i18n('yourUniqueSessionID')}
|
||||
</div>
|
||||
</Flex>
|
||||
<SessionIdEditable editable={false} placeholder={undefined} />
|
||||
<SessionIdEditable editable={false} placeholder={undefined} dataTestId="session-id-signup" />
|
||||
<div className="session-description-long">{window.i18n('allUsersAreRandomly...')}</div>
|
||||
<ContinueSignUpButton continueSignUp={props.continueSignUp} />
|
||||
<TermsAndConditions />
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
import _ from 'lodash';
|
||||
import { SignalService } from '../protobuf';
|
||||
import { sha256 } from '../session/crypto';
|
||||
|
||||
const recentHashByConvo = new Map<string, Array<string>>();
|
||||
|
||||
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<string>;
|
||||
|
||||
// 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
|
|
@ -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);
|
||||
|
|
|
@ -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<void> => {
|
||||
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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue