From d87d00e4ae277beba9104770bd7c8166f086c8cb Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 11 Jan 2019 13:15:09 +0000 Subject: [PATCH] Different dialog for new trusted backup Split the 'new recovery method' into two cases: one where the new recovery method isn't trusted and you need to verify the device, and another where it is and the client is using it (where it's more of an FYI). https://github.com/vector-im/riot-web/issues/8069 --- .../keybackup/NewRecoveryMethodDialog.js | 80 +++++++++++++------ src/components/structures/MatrixChat.js | 40 ++++++---- src/i18n/strings/en_EN.json | 5 +- 3 files changed, 83 insertions(+), 42 deletions(-) diff --git a/src/async-components/views/dialogs/keybackup/NewRecoveryMethodDialog.js b/src/async-components/views/dialogs/keybackup/NewRecoveryMethodDialog.js index ad29ba64b2..bd191a7c13 100644 --- a/src/async-components/views/dialogs/keybackup/NewRecoveryMethodDialog.js +++ b/src/async-components/views/dialogs/keybackup/NewRecoveryMethodDialog.js @@ -1,5 +1,5 @@ /* -Copyright 2018 New Vector Ltd +Copyright 2018-2019 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -24,9 +24,15 @@ import Modal from "../../../../Modal"; export default class NewRecoveryMethodDialog extends React.PureComponent { static propTypes = { + // As returned by js-sdk getKeyBackupVersion() + newVersionInfo: PropTypes.object.isRequired, onFinished: PropTypes.func.isRequired, } + onOkClick = () => { + this.props.onFinished(); + } + onGoToSettingsClick = () => { this.props.onFinished(); dis.dispatch({ action: 'view_user_settings' }); @@ -41,8 +47,7 @@ export default class NewRecoveryMethodDialog extends React.PureComponent { // sending our own new keys to it. let backupSigStatus; try { - const backupInfo = await MatrixClientPeg.get().getKeyBackupVersion(); - backupSigStatus = await MatrixClientPeg.get().isKeyBackupTrusted(backupInfo); + backupSigStatus = await MatrixClientPeg.get().isKeyBackupTrusted(this.props.newVersionInfo); } catch (e) { console.log("Unable to fetch key backup status", e); return; @@ -76,34 +81,57 @@ export default class NewRecoveryMethodDialog extends React.PureComponent { {_t("New Recovery Method")} ; + const newMethodDetected =

{_t( + "A new recovery passphrase and key for Secure " + + "Messages have been detected.", + )}

; + + const hackWarning =

{_t( + "If you didn't set the new recovery method, an " + + "attacker may be trying to access your account. " + + "Change your account password and set a new recovery " + + "method immediately in Settings.", + )}

; + + let content; + if (MatrixClientPeg.get().getKeyBackupEnabled()) { + content =
+ {newMethodDetected} +

{_t( + "This device is encrypting history using the new recovery method." + )}

+ {hackWarning} + +
; + } else { + content =
+ {newMethodDetected} +

{_t( + "Setting up Secure Messages on this device " + + "will re-encrypt this device's message history with " + + "the new recovery method.", + )}

+ {hackWarning} + +
; + } + return ( -
-

{_t( - "A new recovery passphrase and key for Secure " + - "Messages have been detected.", - )}

-

{_t( - "Setting up Secure Messages on this device " + - "will re-encrypt this device's message history with " + - "the new recovery method.", - )}

-

{_t( - "If you didn't set the new recovery method, an " + - "attacker may be trying to access your account. " + - "Change your account password and set a new recovery " + - "method immediately in Settings.", - )}

- -
+ {content}
); } diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index 8480525886..a1913f13be 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -1,7 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd -Copyright 2017, 2018 New Vector Ltd +Copyright 2017-2019 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -1447,20 +1447,32 @@ export default React.createClass({ break; } }); - cli.on("crypto.keyBackupFailed", (errcode) => { - switch (errcode) { - case 'M_NOT_FOUND': - Modal.createTrackedDialogAsync('Recovery Method Removed', 'Recovery Method Removed', - import('../../async-components/views/dialogs/keybackup/RecoveryMethodRemovedDialog'), - ); + cli.on("crypto.keyBackupFailed", async (errcode) => { + let haveNewVersion; + let newVersionInfo; + // if key backup is still enabled, there must be a new backup in place + if (MatrixClientPeg.get().getKeyBackupEnabled()) { + haveNewVersion = true; + } else { + // otherwise check the server to see if there's a new one + try { + newVersionInfo = await MatrixClientPeg.get().getKeyBackupVersion(); + if (newVersionInfo !== null) haveNewVersion = true; + } catch (e) { + console.error("Saw key backup error but failed to check backup version!", e); return; - case 'M_WRONG_ROOM_KEYS_VERSION': - Modal.createTrackedDialogAsync('New Recovery Method', 'New Recovery Method', - import('../../async-components/views/dialogs/keybackup/NewRecoveryMethodDialog'), - ); - return; - default: - console.error(`Invalid key backup failure code: ${errcode}`); + } + } + + if (haveNewVersion) { + Modal.createTrackedDialogAsync('New Recovery Method', 'New Recovery Method', + import('../../async-components/views/dialogs/keybackup/NewRecoveryMethodDialog'), + { newVersionInfo } + ); + } else { + Modal.createTrackedDialogAsync('Recovery Method Removed', 'Recovery Method Removed', + import('../../async-components/views/dialogs/keybackup/RecoveryMethodRemovedDialog'), + ); } }); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 9e5b98afdd..0fbed11e20 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1410,10 +1410,11 @@ "If you don't want to set this up now, you can later in Settings.": "If you don't want to set this up now, you can later in Settings.", "New Recovery Method": "New Recovery Method", "A new recovery passphrase and key for Secure Messages have been detected.": "A new recovery passphrase and key for Secure Messages have been detected.", - "Setting up Secure Messages on this device will re-encrypt this device's message history with the new recovery method.": "Setting up Secure Messages on this device will re-encrypt this device's message history with the new recovery method.", "If you didn't set the new recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "If you didn't set the new recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.", - "Set up Secure Messages": "Set up Secure Messages", + "This device is encrypting history using the new recovery method.": "This device is encrypting history using the new recovery method.", "Go to Settings": "Go to Settings", + "Setting up Secure Messages on this device will re-encrypt this device's message history with the new recovery method.": "Setting up Secure Messages on this device will re-encrypt this device's message history with the new recovery method.", + "Set up Secure Messages": "Set up Secure Messages", "Recovery Method Removed": "Recovery Method Removed", "This device has detected that your recovery passphrase and key for Secure Messages have been removed.": "This device has detected that your recovery passphrase and key for Secure Messages have been removed.", "If you did this accidentally, you can setup Secure Messages on this device which will re-encrypt this device's message history with a new recovery method.": "If you did this accidentally, you can setup Secure Messages on this device which will re-encrypt this device's message history with a new recovery method.",