Listen to events so that encryption icon updates when status changes (#28407)
* listen to events so that encryption icon updates when status changes * remove debugging message
This commit is contained in:
parent
4f8e9eb9ac
commit
ed9795137b
2 changed files with 86 additions and 11 deletions
|
@ -6,21 +6,40 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||||
Please see LICENSE files in the repository root for full details.
|
Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { MatrixClient, Room } from "matrix-js-sdk/src/matrix";
|
import { CryptoEvent, MatrixClient, Room, RoomStateEvent } from "matrix-js-sdk/src/matrix";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
|
import { throttle } from "lodash";
|
||||||
|
|
||||||
import { E2EStatus, shieldStatusForRoom } from "../utils/ShieldUtils";
|
import { E2EStatus, shieldStatusForRoom } from "../utils/ShieldUtils";
|
||||||
|
import { useTypedEventEmitter } from "./useEventEmitter";
|
||||||
|
|
||||||
export function useEncryptionStatus(client: MatrixClient, room: Room): E2EStatus | null {
|
export function useEncryptionStatus(client: MatrixClient, room: Room): E2EStatus | null {
|
||||||
const [e2eStatus, setE2eStatus] = useState<E2EStatus | null>(null);
|
const [e2eStatus, setE2eStatus] = useState<E2EStatus | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
const updateEncryptionStatus = useMemo(
|
||||||
|
() =>
|
||||||
|
throttle(
|
||||||
|
() => {
|
||||||
if (client.getCrypto()) {
|
if (client.getCrypto()) {
|
||||||
shieldStatusForRoom(client, room).then((e2eStatus) => {
|
shieldStatusForRoom(client, room).then((e2eStatus) => {
|
||||||
setE2eStatus(e2eStatus);
|
setE2eStatus(e2eStatus);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [client, room]);
|
},
|
||||||
|
250,
|
||||||
|
{ leading: true, trailing: true },
|
||||||
|
),
|
||||||
|
[client, room],
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(updateEncryptionStatus, [updateEncryptionStatus]);
|
||||||
|
|
||||||
|
// shieldStatusForRoom depends on the room membership, each member's trust
|
||||||
|
// status for each member, and each member's devices, so we update the
|
||||||
|
// status whenever any of those changes.
|
||||||
|
useTypedEventEmitter(room, RoomStateEvent.Members, updateEncryptionStatus);
|
||||||
|
useTypedEventEmitter(client, CryptoEvent.UserTrustStatusChanged, updateEncryptionStatus);
|
||||||
|
useTypedEventEmitter(client, CryptoEvent.DevicesUpdated, updateEncryptionStatus);
|
||||||
|
|
||||||
return e2eStatus;
|
return e2eStatus;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,19 @@ Please see LICENSE files in the repository root for full details.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { CallType, MatrixCall } from "matrix-js-sdk/src/webrtc/call";
|
import { CallType, MatrixCall } from "matrix-js-sdk/src/webrtc/call";
|
||||||
import { EventType, JoinRule, MatrixEvent, PendingEventOrdering, Room, RoomMember } from "matrix-js-sdk/src/matrix";
|
|
||||||
import { KnownMembership } from "matrix-js-sdk/src/types";
|
|
||||||
import {
|
import {
|
||||||
|
EventType,
|
||||||
|
JoinRule,
|
||||||
|
MatrixEvent,
|
||||||
|
PendingEventOrdering,
|
||||||
|
Room,
|
||||||
|
RoomStateEvent,
|
||||||
|
RoomMember,
|
||||||
|
} from "matrix-js-sdk/src/matrix";
|
||||||
|
import { KnownMembership } from "matrix-js-sdk/src/types";
|
||||||
|
import { CryptoEvent, UserVerificationStatus } from "matrix-js-sdk/src/crypto-api";
|
||||||
|
import {
|
||||||
|
act,
|
||||||
createEvent,
|
createEvent,
|
||||||
fireEvent,
|
fireEvent,
|
||||||
getAllByLabelText,
|
getAllByLabelText,
|
||||||
|
@ -632,6 +642,52 @@ describe("RoomHeader", () => {
|
||||||
|
|
||||||
expect(asFragment()).toMatchSnapshot();
|
expect(asFragment()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("updates the icon when the encryption status changes", async () => {
|
||||||
|
// The room starts verified
|
||||||
|
jest.spyOn(ShieldUtils, "shieldStatusForRoom").mockResolvedValue(ShieldUtils.E2EStatus.Verified);
|
||||||
|
render(<RoomHeader room={room} />, getWrapper());
|
||||||
|
await waitFor(() => expect(getByLabelText(document.body, "Verified")).toBeInTheDocument());
|
||||||
|
|
||||||
|
// A new member joins, and the room becomes unverified
|
||||||
|
jest.spyOn(ShieldUtils, "shieldStatusForRoom").mockResolvedValue(ShieldUtils.E2EStatus.Warning);
|
||||||
|
act(() => {
|
||||||
|
room.emit(
|
||||||
|
RoomStateEvent.Members,
|
||||||
|
new MatrixEvent({
|
||||||
|
event_id: "$event_id",
|
||||||
|
type: EventType.RoomMember,
|
||||||
|
state_key: "@alice:example.org",
|
||||||
|
content: {
|
||||||
|
membership: "join",
|
||||||
|
},
|
||||||
|
room_id: ROOM_ID,
|
||||||
|
sender: "@alice:example.org",
|
||||||
|
}),
|
||||||
|
room.currentState,
|
||||||
|
new RoomMember(room.roomId, "@alice:example.org"),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
await waitFor(() => expect(getByLabelText(document.body, "Untrusted")).toBeInTheDocument());
|
||||||
|
|
||||||
|
// The user becomes verified
|
||||||
|
jest.spyOn(ShieldUtils, "shieldStatusForRoom").mockResolvedValue(ShieldUtils.E2EStatus.Verified);
|
||||||
|
act(() => {
|
||||||
|
MatrixClientPeg.get()!.emit(
|
||||||
|
CryptoEvent.UserTrustStatusChanged,
|
||||||
|
"@alice:example.org",
|
||||||
|
new UserVerificationStatus(true, true, true, false),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
await waitFor(() => expect(getByLabelText(document.body, "Verified")).toBeInTheDocument());
|
||||||
|
|
||||||
|
// An unverified device is added
|
||||||
|
jest.spyOn(ShieldUtils, "shieldStatusForRoom").mockResolvedValue(ShieldUtils.E2EStatus.Warning);
|
||||||
|
act(() => {
|
||||||
|
MatrixClientPeg.get()!.emit(CryptoEvent.DevicesUpdated, ["@alice:example.org"], false);
|
||||||
|
});
|
||||||
|
await waitFor(() => expect(getByLabelText(document.body, "Untrusted")).toBeInTheDocument());
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("renders additionalButtons", async () => {
|
it("renders additionalButtons", async () => {
|
||||||
|
|
Loading…
Reference in a new issue