From 07cc640089919a228f3c5c7e7405d4f85fe63905 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 29 Mar 2019 11:45:07 -0600 Subject: [PATCH] Add common utility for checking 3pid invites We just need to make sure they are structurally sound - actual validation is done by other parties. --- src/RoomInvite.js | 18 ++++++++++++++++++ src/TextForEvent.js | 3 ++- src/components/views/rooms/MemberList.js | 7 ++----- .../views/rooms/ThirdPartyMemberInfo.js | 7 ++++--- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/RoomInvite.js b/src/RoomInvite.js index 3547b9195f..b808b935a6 100644 --- a/src/RoomInvite.js +++ b/src/RoomInvite.js @@ -65,6 +65,24 @@ export function showRoomInviteDialog(roomId) { }); } +/** + * Checks if the given MatrixEvent is a valid 3rd party user invite. + * @param {MatrixEvent} event The event to check + * @returns {boolean} True if valid, false otherwise + */ +export function isValid3pidInvite(event) { + if (!event || event.getType() !== "m.room.third_party_invite") return false; + + // any events without these keys are not valid 3pid invites, so we ignore them + const requiredKeys = ['key_validity_url', 'public_key', 'display_name']; + for (let i = 0; i < requiredKeys.length; ++i) { + if (!event.getContent()[requiredKeys[i]]) return false; + } + + // Valid enough by our standards + return true; +} + function _onStartChatFinished(shouldInvite, addrs) { if (!shouldInvite) return; diff --git a/src/TextForEvent.js b/src/TextForEvent.js index 05d83d740a..a700fe2a3c 100644 --- a/src/TextForEvent.js +++ b/src/TextForEvent.js @@ -17,6 +17,7 @@ import MatrixClientPeg from './MatrixClientPeg'; import CallHandler from './CallHandler'; import { _t } from './languageHandler'; import * as Roles from './Roles'; +import {isValid3pidInvite} from "./RoomInvite"; function textForMemberEvent(ev) { // XXX: SYJS-16 "sender is sometimes null for join messages" @@ -367,7 +368,7 @@ function textForCallInviteEvent(event) { function textForThreePidInviteEvent(event) { const senderName = event.sender ? event.sender.name : event.getSender(); - if (!event.getContent().display_name) { + if (!isValid3pidInvite(event)) { const targetDisplayName = event.getPrevContent().display_name || _t("Someone"); return _t('%(senderName)s revoked the invitation for %(targetDisplayName)s to join the room.', { senderName, diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index a8cc948f63..e79f2f21d4 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -20,6 +20,7 @@ import React from 'react'; import { _t } from '../../../languageHandler'; import SdkConfig from '../../../SdkConfig'; import dis from '../../../dispatcher'; +import {isValid3pidInvite} from "../../../RoomInvite"; const MatrixClientPeg = require("../../../MatrixClientPeg"); const sdk = require('../../../index'); const rate_limited_func = require('../../../ratelimitedfunc'); @@ -379,11 +380,7 @@ module.exports = React.createClass({ if (room) { return room.currentState.getStateEvents("m.room.third_party_invite").filter(function(e) { - // any events without these keys are not valid 3pid invites, so we ignore them - const requiredKeys = ['key_validity_url', 'public_key', 'display_name']; - for (let i = 0; i < requiredKeys.length; ++i) { - if (e.getContent()[requiredKeys[i]] === undefined) return false; - } + if (!isValid3pidInvite(e)) return false; // discard all invites which have a m.room.member event since we've // already added them. diff --git a/src/components/views/rooms/ThirdPartyMemberInfo.js b/src/components/views/rooms/ThirdPartyMemberInfo.js index 3fe8382251..754e32871f 100644 --- a/src/components/views/rooms/ThirdPartyMemberInfo.js +++ b/src/components/views/rooms/ThirdPartyMemberInfo.js @@ -22,6 +22,7 @@ import {_t} from "../../../languageHandler"; import dis from "../../../dispatcher"; import sdk from "../../../index"; import Modal from "../../../Modal"; +import {isValid3pidInvite} from "../../../RoomInvite"; export default class ThirdPartyMemberInfo extends React.Component { static propTypes = { @@ -64,7 +65,7 @@ export default class ThirdPartyMemberInfo extends React.Component { onRoomStateEvents = (ev) => { if (ev.getType() === "m.room.third_party_invite" && ev.getStateKey() === this.state.stateKey) { const newDisplayName = ev.getContent().display_name; - const isInvited = !!newDisplayName; // display_name indicates a valid invite + const isInvited = isValid3pidInvite(ev); const newState = {invited: isInvited}; if (newDisplayName) newState['displayName'] = newDisplayName; @@ -123,8 +124,8 @@ export default class ThirdPartyMemberInfo extends React.Component {

{this.state.displayName}