diff --git a/src/CrossSigningManager.js b/src/CrossSigningManager.js
index 694b2b0a25..f19be03574 100644
--- a/src/CrossSigningManager.js
+++ b/src/CrossSigningManager.js
@@ -148,18 +148,21 @@ 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 () => { }) {
+export async function accessSecretStorage(func = async () => { }, force = false) {
const cli = MatrixClientPeg.get();
secretStorageBeingAccessed = true;
-
try {
- if (!await cli.hasSecretStorageKey()) {
+ if (!await cli.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 f68ee32a15..db2f4c35cc 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..9e1980e98d
--- /dev/null
+++ b/src/components/views/dialogs/ConfirmDestroyCrossSigningDialog.js
@@ -0,0 +1,65 @@
+/*
+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.",
+ )}
+