Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Delegate decisions on event shields to the js-sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
richvdh committed Sep 5, 2023
1 parent c853257 commit a3863fb
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 100 deletions.
4 changes: 2 additions & 2 deletions cypress/e2e/crypto/crypto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ describe("Cryptography", function () {
.should("contain", "test encrypted from unverified")
.find(".mx_EventTile_e2eIcon", { timeout: 100000 })
.should("have.class", "mx_EventTile_e2eIcon_warning")
.should("have.attr", "aria-label", "Encrypted by an unverified session");
.should("have.attr", "aria-label", "Encrypted by an unverified user.");

/* Should show a grey padlock for a message from an unknown device */

Expand All @@ -423,7 +423,7 @@ describe("Cryptography", function () {
.should("contain", "test encrypted from unverified")
.find(".mx_EventTile_e2eIcon")
.should("have.class", "mx_EventTile_e2eIcon_normal")
.should("have.attr", "aria-label", "Encrypted by a deleted session");
.should("have.attr", "aria-label", "Encrypted by an unknown or deleted device.");
});

it("Should show a grey padlock for a key restored from backup", () => {
Expand Down
10 changes: 5 additions & 5 deletions res/css/views/rooms/_EventTile.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -846,17 +846,17 @@ $left-gutter: 64px;
}

&.mx_EventTile_e2eIcon_warning::after {
mask-image: url("$(res)/img/e2e/warning.svg");
background-color: $e2e-warning-color;
mask-image: url("$(res)/img/e2e/warning.svg"); // (!) in a shield
background-color: $e2e-warning-color; // red
}

&.mx_EventTile_e2eIcon_normal::after {
mask-image: url("$(res)/img/e2e/normal.svg");
background-color: $header-panel-text-primary-color;
mask-image: url("$(res)/img/e2e/normal.svg"); // regular shield
background-color: $header-panel-text-primary-color; // grey
}

&.mx_EventTile_e2eIcon_decryption_failure::after {
mask-image: url("$(res)/img/e2e/decryption-failure.svg");
mask-image: url("$(res)/img/e2e/decryption-failure.svg"); // key in a circle
background-color: $secondary-content;
}
}
Expand Down
167 changes: 77 additions & 90 deletions src/components/views/rooms/EventTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,25 @@ limitations under the License.
import React, { createRef, forwardRef, MouseEvent, ReactNode, useRef } from "react";
import classNames from "classnames";
import {
EventType,
MsgType,
RelationType,
EventStatus,
EventType,
MatrixEvent,
MatrixEventEvent,
RoomMember,
MsgType,
NotificationCountType,
Relations,
RelationType,
Room,
RoomEvent,
Relations,
RoomMember,
Thread,
ThreadEvent,
} from "matrix-js-sdk/src/matrix";
import { logger } from "matrix-js-sdk/src/logger";
import { CallErrorCode } from "matrix-js-sdk/src/webrtc/call";
import { CryptoEvent } from "matrix-js-sdk/src/crypto";
import { UserTrustLevel } from "matrix-js-sdk/src/crypto/CrossSigning";
import { EventShieldColour, EventShieldReason } from "matrix-js-sdk/src/crypto-api";

import ReplyChain from "../elements/ReplyChain";
import { _t } from "../../../languageHandler";
Expand All @@ -44,7 +45,6 @@ import { Layout } from "../../../settings/enums/Layout";
import { formatTime } from "../../../DateUtils";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import { DecryptionFailureBody } from "../messages/DecryptionFailureBody";
import { E2EState } from "./E2EIcon";
import RoomAvatar from "../avatars/RoomAvatar";
import MessageContextMenu from "../context_menus/MessageContextMenu";
import { aboveRightOf } from "../../structures/ContextMenu";
Expand Down Expand Up @@ -236,8 +236,19 @@ export interface EventTileProps {
interface IState {
// Whether the action bar is focused.
actionBarFocused: boolean;
// Whether the event's sender has been verified.
verified: string | null;

/**
* E2EE shield we should show for decryption problems.
*
* Note this will be `EventShieldColour.NONE` for all unencrypted events, **including those in encrypted rooms**.
*/
shieldColour: EventShieldColour;

/**
* Reason code for the E2EE shield. `null` if `shieldColour` is `EventShieldColour.NONE`
*/
shieldReason: EventShieldReason | null;

// The Relations model from the JS SDK for reactions to `mxEvent`
reactions?: Relations | null | undefined;

Expand Down Expand Up @@ -299,9 +310,10 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
this.state = {
// Whether the action bar is focused.
actionBarFocused: false,
// Whether the event's sender has been verified. `null` if no attempt has yet been made to verify
// (including if the event is not encrypted).
verified: null,

shieldColour: EventShieldColour.NONE,
shieldReason: null,

// The Relations model from the JS SDK for reactions to `mxEvent`
reactions: this.getReactions(),

Expand Down Expand Up @@ -437,8 +449,9 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
}

public componentDidUpdate(prevProps: Readonly<EventTileProps>, prevState: Readonly<IState>): void {
// If the verification state changed, the height might have changed
if (prevState.verified !== this.state.verified && this.props.onHeightChanged) {
// If the shield state changed, the height might have changed.
// XXX: does the shield *actually* cause a change in height? Not sure.
if (prevState.shieldColour !== this.state.shieldColour && this.props.onHeightChanged) {
this.props.onHeightChanged();
}
// If we're not listening for receipts and expect to be, register a listener.
Expand Down Expand Up @@ -582,59 +595,20 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
const mxEvent = this.props.mxEvent.replacingEvent() ?? this.props.mxEvent;

if (!mxEvent.isEncrypted() || mxEvent.isRedacted()) {
this.setState({ verified: null });
this.setState({ shieldColour: EventShieldColour.NONE, shieldReason: null });
return;
}

const encryptionInfo = MatrixClientPeg.safeGet().getEventEncryptionInfo(mxEvent);
const senderId = mxEvent.getSender();
if (!senderId) {
// something definitely wrong is going on here
this.setState({ verified: E2EState.Warning });
return;
}

const userTrust = MatrixClientPeg.safeGet().checkUserTrust(senderId);

if (encryptionInfo.mismatchedSender) {
// something definitely wrong is going on here
this.setState({ verified: E2EState.Warning });
return;
}

if (!userTrust.isCrossSigningVerified()) {
// If the message is unauthenticated, then display a grey
// shield, otherwise if the user isn't cross-signed then
// nothing's needed
this.setState({ verified: encryptionInfo.authenticated ? E2EState.Normal : E2EState.Unauthenticated });
return;
}

const eventSenderTrust =
senderId &&
encryptionInfo.sender &&
(await MatrixClientPeg.safeGet()
.getCrypto()
?.getDeviceVerificationStatus(senderId, encryptionInfo.sender.deviceId));

const encryptionInfo =
(await MatrixClientPeg.safeGet().getCrypto()?.getEncryptionInfoForEvent(mxEvent)) ?? null;

Check failure on line 603 in src/components/views/rooms/EventTile.tsx

View workflow job for this annotation

GitHub Actions / Jest

EventTile › Event verification › shows a warning for an event from an unverified device

TypeError: _MatrixClientPeg.MatrixClientPeg.safeGet(...).getCrypto(...)?.getEncryptionInfoForEvent is not a function at UnwrappedEventTile.getEncryptionInfoForEvent [as verifyEvent] (src/components/views/rooms/EventTile.tsx:603:59) at UnwrappedEventTile.verifyEvent [as componentDidMount] (src/components/views/rooms/EventTile.tsx:417:14) at commitLifeCycles (node_modules/react-dom/cjs/react-dom.development.js:20663:24) at commitLayoutEffects (node_modules/react-dom/cjs/react-dom.development.js:23426:7) at HTMLUnknownElement.callCallback (node_modules/react-dom/cjs/react-dom.development.js:3945:14) at HTMLUnknownElement.callTheUserObjectsOperation (node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30) at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:350:25) at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:286:3) at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:233:9) at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:104:17) at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:241:34) at Object.invokeGuardedCallbackDev (node_modules/react-dom/cjs/react-dom.development.js:3994:16) at invokeGuardedCallback (node_modules/react-dom/cjs/react-dom.development.js:4056:31) at commitRootImpl (node_modules/react-dom/cjs/react-dom.development.js:23151:9) at unstable_runWithPriority (node_modules/scheduler/cjs/scheduler.development.js:468:12) at runWithPriority$1 (node_modules/react-dom/cjs/react-dom.development.js:11276:10) at commitRoot (node_modules/react-dom/cjs/react-dom.development.js:22990:3) at performSyncWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:22329:3) at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom.development.js:21881:7) at updateContainer (node_modules/react-dom/cjs/react-dom.development.js:25482:3) at node_modules/react-dom/cjs/react-dom.development.js:26021:7 at unbatchedUpdates (node_modules/react-dom/cjs/react-dom.development.js:22431:12) at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:26020:5) at Object.render (node_modules/react-dom/cjs/react-dom.development.js:26103:10) at node_modules/@testing-library/react/dist/pure.js:101:25 at batchedUpdates$1 (node_modules/react-dom/cjs/react-dom.development.js:22380:12) at act (node_modules/react-dom/cjs/react-dom-test-utils.development.js:1042:14) at render (node_modules/@testing-library/react/dist/pure.js:97:26) at getComponent (test/components/views/rooms/EventTile-test.tsx:67:22) at Object.getComponent (test/components/views/rooms/EventTile-test.tsx:243:35)

