Don't setup keys on login when encryption is force disabled (#11125)
* move shouldForceDisableEncryption to /crypto * dont setup encryption when encryption is force disabled * shuffle testing functions * test post login security setup flows * remove debug * lint fixes * strict fixes * strict fixes p2 --------- Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>pull/28788/head^2
parent
5cf818fefa
commit
79a7b9aedc
|
@ -144,6 +144,7 @@ import { findDMForUser } from "../../utils/dm/findDMForUser";
|
||||||
import { Linkify } from "../../HtmlUtils";
|
import { Linkify } from "../../HtmlUtils";
|
||||||
import { NotificationColor } from "../../stores/notifications/NotificationColor";
|
import { NotificationColor } from "../../stores/notifications/NotificationColor";
|
||||||
import { UserTab } from "../views/dialogs/UserTab";
|
import { UserTab } from "../views/dialogs/UserTab";
|
||||||
|
import { shouldSkipSetupEncryption } from "../../utils/crypto/shouldSkipSetupEncryption";
|
||||||
|
|
||||||
// legacy export
|
// legacy export
|
||||||
export { default as Views } from "../../Views";
|
export { default as Views } from "../../Views";
|
||||||
|
@ -394,7 +395,10 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||||
} else {
|
} else {
|
||||||
this.setStateForNewView({ view: Views.COMPLETE_SECURITY });
|
this.setStateForNewView({ view: Views.COMPLETE_SECURITY });
|
||||||
}
|
}
|
||||||
} else if (await cli.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing")) {
|
} else if (
|
||||||
|
(await cli.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing")) &&
|
||||||
|
!shouldSkipSetupEncryption(cli)
|
||||||
|
) {
|
||||||
// if cross-signing is not yet set up, do so now if possible.
|
// if cross-signing is not yet set up, do so now if possible.
|
||||||
this.setStateForNewView({ view: Views.E2E_SETUP });
|
this.setStateForNewView({ view: Views.E2E_SETUP });
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -44,7 +44,7 @@ import MatrixClientContext from "../../../../../contexts/MatrixClientContext";
|
||||||
import { SettingsSection } from "../../shared/SettingsSection";
|
import { SettingsSection } from "../../shared/SettingsSection";
|
||||||
import SettingsTab from "../SettingsTab";
|
import SettingsTab from "../SettingsTab";
|
||||||
import SdkConfig from "../../../../../SdkConfig";
|
import SdkConfig from "../../../../../SdkConfig";
|
||||||
import { shouldForceDisableEncryption } from "../../../../../utils/room/shouldForceDisableEncryption";
|
import { shouldForceDisableEncryption } from "../../../../../utils/crypto/shouldForceDisableEncryption";
|
||||||
import { Caption } from "../../../typography/Caption";
|
import { Caption } from "../../../typography/Caption";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
|
|
|
@ -43,7 +43,7 @@ import Spinner from "./components/views/elements/Spinner";
|
||||||
import { ViewRoomPayload } from "./dispatcher/payloads/ViewRoomPayload";
|
import { ViewRoomPayload } from "./dispatcher/payloads/ViewRoomPayload";
|
||||||
import { findDMForUser } from "./utils/dm/findDMForUser";
|
import { findDMForUser } from "./utils/dm/findDMForUser";
|
||||||
import { privateShouldBeEncrypted } from "./utils/rooms";
|
import { privateShouldBeEncrypted } from "./utils/rooms";
|
||||||
import { shouldForceDisableEncryption } from "./utils/room/shouldForceDisableEncryption";
|
import { shouldForceDisableEncryption } from "./utils/crypto/shouldForceDisableEncryption";
|
||||||
import { waitForMember } from "./utils/membership";
|
import { waitForMember } from "./utils/membership";
|
||||||
import { PreferredRoomVersions } from "./utils/PreferredRoomVersions";
|
import { PreferredRoomVersions } from "./utils/PreferredRoomVersions";
|
||||||
import SettingsStore from "./settings/SettingsStore";
|
import SettingsStore from "./settings/SettingsStore";
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||||
|
|
||||||
|
import { shouldForceDisableEncryption } from "./shouldForceDisableEncryption";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 => {
|
||||||
|
const isEncryptionForceDisabled = shouldForceDisableEncryption(client);
|
||||||
|
return isEncryptionForceDisabled && !client.getRooms().some((r) => client.isRoomEncrypted(r.roomId));
|
||||||
|
};
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||||
|
|
||||||
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||||
|
|
||||||
import { shouldForceDisableEncryption } from "./room/shouldForceDisableEncryption";
|
import { shouldForceDisableEncryption } from "./crypto/shouldForceDisableEncryption";
|
||||||
import { getE2EEWellKnown } from "./WellKnownUtils";
|
import { getE2EEWellKnown } from "./WellKnownUtils";
|
||||||
|
|
||||||
export function privateShouldBeEncrypted(client: MatrixClient): boolean {
|
export function privateShouldBeEncrypted(client: MatrixClient): boolean {
|
||||||
|
|
|
@ -85,6 +85,7 @@ describe("<MatrixChat />", () => {
|
||||||
isStored: jest.fn().mockReturnValue(null),
|
isStored: jest.fn().mockReturnValue(null),
|
||||||
},
|
},
|
||||||
getDehydratedDevice: jest.fn(),
|
getDehydratedDevice: jest.fn(),
|
||||||
|
isRoomEncrypted: jest.fn(),
|
||||||
});
|
});
|
||||||
let mockClient = getMockClientWithEventEmitter(getMockClientMethods());
|
let mockClient = getMockClientWithEventEmitter(getMockClientMethods());
|
||||||
const serverConfig = {
|
const serverConfig = {
|
||||||
|
@ -454,6 +455,59 @@ describe("<MatrixChat />", () => {
|
||||||
await screen.findByLabelText("User menu");
|
await screen.findByLabelText("User menu");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("when server supports cross signing and user does not have cross signing setup", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
loginClient.doesServerSupportUnstableFeature.mockResolvedValue(true);
|
||||||
|
loginClient.userHasCrossSigningKeys.mockResolvedValue(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("when encryption is force disabled", () => {
|
||||||
|
const unencryptedRoom = new Room("!unencrypted:server.org", loginClient, userId);
|
||||||
|
const encryptedRoom = new Room("!encrypted:server.org", loginClient, userId);
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
loginClient.getClientWellKnown.mockReturnValue({
|
||||||
|
"io.element.e2ee": {
|
||||||
|
force_disable: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
loginClient.isRoomEncrypted.mockImplementation((roomId) => roomId === encryptedRoom.roomId);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should go straight to logged in view when user is not in any encrypted rooms", async () => {
|
||||||
|
loginClient.getRooms.mockReturnValue([unencryptedRoom]);
|
||||||
|
await getComponentAndLogin(false);
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
|
||||||
|
// logged in, did not setup keys
|
||||||
|
await screen.findByLabelText("User menu");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should go to setup e2e screen when user is in encrypted rooms", async () => {
|
||||||
|
loginClient.getRooms.mockReturnValue([unencryptedRoom, encryptedRoom]);
|
||||||
|
await getComponentAndLogin();
|
||||||
|
await flushPromises();
|
||||||
|
// set up keys screen is rendered
|
||||||
|
expect(screen.getByText("Setting up keys")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should go to setup e2e screen", async () => {
|
||||||
|
loginClient.doesServerSupportUnstableFeature.mockResolvedValue(true);
|
||||||
|
|
||||||
|
await getComponentAndLogin();
|
||||||
|
|
||||||
|
expect(loginClient.userHasCrossSigningKeys).toHaveBeenCalled();
|
||||||
|
|
||||||
|
await flushPromises();
|
||||||
|
|
||||||
|
// set up keys screen is rendered
|
||||||
|
expect(screen.getByText("Setting up keys")).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("should show complete security screen when user has cross signing setup", async () => {
|
it("should show complete security screen when user has cross signing setup", async () => {
|
||||||
loginClient.userHasCrossSigningKeys.mockResolvedValue(true);
|
loginClient.userHasCrossSigningKeys.mockResolvedValue(true);
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { shouldForceDisableEncryption } from "../../../src/utils/room/shouldForceDisableEncryption";
|
import { shouldForceDisableEncryption } from "../../../src/utils/crypto/shouldForceDisableEncryption";
|
||||||
import { getMockClientWithEventEmitter } from "../../test-utils";
|
import { getMockClientWithEventEmitter } from "../../test-utils";
|
||||||
|
|
||||||
describe("shouldForceDisableEncryption()", () => {
|
describe("shouldForceDisableEncryption()", () => {
|
Loading…
Reference in New Issue