Replace `MatrixClient.isRoomEncrypted` by `MatrixClient.CryptoApi.isEncryptionEnabledInRoom` in RoomView

Florian Duros 2024-10-23 15:24:38 +02:00
parent 83777a6c57
commit 11ddcc1e90
No known key found for this signature in database
GPG Key ID: A5BBB4041B493F15
3 changed files with 36 additions and 12 deletions

View File

@ -233,6 +233,10 @@ export interface IRoomState {
liveTimeline?: EventTimeline; liveTimeline?: EventTimeline;
narrow: boolean; narrow: boolean;
msc3946ProcessDynamicPredecessor: boolean; msc3946ProcessDynamicPredecessor: boolean;
/**
* Wether the room is encrypted or not.
*/
isRoomEncrypted: boolean;
canAskToJoin: boolean; canAskToJoin: boolean;
promptAskToJoin: boolean; promptAskToJoin: boolean;
@ -417,6 +421,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
canAskToJoin: this.askToJoinEnabled, canAskToJoin: this.askToJoinEnabled,
promptAskToJoin: false, promptAskToJoin: false,
viewRoomOpts: { buttons: [] }, viewRoomOpts: { buttons: [] },
isRoomEncrypted: false,
}; };
this.dispatcherRef = dis.register(this.onAction); this.dispatcherRef = dis.register(this.onAction);
@ -903,13 +908,17 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
return isManuallyShown && widgets.length > 0; return isManuallyShown && widgets.length > 0;
} }
public componentDidMount(): void { public async componentDidMount(): Promise<void> {
this.onRoomViewStoreUpdate(true); this.onRoomViewStoreUpdate(true);
const isRoomEncrypted = Boolean(
this.state.roomId && (await this.context.client?.getCrypto()?.isEncryptionEnabledInRoom(this.state.roomId)),
);
const call = this.getCallForRoom(); const call = this.getCallForRoom();
const callState = call?.state; const callState = call?.state;
this.setState({ this.setState({
callState, callState,
isRoomEncrypted,
}); });
this.context.legacyCallHandler.on(LegacyCallHandlerEvent.CallState, this.onCallState); this.context.legacyCallHandler.on(LegacyCallHandlerEvent.CallState, this.onCallState);
@ -1405,10 +1414,12 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
}); });
} }
private updatePreviewUrlVisibility({ roomId }: Room): void { private async updatePreviewUrlVisibility({ roomId }: Room): Promise<void> {
const isRoomEncrypted = Boolean(await this.context.client?.getCrypto()?.isEncryptionEnabledInRoom(roomId));
// URL Previews in E2EE rooms can be a privacy leak so use a different setting which is per-room explicit // URL Previews in E2EE rooms can be a privacy leak so use a different setting which is per-room explicit
const key = this.context.client?.isRoomEncrypted(roomId) ? "urlPreviewsEnabled_e2ee" : "urlPreviewsEnabled"; const key = isRoomEncrypted ? "urlPreviewsEnabled_e2ee" : "urlPreviewsEnabled";
this.setState({ this.setState({
isRoomEncrypted,
showUrlPreview: SettingsStore.getValue(key, roomId), showUrlPreview: SettingsStore.getValue(key, roomId),
}); });
} }
@ -1452,7 +1463,11 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
}; };
private async updateE2EStatus(room: Room): Promise<void> { private async updateE2EStatus(room: Room): Promise<void> {
if (!this.context.client?.isRoomEncrypted(room.roomId)) return; if (!this.context.client) return;
const isRoomEncrypted = Boolean(await this.context.client.getCrypto()?.isEncryptionEnabledInRoom(room.roomId));
this.setState({ isRoomEncrypted });
if (!isRoomEncrypted) return;
// If crypto is not currently enabled, we aren't tracking devices at all, // If crypto is not currently enabled, we aren't tracking devices at all,
// so we don't know what the answer is. Let's error on the safe side and show // so we don't know what the answer is. Let's error on the safe side and show
@ -2243,7 +2258,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
searchInfo={this.state.search} searchInfo={this.state.search}
onCancelClick={this.onCancelSearchClick} onCancelClick={this.onCancelSearchClick}
onSearchScopeChange={this.onSearchScopeChange} onSearchScopeChange={this.onSearchScopeChange}
isRoomEncrypted={this.context.client.isRoomEncrypted(this.state.room.roomId)} isRoomEncrypted={this.state.isRoomEncrypted}
/> />
); );
} else if (showRoomUpgradeBar) { } else if (showRoomUpgradeBar) {

View File

@ -117,7 +117,7 @@ export function createTestClient(): MatrixClient {
getCrypto: jest.fn().mockReturnValue({ getCrypto: jest.fn().mockReturnValue({
getOwnDeviceKeys: jest.fn(), getOwnDeviceKeys: jest.fn(),
getUserDeviceInfo: jest.fn(), getUserDeviceInfo: jest.fn().mockResolvedValue(new Map()),
getUserVerificationStatus: jest.fn(), getUserVerificationStatus: jest.fn(),
getDeviceVerificationStatus: jest.fn(), getDeviceVerificationStatus: jest.fn(),
resetKeyBackup: jest.fn(), resetKeyBackup: jest.fn(),

View File

@ -21,6 +21,7 @@ import {
SearchResult, SearchResult,
IEvent, IEvent,
} from "matrix-js-sdk/src/matrix"; } from "matrix-js-sdk/src/matrix";
import { CryptoApi, UserVerificationStatus } from "matrix-js-sdk/src/crypto-api";
import { KnownMembership } from "matrix-js-sdk/src/types"; import { KnownMembership } from "matrix-js-sdk/src/types";
import { fireEvent, render, screen, RenderResult, waitForElementToBeRemoved, waitFor } from "jest-matrix-react"; import { fireEvent, render, screen, RenderResult, waitForElementToBeRemoved, waitFor } from "jest-matrix-react";
import userEvent from "@testing-library/user-event"; import userEvent from "@testing-library/user-event";
@ -72,14 +73,14 @@ describe("RoomView", () => {
let rooms: Map<string, Room>; let rooms: Map<string, Room>;
let roomCount = 0; let roomCount = 0;
let stores: SdkContextClass; let stores: SdkContextClass;
let cryptoApi: CryptoApi;
// mute some noise // mute some noise
filterConsole("RVS update", "does not have an m.room.create event", "Current version: 1", "Version capability"); filterConsole("RVS update", "does not have an m.room.create event", "Current version: 1", "Version capability");
beforeEach(() => { beforeEach(() => {
mockPlatformPeg({ reload: () => {} }); mockPlatformPeg({ reload: () => {} });
stubClient(); cli = mocked(stubClient());
cli = mocked(MatrixClientPeg.safeGet());
room = new Room(`!${roomCount++}:example.org`, cli, "@alice:example.org"); room = new Room(`!${roomCount++}:example.org`, cli, "@alice:example.org");
jest.spyOn(room, "findPredecessor"); jest.spyOn(room, "findPredecessor");
@ -97,6 +98,7 @@ describe("RoomView", () => {
stores.rightPanelStore.useUnitTestClient(cli); stores.rightPanelStore.useUnitTestClient(cli);
jest.spyOn(VoipUserMapper.sharedInstance(), "getVirtualRoomForRoom").mockResolvedValue(undefined); jest.spyOn(VoipUserMapper.sharedInstance(), "getVirtualRoomForRoom").mockResolvedValue(undefined);
cryptoApi = cli.getCrypto()!;
jest.spyOn(cli, "getCrypto").mockReturnValue(undefined); jest.spyOn(cli, "getCrypto").mockReturnValue(undefined);
}); });
@ -230,8 +232,9 @@ describe("RoomView", () => {
it("updates url preview visibility on encryption state change", async () => { it("updates url preview visibility on encryption state change", async () => {
room.getMyMembership = jest.fn().mockReturnValue(KnownMembership.Join); room.getMyMembership = jest.fn().mockReturnValue(KnownMembership.Join);
jest.spyOn(cli, "getCrypto").mockReturnValue(cryptoApi);
// we should be starting unencrypted // we should be starting unencrypted
expect(cli.isRoomEncrypted(room.roomId)).toEqual(false); expect(await cli.getCrypto()?.isEncryptionEnabledInRoom(room.roomId)).toEqual(false);
const roomViewInstance = await getRoomViewInstance(); const roomViewInstance = await getRoomViewInstance();
@ -246,10 +249,10 @@ describe("RoomView", () => {
expect(roomViewInstance.state.showUrlPreview).toBe(true); expect(roomViewInstance.state.showUrlPreview).toBe(true);
// now enable encryption // now enable encryption
cli.isRoomEncrypted.mockReturnValue(true); jest.spyOn(cli.getCrypto()!, "isEncryptionEnabledInRoom").mockResolvedValue(true);
// and fake an encryption event into the room to prompt it to re-check // and fake an encryption event into the room to prompt it to re-check
room.addLiveEvents([ await room.addLiveEvents([
new MatrixEvent({ new MatrixEvent({
type: "m.room.encryption", type: "m.room.encryption",
sender: cli.getUserId()!, sender: cli.getUserId()!,
@ -341,6 +344,11 @@ describe("RoomView", () => {
describe("that is encrypted", () => { describe("that is encrypted", () => {
beforeEach(() => { beforeEach(() => {
jest.spyOn(cli, "getCrypto").mockReturnValue(cryptoApi);
jest.spyOn(cli.getCrypto()!, "isEncryptionEnabledInRoom").mockResolvedValue(true);
jest.spyOn(cli.getCrypto()!, "getUserVerificationStatus").mockResolvedValue(
new UserVerificationStatus(false, true, false),
);
mocked(cli.isRoomEncrypted).mockReturnValue(true); mocked(cli.isRoomEncrypted).mockReturnValue(true);
localRoom.encrypted = true; localRoom.encrypted = true;
localRoom.currentState.setStateEvents([ localRoom.currentState.setStateEvents([
@ -402,7 +410,8 @@ describe("RoomView", () => {
]); ]);
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(cli.getSafeUserId()); jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(cli.getSafeUserId());
jest.spyOn(DMRoomMap.shared(), "getRoomIds").mockReturnValue(new Set([room.roomId])); jest.spyOn(DMRoomMap.shared(), "getRoomIds").mockReturnValue(new Set([room.roomId]));
mocked(cli).isRoomEncrypted.mockReturnValue(true); jest.spyOn(cli, "getCrypto").mockReturnValue(cryptoApi);
jest.spyOn(cli.getCrypto()!, "isEncryptionEnabledInRoom").mockResolvedValue(true);
await renderRoomView(); await renderRoomView();
}); });