Check failure on line 603 in src/components/views/rooms/EventTile.tsx

View workflow job for this annotation

GitHub Actions / Jest

EventTile › Event verification › shows no shield for a verified event

TypeError: _MatrixClientPeg.MatrixClientPeg.safeGet(...).getCrypto(...)?.getEncryptionInfoForEvent is not a function at UnwrappedEventTile.getEncryptionInfoForEvent [as verifyEvent] (src/components/views/rooms/EventTile.tsx:603:59) at UnwrappedEventTile.verifyEvent [as componentDidMount] (src/components/views/rooms/EventTile.tsx:417:14) at commitLifeCycles (node_modules/react-dom/cjs/react-dom.development.js:20663:24) at commitLayoutEffects (node_modules/react-dom/cjs/react-dom.development.js:23426:7) at HTMLUnknownElement.callCallback (node_modules/react-dom/cjs/react-dom.development.js:3945:14) at HTMLUnknownElement.callTheUserObjectsOperation (node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30) at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:350:25) at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:286:3) at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:233:9) at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:104:17) at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:241:34) at Object.invokeGuardedCallbackDev (node_modules/react-dom/cjs/react-dom.development.js:3994:16) at invokeGuardedCallback (node_modules/react-dom/cjs/react-dom.development.js:4056:31) at commitRootImpl (node_modules/react-dom/cjs/react-dom.development.js:23151:9) at unstable_runWithPriority (node_modules/scheduler/cjs/scheduler.development.js:468:12) at runWithPriority$1 (node_modules/react-dom/cjs/react-dom.development.js:11276:10) at commitRoot (node_modules/react-dom/cjs/react-dom.development.js:22990:3) at performSyncWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:22329:3) at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom.development.js:21881:7) at updateContainer (node_modules/react-dom/cjs/react-dom.development.js:25482:3) at node_modules/react-dom/cjs/react-dom.development.js:26021:7 at unbatchedUpdates (node_modules/react-dom/cjs/react-dom.development.js:22431:12) at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:26020:5) at Object.render (node_modules/react-dom/cjs/react-dom.development.js:26103:10) at node_modules/@testing-library/react/dist/pure.js:101:25 at batchedUpdates$1 (node_modules/react-dom/cjs/react-dom.development.js:22380:12) at act (node_modules/react-dom/cjs/react-dom-test-utils.development.js:1042:14) at render (node_modules/@testing-library/react/dist/pure.js:97:26) at getComponent (test/components/views/rooms/EventTile-test.tsx:67:22) at Object.getComponent (test/components/views/rooms/EventTile-test.tsx:268:35)

