From 8fdae73e030546decf346d0f23a9c956faa456e2 Mon Sep 17 00:00:00 2001
From: Zoe
Date: Fri, 7 Feb 2020 14:55:01 +0000
Subject: [PATCH 1/6] Button to reset cross-signing and SSSS keys
---
src/CrossSigningManager.js | 11 ++--
.../CreateSecretStorageDialog.js | 10 ++-
.../ConfirmDestroyCrossSigningDialog.js | 63 +++++++++++++++++++
.../views/settings/CrossSigningPanel.js | 24 ++++++-
src/i18n/strings/en_EN.json | 4 ++
5 files changed, 104 insertions(+), 8 deletions(-)
create mode 100644 src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js
diff --git a/src/CrossSigningManager.js b/src/CrossSigningManager.js
index a560c956f1..08ec459f26 100644
--- a/src/CrossSigningManager.js
+++ b/src/CrossSigningManager.js
@@ -116,17 +116,20 @@ export const crossSigningCallbacks = {
* @param {Function} [func] An operation to perform once secret storage has been
* bootstrapped. Optional.
*/
-export async function accessSecretStorage(func = async () => { }) {
+export async function accessSecretStorage(func = async () => { }, force = false) {
const cli = MatrixClientPeg.get();
secretStorageBeingAccessed = true;
-
try {
- if (!await cli.hasSecretStorageKey()) {
+ if (!await cli.hasSecretStorageKey() || force) {
+ console.warn(!force ? "!hasSecretStorageKey()" : "force");
// This dialog calls bootstrap itself after guiding the user through
// passphrase creation.
const { finished } = Modal.createTrackedDialogAsync('Create Secret Storage dialog', '',
import("./async-components/views/dialogs/secretstorage/CreateSecretStorageDialog"),
- null, null, /* priority = */ false, /* static = */ true,
+ {
+ force,
+ },
+ null, /* priority = */ false, /* static = */ true,
);
const [confirmed] = await finished;
if (!confirmed) {
diff --git a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js
index 679b3907d1..c3574c0094 100644
--- a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js
+++ b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js
@@ -55,10 +55,12 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
static propTypes = {
hasCancel: PropTypes.bool,
accountPassword: PropTypes.string,
+ force: PropTypes.bool,
};
static defaultProps = {
hasCancel: true,
+ force: false,
};
constructor(props) {
@@ -107,7 +109,8 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
MatrixClientPeg.get().isCryptoEnabled() && await MatrixClientPeg.get().isKeyBackupTrusted(backupInfo)
);
- const phase = backupInfo ? PHASE_MIGRATE : PHASE_PASSPHRASE;
+ const { force } = this.props;
+ const phase = (backupInfo && !force) ? PHASE_MIGRATE : PHASE_PASSPHRASE;
this.setState({
phase,
@@ -219,12 +222,15 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
const cli = MatrixClientPeg.get();
+ const { force } = this.props;
+
try {
await cli.bootstrapSecretStorage({
+ setupNewSecretStorage: force,
authUploadDeviceSigningKeys: this._doBootstrapUIAuth,
createSecretStorageKey: async () => this._keyInfo,
keyBackupInfo: this.state.backupInfo,
- setupNewKeyBackup: !this.state.backupInfo && this.state.useKeyBackup,
+ setupNewKeyBackup: force || !this.state.backupInfo && this.state.useKeyBackup,
});
this.setState({
phase: PHASE_DONE,
diff --git a/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js b/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js
new file mode 100644
index 0000000000..942249e07d
--- /dev/null
+++ b/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js
@@ -0,0 +1,63 @@
+/*
+Copyright 2020 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import React from 'react';
+import PropTypes from 'prop-types';
+import {_t} from "../../../languageHandler";
+import * as sdk from "../../../index";
+
+export default class ConfirmDestroyCrossSigningDialog extends React.Component {
+ static propTypes = {
+ onFinished: PropTypes.func.isRequired,
+ };
+
+ _onConfirm = () => {
+ this.props.onFinished(true);
+ };
+
+ _onDecline = () => {
+ this.props.onFinished(false);
+ };
+
+ render() {
+ const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
+ const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
+
+ return (
+
+
+
+ {_t(
+ "Deleting cross-signing keys is permanent. " +
+ "Anyone you have verified with will see security alerts. " +
+ "You almost certainly don't want to do this, unless " +
+ "you've lost every device you can cross-sign from."
+ )}
+
+
+
+
+ );
+ }
+}
diff --git a/src/components/views/settings/CrossSigningPanel.js b/src/components/views/settings/CrossSigningPanel.js
index f99968c44f..35f617b83b 100644
--- a/src/components/views/settings/CrossSigningPanel.js
+++ b/src/components/views/settings/CrossSigningPanel.js
@@ -20,6 +20,7 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg';
import { _t } from '../../../languageHandler';
import * as sdk from '../../../index';
import { accessSecretStorage } from '../../../CrossSigningManager';
+import Modal from '../../../Modal';
export default class CrossSigningPanel extends React.PureComponent {
constructor(props) {
@@ -87,10 +88,10 @@ export default class CrossSigningPanel extends React.PureComponent {
* cross-signing keys as needed.
* 3. All keys are loaded and there's nothing to do.
*/
- _bootstrapSecureSecretStorage = async () => {
+ _bootstrapSecureSecretStorage = async (force=false) => {
this.setState({ error: null });
try {
- await accessSecretStorage();
+ await accessSecretStorage(() => undefined, force);
} catch (e) {
this.setState({ error: e });
console.error("Error bootstrapping secret storage", e);
@@ -99,6 +100,19 @@ export default class CrossSigningPanel extends React.PureComponent {
this._getUpdatedStatus();
}
+ onDestroyStorage = (act) => {
+ if (!act) return;
+ console.log("Destroy secret storage:", act);
+ this._bootstrapSecureSecretStorage(true);
+ }
+
+ _destroySecureSecretStorage = () => {
+ const ConfirmDestoryCrossSigningDialog = sdk.getComponent("dialogs.ConfirmDestroyCrossSigningDialog");
+ Modal.createDialog(ConfirmDestoryCrossSigningDialog, {
+ onFinished: this.onDestroyStorage
+ });
+ }
+
render() {
const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
const {
@@ -142,6 +156,12 @@ export default class CrossSigningPanel extends React.PureComponent {
{_t("Bootstrap cross-signing and secret storage")}
;
+ } else {
+ bootstrapButton =
+
+ {_t("Torpedo cross-signing")}
+
+
;
}
return (
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index d125d10cfb..edb0da8780 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -553,6 +553,7 @@
"Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.",
"Cross-signing and secret storage are not yet set up.": "Cross-signing and secret storage are not yet set up.",
"Bootstrap cross-signing and secret storage": "Bootstrap cross-signing and secret storage",
+ "Torpedo cross-signing": "Torpedo cross-signing",
"Cross-signing public keys:": "Cross-signing public keys:",
"in memory": "in memory",
"not found": "not found",
@@ -1430,6 +1431,9 @@
"Changelog": "Changelog",
"You cannot delete this message. (%(code)s)": "You cannot delete this message. (%(code)s)",
"Removing…": "Removing…",
+ "Destroy cross-signing keys?": "Destroy cross-signing keys?",
+ "Deleting cross-signing keys is permanent. Anyone you have verified with will see security alerts. You almost certainly don't want to do this, unless you've lost every device you can cross-sign from.": "Deleting cross-signing keys is permanent. Anyone you have verified with will see security alerts. You almost certainly don't want to do this, unless you've lost every device you can cross-sign from.",
+ "Clear cross-signing keys": "Clear cross-signing keys",
"Confirm Removal": "Confirm Removal",
"Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.",
"Clear all data in this session?": "Clear all data in this session?",
From b08c5d84107b0e60b89f932c830b4767d0bc60d7 Mon Sep 17 00:00:00 2001
From: Zoe
Date: Fri, 7 Feb 2020 15:46:31 +0000
Subject: [PATCH 2/6] lint
---
src/CrossSigningManager.js | 1 +
.../views/dialogs/ConfirmDestroyCrossSigningDialog.js | 2 +-
src/components/views/settings/CrossSigningPanel.js | 3 ++-
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/CrossSigningManager.js b/src/CrossSigningManager.js
index 08ec459f26..3381f3e93b 100644
--- a/src/CrossSigningManager.js
+++ b/src/CrossSigningManager.js
@@ -115,6 +115,7 @@ export const crossSigningCallbacks = {
*
* @param {Function} [func] An operation to perform once secret storage has been
* bootstrapped. Optional.
+ * @param {bool} [force] Reset secret storage even if it's already set up
*/
export async function accessSecretStorage(func = async () => { }, force = false) {
const cli = MatrixClientPeg.get();
diff --git a/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js b/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js
index 942249e07d..3242afd5f1 100644
--- a/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js
+++ b/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js
@@ -46,7 +46,7 @@ export default class ConfirmDestroyCrossSigningDialog extends React.Component {
"Deleting cross-signing keys is permanent. " +
"Anyone you have verified with will see security alerts. " +
"You almost certainly don't want to do this, unless " +
- "you've lost every device you can cross-sign from."
+ "you've lost every device you can cross-sign from.",
)}
diff --git a/src/components/views/settings/CrossSigningPanel.js b/src/components/views/settings/CrossSigningPanel.js
index 35f617b83b..77cae79324 100644
--- a/src/components/views/settings/CrossSigningPanel.js
+++ b/src/components/views/settings/CrossSigningPanel.js
@@ -87,6 +87,7 @@ export default class CrossSigningPanel extends React.PureComponent {
* 2. Access existing secret storage by requesting passphrase and accessing
* cross-signing keys as needed.
* 3. All keys are loaded and there's nothing to do.
+ * @param {bool} [force] Bootstrap again even if keys already present
*/
_bootstrapSecureSecretStorage = async (force=false) => {
this.setState({ error: null });
@@ -109,7 +110,7 @@ export default class CrossSigningPanel extends React.PureComponent {
_destroySecureSecretStorage = () => {
const ConfirmDestoryCrossSigningDialog = sdk.getComponent("dialogs.ConfirmDestroyCrossSigningDialog");
Modal.createDialog(ConfirmDestoryCrossSigningDialog, {
- onFinished: this.onDestroyStorage
+ onFinished: this.onDestroyStorage,
});
}
From a260d7a1471d15b8af31dea56f220d457e5dfd1d Mon Sep 17 00:00:00 2001
From: Zoe
Date: Fri, 7 Feb 2020 15:53:43 +0000
Subject: [PATCH 3/6] manual lint
---
src/CrossSigningManager.js | 1 -
.../views/dialogs/ConfirmDestroyCrossSigningDialog.js | 8 +++++---
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/CrossSigningManager.js b/src/CrossSigningManager.js
index 3381f3e93b..45e0a336d5 100644
--- a/src/CrossSigningManager.js
+++ b/src/CrossSigningManager.js
@@ -122,7 +122,6 @@ export async function accessSecretStorage(func = async () => { }, force = false)
secretStorageBeingAccessed = true;
try {
if (!await cli.hasSecretStorageKey() || force) {
- console.warn(!force ? "!hasSecretStorageKey()" : "force");
// This dialog calls bootstrap itself after guiding the user through
// passphrase creation.
const { finished } = Modal.createTrackedDialogAsync('Create Secret Storage dialog', '',
diff --git a/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js b/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js
index 3242afd5f1..9e1980e98d 100644
--- a/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js
+++ b/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js
@@ -37,9 +37,11 @@ export default class ConfirmDestroyCrossSigningDialog extends React.Component {
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return (
-
+
{_t(
From 69dc725006960053be0fa69cd16f303074c7035d Mon Sep 17 00:00:00 2001
From: Zoe
Date: Mon, 10 Feb 2020 15:43:02 +0000
Subject: [PATCH 4/6] rename button
---
src/components/views/settings/CrossSigningPanel.js | 2 +-
src/i18n/strings/en_EN.json | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/components/views/settings/CrossSigningPanel.js b/src/components/views/settings/CrossSigningPanel.js
index 77cae79324..6f68193729 100644
--- a/src/components/views/settings/CrossSigningPanel.js
+++ b/src/components/views/settings/CrossSigningPanel.js
@@ -160,7 +160,7 @@ export default class CrossSigningPanel extends React.PureComponent {
} else {
bootstrapButton =
- {_t("Torpedo cross-signing")}
+ {_t("Reset Secret Store and Cross-signing")}
;
}
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index edb0da8780..1832a6123b 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -553,7 +553,7 @@
"Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.",
"Cross-signing and secret storage are not yet set up.": "Cross-signing and secret storage are not yet set up.",
"Bootstrap cross-signing and secret storage": "Bootstrap cross-signing and secret storage",
- "Torpedo cross-signing": "Torpedo cross-signing",
+ "Reset Secret Store and Cross-signing": "Reset Secret Store and Cross-signing",
"Cross-signing public keys:": "Cross-signing public keys:",
"in memory": "in memory",
"not found": "not found",
From 4f4b52d6665ad318c2dae57e1f217587a30ca65a Mon Sep 17 00:00:00 2001
From: Zoe
Date: Mon, 10 Feb 2020 16:59:17 +0000
Subject: [PATCH 5/6] Update src/components/views/settings/CrossSigningPanel.js
Co-Authored-By: J. Ryan Stinnett
---
src/components/views/settings/CrossSigningPanel.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/views/settings/CrossSigningPanel.js b/src/components/views/settings/CrossSigningPanel.js
index 6f68193729..95b9f76858 100644
--- a/src/components/views/settings/CrossSigningPanel.js
+++ b/src/components/views/settings/CrossSigningPanel.js
@@ -160,7 +160,7 @@ export default class CrossSigningPanel extends React.PureComponent {
} else {
bootstrapButton =
- {_t("Reset Secret Store and Cross-signing")}
+ {_t("Reset cross-signing and secret storage")}
;
}
From 2d425051245763b605f63b6250bc31af80757bd2 Mon Sep 17 00:00:00 2001
From: Zoe
Date: Mon, 10 Feb 2020 17:00:03 +0000
Subject: [PATCH 6/6] and re-run yarn i18n
---
src/i18n/strings/en_EN.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 1832a6123b..d9bd4c3b14 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -553,7 +553,7 @@
"Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.",
"Cross-signing and secret storage are not yet set up.": "Cross-signing and secret storage are not yet set up.",
"Bootstrap cross-signing and secret storage": "Bootstrap cross-signing and secret storage",
- "Reset Secret Store and Cross-signing": "Reset Secret Store and Cross-signing",
+ "Reset cross-signing and secret storage": "Reset cross-signing and secret storage",
"Cross-signing public keys:": "Cross-signing public keys:",
"in memory": "in memory",
"not found": "not found",