Update the 'save your security key' screen

This commit is contained in:
David Baker 2020-06-23 16:27:41 +01:00
parent 6ce8584337
commit 0694776b25
3 changed files with 66 additions and 90 deletions

View file

@ -91,33 +91,42 @@ limitations under the License.
margin-left: 20px; margin-left: 20px;
} }
.mx_CreateSecretStorageDialog_recoveryKeyHeader {
margin-bottom: 1em;
}
.mx_CreateSecretStorageDialog_recoveryKeyContainer { .mx_CreateSecretStorageDialog_recoveryKeyContainer {
display: flex; width: 380px;
margin-left: auto;
margin-right: auto;
} }
.mx_CreateSecretStorageDialog_recoveryKey { .mx_CreateSecretStorageDialog_recoveryKey {
width: 262px; font-weight: bold;
text-align: center;
padding: 20px; padding: 20px;
color: $info-plinth-fg-color; color: $info-plinth-fg-color;
background-color: $info-plinth-bg-color; background-color: $info-plinth-bg-color;
margin-right: 12px; border-radius: 6px;
word-spacing: 1em;
margin-bottom: 20px;
} }
.mx_CreateSecretStorageDialog_recoveryKeyButtons { .mx_CreateSecretStorageDialog_recoveryKeyButtons {
flex: 1;
display: flex; display: flex;
justify-content: space-between;
align-items: center; align-items: center;
} }
.mx_CreateSecretStorageDialog_recoveryKeyButtons .mx_AccessibleButton { .mx_CreateSecretStorageDialog_recoveryKeyButtons .mx_AccessibleButton {
margin-right: 10px; width: 160px;
} padding-left: 0px;
padding-right: 0px;
.mx_CreateSecretStorageDialog_recoveryKeyButtons button {
flex: 1;
white-space: nowrap; white-space: nowrap;
} }
.mx_CreateSecretStorageDialog_continueSpinner {
margin-top: 33px;
text-align: right;
}
.mx_CreateSecretStorageDialog_continueSpinner img {
width: 20px;
height: 20px;
}

View file