Check failure on line 603 in src/components/views/rooms/EventTile.tsx

View workflow job for this annotation

GitHub Actions / Jest

EventTile › Event verification › should update the warning when the event is edited

TypeError: _MatrixClientPeg.MatrixClientPeg.safeGet(...).getCrypto(...)?.getEncryptionInfoForEvent is not a function at UnwrappedEventTile.getEncryptionInfoForEvent [as verifyEvent] (src/components/views/rooms/EventTile.tsx:603:59) at UnwrappedEventTile.verifyEvent [as componentDidMount] (src/components/views/rooms/EventTile.tsx:417:14) at commitLifeCycles (node_modules/react-dom/cjs/react-dom.development.js:20663:24) at commitLayoutEffects (node_modules/react-dom/cjs/react-dom.development.js:23426:7) at HTMLUnknownElement.callCallback (node_modules/react-dom/cjs/react-dom.development.js:3945:14) at HTMLUnknownElement.callTheUserObjectsOperation (node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30) at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:350:25) at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:286:3) at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:233:9) at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:104:17) at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:241:34) at Object.invokeGuardedCallbackDev (node_modules/react-dom/cjs/react-dom.development.js:3994:16) at invokeGuardedCallback (node_modules/react-dom/cjs/react-dom.development.js:4056:31) at commitRootImpl (node_modules/react-dom/cjs/react-dom.development.js:23151:9) at unstable_runWithPriority (node_modules/scheduler/cjs/scheduler.development.js:468:12) at runWithPriority$1 (node_modules/react-dom/cjs/react-dom.development.js:11276:10) at commitRoot (node_modules/react-dom/cjs/react-dom.development.js:22990:3) at performSyncWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:22329:3) at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom.development.js:21881:7) at updateContainer (node_modules/react-dom/cjs/react-dom.development.js:25482:3) at node_modules/react-dom/cjs/react-dom.development.js:26021:7 at unbatchedUpdates (node_modules/react-dom/cjs/react-dom.development.js:22431:12) at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:26020:5) at Object.render (node_modules/react-dom/cjs/react-dom.development.js:26103:10) at node_modules/@testing-library/react/dist/pure.js:101:25 at batchedUpdates$1 (node_modules/react-dom/cjs/react-dom.development.js:22380:12) at act (node_modules/react-dom/cjs/react-dom-test-utils.development.js:1042:14) at render (node_modules/@testing-library/react/dist/pure.js:97:26) at getComponent (test/components/views/rooms/EventTile-test.tsx:67:22) at Object.getComponent (test/components/views/rooms/EventTile-test.tsx:291:35)

Check failure on line 603 in src/components/views/rooms/EventTile.tsx

View workflow job for this annotation

GitHub Actions / Jest

EventTile › Event verification › should update the warning when the event is edited

TypeError: _MatrixClientPeg.MatrixClientPeg.safeGet(...).getCrypto(...)?.getEncryptionInfoForEvent is not a function at UnwrappedEventTile.getEncryptionInfoForEvent [as verifyEvent] (src/components/views/rooms/EventTile.tsx:603:59) at MatrixEvent.verifyEvent (src/components/views/rooms/EventTile.tsx:589:14) at MatrixEvent.emit (matrix-js-sdk/src/models/typed-event-emitter.ts:89:22) at MatrixEvent.emit [as makeReplaced] (matrix-js-sdk/src/models/event.ts:1422:18) at makeReplaced (test/components/views/rooms/EventTile-test.tsx:313:25) at batchedUpdates$1 (node_modules/react-dom/cjs/react-dom.development.js:22380:12) at act (node_modules/react-dom/cjs/react-dom-test-utils.development.js:1042:14) at Object.<anonymous> (test/components/views/rooms/EventTile-test.tsx:312:22)

Check failure on line 603 in src/components/views/rooms/EventTile.tsx

View workflow job for this annotation

GitHub Actions / Jest

EventTile › Event verification › should update the warning when the event is replaced with an unencrypted one

