From c2c108957ee9482ce155d9aa2b1b92d2f3c3566d Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 29 Jul 2024 13:53:44 +0100 Subject: [PATCH] Add sign out button to settings profile section (#12666) * Add sign out button to settings profile section And move the logic for displaying the dialog out of the user menu to somewhere it can be re-used. Also close any open dialog on logout, because otherwise, well... you can guess. * Missing import * Update screenshot * This button doesn't need to be an anchor * Use Flex component * Use new force-close function * More tests --- .../general-linux.png | Bin 49237 -> 48665 bytes src/components/structures/UserMenu.tsx | 25 +----------- src/components/views/dialogs/LogoutDialog.tsx | 20 ++++++++++ .../views/settings/UserProfileSettings.tsx | 33 ++++++++++++++-- .../settings/UserProfileSettings-test.tsx | 36 +++++++++++++++++- 5 files changed, 86 insertions(+), 28 deletions(-) diff --git a/playwright/snapshots/settings/general-user-settings-tab.spec.ts/general-linux.png b/playwright/snapshots/settings/general-user-settings-tab.spec.ts/general-linux.png index 4cf8df1c32692643168a448e8cd9096c620b3408..4924832093a6c29e3f053044aff9b47c105cea1c 100644 GIT binary patch delta 12050 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 diff --git a/src/components/structures/UserMenu.tsx b/src/components/structures/UserMenu.tsx index 0e6b17ccc0..6921c26264 100644 --- a/src/components/structures/UserMenu.tsx +++ b/src/components/structures/UserMenu.tsx @@ -27,7 +27,7 @@ import { UserTab } from "../views/dialogs/UserTab"; import { OpenToTabPayload } from "../../dispatcher/payloads/OpenToTabPayload"; import FeedbackDialog from "../views/dialogs/FeedbackDialog"; import Modal from "../../Modal"; -import LogoutDialog from "../views/dialogs/LogoutDialog"; +import LogoutDialog, { shouldShowLogoutDialog } from "../views/dialogs/LogoutDialog"; import SettingsStore from "../../settings/SettingsStore"; import { findHighContrastTheme, getCustomTheme, isHighContrastTheme } from "../../theme"; import { RovingAccessibleButton } from "../../accessibility/RovingTabIndex"; @@ -288,7 +288,7 @@ export default class UserMenu extends React.Component { ev.preventDefault(); ev.stopPropagation(); - if (await this.shouldShowLogoutDialog()) { + if (await shouldShowLogoutDialog(MatrixClientPeg.safeGet())) { Modal.createDialog(LogoutDialog); } else { defaultDispatcher.dispatch({ action: "logout" }); @@ -297,27 +297,6 @@ export default class UserMenu extends React.Component { this.setState({ contextMenuPosition: null }); // also close the menu }; - /** - * Checks if the `LogoutDialog` should be shown instead of the simple logout flow. - * The `LogoutDialog` will check the crypto recovery status of the account and - * help the user setup recovery properly if needed. - * @private - */ - private async shouldShowLogoutDialog(): Promise { - const cli = MatrixClientPeg.get(); - const crypto = cli?.getCrypto(); - if (!crypto) return false; - - // If any room is encrypted, we need to show the advanced logout flow - const allRooms = cli!.getRooms(); - for (const room of allRooms) { - const isE2e = await crypto.isEncryptionEnabledInRoom(room.roomId); - if (isE2e) return true; - } - - return false; - } - private onSignInClick = (): void => { defaultDispatcher.dispatch({ action: "start_login" }); this.setState({ contextMenuPosition: null }); // also close the menu diff --git a/src/components/views/dialogs/LogoutDialog.tsx b/src/components/views/dialogs/LogoutDialog.tsx index 253a43b0f0..3714a71e8c 100644 --- a/src/components/views/dialogs/LogoutDialog.tsx +++ b/src/components/views/dialogs/LogoutDialog.tsx @@ -17,6 +17,7 @@ limitations under the License. import React from "react"; import { logger } from "matrix-js-sdk/src/logger"; +import { MatrixClient } from "matrix-js-sdk/src/matrix"; import type CreateKeyBackupDialog from "../../../async-components/views/dialogs/security/CreateKeyBackupDialog"; import type ExportE2eKeysDialog from "../../../async-components/views/dialogs/security/ExportE2eKeysDialog"; @@ -58,6 +59,25 @@ interface IState { backupStatus: BackupStatus; } +/** + * Checks if the `LogoutDialog` should be shown instead of the simple logout flow. + * The `LogoutDialog` will check the crypto recovery status of the account and + * help the user setup recovery properly if needed. + */ +export async function shouldShowLogoutDialog(cli: MatrixClient): Promise { + const crypto = cli?.getCrypto(); + if (!crypto) return false; + + // If any room is encrypted, we need to show the advanced logout flow + const allRooms = cli!.getRooms(); + for (const room of allRooms) { + const isE2e = await crypto.isEncryptionEnabledInRoom(room.roomId); + if (isE2e) return true; + } + + return false; +} + export default class LogoutDialog extends React.Component { public static defaultProps = { onFinished: function () {}, diff --git a/src/components/views/settings/UserProfileSettings.tsx b/src/components/views/settings/UserProfileSettings.tsx index a5ff435676..a104aabb1d 100644 --- a/src/components/views/settings/UserProfileSettings.tsx +++ b/src/components/views/settings/UserProfileSettings.tsx @@ -18,6 +18,7 @@ import React, { ChangeEvent, useCallback, useEffect, useMemo, useState } from "r import { logger } from "matrix-js-sdk/src/logger"; import { EditInPlace, Alert, ErrorMessage } from "@vector-im/compound-web"; import { Icon as PopOutIcon } from "@vector-im/compound-design-tokens/icons/pop-out.svg"; +import { Icon as SignOutIcon } from "@vector-im/compound-design-tokens/icons/sign-out.svg"; import { _t } from "../../../languageHandler"; import { OwnProfileStore } from "../../../stores/OwnProfileStore"; @@ -31,6 +32,10 @@ import { useId } from "../../../utils/useId"; import CopyableText from "../elements/CopyableText"; import { useMatrixClientContext } from "../../../contexts/MatrixClientContext"; import AccessibleButton from "../elements/AccessibleButton"; +import LogoutDialog, { shouldShowLogoutDialog } from "../dialogs/LogoutDialog"; +import Modal from "../../../Modal"; +import defaultDispatcher from "../../../dispatcher/dispatcher"; +import { Flex } from "../../utils/Flex"; const SpinnerToast: React.FC = ({ children }) => ( <> @@ -76,6 +81,25 @@ const ManageAccountButton: React.FC = ({ externalAccou ); +const SignOutButton: React.FC = () => { + const client = useMatrixClientContext(); + + const onClick = useCallback(async () => { + if (await shouldShowLogoutDialog(client)) { + Modal.createDialog(LogoutDialog); + } else { + defaultDispatcher.dispatch({ action: "logout" }); + } + }, [client]); + + return ( + + + {_t("action|sign_out")} + + ); +}; + interface UserProfileSettingsProps { // The URL to redirect the user to in order to manage their account. externalAccountManagementUrl?: string; @@ -219,11 +243,12 @@ const UserProfileSettings: React.FC = ({ )} {userIdentifier && } - {externalAccountManagementUrl && ( -
+ + {externalAccountManagementUrl && ( -
- )} + )} + + ); }; diff --git a/test/components/views/settings/UserProfileSettings-test.tsx b/test/components/views/settings/UserProfileSettings-test.tsx index 6b7f278e5a..6aba71d81b 100644 --- a/test/components/views/settings/UserProfileSettings-test.tsx +++ b/test/components/views/settings/UserProfileSettings-test.tsx @@ -18,12 +18,15 @@ import React, { ChangeEvent } from "react"; import { act, render, screen } from "@testing-library/react"; import { MatrixClient, UploadResponse } from "matrix-js-sdk/src/matrix"; import { mocked } from "jest-mock"; +import userEvent from "@testing-library/user-event"; import UserProfileSettings from "../../../../src/components/views/settings/UserProfileSettings"; -import { stubClient } from "../../../test-utils"; +import { mkStubRoom, stubClient } from "../../../test-utils"; import { ToastContext, ToastRack } from "../../../../src/contexts/ToastContext"; import { OwnProfileStore } from "../../../../src/stores/OwnProfileStore"; import MatrixClientContext from "../../../../src/contexts/MatrixClientContext"; +import dis from "../../../../src/dispatcher/dispatcher"; +import Modal from "../../../../src/Modal"; interface MockedAvatarSettingProps { removeAvatar: () => void; @@ -43,6 +46,11 @@ jest.mock( }) as React.FC, ); +jest.mock("../../../../src/dispatcher/dispatcher", () => ({ + dispatch: jest.fn(), + register: jest.fn(), +})); + let editInPlaceOnChange: (e: ChangeEvent) => void; let editInPlaceOnSave: () => void; let editInPlaceOnCancel: () => void; @@ -209,4 +217,30 @@ describe("ProfileSettings", () => { expect(await screen.findByText("Mocked EditInPlace: Alice")).toBeInTheDocument(); }); + + it("signs out directly if no rooms are encrypted", async () => { + renderProfileSettings(toastRack, client); + + const signOutButton = await screen.findByText("Sign out"); + await userEvent.click(signOutButton); + + expect(dis.dispatch).toHaveBeenCalledWith({ action: "logout" }); + }); + + it("displays confirmation dialog if rooms are encrypted", async () => { + jest.spyOn(Modal, "createDialog"); + + const mockRoom = mkStubRoom("!test:room", "Test Room", client); + client.getRooms = jest.fn().mockReturnValue([mockRoom]); + client.getCrypto = jest.fn().mockReturnValue({ + isEncryptionEnabledInRoom: jest.fn().mockReturnValue(true), + }); + + renderProfileSettings(toastRack, client); + + const signOutButton = await screen.findByText("Sign out"); + await userEvent.click(signOutButton); + + expect(Modal.createDialog).toHaveBeenCalled(); + }); });