@ -27,6 +27,9 @@ import {copyNode} from "../../../../utils/strings";
import {SSOAuthEntry} from "../../../../components/views/auth/InteractiveAuthEntryComponents"; import {SSOAuthEntry} from "../../../../components/views/auth/InteractiveAuthEntryComponents";
import PassphraseField from "../../../../components/views/auth/PassphraseField"; import PassphraseField from "../../../../components/views/auth/PassphraseField";
import StyledRadioButton from '../../../../components/views/elements/StyledRadioButton'; import StyledRadioButton from '../../../../components/views/elements/StyledRadioButton';
import AccessibleButton from "../../../../components/views/elements/AccessibleButton";
import DialogButtons from "../../../../components/views/elements/DialogButtons";
import InlineSpinner from "../../../../components/views/elements/InlineSpinner";
const PHASE_LOADING = 0; const PHASE_LOADING = 0;
const PHASE_LOADERROR = 1; const PHASE_LOADERROR = 1;
@ -35,7 +38,6 @@ const PHASE_MIGRATE = 3;
const PHASE_PASSPHRASE = 4; const PHASE_PASSPHRASE = 4;
const PHASE_PASSPHRASE_CONFIRM = 5; const PHASE_PASSPHRASE_CONFIRM = 5;
const PHASE_SHOWKEY = 6; const PHASE_SHOWKEY = 6;
const PHASE_KEEPITSAFE = 7;
const PHASE_STORING = 8; const PHASE_STORING = 8;
const PHASE_DONE = 9; const PHASE_DONE = 9;
const PHASE_CONFIRM_SKIP = 10; const PHASE_CONFIRM_SKIP = 10;
@ -208,7 +210,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
if (successful) { if (successful) {
this.setState({ this.setState({
copied: true, copied: true,
phase: PHASE_KEEPITSAFE,
}); });
} }
} }
@ -221,7 +222,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
this.setState({ this.setState({
downloaded: true, downloaded: true,
phase: PHASE_KEEPITSAFE,
}); });
} }
@ -374,6 +374,10 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
this._fetchBackupInfo(); this._fetchBackupInfo();
} }
_onShowKeyContinueClick = () => {
this._bootstrapSecretStorage();
}
_onSkipSetupClick = () => { _onSkipSetupClick = () => {
this.setState({phase: PHASE_CONFIRM_SKIP}); this.setState({phase: PHASE_CONFIRM_SKIP});
} }
@ -429,12 +433,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
}); });
} }
_onKeepItSafeBackClick = () => {
this.setState({
phase: PHASE_SHOWKEY,
});
}
_onPassPhraseValidate = (result) => { _onPassPhraseValidate = (result) => {
this.setState({ this.setState({
passPhraseValid: result.valid, passPhraseValid: result.valid,
@ -460,8 +458,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
} }
_renderPhaseChooseKeyPassphrase() { _renderPhaseChooseKeyPassphrase() {
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return <form onSubmit={this._onChooseKeyPassphraseFormSubmit}> return <form onSubmit={this._onChooseKeyPassphraseFormSubmit}>
<p>{_t( <p>{_t(
"Safeguard against losing access to encrypted messages & data by " + "Safeguard against losing access to encrypted messages & data by " +
@ -512,7 +508,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
// Once we're confident enough in this (and it's supported enough) we can do // Once we're confident enough in this (and it's supported enough) we can do
// it automatically. // it automatically.
// https://github.com/vector-im/riot-web/issues/11696 // https://github.com/vector-im/riot-web/issues/11696
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
const Field = sdk.getComponent('views.elements.Field'); const Field = sdk.getComponent('views.elements.Field');
let authPrompt; let authPrompt;
@ -561,8 +556,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
} }
_renderPhasePassPhrase() { _renderPhasePassPhrase() {
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
const LabelledToggleSwitch = sdk.getComponent('views.elements.LabelledToggleSwitch'); const LabelledToggleSwitch = sdk.getComponent('views.elements.LabelledToggleSwitch');
return <form onSubmit={this._onPassPhraseNextClick}> return <form onSubmit={this._onPassPhraseNextClick}>
@ -614,7 +607,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
} }
_renderPhasePassPhraseConfirm() { _renderPhasePassPhraseConfirm() {
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
const Field = sdk.getComponent('views.elements.Field'); const Field = sdk.getComponent('views.elements.Field');
let matchText; let matchText;
@ -645,7 +637,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
</div> </div>
</div>; </div>;
} }
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return <form onSubmit={this._onPassPhraseConfirmNextClick}> return <form onSubmit={this._onPassPhraseConfirmNextClick}>
<p>{_t( <p>{_t(
"Enter your recovery passphrase a second time to confirm it.", "Enter your recovery passphrase a second time to confirm it.",
@ -679,66 +670,48 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
} }
_renderPhaseShowKey() { _renderPhaseShowKey() {
const AccessibleButton = sdk.getComponent('elements.AccessibleButton'); let continueButton;
if (this.state.phase === PHASE_SHOWKEY) {
continueButton = <DialogButtons primaryButton={_t("Continue")}
disabled={!this.state.downloaded && !this.state.copied}
onPrimaryButtonClick={this._onShowKeyContinueClick}
hasCancel={false}
/>;
} else {
continueButton = <div className="mx_CreateSecretStorageDialog_continueSpinner">
<InlineSpinner />
</div>;
}
return <div> return <div>
<p>{_t( <p>{_t(
"Your recovery key is a safety net - you can use it to restore " + "Store your Security Key somewhere safe, like a password manager or a safe, " +
"access to your encrypted messages if you forget your recovery passphrase.", "as its used to safeguard your encrypted data.",
)}</p>
<p>{_t(
"Keep a copy of it somewhere secure, like a password manager or even a safe.",
)}</p> )}</p>
<div className="mx_CreateSecretStorageDialog_primaryContainer"> <div className="mx_CreateSecretStorageDialog_primaryContainer">
<div className="mx_CreateSecretStorageDialog_recoveryKeyHeader">
{_t("Your recovery key")}
</div>
<div className="mx_CreateSecretStorageDialog_recoveryKeyContainer"> <div className="mx_CreateSecretStorageDialog_recoveryKeyContainer">
<div className="mx_CreateSecretStorageDialog_recoveryKey"> <div className="mx_CreateSecretStorageDialog_recoveryKey">
<code ref={this._collectRecoveryKeyNode}>{this._recoveryKey.encodedPrivateKey}</code> <code ref={this._collectRecoveryKeyNode}>{this._recoveryKey.encodedPrivateKey}</code>
</div> </div>
<div className="mx_CreateSecretStorageDialog_recoveryKeyButtons"> <div className="mx_CreateSecretStorageDialog_recoveryKeyButtons">
<AccessibleButton kind='primary' className="mx_Dialog_primary"
onClick={this._onDownloadClick}
disabled={this.state.phase === PHASE_STORING}
>
{_t("Download")}
</AccessibleButton>
<span>{_t("or")}</span>
<AccessibleButton <AccessibleButton
kind='primary' kind='primary'
className="mx_Dialog_primary mx_CreateSecretStorageDialog_recoveryKeyButtons_copyBtn" className="mx_Dialog_primary mx_CreateSecretStorageDialog_recoveryKeyButtons_copyBtn"
onClick={this._onCopyClick} onClick={this._onCopyClick}
disabled={this.state.phase === PHASE_STORING}
> >
{_t("Copy")} {this.state.copied ? _t("Copied!") : _t("Copy")}
</AccessibleButton>
<AccessibleButton kind='primary' className="mx_Dialog_primary" onClick={this._onDownloadClick}>
{_t("Download")}
</AccessibleButton> </AccessibleButton>
</div> </div>
</div> </div>
</div> </div>
</div>; {continueButton}
}
_renderPhaseKeepItSafe() {
let introText;
if (this.state.copied) {
introText = _t(
"Your recovery key has been <b>copied to your clipboard</b>, paste it to:",
{}, {b: s => <b>{s}</b>},
);
} else if (this.state.downloaded) {
introText = _t(
"Your recovery key is in your <b>Downloads</b> folder.",
{}, {b: s => <b>{s}</b>},
);
}
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return <div>
{introText}
<ul>
<li>{_t("<b>Print it</b> and store it somewhere safe", {}, {b: s => <b>{s}</b>})}</li>
<li>{_t("<b>Save it</b> on a USB key or backup drive", {}, {b: s => <b>{s}</b>})}</li>
<li>{_t("<b>Copy it</b> to your personal cloud storage", {}, {b: s => <b>{s}</b>})}</li>
</ul>
<DialogButtons primaryButton={_t("Continue")}
onPrimaryButtonClick={this._bootstrapSecretStorage}
hasCancel={false}>
<button onClick={this._onKeepItSafeBackClick}>{_t("Back")}</button>
</DialogButtons>
</div>; </div>;
} }
@ -750,7 +723,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
} }
_renderPhaseLoadError() { _renderPhaseLoadError() {
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return <div> return <div>
<p>{_t("Unable to query secret storage status")}</p> <p>{_t("Unable to query secret storage status")}</p>
<div className="mx_Dialog_buttons"> <div className="mx_Dialog_buttons">
@ -764,7 +736,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
} }
_renderPhaseDone() { _renderPhaseDone() {
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return <div> return <div>
<p>{_t( <p>{_t(
"You can now verify your other devices, " + "You can now verify your other devices, " +
@ -778,7 +749,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
} }
_renderPhaseSkipConfirm() { _renderPhaseSkipConfirm() {
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return <div> return <div>
{_t( {_t(
"Without completing security on this session, it wont have " + "Without completing security on this session, it wont have " +
@ -806,8 +776,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
case PHASE_CONFIRM_SKIP: case PHASE_CONFIRM_SKIP:
return _t('Are you sure?'); return _t('Are you sure?');
case PHASE_SHOWKEY: case PHASE_SHOWKEY:
case PHASE_KEEPITSAFE: return _t('Save your Security Key');
return _t('Make a copy of your recovery key');
case PHASE_STORING: case PHASE_STORING:
return _t('Setting up keys'); return _t('Setting up keys');
case PHASE_DONE: case PHASE_DONE:
@ -822,7 +791,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
let content; let content;
if (this.state.error) { if (this.state.error) {
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
content = <div> content = <div>
<p>{_t("Unable to set up secret storage")}</p> <p>{_t("Unable to set up secret storage")}</p>
<div className="mx_Dialog_buttons"> <div className="mx_Dialog_buttons">
@ -856,9 +824,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
case PHASE_SHOWKEY: case PHASE_SHOWKEY:
content = this._renderPhaseShowKey(); content = this._renderPhaseShowKey();
break; break;
case PHASE_KEEPITSAFE:
content = this._renderPhaseKeepItSafe();
break;
case PHASE_STORING: case PHASE_STORING:
content = this._renderBusyPhase(); content = this._renderBusyPhase();
break; break;

View file

@ -2192,33 +2192,35 @@
"Go back to set it again.": "Go back to set it again.", "Go back to set it again.": "Go back to set it again.",
"Enter your recovery passphrase a second time to confirm it.": "Enter your recovery passphrase a second time to confirm it.", "Enter your recovery passphrase a second time to confirm it.": "Enter your recovery passphrase a second time to confirm it.",
"Confirm your recovery passphrase": "Confirm your recovery passphrase", "Confirm your recovery passphrase": "Confirm your recovery passphrase",
"Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your recovery passphrase.": "Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your recovery passphrase.", "Store your Security Key somewhere safe, like a password manager or a safe, as its used to safeguard your encrypted data.": "Store your Security Key somewhere safe, like a password manager or a safe, as its used to safeguard your encrypted data.",
"Keep a copy of it somewhere secure, like a password manager or even a safe.": "Keep a copy of it somewhere secure, like a password manager or even a safe.",
"Your recovery key": "Your recovery key",
"Copy": "Copy",
"Download": "Download", "Download": "Download",
"Your recovery key has been <b>copied to your clipboard</b>, paste it to:": "Your recovery key has been <b>copied to your clipboard</b>, paste it to:", "Copy": "Copy",
"Your recovery key is in your <b>Downloads</b> folder.": "Your recovery key is in your <b>Downloads</b> folder.",
"<b>Print it</b> and store it somewhere safe": "<b>Print it</b> and store it somewhere safe",
"<b>Save it</b> on a USB key or backup drive": "<b>Save it</b> on a USB key or backup drive",
"<b>Copy it</b> to your personal cloud storage": "<b>Copy it</b> to your personal cloud storage",
"Unable to query secret storage status": "Unable to query secret storage status", "Unable to query secret storage status": "Unable to query secret storage status",
"Retry": "Retry", "Retry": "Retry",
"You can now verify your other devices, and other users to keep your chats safe.": "You can now verify your other devices, and other users to keep your chats safe.", "You can now verify your other devices, and other users to keep your chats safe.": "You can now verify your other devices, and other users to keep your chats safe.",
"Set up Secure backup": "Set up Secure backup", "Set up Secure backup": "Set up Secure backup",
"Upgrade your encryption": "Upgrade your encryption", "Upgrade your encryption": "Upgrade your encryption",
"Confirm recovery passphrase": "Confirm recovery passphrase", "Confirm recovery passphrase": "Confirm recovery passphrase",
"Make a copy of your recovery key": "Make a copy of your recovery key", "Save your Security Key": "Save your Security Key",
"You're done!": "You're done!", "You're done!": "You're done!",
"Unable to set up secret storage": "Unable to set up secret storage", "Unable to set up secret storage": "Unable to set up secret storage",
"We'll store an encrypted copy of your keys on our server. Secure your backup with a recovery passphrase.": "We'll store an encrypted copy of your keys on our server. Secure your backup with a recovery passphrase.", "We'll store an encrypted copy of your keys on our server. Secure your backup with a recovery passphrase.": "We'll store an encrypted copy of your keys on our server. Secure your backup with a recovery passphrase.",
"For maximum security, this should be different from your account password.": "For maximum security, this should be different from your account password.", "For maximum security, this should be different from your account password.": "For maximum security, this should be different from your account password.",
"Please enter your recovery passphrase a second time to confirm.": "Please enter your recovery passphrase a second time to confirm.", "Please enter your recovery passphrase a second time to confirm.": "Please enter your recovery passphrase a second time to confirm.",
"Repeat your recovery passphrase...": "Repeat your recovery passphrase...", "Repeat your recovery passphrase...": "Repeat your recovery passphrase...",
"Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your recovery passphrase.": "Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your recovery passphrase.",
"Keep a copy of it somewhere secure, like a password manager or even a safe.": "Keep a copy of it somewhere secure, like a password manager or even a safe.",
"Your recovery key": "Your recovery key",
"Your recovery key has been <b>copied to your clipboard</b>, paste it to:": "Your recovery key has been <b>copied to your clipboard</b>, paste it to:",
"Your recovery key is in your <b>Downloads</b> folder.": "Your recovery key is in your <b>Downloads</b> folder.",
"<b>Print it</b> and store it somewhere safe": "<b>Print it</b> and store it somewhere safe",
"<b>Save it</b> on a USB key or backup drive": "<b>Save it</b> on a USB key or backup drive",
"<b>Copy it</b> to your personal cloud storage": "<b>Copy it</b> to your personal cloud storage",
"Your keys are being backed up (the first backup could take a few minutes).": "Your keys are being backed up (the first backup could take a few minutes).", "Your keys are being backed up (the first backup could take a few minutes).": "Your keys are being backed up (the first backup could take a few minutes).",
"Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.": "Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.", "Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.": "Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.",
"Set up Secure Message Recovery": "Set up Secure Message Recovery", "Set up Secure Message Recovery": "Set up Secure Message Recovery",
"Secure your backup with a recovery passphrase": "Secure your backup with a recovery passphrase", "Secure your backup with a recovery passphrase": "Secure your backup with a recovery passphrase",
"Make a copy of your recovery key": "Make a copy of your recovery key",
"Starting backup...": "Starting backup...", "Starting backup...": "Starting backup...",
"Success!": "Success!", "Success!": "Success!",
"Create key backup": "Create key backup", "Create key backup": "Create key backup",