Skip to content

Commit

Permalink
Replace MatrixClient.isRoomEncrypted by `MatrixClient.CryptoApi.isE…
Browse files Browse the repository at this point in the history
…ncryptionEnabledInRoom` in RoomView
  • Loading branch information
florianduros committed Nov 22, 2024
1 parent c2ce7db commit 50c3d75
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 13 deletions.
35 changes: 28 additions & 7 deletions src/components/structures/RoomView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,10 @@ export interface IRoomState {
liveTimeline?: EventTimeline;
narrow: boolean;
msc3946ProcessDynamicPredecessor: boolean;
/**
* Wether the room is encrypted or not.
*/
isRoomEncrypted: boolean;

canAskToJoin: boolean;
promptAskToJoin: boolean;
Expand Down Expand Up @@ -417,6 +421,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
canAskToJoin: this.askToJoinEnabled,
promptAskToJoin: false,
viewRoomOpts: { buttons: [] },
isRoomEncrypted: false,
};
}

Expand Down Expand Up @@ -847,7 +852,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
return isManuallyShown && widgets.length > 0;
}

public componentDidMount(): void {
public async componentDidMount(): Promise<void> {
this.unmounted = false;

this.dispatcherRef = defaultDispatcher.register(this.onAction);
Expand Down Expand Up @@ -914,6 +919,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
const callState = call?.state;
this.setState({
callState,
isRoomEncrypted: await this.getIsRoomEncrypted(),
});

this.context.legacyCallHandler.on(LegacyCallHandlerEvent.CallState, this.onCallState);
Expand Down Expand Up @@ -1377,6 +1383,13 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
return room?.currentState.getStateEvents(EventType.RoomTombstone, "") ?? undefined;
}

private async getIsRoomEncrypted(roomId = this.state.roomId): Promise<boolean> {
const crypto = this.context.client?.getCrypto();
if (!crypto || !roomId) return false;

return await crypto.isEncryptionEnabledInRoom(roomId);
}

private async calculateRecommendedVersion(room: Room): Promise<void> {
const upgradeRecommendation = await room.getRecommendedVersion();
if (this.unmounted) return;
Expand Down Expand Up @@ -1409,10 +1422,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
const key = this.context.client?.isRoomEncrypted(roomId) ? "urlPreviewsEnabled_e2ee" : "urlPreviewsEnabled";
const key = isRoomEncrypted ? "urlPreviewsEnabled_e2ee" : "urlPreviewsEnabled";
this.setState({
isRoomEncrypted,
showUrlPreview: SettingsStore.getValue(key, roomId),
});
}
Expand Down Expand Up @@ -1456,7 +1471,11 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
};

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,
// so we don't know what the answer is. Let's error on the safe side and show
Expand All @@ -1480,15 +1499,17 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
}
};

private onRoomStateEvents = (ev: MatrixEvent, state: RoomState): void => {
private onRoomStateEvents = async (ev: MatrixEvent, state: RoomState): Promise<void> => {
// ignore if we don't have a room yet
if (!this.state.room || this.state.room.roomId !== state.roomId) return;

switch (ev.getType()) {
case EventType.RoomTombstone:
this.setState({ tombstone: this.getRoomTombstone() });
break;

case EventType.RoomEncryption:
this.setState({ isRoomEncrypted: await this.getIsRoomEncrypted() });
break;
default:
this.updatePermissions(this.state.room);
}
Expand Down Expand Up @@ -2247,7 +2268,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
searchInfo={this.state.search}
onCancelClick={this.onCancelSearchClick}
onSearchScopeChange={this.onSearchScopeChange}
isRoomEncrypted={this.context.client.isRoomEncrypted(this.state.room.roomId)}
isRoomEncrypted={this.state.isRoomEncrypted}
/>
);
} else if (showRoomUpgradeBar) {
Expand Down
2 changes: 1 addition & 1 deletion test/test-utils/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export function createTestClient(): MatrixClient {

getCrypto: jest.fn().mockReturnValue({
getOwnDeviceKeys: jest.fn(),
getUserDeviceInfo: jest.fn(),
getUserDeviceInfo: jest.fn().mockResolvedValue(new Map()),
getUserVerificationStatus: jest.fn(),
getDeviceVerificationStatus: jest.fn(),
resetKeyBackup: jest.fn(),
Expand Down
11 changes: 6 additions & 5 deletions test/unit-tests/components/structures/RoomView-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ describe("RoomView", () => {

beforeEach(() => {
mockPlatformPeg({ reload: () => {} });
stubClient();
cli = mocked(MatrixClientPeg.safeGet());
cli = mocked(stubClient());

room = new Room(`!${roomCount++}:example.org`, cli, "@alice:example.org");
jest.spyOn(room, "findPredecessor");
Expand Down Expand Up @@ -247,8 +246,9 @@ describe("RoomView", () => {

it("updates url preview visibility on encryption state change", async () => {
room.getMyMembership = jest.fn().mockReturnValue(KnownMembership.Join);
jest.spyOn(cli, "getCrypto").mockReturnValue(crypto);
// 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();

Expand All @@ -263,7 +263,7 @@ describe("RoomView", () => {
expect(roomViewInstance.state.showUrlPreview).toBe(true);

// 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
await act(() =>
Expand Down Expand Up @@ -427,7 +427,8 @@ describe("RoomView", () => {
]);
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(cli.getSafeUserId());
jest.spyOn(DMRoomMap.shared(), "getRoomIds").mockReturnValue(new Set([room.roomId]));
mocked(cli).isRoomEncrypted.mockReturnValue(true);
jest.spyOn(cli, "getCrypto").mockReturnValue(crypto);
jest.spyOn(cli.getCrypto()!, "isEncryptionEnabledInRoom").mockResolvedValue(true);
await renderRoomView();
});

Expand Down

0 comments on commit 50c3d75

Please sign in to comment.