Merge branch 'develop' into move-read-receipts-to-bottom

This commit is contained in:
Travis Ralston 2020-03-05 17:13:24 -07:00
commit 1975a8e082
320 changed files with 14874 additions and 9037 deletions

View file

@ -33,18 +33,21 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg';
import {ALL_RULE_TYPES} from "../../../mjolnir/BanList";
import * as ObjectUtils from "../../../ObjectUtils";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import {E2E_STATE} from "./E2EIcon";
const eventTileTypes = {
'm.room.message': 'messages.MessageEvent',
'm.sticker': 'messages.MessageEvent',
'm.key.verification.cancel': 'messages.MKeyVerificationConclusion',
'm.key.verification.done': 'messages.MKeyVerificationConclusion',
'm.room.encryption': 'messages.EncryptionEvent',
'm.call.invite': 'messages.TextualEvent',
'm.call.answer': 'messages.TextualEvent',
'm.call.hangup': 'messages.TextualEvent',
};
const stateEventTileTypes = {
'm.room.encryption': 'messages.EncryptionEvent',
'm.room.aliases': 'messages.TextualEvent',
// 'm.room.aliases': 'messages.RoomAliasesEvent', // too complex
'm.room.canonical_alias': 'messages.TextualEvent',
@ -54,7 +57,6 @@ const stateEventTileTypes = {
'm.room.avatar': 'messages.RoomAvatarEvent',
'm.room.third_party_invite': 'messages.TextualEvent',
'm.room.history_visibility': 'messages.TextualEvent',
'm.room.encryption': 'messages.TextualEvent',
'm.room.topic': 'messages.TextualEvent',
'm.room.power_levels': 'messages.TextualEvent',
'm.room.pinned_events': 'messages.TextualEvent',
@ -98,6 +100,17 @@ export function getHandlerTile(ev) {
}
}
// sometimes MKeyVerificationConclusion declines to render. Jankily decline to render and
// fall back to showing hidden events, if we're viewing hidden events
// XXX: This is extremely a hack. Possibly these components should have an interface for
// declining to render?
if (type === "m.key.verification.cancel" && SettingsStore.getValue("showHiddenEventsInTimeline")) {
const MKeyVerificationConclusion = sdk.getComponent("messages.MKeyVerificationConclusion");
if (!MKeyVerificationConclusion.prototype._shouldRender.call(null, ev, ev.request)) {
return;
}
}
return ev.isState() ? stateEventTileTypes[type] : eventTileTypes[type];
}
@ -235,6 +248,7 @@ export default createReactClass({
this._suppressReadReceiptAnimation = false;
const client = this.context;
client.on("deviceVerificationChanged", this.onDeviceVerificationChanged);
client.on("userTrustStatusChanged", this.onUserVerificationChanged);
this.props.mxEvent.on("Event.decrypted", this._onDecrypted);
if (this.props.showReactions) {
this.props.mxEvent.on("Event.relationsCreated", this._onReactionsCreated);
@ -260,6 +274,7 @@ export default createReactClass({
componentWillUnmount: function() {
const client = this.context;
client.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged);
client.removeListener("userTrustStatusChanged", this.onUserVerificationChanged);
this.props.mxEvent.removeListener("Event.decrypted", this._onDecrypted);
if (this.props.showReactions) {
this.props.mxEvent.removeListener("Event.relationsCreated", this._onReactionsCreated);
@ -282,18 +297,56 @@ export default createReactClass({
}
},
onUserVerificationChanged: function(userId, _trustStatus) {
if (userId === this.props.mxEvent.getSender()) {
this._verifyEvent(this.props.mxEvent);
}
},
_verifyEvent: async function(mxEvent) {
if (!mxEvent.isEncrypted()) {
return;
}
// If we directly trust the device, short-circuit here
const verified = await this.context.isEventSenderVerified(mxEvent);
if (verified) {
this.setState({
verified: E2E_STATE.VERIFIED,
}, () => {
// Decryption may have caused a change in size
this.props.onHeightChanged();
});
return;
}
// If cross-signing is off, the old behaviour is to scream at the user
// as if they've done something wrong, which they haven't
if (!SettingsStore.isFeatureEnabled("feature_cross_signing")) {
this.setState({
verified: E2E_STATE.WARNING,
}, this.props.onHeightChanged);
return;
}
if (!this.context.checkUserTrust(mxEvent.getSender()).isCrossSigningVerified()) {
this.setState({
verified: E2E_STATE.NORMAL,
}, this.props.onHeightChanged);
return;
}
const eventSenderTrust = await this.context.checkEventSenderTrust(mxEvent);
if (!eventSenderTrust) {
this.setState({
verified: E2E_STATE.UNKNOWN,
}, this.props.onHeightChanged); // Decryption may have cause a change in size
return;
}
this.setState({
verified: verified,
}, () => {
// Decryption may have caused a change in size
this.props.onHeightChanged();
});
verified: eventSenderTrust.isVerified() ? E2E_STATE.VERIFIED : E2E_STATE.WARNING,
}, this.props.onHeightChanged); // Decryption may have caused a change in size
},
_propsEqual: function(objA, objB) {
@ -473,8 +526,12 @@ export default createReactClass({
// event is encrypted, display padlock corresponding to whether or not it is verified
if (ev.isEncrypted()) {
if (this.state.verified) {
if (this.state.verified === E2E_STATE.NORMAL) {
return; // no icon if we've not even cross-signed the user
} else if (this.state.verified === E2E_STATE.VERIFIED) {
return; // no icon for verified
} else if (this.state.verified === E2E_STATE.UNKNOWN) {
return (<E2ePadlockUnknown />);
} else {
return (<E2ePadlockUnverified />);
}
@ -527,6 +584,7 @@ export default createReactClass({
console.error("EventTile attempted to get relations for an event without an ID");
// Use event's special `toJSON` method to log key data.
console.log(JSON.stringify(this.props.mxEvent, null, 4));
console.trace("Stacktrace for https://github.com/vector-im/riot-web/issues/11120");
}
return this.props.getRelationsForEvent(eventId, "m.annotation", "m.reaction");
},
@ -554,7 +612,8 @@ export default createReactClass({
// Info messages are basically information about commands processed on a room
const isBubbleMessage = eventType.startsWith("m.key.verification") ||
(eventType === "m.room.message" && msgtype && msgtype.startsWith("m.key.verification"));
(eventType === "m.room.message" && msgtype && msgtype.startsWith("m.key.verification")) ||
(eventType === "m.room.encryption");
let isInfoMessage = (
!isBubbleMessage && eventType !== 'm.room.message' &&
eventType !== 'm.sticker' && eventType !== 'm.room.create'
@ -604,8 +663,9 @@ export default createReactClass({
mx_EventTile_last: this.props.last,
mx_EventTile_contextual: this.props.contextual,
mx_EventTile_actionBarFocused: this.state.actionBarFocused,
mx_EventTile_verified: !isBubbleMessage && this.state.verified === true,
mx_EventTile_unverified: !isBubbleMessage && this.state.verified === false,
mx_EventTile_verified: !isBubbleMessage && this.state.verified === E2E_STATE.VERIFIED,
mx_EventTile_unverified: !isBubbleMessage && this.state.verified === E2E_STATE.WARNING,
mx_EventTile_unknown: !isBubbleMessage && this.state.verified === E2E_STATE.UNKNOWN,
mx_EventTile_bad: isEncryptionFailure,
mx_EventTile_emote: msgtype === 'm.emote',
mx_EventTile_redacted: isRedacted,
@ -686,15 +746,15 @@ export default createReactClass({
<div className="mx_EventTile_keyRequestInfo_tooltip_contents">
<p>
{ this.state.previouslyRequestedKeys ?
_t( 'Your key share request has been sent - please check your other devices ' +
_t( 'Your key share request has been sent - please check your other sessions ' +
'for key share requests.') :
_t( 'Key share requests are sent to your other devices automatically. If you ' +
'rejected or dismissed the key share request on your other devices, click ' +
_t( 'Key share requests are sent to your other sessions automatically. If you ' +
'rejected or dismissed the key share request on your other sessions, click ' +
'here to request the keys for this session again.')
}
</p>
<p>
{ _t( 'If your other devices do not have the key for this message you will not ' +
{ _t( 'If your other sessions do not have the key for this message you will not ' +
'be able to decrypt them.')
}
</p>
@ -702,7 +762,7 @@ export default createReactClass({
const keyRequestInfoContent = this.state.previouslyRequestedKeys ?
_t('Key request sent.') :
_t(
'<requestLink>Re-request encryption keys</requestLink> from your other devices.',
'<requestLink>Re-request encryption keys</requestLink> from your other sessions.',
{},
{'requestLink': (sub) => <a onClick={this.onRequestKeysClick}>{ sub }</a>},
);
@ -891,7 +951,7 @@ function E2ePadlockUndecryptable(props) {
function E2ePadlockUnverified(props) {
return (
<E2ePadlock title={_t("Encrypted by an unverified device")} icon="unverified" {...props} />
<E2ePadlock title={_t("Encrypted by an unverified session")} icon="unverified" {...props} />
);
}
@ -901,6 +961,12 @@ function E2ePadlockUnencrypted(props) {
);
}
function E2ePadlockUnknown(props) {
return (
<E2ePadlock title={_t("Encrypted by a deleted session")} icon="unknown" {...props} />
);
}
class E2ePadlock extends React.Component {
static propTypes = {
icon: PropTypes.string.isRequired,