TypeError: _MatrixClientPeg.MatrixClientPeg.safeGet(...).getCrypto(...)?.getEncryptionInfoForEvent is not a function at UnwrappedEventTile.getEncryptionInfoForEvent [as verifyEvent] (src/components/views/rooms/EventTile.tsx:603:59) at UnwrappedEventTile.verifyEvent [as componentDidMount] (src/components/views/rooms/EventTile.tsx:417:14) at commitLifeCycles (node_modules/react-dom/cjs/react-dom.development.js:20663:24) at commitLayoutEffects (node_modules/react-dom/cjs/react-dom.development.js:23426:7) at HTMLUnknownElement.callCallback (node_modules/react-dom/cjs/react-dom.development.js:3945:14) at HTMLUnknownElement.callTheUserObjectsOperation (node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30) at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:350:25) at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:286:3) at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:233:9) at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:104:17) at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:241:34) at Object.invokeGuardedCallbackDev (node_modules/react-dom/cjs/react-dom.development.js:3994:16) at invokeGuardedCallback (node_modules/react-dom/cjs/react-dom.development.js:4056:31) at commitRootImpl (node_modules/react-dom/cjs/react-dom.development.js:23151:9) at unstable_runWithPriority (node_modules/scheduler/cjs/scheduler.development.js:468:12) at runWithPriority$1 (node_modules/react-dom/cjs/react-dom.development.js:11276:10) at commitRoot (node_modules/react-dom/cjs/react-dom.development.js:22990:3) at performSyncWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:22329:3) at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom.development.js:21881:7) at updateContainer (node_modules/react-dom/cjs/react-dom.development.js:25482:3) at node_modules/react-dom/cjs/react-dom.development.js:26021:7 at unbatchedUpdates (node_modules/react-dom/cjs/react-dom.development.js:22431:12) at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:26020:5) at Object.render (node_modules/react-dom/cjs/react-dom.development.js:26103:10) at node_modules/@testing-library/react/dist/pure.js:101:25 at batchedUpdates$1 (node_modules/react-dom/cjs/react-dom.development.js:22380:12) at act (node_modules/react-dom/cjs/react-dom-test-utils.development.js:1042:14) at render (node_modules/@testing-library/react/dist/pure.js:97:26) at getComponent (test/components/views/rooms/EventTile-test.tsx:67:22) at Object.getComponent (test/components/views/rooms/EventTile-test.tsx:339:35)
if (this.unmounted) return;

if (!eventSenderTrust) {
this.setState({ verified: E2EState.Unknown });
return;
}

if (!eventSenderTrust.isVerified()) {
this.setState({ verified: E2EState.Warning });
if (encryptionInfo === null) {
// likely a decryption error
this.setState({ shieldColour: EventShieldColour.NONE, shieldReason: null });
return;
}

if (!encryptionInfo.authenticated) {
this.setState({ verified: E2EState.Unauthenticated });
return;
}

this.setState({ verified: E2EState.Verified });
this.setState({ shieldColour: encryptionInfo.shieldColour, shieldReason: encryptionInfo.shieldReason });
}

private propsEqual(objA: EventTileProps, objB: EventTileProps): boolean {
Expand Down Expand Up @@ -751,18 +725,42 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
return <E2ePadlockDecryptionFailure />;
}

