diff --git a/src/components/views/messages/MKeyVerificationConclusion.tsx b/src/components/views/messages/MKeyVerificationConclusion.tsx deleted file mode 100644 index 01627619ea..0000000000 --- a/src/components/views/messages/MKeyVerificationConclusion.tsx +++ /dev/null @@ -1,144 +0,0 @@ -/* -Copyright 2019, 2020 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import React from "react"; -import classNames from "classnames"; -import { MatrixEvent, EventType } from "matrix-js-sdk/src/matrix"; -import { VerificationPhase, VerificationRequest, VerificationRequestEvent } from "matrix-js-sdk/src/crypto-api"; -import { CryptoEvent } from "matrix-js-sdk/src/crypto"; - -import { MatrixClientPeg } from "../../../MatrixClientPeg"; -import { _t } from "../../../languageHandler"; -import { getNameForEventRoom, userLabelForEventRoom } from "../../../utils/KeyVerificationStateObserver"; -import EventTileBubble from "./EventTileBubble"; - -interface IProps { - /* the MatrixEvent to show */ - mxEvent: MatrixEvent; - timestamp?: JSX.Element; -} - -export default class MKeyVerificationConclusion extends React.Component { - public constructor(props: IProps) { - super(props); - } - - public componentDidMount(): void { - const request = this.props.mxEvent.verificationRequest; - if (request) { - request.on(VerificationRequestEvent.Change, this.onRequestChanged); - } - MatrixClientPeg.safeGet().on(CryptoEvent.UserTrustStatusChanged, this.onTrustChanged); - } - - public componentWillUnmount(): void { - const request = this.props.mxEvent.verificationRequest; - if (request) { - request.off(VerificationRequestEvent.Change, this.onRequestChanged); - } - const cli = MatrixClientPeg.get(); - if (cli) { - cli.removeListener(CryptoEvent.UserTrustStatusChanged, this.onTrustChanged); - } - } - - private onRequestChanged = (): void => { - this.forceUpdate(); - }; - - private onTrustChanged = (userId: string): void => { - const { mxEvent } = this.props; - const request = mxEvent.verificationRequest; - if (!request || request.otherUserId !== userId) { - return; - } - this.forceUpdate(); - }; - - public static shouldRender(mxEvent: MatrixEvent, request?: VerificationRequest): boolean { - // normally should not happen - if (!request) { - return false; - } - // .cancel event that was sent after the verification finished, ignore - if (mxEvent.getType() === EventType.KeyVerificationCancel && request.phase !== VerificationPhase.Cancelled) { - return false; - } - // .done event that was sent after the verification cancelled, ignore - if (mxEvent.getType() === EventType.KeyVerificationDone && request.phase !== VerificationPhase.Done) { - return false; - } - - // request hasn't concluded yet - if (request.pending) { - return false; - } - - // User isn't actually verified - if (!MatrixClientPeg.safeGet().checkUserTrust(request.otherUserId).isCrossSigningVerified()) { - return false; - } - - return true; - } - - public render(): JSX.Element | null { - const { mxEvent } = this.props; - const request = mxEvent.verificationRequest!; - - if (!MKeyVerificationConclusion.shouldRender(mxEvent, request)) { - return null; - } - - const client = MatrixClientPeg.safeGet(); - const myUserId = client.getUserId(); - - let title: string | undefined; - - if (request.phase === VerificationPhase.Done) { - title = _t("timeline|m.key.verification.done", { - name: getNameForEventRoom(client, request.otherUserId, mxEvent.getRoomId()!), - }); - } else if (request.phase === VerificationPhase.Cancelled) { - const userId = request.cancellingUserId; - if (userId === myUserId) { - title = _t("timeline|m.key.verification.cancel|you_cancelled", { - name: getNameForEventRoom(client, request.otherUserId, mxEvent.getRoomId()!), - }); - } else if (userId) { - title = _t("timeline|m.key.verification.cancel|user_cancelled", { - name: getNameForEventRoom(client, userId, mxEvent.getRoomId()!), - }); - } - } - - if (title) { - const classes = classNames("mx_cryptoEvent mx_cryptoEvent_icon", { - mx_cryptoEvent_icon_verified: request.phase === VerificationPhase.Done, - }); - return ( - - ); - } - - return null; - } -} diff --git a/src/events/EventTileFactory.tsx b/src/events/EventTileFactory.tsx index 4464d6b24e..88ebb0a560 100644 --- a/src/events/EventTileFactory.tsx +++ b/src/events/EventTileFactory.tsx @@ -32,7 +32,6 @@ import LegacyCallEventGrouper from "../components/structures/LegacyCallEventGrou import { EventTileProps } from "../components/views/rooms/EventTile"; import { TimelineRenderingType } from "../contexts/RoomContext"; import MessageEvent from "../components/views/messages/MessageEvent"; -import MKeyVerificationConclusion from "../components/views/messages/MKeyVerificationConclusion"; import LegacyCallEvent from "../components/views/messages/LegacyCallEvent"; import { CallEvent } from "../components/views/messages/CallEvent"; import TextualEvent from "../components/views/messages/TextualEvent"; @@ -87,7 +86,6 @@ type FactoryProps = Omit; type Factory = (ref: Optional>, props: X) => JSX.Element; export const MessageEventFactory: Factory = (ref, props) => ; -const KeyVerificationConclFactory: Factory = (ref, props) => ; const LegacyCallEventFactory: Factory = (ref, props) => ( ); @@ -108,8 +106,6 @@ const EVENT_TILE_TYPES = new Map([ [M_POLL_START.altName, MessageEventFactory], [M_POLL_END.name, MessageEventFactory], [M_POLL_END.altName, MessageEventFactory], - [EventType.KeyVerificationCancel, KeyVerificationConclFactory], - [EventType.KeyVerificationDone, KeyVerificationConclFactory], [EventType.CallInvite, LegacyCallEventFactory as Factory], // note that this requires a special factory type ]); @@ -205,23 +201,6 @@ export function pickFactory( return VerificationReqFactory; } } - } else if (evType === EventType.KeyVerificationDone) { - // these events are sent by both parties during verification, but we only want to render one - // tile once the verification concludes, so filter out the one from the other party. - const me = cli.getUserId(); - if (mxEvent.getSender() !== me) { - return noEventFactoryFactory(); - } - } - - if (evType === EventType.KeyVerificationCancel || evType === EventType.KeyVerificationDone) { - // 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 (!MKeyVerificationConclusion.shouldRender(mxEvent, mxEvent.verificationRequest)) { - return noEventFactoryFactory(); - } } if (evType === EventType.RoomCreate) { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 0fc2e502c8..7b687d9a03 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -3261,11 +3261,6 @@ "sent": "%(senderDisplayName)s sent an image.", "show_image": "Show image" }, - "m.key.verification.cancel": { - "user_cancelled": "%(name)s cancelled verifying", - "you_cancelled": "You cancelled verifying %(name)s" - }, - "m.key.verification.done": "You verified %(name)s", "m.key.verification.request": { "user_wants_to_verify": "%(name)s wants to verify", "you_started": "You sent a verification request" diff --git a/test/components/views/messages/MKeyVerificationConclusion-test.tsx b/test/components/views/messages/MKeyVerificationConclusion-test.tsx deleted file mode 100644 index b9cb024e73..0000000000 --- a/test/components/views/messages/MKeyVerificationConclusion-test.tsx +++ /dev/null @@ -1,156 +0,0 @@ -/* -Copyright 2022 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import React from "react"; -import { render } from "@testing-library/react"; -import { EventEmitter } from "events"; -import { EventType, MatrixEvent } from "matrix-js-sdk/src/matrix"; -import { CryptoEvent } from "matrix-js-sdk/src/crypto"; -import { UserTrustLevel } from "matrix-js-sdk/src/crypto/CrossSigning"; -import { - Phase as VerificationPhase, - VerificationRequest, -} from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest"; - -import { MatrixClientPeg } from "../../../../src/MatrixClientPeg"; -import MKeyVerificationConclusion from "../../../../src/components/views/messages/MKeyVerificationConclusion"; -import { getMockClientWithEventEmitter } from "../../../test-utils"; - -const trustworthy = { isCrossSigningVerified: () => true } as unknown as UserTrustLevel; -const untrustworthy = { isCrossSigningVerified: () => false } as unknown as UserTrustLevel; - -describe("MKeyVerificationConclusion", () => { - const userId = "@user:server"; - const mockClient = getMockClientWithEventEmitter({ - getRoom: jest.fn(), - getUserId: jest.fn().mockReturnValue(userId), - checkUserTrust: jest.fn(), - }); - - const getMockVerificationRequest = ({ - pending = false, - phase = VerificationPhase.Unsent, - otherUserId, - cancellingUserId, - }: { - pending?: boolean; - phase?: VerificationPhase; - otherUserId?: string; - cancellingUserId?: string; - }) => { - class MockVerificationRequest extends EventEmitter { - constructor( - public readonly pending: boolean, - public readonly phase: VerificationPhase, - public readonly otherUserId?: string, - public readonly cancellingUserId?: string, - ) { - super(); - } - } - return new MockVerificationRequest( - pending, - phase, - otherUserId, - cancellingUserId, - ) as unknown as VerificationRequest; - }; - - beforeEach(() => { - jest.clearAllMocks(); - mockClient.checkUserTrust.mockReturnValue(trustworthy); - }); - - afterAll(() => { - jest.spyOn(MatrixClientPeg, "get").mockRestore(); - }); - - it("shouldn't render if there's no verificationRequest", () => { - const event = new MatrixEvent({}); - const { container } = render(); - expect(container).toBeEmpty(); - }); - - it("shouldn't render if the verificationRequest is pending", () => { - const event = new MatrixEvent({}); - event.verificationRequest = getMockVerificationRequest({ pending: true }); - const { container } = render(); - expect(container).toBeEmpty(); - }); - - it("shouldn't render if the event type is cancel but the request type isn't", () => { - const event = new MatrixEvent({ type: EventType.KeyVerificationCancel }); - event.verificationRequest = getMockVerificationRequest({}); - const { container } = render(); - expect(container).toBeEmpty(); - }); - - 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 = getMockVerificationRequest({}); - const { container } = render(); - expect(container).toBeEmpty(); - }); - - it("shouldn't render if the user isn't actually trusted", () => { - mockClient.checkUserTrust.mockReturnValue(untrustworthy); - - const event = new MatrixEvent({ type: "m.key.verification.done" }); - event.verificationRequest = getMockVerificationRequest({ phase: VerificationPhase.Done }); - const { container } = render(); - expect(container).toBeEmpty(); - }); - - it("should rerender appropriately if user trust status changes", () => { - mockClient.checkUserTrust.mockReturnValue(untrustworthy); - - const event = new MatrixEvent({ type: "m.key.verification.done" }); - event.verificationRequest = getMockVerificationRequest({ - phase: VerificationPhase.Done, - otherUserId: "@someuser:domain", - }); - const { container } = render(); - expect(container).toBeEmpty(); - - mockClient.checkUserTrust.mockReturnValue(trustworthy); - - /* Ensure we don't rerender for every trust status change of any user */ - mockClient.emit( - CryptoEvent.UserTrustStatusChanged, - "@anotheruser:domain", - new UserTrustLevel(true, true, true), - ); - expect(container).toBeEmpty(); - - /* But when our user changes, we do rerender */ - mockClient.emit( - CryptoEvent.UserTrustStatusChanged, - event.verificationRequest.otherUserId, - new UserTrustLevel(true, true, true), - ); - expect(container).not.toBeEmpty(); - }); - - it("should render appropriately if we cancelled the verification", () => { - const event = new MatrixEvent({ type: "m.key.verification.cancel" }); - event.verificationRequest = getMockVerificationRequest({ - phase: VerificationPhase.Cancelled, - cancellingUserId: userId, - }); - const { container } = render(); - expect(container).toHaveTextContent("You cancelled verifying"); - }); -});