Merge remote-tracking branch 'upstream/clearnet' into remove-conversationct-singleton

This commit is contained in:
Audric Ackermann 2021-06-24 16:42:00 +10:00
commit 712f76a53c
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4
13 changed files with 169 additions and 40 deletions

View File

@ -407,5 +407,8 @@
"playAtCustomSpeed": "Play at $multipler$x speed",
"linkVisitWarningTitle": "Open this link in your browser?",
"linkVisitWarningMessage": "Are you sure you want to open $url$ in your browser?",
"open": "Open"
"open": "Open",
"clickToTrustContact": "Tap to download media",
"trustThisContactDialogTitle": "Trust $name$?",
"trustThisContactDialogDescription": "Are you sure you want to download media sent by $name$?"
}

View File

@ -57,27 +57,27 @@ describe('MessageCollection', () => {
assert(firstTimestamp < secondTimestamp);
});
it('checks if is incoming message', () => {
const messages = new window.models.Message.MessageCollection();
let message = messages.add(attributes);
assert.notOk(message.isIncoming());
message = messages.add({
type: 'incoming',
conversationId: 'conversationId',
});
assert.ok(message.isIncoming());
});
// it('checks if is incoming message', () => {
// const messages = new window.models.Message.MessageCollection();
// let message = messages.add(attributes);
// assert.notOk(message.isIncoming());
// message = messages.add({
// type: 'incoming',
// conversationId: 'conversationId',
// });
// assert.ok(message.isIncoming());
// });
it('checks if is outgoing message', () => {
const messages = new window.models.Message.MessageCollection();
let message = messages.add(attributes);
assert.ok(message.isOutgoing());
message = messages.add({
type: 'incoming',
conversationId: 'conversationId',
});
assert.notOk(message.isOutgoing());
});
// it('checks if is outgoing message', () => {
// const messages = new window.models.Message.MessageCollection();
// let message = messages.add(attributes);
// assert.ok(message.isOutgoing());
// message = messages.add({
// type: 'incoming',
// conversationId: 'conversationId',
// });
// assert.notOk(message.isOutgoing());
// });
it('checks if is group update', () => {
const messages = new window.models.Message.MessageCollection();

View File

@ -41,6 +41,7 @@ import { updateUserDetailsModal } from '../../state/ducks/modalDialog';
import { MessageInteraction } from '../../interactions';
import autoBind from 'auto-bind';
import { AudioPlayerWithEncryptedFile } from './H5AudioPlayer';
import { ClickToTrustSender } from './message/ClickToTrustSender';
// Same as MIN_WIDTH in ImageGrid.tsx
const MINIMUM_LINK_PREVIEW_IMAGE_WIDTH = 200;
@ -146,6 +147,7 @@ class MessageInner extends React.PureComponent<MessageRegularProps, State> {
onClickAttachment,
multiSelectMode,
onSelectMessage,
isTrustedForAttachmentDownload,
} = this.props;
const { imageBroken } = this.state;
@ -160,6 +162,10 @@ class MessageInner extends React.PureComponent<MessageRegularProps, State> {
Boolean(quote) || (conversationType === 'group' && direction === 'incoming');
const displayImage = canDisplayImage(attachments);
if (!isTrustedForAttachmentDownload) {
return <ClickToTrustSender messageId={id} />;
}
if (
displayImage &&
!imageBroken &&

View File

@ -0,0 +1,83 @@
import React from 'react';
import styled from 'styled-components';
import { getMessageById, getMessagesByConversation } from '../../../data/data';
import { getConversationController } from '../../../session/conversations';
import { AttachmentDownloads } from '../../../session/utils';
import { updateConfirmModal } from '../../../state/ducks/modalDialog';
import { SessionIcon, SessionIconSize, SessionIconType } from '../../session/icon';
import { SessionButtonColor } from '../../session/SessionButton';
const StyledTrustSenderUI = styled.div`
padding: '${props => props.theme.common.margins.md}px';
display: flex;
align-items: center;
`;
const ClickToDownload = styled.div`
padding: ${props => props.theme.common.margins.xs} ${props => props.theme.common.margins.md};
`;
export const ClickToTrustSender = (props: { messageId: string }) => {
const openConfirmationModal = async (e: any) => {
e.stopPropagation();
e.preventDefault();
const found = await getMessageById(props.messageId);
if (!found) {
window.log.warn('message not found ClickToTrustSender');
return;
}
const sender = found.getSource();
const convo = getConversationController().get(sender);
window.inboxStore?.dispatch(
updateConfirmModal({
title: window.i18n(
'trustThisContactDialogTitle',
convo.getContactProfileNameOrShortenedPubKey()
),
message: window.i18n(
'trustThisContactDialogDescription',
convo.getContactProfileNameOrShortenedPubKey()
),
okTheme: SessionButtonColor.Green,
onClickOk: async () => {
convo.set({ isTrustedForAttachmentDownload: true });
await convo.commit();
const messagesInConvo = await getMessagesByConversation(convo.id, {
limit: 100,
});
await Promise.all(
messagesInConvo.map(async message => {
const msgAttachments = message.get('attachments');
if (!msgAttachments || msgAttachments.length === 0) {
return;
}
const downloadedAttachments = await Promise.all(
msgAttachments.map(async (attachment: any, index: any) => {
return AttachmentDownloads.addJob(attachment, {
messageId: message.id,
type: 'attachment',
index,
isOpenGroupV2: false,
openGroupV2Details: undefined,
});
})
);
message.set({ attachments: downloadedAttachments });
await message.commit();
})
);
},
})
);
};
return (
<StyledTrustSenderUI onClick={openConfirmationModal}>
<SessionIcon iconSize={SessionIconSize.Small} iconType={SessionIconType.Gallery} />
<ClickToDownload>{window.i18n('clickToTrustContact')}</ClickToDownload>
</StyledTrustSenderUI>
);
};

View File

@ -102,8 +102,6 @@ const SessionConfirmInner = (props: SessionConfirmDialogProps) => {
</div>
<div className="session-modal__button-group">
<SessionButton text={okText} buttonColor={okTheme} onClick={onClickOkHandler} />
{!hideCancel && (
<SessionButton
text={cancelText}
@ -111,6 +109,7 @@ const SessionConfirmInner = (props: SessionConfirmDialogProps) => {
onClick={onClickCancelHandler}
/>
)}
<SessionButton text={okText} buttonColor={okTheme} onClick={onClickOkHandler} />
</div>
</SessionWrapperModal>
);

View File

@ -3,9 +3,6 @@ import styled, { ThemeContext } from 'styled-components';
import { Flex } from '../../basic/Flex';
import { SessionIcon, SessionIconSize, SessionIconType } from '../icon';
// padding-inline-end: ${props => props.theme.common.margins.md};
// padding-inline-start: ${props => props.theme.common.margins.md};
const DropZoneContainer = styled.div`
display: inline-block;
position: absolute;

View File

@ -40,6 +40,7 @@ export enum SessionIconType {
Warning = 'warning',
Sending = 'sending',
DoubleCheckCircle = 'doubleCheckCircle',
Gallery = 'gallery',
Timer00 = 'timer00',
Timer05 = 'timer05',
Timer10 = 'timer10',
@ -309,6 +310,12 @@ export const icons = {
viewBox: '3 0 12 12',
ratio: 1.6,
},
[SessionIconType.Gallery]: {
path:
'M218.8,52.1H110.2v-0.9c0.1-0.5,0.1-1.1,0.1-1.6V38.2c0-7.8-6.4-14.2-14.2-14.2H85.9H33.4H23.3c-7.8,0-14.2,6.4-14.2,14.2v10.1v1.2V75v130.7c0,15.5,12.6,28,28.1,28.1h181.6c15.5,0,28.1-12.6,28.1-28.1V80.2C246.9,64.7,234.3,52.1,218.8,52.1zM218.8,215.1H37.2c-5.2-0.1-9.3-4.2-9.4-9.4V80.3c0.1-5.2,4.2-9.3,9.4-9.4h181.6c5.2,0.1,9.3,4.2,9.4,9.4v125.4h0C228.1,210.9,224,215,218.8,215.1z M170.2,108.3c0-11.2,9.1-20.4,20.4-20.4s20.4,9.1,20.4,20.4c0,11.2-9.1,20.4-20.4,20.4h-0.1c0,0,0,0,0,0C179.2,128.7,170.2,119.5,170.2,108.3z M158.8,149.9l54.7,52.5h-173l51-103.7l33.8,75.3L158.8,149.9z',
viewBox: '0 0 256 256',
ratio: 1,
},
[SessionIconType.Timer00]: {
path:
'M11.428367,3.44328115 L10.5587469,3.94535651 C10.4906607,3.79477198 10.4145019,3.64614153 10.330127,3.5 C10.2457522,3.35385847 10.1551138,3.21358774 10.0587469,3.07933111 L10.928367,2.57725574 C11.0225793,2.71323387 11.1119641,2.85418158 11.1961524,3 C11.2803407,3.14581842 11.3577126,3.2937018 11.428367,3.44328115 Z M9.42274426,1.07163304 L8.92066889,1.94125309 C8.78641226,1.84488615 8.64614153,1.75424783 8.5,1.66987298 C8.35385847,1.58549813 8.20522802,1.50933927 8.05464349,1.44125309 L8.55671885,0.571633044 C8.7062982,0.642287382 8.85418158,0.719659271 9,0.803847577 C9.14581842,0.888035884 9.28676613,0.977420696 9.42274426,1.07163304 Z M11.9794631,6.5 L10.9753124,6.5 C10.9916403,6.33554688 11,6.1687497 11,6 C11,5.8312503 10.9916403,5.66445312 10.9753124,5.5 L11.9794631,5.5 C11.9930643,5.66486669 12,5.83162339 12,6 C12,6.16837661 11.9930643,6.33513331 11.9794631,6.5 Z M10.928367,9.42274426 L10.0587469,8.92066889 C10.1551138,8.78641226 10.2457522,8.64614153 10.330127,8.5 C10.4145019,8.35385847 10.4906607,8.20522802 10.5587469,8.05464349 L11.428367,8.55671885 C11.3577126,8.7062982 11.2803407,8.85418158 11.1961524,9 C11.1119641,9.14581842 11.0225793,9.28676613 10.928367,9.42274426 Z M8.55671885,11.428367 L8.05464349,10.5587469 C8.20522802,10.4906607 8.35385847,10.4145019 8.5,10.330127 C8.64614153,10.2457522 8.78641226,10.1551138 8.92066889,10.0587469 L9.42274426,10.928367 C9.28676613,11.0225793 9.14581842,11.1119641 9,11.1961524 C8.85418158,11.2803407 8.7062982,11.3577126 8.55671885,11.428367 Z M2.57725574,10.928367 L3.07933111,10.0587469 C3.21358774,10.1551138 3.35385847,10.2457522 3.5,10.330127 C3.64614153,10.4145019 3.79477198,10.4906607 3.94535651,10.5587469 L3.44328115,11.428367 C3.2937018,11.3577126 3.14581842,11.2803407 3,11.1961524 C2.85418158,11.1119641 2.71323387,11.0225793 2.57725574,10.928367 Z M5.5,11.9794631 L5.5,10.9753124 C5.66445312,10.9916403 5.8312503,11 6,11 C6.1687497,11 6.33554688,10.9916403 6.5,10.9753124 L6.5,11.9794631 C6.33513331,11.9930643 6.16837661,12 6,12 C5.83162339,12 5.66486669,11.9930643 5.5,11.9794631 Z M0.571633044,8.55671885 L1.44125309,8.05464349 C1.50933927,8.20522802 1.58549813,8.35385847 1.66987298,8.5 C1.75424783,8.64614153 1.84488615,8.78641226 1.94125309,8.92066889 L1.07163304,9.42274426 C0.977420696,9.28676613 0.888035884,9.14581842 0.803847577,9 C0.719659271,8.85418158 0.642287382,8.7062982 0.571633044,8.55671885 Z M0.0205368885,5.5 L1.02468762,5.5 C1.00835972,5.66445312 1,5.8312503 1,6 C1,6.1687497 1.00835972,6.33554688 1.02468762,6.5 L0.0205368885,6.5 C0.00693566443,6.33513331 -9.95062878e-13,6.16837661 -9.95093808e-13,6 C-9.95124738e-13,5.83162339 0.00693566443,5.66486669 0.0205368885,5.5 Z M1.07163304,2.57725574 L1.94125309,3.07933111 C1.84488615,3.21358774 1.75424783,3.35385847 1.66987298,3.5 C1.58549813,3.64614153 1.50933927,3.79477198 1.44125309,3.94535651 L0.571633044,3.44328115 C0.642287382,3.2937018 0.719659271,3.14581842 0.803847577,3 C0.888035884,2.85418158 0.977420696,2.71323387 1.07163304,2.57725574 Z M3.44328115,0.571633044 L3.94535651,1.44125309 C3.79477198,1.50933927 3.64614153,1.58549813 3.5,1.66987298 C3.35385847,1.75424783 3.21358774,1.84488615 3.07933111,1.94125309 L2.57725574,1.07163304 C2.71323387,0.977420696 2.85418158,0.888035884 3,0.803847577 C3.14581842,0.719659271 3.2937018,0.642287382 3.44328115,0.571633044 Z M6.5,0.0205368885 L6.5,7 L5.5,7 L5.5,0.0205368885 C5.66486669,0.00693566443 5.83162339,5.01e-14 6,5.01e-14 C6.16837661,5.01e-14 6.33513331,0.00693566443 6.5,0.0205368885 Z',

View File

@ -94,6 +94,7 @@ export interface ConversationAttributes {
profileKey?: string;
accessKey?: any;
triggerNotificationsFor: ConversationNotificationSettingType;
isTrustedForAttachmentDownload: boolean;
}
export interface ConversationAttributesOptionals {
@ -130,6 +131,7 @@ export interface ConversationAttributesOptionals {
profileKey?: string;
accessKey?: any;
triggerNotificationsFor?: ConversationNotificationSettingType;
isTrustedForAttachmentDownload?: boolean;
}
/**
@ -158,6 +160,7 @@ export const fillConvoAttributesWithDefaults = (
mentionedUs: false,
active_at: 0,
triggerNotificationsFor: 'all', // if the settings is not set in the db, this is the default
isTrustedForAttachmentDownload: false, // we don't trust a contact until we say so
});
};

View File

@ -34,6 +34,7 @@ import { acceptOpenGroupInvitation } from '../interactions/messageInteractions';
import { OpenGroupVisibleMessage } from '../session/messages/outgoing/visibleMessage/OpenGroupVisibleMessage';
import { getV2OpenGroupRoom } from '../data/opengroups';
import { getMessageController } from '../session/messages';
import { isUsFromCache } from '../session/utils/User';
export class MessageModel extends Backbone.Model<MessageAttributes> {
public propsForTimerNotification: any;
@ -516,6 +517,7 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
const isPublicOpenGroupV2 = isOpenGroupV2(this.getConversation()?.id || '');
const attachments = this.get('attachments') || [];
const isTrustedForAttachmentDownload = this.isTrustedForAttachmentDownload();
return {
text: this.createNonBreakingLastSeparator(this.get('body')),
@ -541,6 +543,7 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
isPublic,
isOpenGroupV2: isPublicOpenGroupV2,
isKickedFromGroup: conversation && conversation.get('isKickedFromGroup'),
isTrustedForAttachmentDownload,
onRetrySend: this.retrySend,
markRead: this.markRead,
@ -1108,6 +1111,20 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
});
}
}
public isTrustedForAttachmentDownload() {
const convoId = this.getSource();
if (!!this.get('isPublic') || isUsFromCache(convoId)) {
return true;
}
// check the convo from this user
// we want the convo of the sender of this message
const senderConvo = getConversationController().get(convoId);
if (!senderConvo) {
return false;
}
return senderConvo.get('isTrustedForAttachmentDownload') || false;
}
}
export class MessageCollection extends Backbone.Collection<MessageModel> {}

View File

@ -241,6 +241,7 @@ export interface MessageRegularProps {
firstMessageOfSeries: boolean;
isUnread: boolean;
isQuotedMessageToAnimate?: boolean;
isTrustedForAttachmentDownload: boolean;
onClickAttachment?: (attachment: AttachmentType) => void;
onClickLinkPreview?: (url: string) => void;

View File

@ -136,22 +136,27 @@ async function processNormalAttachments(
convo: ConversationModel
): Promise<number> {
const isOpenGroupV2 = convo.isOpenGroupV2();
const openGroupV2Details = (isOpenGroupV2 && convo.toOpenGroupV2()) || undefined;
const attachments = await Promise.all(
normalAttachments.map(async (attachment: any, index: any) => {
return AttachmentDownloads.addJob(attachment, {
messageId: message.id,
type: 'attachment',
index,
isOpenGroupV2,
openGroupV2Details,
});
})
);
message.set({ attachments });
if (message.isTrustedForAttachmentDownload()) {
const openGroupV2Details = (isOpenGroupV2 && convo.toOpenGroupV2()) || undefined;
const attachments = await Promise.all(
normalAttachments.map(async (attachment: any, index: any) => {
return AttachmentDownloads.addJob(attachment, {
messageId: message.id,
type: 'attachment',
index,
isOpenGroupV2,
openGroupV2Details,
});
})
);
return attachments.length;
message.set({ attachments });
return attachments.length;
}
window.log.info('No downloading attachments yet as this user is not trusted for now.');
return 0;
}
async function processPreviews(message: MessageModel, convo: ConversationModel): Promise<number> {

View File

@ -145,6 +145,13 @@ async function _runJob(job: any) {
await _finishJob(null, id);
return;
}
const isTrusted = found.isTrustedForAttachmentDownload();
if (!isTrusted) {
logger.info('_runJob: sender conversation not trusted yet, deleting job');
await _finishJob(null, id);
return;
}
if (isOpenGroupV2 && (!openGroupV2Details?.serverUrl || !openGroupV2Details.roomId)) {
window?.log?.warn(

View File

@ -87,6 +87,7 @@ export class MockConversation {
lastMessage: null,
zombies: [],
triggerNotificationsFor: 'all',
isTrustedForAttachmentDownload: false,
};
}