// event is encrypted and not redacted, display padlock corresponding to whether or not it is verified
if (ev.isEncrypted() && !ev.isRedacted()) {
if (this.state.verified === E2EState.Normal) {
return null; // no icon if we've not even cross-signed the user
} else if (this.state.verified === E2EState.Verified) {
return null; // no icon for verified
} else if (this.state.verified === E2EState.Unauthenticated) {
return <E2ePadlockUnauthenticated />;
} else if (this.state.verified === E2EState.Unknown) {
return <E2ePadlockUnknown />;
if (this.state.shieldColour !== EventShieldColour.NONE) {
let shieldReasonMessage: string;
switch (this.state.shieldReason) {
case null:
case EventShieldReason.UNKNOWN:
shieldReasonMessage = _t("Unknown error");
break;

case EventShieldReason.UNVERIFIED_IDENTITY:
shieldReasonMessage = _t("Encrypted by an unverified user.");
break;

case EventShieldReason.UNSIGNED_DEVICE:
shieldReasonMessage = _t("Encrypted by a device not verified by its owner.");
break;

case EventShieldReason.UNKNOWN_DEVICE:
shieldReasonMessage = _t("Encrypted by an unknown or deleted device.");
break;

case EventShieldReason.AUTHENTICITY_NOT_GUARANTEED:
shieldReasonMessage = _t(
"The authenticity of this encrypted message can't be guaranteed on this device.",
);
break;

case EventShieldReason.MISMATCHED_SENDER_KEY:
shieldReasonMessage = _t("Encrypted by an unverified session");
break;
}

if (this.state.shieldColour === EventShieldColour.GREY) {
return <E2ePadlock icon={E2ePadlockIcon.Normal} title={shieldReasonMessage} />;
} else {
return <E2ePadlockUnverified />;
// red, by elimination
return <E2ePadlock icon={E2ePadlockIcon.Warning} title={shieldReasonMessage} />;
}
}

Expand All @@ -781,8 +779,10 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
if (ev.isRedacted()) {
return null; // we expect this to be unencrypted
}
// if the event is not encrypted, but it's an e2e room, show the open padlock
return <E2ePadlockUnencrypted />;
if (!ev.isEncrypted()) {
// if the event is not encrypted, but it's an e2e room, show a warning
return <E2ePadlockUnencrypted />;
}
}

// no padlock needed
Expand Down Expand Up @@ -1460,28 +1460,10 @@ const SafeEventTile = forwardRef<UnwrappedEventTile, EventTileProps>((props, ref
});
export default SafeEventTile;

function E2ePadlockUnverified(props: Omit<IE2ePadlockProps, "title" | "icon">): JSX.Element {
return <E2ePadlock title={_t("Encrypted by an unverified session")} icon={E2ePadlockIcon.Warning} {...props} />;
}

function E2ePadlockUnencrypted(props: Omit<IE2ePadlockProps, "title" | "icon">): JSX.Element {
return <E2ePadlock title={_t("Unencrypted")} icon={E2ePadlockIcon.Warning} {...props} />;
}

function E2ePadlockUnknown(props: Omit<IE2ePadlockProps, "title" | "icon">): JSX.Element {
return <E2ePadlock title={_t("Encrypted by a deleted session")} icon={E2ePadlockIcon.Normal} {...props} />;
}

function E2ePadlockUnauthenticated(props: Omit<IE2ePadlockProps, "title" | "icon">): JSX.Element {
return (
<E2ePadlock
title={_t("The authenticity of this encrypted message can't be guaranteed on this device.")}
icon={E2ePadlockIcon.Normal}
{...props}
/>
);
}

function E2ePadlockDecryptionFailure(props: Omit<IE2ePadlockProps, "title" | "icon">): JSX.Element {
return (
<E2ePadlock
Expand All @@ -1493,8 +1475,13 @@ function E2ePadlockDecryptionFailure(props: Omit<IE2ePadlockProps, "title" | "ic
}

enum E2ePadlockIcon {
/** grey shield */
Normal = "normal",

/** red shield with (!) */
Warning = "warning",

/** key in grey circle */
DecryptionFailure = "decryption_failure",
}

Expand Down
8 changes: 5 additions & 3 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1786,12 +1786,14 @@
"Everyone in this room is verified": "Everyone in this room is verified",
"Edit message": "Edit message",
"From a thread": "From a thread",
"Encrypted by an unverified user.": "Encrypted by an unverified user.",
"Encrypted by a device not verified by its owner.": "Encrypted by a device not verified by its owner.",
"Encrypted by an unknown or deleted device.": "Encrypted by an unknown or deleted device.",
"The authenticity of this encrypted message can't be guaranteed on this device.": "The authenticity of this encrypted message can't be guaranteed on this device.",
"Encrypted by an unverified session": "Encrypted by an unverified session",
"This event could not be displayed": "This event could not be displayed",
" in <strong>%(room)s</strong>": " in <strong>%(room)s</strong>",
"Encrypted by an unverified session": "Encrypted by an unverified session",
"Unencrypted": "Unencrypted",
"Encrypted by a deleted session": "Encrypted by a deleted session",
"The authenticity of this encrypted message can't be guaranteed on this device.": "The authenticity of this encrypted message can't be guaranteed on this device.",
"This message could not be decrypted": "This message could not be decrypted",
"Sending your message…": "Sending your message…",
"Encrypting your message…": "Encrypting your message…",
Expand Down

0 comments on commit a3863fb

Please sign in to comment.