From 115c7ccd4e5d22c27ca757102fbca0be0c34882f Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Mon, 21 Sep 2020 15:48:47 +0100 Subject: [PATCH 1/2] Support HS-preferred Secure Backup setup methods This adds support for the `secure_backup_setup_methods` key, which allows HS admins to state that Element should simplify down to only one setup method, rather than offering both. Fixes https://github.com/vector-im/element-web/issues/15238 --- .../security/CreateSecretStorageDialog.js | 78 ++++++++++++------- src/i18n/strings/en_EN.json | 2 +- src/utils/WellKnownUtils.ts | 16 ++++ 3 files changed, 67 insertions(+), 29 deletions(-) diff --git a/src/async-components/views/dialogs/security/CreateSecretStorageDialog.js b/src/async-components/views/dialogs/security/CreateSecretStorageDialog.js index f3b52da141..00aad2a0ce 100644 --- a/src/async-components/views/dialogs/security/CreateSecretStorageDialog.js +++ b/src/async-components/views/dialogs/security/CreateSecretStorageDialog.js @@ -31,7 +31,7 @@ import AccessibleButton from "../../../../components/views/elements/AccessibleBu import DialogButtons from "../../../../components/views/elements/DialogButtons"; import InlineSpinner from "../../../../components/views/elements/InlineSpinner"; import RestoreKeyBackupDialog from "../../../../components/views/dialogs/security/RestoreKeyBackupDialog"; -import { isSecureBackupRequired } from '../../../../utils/WellKnownUtils'; +import { getSecureBackupSetupMethods, isSecureBackupRequired } from '../../../../utils/WellKnownUtils'; const PHASE_LOADING = 0; const PHASE_LOADERROR = 1; @@ -87,10 +87,16 @@ export default class CreateSecretStorageDialog extends React.PureComponent { canUploadKeysWithPasswordOnly: null, accountPassword: props.accountPassword || "", accountPasswordCorrect: null, - passPhraseKeySelected: CREATE_STORAGE_OPTION_KEY, canSkip: !isSecureBackupRequired(), }; + const setupMethods = getSecureBackupSetupMethods(); + if (setupMethods.includes("key")) { + this.state.passPhraseKeySelected = CREATE_STORAGE_OPTION_KEY; + } else { + this.state.passPhraseKeySelected = CREATE_STORAGE_OPTION_PASSPHRASE; + } + this._passphraseField = createRef(); this._fetchBackupInfo(); @@ -441,39 +447,55 @@ export default class CreateSecretStorageDialog extends React.PureComponent { }); } + _renderOptionKey() { + return ( + +
+ + {_t("Generate a Security Key")} +
+
{_t("We’ll generate a Security Key for you to store somewhere safe, like a password manager or a safe.")}
+
+ ); + } + + _renderOptionPassphrase() { + return ( + +
+ + {_t("Enter a Security Phrase")} +
+
{_t("Use a secret phrase only you know, and optionally save a Security Key to use for backup.")}
+
+ ); + } + _renderPhaseChooseKeyPassphrase() { + const setupMethods = getSecureBackupSetupMethods(); + const optionKey = setupMethods.includes("key") ? this._renderOptionKey() : null; + const optionPassphrase = setupMethods.includes("passphrase") ? this._renderOptionPassphrase() : null; + return

{_t( "Safeguard against losing access to encrypted messages & data by " + "backing up encryption keys on your server.", )}

- -
- - {_t("Generate a Security Key")} -
-
{_t("We’ll generate a Security Key for you to store somewhere safe, like a password manager or a safe.")}
-
- -
- - {_t("Enter a Security Phrase")} -
-
{_t("Use a secret phrase only you know, and optionally save a Security Key to use for backup.")}
-
+ {optionKey} + {optionPassphrase}
Date: Tue, 22 Sep 2020 15:22:39 +0100 Subject: [PATCH 2/2] Add more types and enums --- src/utils/WellKnownUtils.ts | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/utils/WellKnownUtils.ts b/src/utils/WellKnownUtils.ts index 6437d22cb3..69ed39e0ee 100644 --- a/src/utils/WellKnownUtils.ts +++ b/src/utils/WellKnownUtils.ts @@ -19,9 +19,13 @@ import {MatrixClientPeg} from '../MatrixClientPeg'; const E2EE_WK_KEY = "io.element.e2ee"; const E2EE_WK_KEY_DEPRECATED = "im.vector.riot.e2ee"; +/* eslint-disable camelcase */ export interface IE2EEWellKnown { default?: boolean; + secure_backup_required?: boolean; + secure_backup_setup_methods?: SecureBackupSetupMethod[]; } +/* eslint-enable camelcase */ export function getE2EEWellKnown(): IE2EEWellKnown { const clientWellKnown = MatrixClientPeg.get().getClientWellKnown(); @@ -39,18 +43,26 @@ export function isSecureBackupRequired(): boolean { return wellKnown && wellKnown["secure_backup_required"] === true; } -export function getSecureBackupSetupMethods(): string[] { +export enum SecureBackupSetupMethod { + Key = "key", + Passphrase = "passphrase", +} + +export function getSecureBackupSetupMethods(): SecureBackupSetupMethod[] { const wellKnown = getE2EEWellKnown(); if ( !wellKnown || !wellKnown["secure_backup_setup_methods"] || !wellKnown["secure_backup_setup_methods"].length || !( - wellKnown["secure_backup_setup_methods"].includes("key") || - wellKnown["secure_backup_setup_methods"].includes("passphrase") + wellKnown["secure_backup_setup_methods"].includes(SecureBackupSetupMethod.Key) || + wellKnown["secure_backup_setup_methods"].includes(SecureBackupSetupMethod.Passphrase) ) ) { - return ["key", "passphrase"]; + return [ + SecureBackupSetupMethod.Key, + SecureBackupSetupMethod.Passphrase, + ]; } return wellKnown["secure_backup_setup_methods"]; }