Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First batch: Replace MatrixClient.isRoomEncrypted by MatrixClient.CryptoApi.isEncryptionEnabledInRoom #28242

Merged
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
e67142d
Replace `MatrixClient.isRoomEncrypted` by `MatrixClient.CryptoApi.isE…
florianduros Oct 18, 2024
445aa21
Replace `MatrixClient.isRoomEncrypted` by `MatrixClient.CryptoApi.isE…
florianduros Oct 18, 2024
4f07a30
Replace `MatrixClient.isRoomEncrypted` by `MatrixClient.CryptoApi.isE…
florianduros Oct 18, 2024
87803b7
Merge branch 'develop' into florianduros/rip-out-legacy-crypto/1-remo…
florianduros Oct 18, 2024
d170b9d
Merge branch 'develop' into florianduros/rip-out-legacy-crypto/1-remo…
florianduros Nov 12, 2024
b65e9fe
Merge branch 'develop' into florianduros/rip-out-legacy-crypto/1-remo…
florianduros Nov 13, 2024
a57f9e2
Replace `MatrixClient.isRoomEncrypted` by `MatrixClient.CryptoApi.isE…
florianduros Nov 13, 2024
df05085
Replace `MatrixClient.isRoomEncrypted` by `MatrixClient.CryptoApi.isE…
florianduros Nov 13, 2024
be1837e
Replace `MatrixClient.isRoomEncrypted` by `MatrixClient.CryptoApi.isE…
florianduros Nov 13, 2024
6aa6d61
Fix MessagePanel-test.tsx
florianduros Nov 13, 2024
f074ace
ReplaceReplace `MatrixCient..isRoomEncrypted` by `MatrixClient.Crypto…
florianduros Nov 13, 2024
5b1b10e
Add missing `await`
florianduros Nov 14, 2024
7ec5450
Use `Promise.any` instead of `asyncSome`
florianduros Nov 14, 2024
662fbd9
Add `asyncSomeParallel`
florianduros Nov 14, 2024
c0cca69
Use `asyncSomeParallel` instead of `asyncSome`
florianduros Nov 14, 2024
50d22e4
Merge branch 'develop' into florianduros/rip-out-legacy-crypto/1-remo…
florianduros Nov 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/DeviceListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import SettingsStore, { CallbackFn } from "./settings/SettingsStore";
import { UIFeature } from "./settings/UIFeature";
import { isBulkUnverifiedDeviceReminderSnoozed } from "./utils/device/snoozeBulkUnverifiedDeviceReminder";
import { getUserDeviceIds } from "./utils/crypto/deviceInfo";
import { asyncSome } from "./utils/arrays.ts";

const KEY_BACKUP_POLL_INTERVAL = 5 * 60 * 1000;

Expand Down Expand Up @@ -240,13 +241,16 @@ export default class DeviceListener {
return this.keyBackupInfo;
}

private shouldShowSetupEncryptionToast(): boolean {
private shouldShowSetupEncryptionToast(): Promise<boolean> | boolean {
// If we're in the middle of a secret storage operation, we're likely
// modifying the state involved here, so don't add new toasts to setup.
if (isSecretStorageBeingAccessed()) return false;
// Show setup toasts once the user is in at least one encrypted room.
const cli = this.client;
return cli?.getRooms().some((r) => cli.isRoomEncrypted(r.roomId)) ?? false;
const cryptoApi = cli?.getCrypto();
if (!cli || !cryptoApi) return false;

return asyncSome(cli.getRooms(), ({ roomId }) => cryptoApi.isEncryptionEnabledInRoom(roomId));
florianduros marked this conversation as resolved.
Show resolved Hide resolved
}

private recheck(): void {
Expand Down Expand Up @@ -283,7 +287,7 @@ export default class DeviceListener {
hideSetupEncryptionToast();

this.checkKeyBackupStatus();
} else if (this.shouldShowSetupEncryptionToast()) {
} else if (await this.shouldShowSetupEncryptionToast()) {
// make sure our keys are finished downloading
await crypto.getUserDeviceInfo([cli.getSafeUserId()]);

Expand Down
2 changes: 1 addition & 1 deletion src/Searching.ts
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ function eventIndexSearch(
let searchPromise: Promise<ISearchResults>;

if (roomId !== undefined) {
if (client.isRoomEncrypted(roomId)) {
if (client.getCrypto()?.isEncryptionEnabledInRoom(roomId)) {
florianduros marked this conversation as resolved.
Show resolved Hide resolved
// The search is for a single encrypted room, use our local
// search method.
searchPromise = localSearchProcess(client, term, roomId);
Expand Down
2 changes: 1 addition & 1 deletion src/SlidingSyncManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ export class SlidingSyncManager {
subscriptions.delete(roomId);
}
const room = this.client?.getRoom(roomId);
let shouldLazyLoad = !this.client?.isRoomEncrypted(roomId);
let shouldLazyLoad = !(await this.client?.getCrypto()?.isEncryptionEnabledInRoom(roomId));
if (!room) {
// default to safety: request all state if we can't work it out. This can happen if you
// refresh the app whilst viewing a room: we call setRoomVisible before we know anything
Expand Down
2 changes: 1 addition & 1 deletion src/components/structures/MatrixChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}
} else if (
(await cli.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing")) &&
!shouldSkipSetupEncryption(cli)
!(await shouldSkipSetupEncryption(cli))
) {
// if cross-signing is not yet set up, do so now if possible.
this.setStateForNewView({ view: Views.E2E_SETUP });
Expand Down
18 changes: 16 additions & 2 deletions src/components/views/dialogs/ReportEventDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ interface IState {
// If we know it, the nature of the abuse, as specified by MSC3215.
nature?: ExtendedNature;
ignoreUserToo: boolean; // if true, user will be ignored/blocked on submit
/*
* Whether the room is encrypted.
*/
isRoomEncrypted: boolean;
}

const MODERATED_BY_STATE_EVENT_TYPE = [
Expand Down Expand Up @@ -188,9 +192,20 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
// If specified, the nature of the abuse, as specified by MSC3215.
nature: undefined,
ignoreUserToo: false, // default false, for now. Could easily be argued as default true
isRoomEncrypted: false, // async, will be set later
};
}

public componentDidMount = async (): Promise<void> => {
const crypto = MatrixClientPeg.safeGet().getCrypto();
const roomId = this.props.mxEvent.getRoomId();
if (!crypto || !roomId) return;

this.setState({
isRoomEncrypted: await crypto.isEncryptionEnabledInRoom(roomId),
});
};

private onIgnoreUserTooChanged = (newVal: boolean): void => {
this.setState({ ignoreUserToo: newVal });
};
Expand Down Expand Up @@ -319,7 +334,6 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
if (this.moderation) {
// Display report-to-moderator dialog.
// We let the user pick a nature.
const client = MatrixClientPeg.safeGet();
const homeServerName = SdkConfig.get("validated_server_config")!.hsName;
let subtitle: string;
switch (this.state.nature) {
Expand All @@ -336,7 +350,7 @@ export default class ReportEventDialog extends React.Component<IProps, IState> {
subtitle = _t("report_content|nature_spam");
break;
case NonStandardValue.Admin:
if (client.isRoomEncrypted(this.props.mxEvent.getRoomId()!)) {
if (this.state.isRoomEncrypted) {
subtitle = _t("report_content|nature_nonstandard_admin_encrypted", {
homeserver: homeServerName,
});
Expand Down
6 changes: 3 additions & 3 deletions src/components/views/dialogs/devtools/RoomNotifications.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { determineUnreadState } from "../../../../RoomNotifs";
import { humanReadableNotificationLevel } from "../../../../stores/notifications/NotificationLevel";
import { doesRoomOrThreadHaveUnreadMessages } from "../../../../Unread";
import BaseTool, { DevtoolsContext, IDevtoolsProps } from "./BaseTool";
import { useIsEncrypted } from "../../../../hooks/useIsEncrypted.ts";

function UserReadUpTo({ target }: { target: ReadReceipt<any, any> }): JSX.Element {
const cli = useContext(MatrixClientContext);
Expand Down Expand Up @@ -59,6 +60,7 @@ function UserReadUpTo({ target }: { target: ReadReceipt<any, any> }): JSX.Elemen
export default function RoomNotifications({ onBack }: IDevtoolsProps): JSX.Element {
const { room } = useContext(DevtoolsContext);
const cli = useContext(MatrixClientContext);
const isRoomEncrypted = useIsEncrypted(cli, room);

const { level, count } = determineUnreadState(room, undefined, false);
const [notificationState] = useNotificationState(room);
Expand Down Expand Up @@ -93,9 +95,7 @@ export default function RoomNotifications({ onBack }: IDevtoolsProps): JSX.Eleme
</li>
<li>
{_t(
cli.isRoomEncrypted(room.roomId!)
? _td("devtools|room_encrypted")
: _td("devtools|room_not_encrypted"),
isRoomEncrypted ? _td("devtools|room_encrypted") : _td("devtools|room_not_encrypted"),
{},
{
strong: (sub) => <strong>{sub}</strong>,
Expand Down
10 changes: 5 additions & 5 deletions src/components/views/messages/EncryptionEvent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,28 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/

import React, { forwardRef, useContext } from "react";
import React, { forwardRef } from "react";
import { MatrixEvent } from "matrix-js-sdk/src/matrix";

import type { RoomEncryptionEventContent } from "matrix-js-sdk/src/types";
import { _t } from "../../../languageHandler";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import EventTileBubble from "./EventTileBubble";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import { useMatrixClientContext } from "../../../contexts/MatrixClientContext";
import DMRoomMap from "../../../utils/DMRoomMap";
import { objectHasDiff } from "../../../utils/objects";
import { isLocalRoom } from "../../../utils/localRoom/isLocalRoom";
import { MEGOLM_ENCRYPTION_ALGORITHM } from "../../../utils/crypto";
import { useIsEncrypted } from "../../../hooks/useIsEncrypted.ts";

interface IProps {
mxEvent: MatrixEvent;
timestamp?: JSX.Element;
}

const EncryptionEvent = forwardRef<HTMLDivElement, IProps>(({ mxEvent, timestamp }, ref) => {
const cli = useContext(MatrixClientContext);
const cli = useMatrixClientContext();
const roomId = mxEvent.getRoomId()!;
const isRoomEncrypted = MatrixClientPeg.safeGet().isRoomEncrypted(roomId);
const isRoomEncrypted = useIsEncrypted(cli, cli.getRoom(roomId) || undefined);

const prevContent = mxEvent.getPrevContent() as RoomEncryptionEventContent;
const content = mxEvent.getContent<RoomEncryptionEventContent>();
Expand Down
11 changes: 9 additions & 2 deletions src/utils/crypto/shouldSkipSetupEncryption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,21 @@ Please see LICENSE files in the repository root for full details.
import { MatrixClient } from "matrix-js-sdk/src/matrix";

import { shouldForceDisableEncryption } from "./shouldForceDisableEncryption";
import { asyncSome } from "../arrays.ts";

/**
* If encryption is force disabled AND the user is not in any encrypted rooms
* skip setting up encryption
* @param client
* @returns {boolean} true when we can skip settings up encryption
*/
export const shouldSkipSetupEncryption = (client: MatrixClient): boolean => {
export const shouldSkipSetupEncryption = async (client: MatrixClient): Promise<boolean> => {
const isEncryptionForceDisabled = shouldForceDisableEncryption(client);
return isEncryptionForceDisabled && !client.getRooms().some((r) => client.isRoomEncrypted(r.roomId));
const crypto = client.getCrypto();
if (!crypto) return true;

return (
isEncryptionForceDisabled &&
!(await asyncSome(client.getRooms(), ({ roomId }) => crypto.isEncryptionEnabledInRoom(roomId)))
florianduros marked this conversation as resolved.
Show resolved Hide resolved
);
};
1 change: 1 addition & 0 deletions test/test-utils/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ export const mockClientMethodsCrypto = (): Partial<
getVersion: jest.fn().mockReturnValue("Version 0"),
getOwnDeviceKeys: jest.fn().mockReturnValue(new Promise(() => {})),
getCrossSigningKeyId: jest.fn(),
isEncryptionEnabledInRoom: jest.fn().mockResolvedValue(false),
}),
});

Expand Down
6 changes: 3 additions & 3 deletions test/unit-tests/DeviceListener-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ describe("DeviceListener", () => {
},
}),
getSessionBackupPrivateKey: jest.fn(),
isEncryptionEnabledInRoom: jest.fn(),
} as unknown as Mocked<CryptoApi>;
mockClient = getMockClientWithEventEmitter({
isGuest: jest.fn(),
Expand All @@ -105,7 +106,6 @@ describe("DeviceListener", () => {
isVersionSupported: jest.fn().mockResolvedValue(true),
isInitialSyncComplete: jest.fn().mockReturnValue(true),
waitForClientWellKnown: jest.fn(),
isRoomEncrypted: jest.fn(),
getClientWellKnown: jest.fn(),
getDeviceId: jest.fn().mockReturnValue(deviceId),
setAccountData: jest.fn(),
Expand Down Expand Up @@ -292,7 +292,7 @@ describe("DeviceListener", () => {
mockCrypto!.isCrossSigningReady.mockResolvedValue(false);
mockCrypto!.isSecretStorageReady.mockResolvedValue(false);
mockClient!.getRooms.mockReturnValue(rooms);
mockClient!.isRoomEncrypted.mockReturnValue(true);
jest.spyOn(mockClient.getCrypto()!, "isEncryptionEnabledInRoom").mockResolvedValue(true);
});

it("hides setup encryption toast when cross signing and secret storage are ready", async () => {
Expand All @@ -317,7 +317,7 @@ describe("DeviceListener", () => {
});

it("does not show any toasts when no rooms are encrypted", async () => {
mockClient!.isRoomEncrypted.mockReturnValue(false);
jest.spyOn(mockClient.getCrypto()!, "isEncryptionEnabledInRoom").mockResolvedValue(false);
await createAndStart();

expect(SetupEncryptionToast.showToast).not.toHaveBeenCalled();
Expand Down
10 changes: 6 additions & 4 deletions test/unit-tests/components/structures/MatrixChat-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ describe("<MatrixChat />", () => {
matrixRTC: createStubMatrixRTC(),
getDehydratedDevice: jest.fn(),
whoami: jest.fn(),
isRoomEncrypted: jest.fn(),
logout: jest.fn(),
getDeviceId: jest.fn(),
getKeyBackupVersion: jest.fn().mockResolvedValue(null),
Expand Down Expand Up @@ -1011,6 +1010,7 @@ describe("<MatrixChat />", () => {
userHasCrossSigningKeys: jest.fn().mockResolvedValue(false),
// This needs to not finish immediately because we need to test the screen appears
bootstrapCrossSigning: jest.fn().mockImplementation(() => bootstrapDeferred.promise),
isEncryptionEnabledInRoom: jest.fn().mockResolvedValue(false),
};
loginClient.getCrypto.mockReturnValue(mockCrypto as any);
});
Expand Down Expand Up @@ -1058,9 +1058,11 @@ describe("<MatrixChat />", () => {
},
});

loginClient.isRoomEncrypted.mockImplementation((roomId) => {
return roomId === encryptedRoom.roomId;
});
jest.spyOn(loginClient.getCrypto()!, "isEncryptionEnabledInRoom").mockImplementation(
async (roomId) => {
return roomId === encryptedRoom.roomId;
},
);
});

it("should go straight to logged in view when user is not in any encrypted rooms", async () => {
Expand Down
2 changes: 2 additions & 0 deletions test/unit-tests/components/structures/MessagePanel-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
createTestClient,
getMockClientWithEventEmitter,
makeBeaconInfoEvent,
mockClientMethodsCrypto,
mockClientMethodsEvents,
mockClientMethodsUser,
} from "../../../test-utils";
Expand All @@ -42,6 +43,7 @@ describe("MessagePanel", function () {
const client = getMockClientWithEventEmitter({
...mockClientMethodsUser(userId),
...mockClientMethodsEvents(),
...mockClientMethodsCrypto(),
getAccountData: jest.fn(),
isUserIgnored: jest.fn().mockReturnValue(false),
isRoomEncrypted: jest.fn().mockReturnValue(false),
Expand Down
11 changes: 10 additions & 1 deletion test/unit-tests/components/structures/RoomView-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
SearchResult,
IEvent,
} 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 { fireEvent, render, screen, RenderResult, waitForElementToBeRemoved, waitFor } from "jest-matrix-react";
import userEvent from "@testing-library/user-event";
Expand Down Expand Up @@ -72,6 +73,7 @@ describe("RoomView", () => {
let rooms: Map<string, Room>;
let roomCount = 0;
let stores: SdkContextClass;
let crypto: CryptoApi;

// mute some noise
filterConsole("RVS update", "does not have an m.room.create event", "Current version: 1", "Version capability");
Expand All @@ -97,6 +99,7 @@ describe("RoomView", () => {
stores.rightPanelStore.useUnitTestClient(cli);

jest.spyOn(VoipUserMapper.sharedInstance(), "getVirtualRoomForRoom").mockResolvedValue(undefined);
crypto = cli.getCrypto()!;
jest.spyOn(cli, "getCrypto").mockReturnValue(undefined);
});

Expand Down Expand Up @@ -341,7 +344,13 @@ describe("RoomView", () => {

describe("that is encrypted", () => {
beforeEach(() => {
// Not all the calls to cli.isRoomEncrypted are migrated, so we need to mock both.
mocked(cli.isRoomEncrypted).mockReturnValue(true);
jest.spyOn(cli, "getCrypto").mockReturnValue(crypto);
jest.spyOn(cli.getCrypto()!, "isEncryptionEnabledInRoom").mockResolvedValue(true);
jest.spyOn(cli.getCrypto()!, "getUserVerificationStatus").mockResolvedValue(
new UserVerificationStatus(false, true, false),
);
localRoom.encrypted = true;
localRoom.currentState.setStateEvents([
new MatrixEvent({
Expand All @@ -360,7 +369,7 @@ describe("RoomView", () => {

it("should match the snapshot", async () => {
const { container } = await renderRoomView();
expect(container).toMatchSnapshot();
await waitFor(() => expect(container).toMatchSnapshot());
});
});
});
Expand Down
Loading
Loading