Merge pull request #5242 from matrix-org/jryans/secure-backup-setup-methods

Support HS-preferred Secure Backup setup methods
This commit is contained in:
J. Ryan Stinnett 2020-09-22 16:07:38 +01:00 committed by GitHub
commit 93b109105a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 79 additions and 29 deletions

View file

@ -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 (
<StyledRadioButton
key={CREATE_STORAGE_OPTION_KEY}
value={CREATE_STORAGE_OPTION_KEY}
name="keyPassphrase"
checked={this.state.passPhraseKeySelected === CREATE_STORAGE_OPTION_KEY}
outlined
>
<div className="mx_CreateSecretStorageDialog_optionTitle">
<span className="mx_CreateSecretStorageDialog_optionIcon mx_CreateSecretStorageDialog_optionIcon_secureBackup"></span>
{_t("Generate a Security Key")}
</div>
<div>{_t("Well generate a Security Key for you to store somewhere safe, like a password manager or a safe.")}</div>
</StyledRadioButton>
);
}
_renderOptionPassphrase() {
return (
<StyledRadioButton
key={CREATE_STORAGE_OPTION_PASSPHRASE}
value={CREATE_STORAGE_OPTION_PASSPHRASE}
name="keyPassphrase"
checked={this.state.passPhraseKeySelected === CREATE_STORAGE_OPTION_PASSPHRASE}
outlined
>
<div className="mx_CreateSecretStorageDialog_optionTitle">
<span className="mx_CreateSecretStorageDialog_optionIcon mx_CreateSecretStorageDialog_optionIcon_securePhrase"></span>
{_t("Enter a Security Phrase")}
</div>
<div>{_t("Use a secret phrase only you know, and optionally save a Security Key to use for backup.")}</div>
</StyledRadioButton>
);
}
_renderPhaseChooseKeyPassphrase() {
const setupMethods = getSecureBackupSetupMethods();
const optionKey = setupMethods.includes("key") ? this._renderOptionKey() : null;
const optionPassphrase = setupMethods.includes("passphrase") ? this._renderOptionPassphrase() : null;
return <form onSubmit={this._onChooseKeyPassphraseFormSubmit}>
<p className="mx_CreateSecretStorageDialog_centeredBody">{_t(
"Safeguard against losing access to encrypted messages & data by " +
"backing up encryption keys on your server.",
)}</p>
<div className="mx_CreateSecretStorageDialog_primaryContainer" role="radiogroup" onChange={this._onKeyPassphraseChange}>
<StyledRadioButton
key={CREATE_STORAGE_OPTION_KEY}
value={CREATE_STORAGE_OPTION_KEY}
name="keyPassphrase"
checked={this.state.passPhraseKeySelected === CREATE_STORAGE_OPTION_KEY}
outlined
>
<div className="mx_CreateSecretStorageDialog_optionTitle">
<span className="mx_CreateSecretStorageDialog_optionIcon mx_CreateSecretStorageDialog_optionIcon_secureBackup"></span>
{_t("Generate a Security Key")}
</div>
<div>{_t("Well generate a Security Key for you to store somewhere safe, like a password manager or a safe.")}</div>
</StyledRadioButton>
<StyledRadioButton
key={CREATE_STORAGE_OPTION_PASSPHRASE}
value={CREATE_STORAGE_OPTION_PASSPHRASE}
name="keyPassphrase"
checked={this.state.passPhraseKeySelected === CREATE_STORAGE_OPTION_PASSPHRASE}
outlined
>
<div className="mx_CreateSecretStorageDialog_optionTitle">
<span className="mx_CreateSecretStorageDialog_optionIcon mx_CreateSecretStorageDialog_optionIcon_securePhrase"></span>
{_t("Enter a Security Phrase")}
</div>
<div>{_t("Use a secret phrase only you know, and optionally save a Security Key to use for backup.")}</div>
</StyledRadioButton>
{optionKey}
{optionPassphrase}
</div>
<DialogButtons
primaryButton={_t("Continue")}

View file

@ -2266,11 +2266,11 @@
"Success!": "Success!",
"Create key backup": "Create key backup",
"Unable to create key backup": "Unable to create key backup",
"Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server.": "Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server.",
"Generate a Security Key": "Generate a Security Key",
"Well generate a Security Key for you to store somewhere safe, like a password manager or a safe.": "Well generate a Security Key for you to store somewhere safe, like a password manager or a safe.",
"Enter a Security Phrase": "Enter a Security Phrase",
"Use a secret phrase only you know, and optionally save a Security Key to use for backup.": "Use a secret phrase only you know, and optionally save a Security Key to use for backup.",
"Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server.": "Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server.",
"Enter your account password to confirm the upgrade:": "Enter your account password to confirm the upgrade:",
"Restore your key backup to upgrade your encryption": "Restore your key backup to upgrade your encryption",
"Restore": "Restore",

View file

@ -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();
@ -38,3 +42,27 @@ export function isSecureBackupRequired(): boolean {
const wellKnown = getE2EEWellKnown();
return wellKnown && wellKnown["secure_backup_required"] === true;
}
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(SecureBackupSetupMethod.Key) ||
wellKnown["secure_backup_setup_methods"].includes(SecureBackupSetupMethod.Passphrase)
)
) {
return [
SecureBackupSetupMethod.Key,
SecureBackupSetupMethod.Passphrase,
];
}
return wellKnown["secure_backup_setup_methods"];
}