diff --git a/src/components/views/messages/MKeyVerificationConclusion.js b/src/components/views/messages/MKeyVerificationConclusion.js index c410c7fdffc..76370ba1486 100644 --- a/src/components/views/messages/MKeyVerificationConclusion.js +++ b/src/components/views/messages/MKeyVerificationConclusion.js @@ -32,6 +32,7 @@ export default class MKeyVerificationConclusion extends React.Component { if (request) { request.on("change", this._onRequestChanged); } + MatrixClientPeg.get().on("userTrustStatusChanged", this._onTrustChanged); } componentWillUnmount() { @@ -39,12 +40,22 @@ export default class MKeyVerificationConclusion extends React.Component { if (request) { request.off("change", this._onRequestChanged); } + MatrixClientPeg.removeListener("userTrustStatusChanged", this._onTrustChanged); } _onRequestChanged = () => { this.forceUpdate(); }; + _onTrustChanged = (userId, status) => { + const { mxEvent } = this.props; + const request = mxEvent.verificationRequest; + if (!request || request.otherUserId !== userId) { + return; + } + this.forceUpdate(); + }; + _shouldRender(mxEvent, request) { // normally should not happen if (!request) { @@ -63,6 +74,14 @@ export default class MKeyVerificationConclusion extends React.Component { if (request.pending) { return false; } + + // User isn't actually verified + if (!MatrixClientPeg.get() + .checkUserTrust(request.otherUserId) + .isCrossSigningVerified()) { + return false; + } + return true; } diff --git a/test/components/views/messages/MKeyVerificationConclusion-test.js b/test/components/views/messages/MKeyVerificationConclusion-test.js new file mode 100644 index 00000000000..689151fe3fd --- /dev/null +++ b/test/components/views/messages/MKeyVerificationConclusion-test.js @@ -0,0 +1,99 @@ +import React from 'react'; +import TestRenderer from 'react-test-renderer'; +import { EventEmitter } from 'events'; +import * as TestUtils from '../../../test-utils'; + +import { MatrixClientPeg } from '../../../../src/MatrixClientPeg'; +import { MatrixEvent } from 'matrix-js-sdk'; +import MKeyVerificationConclusion from '../../../../src/components/views/messages/MKeyVerificationConclusion'; + +const trustworthy = () => ({ isCrossSigningVerified: () => true }); +const untrustworthy = () => ({ isCrossSigningVerified: () => false }); + +describe("MKeyVerificationConclusion", () => { + beforeEach(() => { + TestUtils.stubClient(); + const client = MatrixClientPeg.get(); + client.checkUserTrust = trustworthy; + + const emitter = new EventEmitter(); + client.on = emitter.on.bind(emitter); + client.removeListener = emitter.removeListener.bind(emitter); + client.emit = emitter.emit.bind(emitter); + }); + + it("shouldn't render if there's no verificationRequest", () => { + const event = new MatrixEvent({}); + const renderer = TestRenderer.create( + , + ); + expect(renderer.toJSON()).toBeNull(); + }); + + it("shouldn't render if the verificationRequest is pending", () => { + const event = new MatrixEvent({}); + event.verificationRequest = new EventEmitter(); + event.verificationRequest.pending = true; + const renderer = TestRenderer.create( + , + ); + expect(renderer.toJSON()).toBeNull(); + }); + + it("shouldn't render if the event type is cancel but the request type isn't", () => { + const event = new MatrixEvent({ type: "m.key.verification.cancel" }); + event.verificationRequest = new EventEmitter(); + event.verificationRequest.cancelled = false; + const renderer = TestRenderer.create( + , + ); + expect(renderer.toJSON()).toBeNull(); + }); + + it("shouldn't render if the event type is done but the request type isn't", () => { + const event = new MatrixEvent({ type: "m.key.verification.done" }); + event.verificationRequest = new EventEmitter(); + event.verificationRequest.done = false; + const renderer = TestRenderer.create( + , + ); + expect(renderer.toJSON()).toBeNull(); + }); + + it("shouldn't render if the user isn't actually trusted", () => { + const client = MatrixClientPeg.get(); + client.checkUserTrust = untrustworthy; + + const event = new MatrixEvent({ type: "m.key.verification.done" }); + event.verificationRequest = new EventEmitter(); + event.verificationRequest.done = true; + const renderer = TestRenderer.create( + , + ); + expect(renderer.toJSON()).toBeNull(); + }); + + it("should rerender appropriately if user trust status changes", () => { + const client = MatrixClientPeg.get(); + client.checkUserTrust = untrustworthy; + + const event = new MatrixEvent({ type: "m.key.verification.done" }); + event.verificationRequest = new EventEmitter(); + event.verificationRequest.done = true; + event.verificationRequest.otherUserId = "@someuser:domain"; + const renderer = TestRenderer.create( + , + ); + expect(renderer.toJSON()).toBeNull(); + + client.checkUserTrust = trustworthy; + + /* Ensure we don't rerender for every trust status change of any user */ + client.emit("userTrustStatusChanged", "@anotheruser:domain"); + expect(renderer.toJSON()).toBeNull(); + + /* But when our user changes, we do rerender */ + client.emit("userTrustStatusChanged", event.verificationRequest.otherUserId); + expect(renderer.toJSON()).not.toBeNull(); + }); +});