From 629b12a7ad2117001af40b8edadeebf047662ec0 Mon Sep 17 00:00:00 2001 From: Andrew Yasynyshyn Date: Thu, 8 Dec 2022 18:51:42 +0200 Subject: [PATCH] enforced key backup setup --- src/DeviceListener.ts | 6 +++++- .../security/CreateSecretStorageDialog.tsx | 4 +--- src/components/structures/MatrixChat.tsx | 6 ++++++ .../structures/auth/CompleteSecurity.tsx | 3 ++- src/toasts/SetupEncryptionToast.ts | 16 +++++++++++++++- 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/DeviceListener.ts b/src/DeviceListener.ts index 1f49c3b34d6..c83f479512b 100644 --- a/src/DeviceListener.ts +++ b/src/DeviceListener.ts @@ -357,7 +357,11 @@ export default class DeviceListener { } // returns null when key backup status hasn't finished being checked const isKeyBackupEnabled = MatrixClientPeg.get().getKeyBackupEnabled(); - this.keyBackupStatusChecked = isKeyBackupEnabled !== null; + + // Ensure user can't dismiss the toast if secure backup is required + if (isKeyBackupEnabled === false && !isSecureBackupRequired()) { + this.keyBackupStatusChecked = isKeyBackupEnabled !== null; + } if (isKeyBackupEnabled === false) { dis.dispatch({ action: Action.ReportKeyBackupNotEnabled }); diff --git a/src/async-components/views/dialogs/security/CreateSecretStorageDialog.tsx b/src/async-components/views/dialogs/security/CreateSecretStorageDialog.tsx index 2953d795655..5cbd8ca6228 100644 --- a/src/async-components/views/dialogs/security/CreateSecretStorageDialog.tsx +++ b/src/async-components/views/dialogs/security/CreateSecretStorageDialog.tsx @@ -65,7 +65,6 @@ enum Phase { const PASSWORD_MIN_SCORE = 4; // So secure, many characters, much complex, wow, etc, etc. interface IProps extends IDialogProps { - hasCancel: boolean; accountPassword: string; forceReset: boolean; } @@ -96,7 +95,6 @@ interface IState { */ export default class CreateSecretStorageDialog extends React.PureComponent { public static defaultProps: Partial = { - hasCancel: true, forceReset: false, }; private recoveryKey: IRecoveryKey; @@ -871,7 +869,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent
diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 04fb4a0fae5..0485442ebc7 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -141,6 +141,7 @@ import { VoiceBroadcastResumer } from '../../voice-broadcast'; import GenericToast from "../views/toasts/GenericToast"; import { Linkify } from "../views/elements/Linkify"; import RovingSpotlightDialog, { Filter } from '../views/dialogs/spotlight/SpotlightDialog'; +import { isSecureBackupRequired } from '../../utils/WellKnownUtils'; // legacy export export { default as Views } from "../../Views"; @@ -826,6 +827,11 @@ export default class MatrixChat extends React.PureComponent { hideAnalyticsToast(); SettingsStore.setValue("pseudonymousAnalyticsOptIn", null, SettingLevel.ACCOUNT, false); break; + case Action.ReportKeyBackupNotEnabled: + if (isSecureBackupRequired()) { + this.setStateForNewView({ view: Views.COMPLETE_SECURITY }); + } + break; case Action.ShowThread: { const { rootEvent, diff --git a/src/components/structures/auth/CompleteSecurity.tsx b/src/components/structures/auth/CompleteSecurity.tsx index b31e259344a..3cd3fc6c5e8 100644 --- a/src/components/structures/auth/CompleteSecurity.tsx +++ b/src/components/structures/auth/CompleteSecurity.tsx @@ -22,6 +22,7 @@ import SetupEncryptionBody from "./SetupEncryptionBody"; import AccessibleButton from '../../views/elements/AccessibleButton'; import CompleteSecurityBody from "../../views/auth/CompleteSecurityBody"; import AuthPage from "../../views/auth/AuthPage"; +import { isSecureBackupRequired } from '../../../utils/WellKnownUtils'; interface IProps { onFinished: () => void; @@ -91,7 +92,7 @@ export default class CompleteSecurity extends React.Component { } let skipButton; - if (phase === Phase.Intro || phase === Phase.ConfirmReset) { + if ((phase === Phase.Intro || phase === Phase.ConfirmReset) && !isSecureBackupRequired()) { skipButton = ( ); diff --git a/src/toasts/SetupEncryptionToast.ts b/src/toasts/SetupEncryptionToast.ts index a3a90a009ff..80b1285b54d 100644 --- a/src/toasts/SetupEncryptionToast.ts +++ b/src/toasts/SetupEncryptionToast.ts @@ -23,6 +23,7 @@ import ToastStore from "../stores/ToastStore"; import GenericToast from "../components/views/toasts/GenericToast"; import SecurityCustomisations from "../customisations/Security"; import Spinner from "../components/views/elements/Spinner"; +import { isSecureBackupRequired } from '../utils/WellKnownUtils'; const TOAST_KEY = "setupencryption"; @@ -78,6 +79,10 @@ const onReject = () => { DeviceListener.sharedInstance().dismissEncryptionSetup(); }; +type LatterButton = { + rejectLabel?: string; +} + export const showToast = (kind: Kind) => { if (SecurityCustomisations.setupEncryptionNeeded?.(kind)) { return; @@ -99,6 +104,12 @@ export const showToast = (kind: Kind) => { } }; + // Ensure user can't dismiss the toast if secure backup is required + let latterButton: LatterButton = { rejectLabel: _t("Later") }; + if (kind === Kind.SET_UP_ENCRYPTION && isSecureBackupRequired()) { + latterButton = {}; + } + ToastStore.sharedInstance().addOrReplaceToast({ key: TOAST_KEY, title: getTitle(kind), @@ -107,8 +118,8 @@ export const showToast = (kind: Kind) => { description: getDescription(kind), acceptLabel: getSetupCaption(kind), onAccept, - rejectLabel: _t("Later"), onReject, + ...latterButton }, component: GenericToast, priority: kind === Kind.VERIFY_THIS_SESSION ? 95 : 40, @@ -116,5 +127,8 @@ export const showToast = (kind: Kind) => { }; export const hideToast = () => { + // Ensure user can't dismiss the toast if secure backup is required + if (isSecureBackupRequired()) return; + ToastStore.sharedInstance().dismissToast(TOAST_KEY); };