Update the 'save your security key' screen
This commit is contained in:
parent
6ce8584337
commit
0694776b25
3 changed files with 66 additions and 90 deletions
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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 it’s 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 won’t have " +
|
"Without completing security on this session, it won’t 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;
|
||||||
|
|
|
@ -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 it’s used to safeguard your encrypted data.": "Store your Security Key somewhere safe, like a password manager or a safe, as it’s 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",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue