Merge pull request #4041 from matrix-org/foldleft/12221-reset-cross-signing
Button to reset cross-signing and SSSS keyspull/21833/head
						commit
						d47d13256f
					
				|  | @ -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) { | ||||
|  |  | |||
|  | @ -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, | ||||
|  |  | |||
|  | @ -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 ( | ||||
|             <BaseDialog | ||||
|                     className='mx_ConfirmDestroyCrossSigningDialog' | ||||
|                     hasCancel={true} | ||||
|                     onFinished={this.props.onFinished} | ||||
|                     title={_t("Destroy cross-signing keys?")}> | ||||
|                 <div className='mx_ConfirmDestroyCrossSigningDialog_content'> | ||||
|                     <p> | ||||
|                         {_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.", | ||||
|                         )} | ||||
|                     </p> | ||||
|                 </div> | ||||
|                 <DialogButtons | ||||
|                     primaryButton={_t("Clear cross-signing keys")} | ||||
|                     onPrimaryButtonClick={this._onConfirm} | ||||
|                     primaryButtonClass="danger" | ||||
|                     cancelButton={_t("Cancel")} | ||||
|                     onCancel={this._onDecline} | ||||
|                 /> | ||||
|             </BaseDialog> | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  | @ -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) { | ||||
|  | @ -86,11 +87,12 @@ 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 () => { | ||||
|     _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 +101,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 +157,12 @@ export default class CrossSigningPanel extends React.PureComponent { | |||
|                     {_t("Bootstrap cross-signing and secret storage")} | ||||
|                 </AccessibleButton> | ||||
|             </div>; | ||||
|         } else { | ||||
|             bootstrapButton = <div className="mx_CrossSigningPanel_buttonRow"> | ||||
|                 <AccessibleButton kind="danger" onClick={this._destroySecureSecretStorage}> | ||||
|                     {_t("Reset cross-signing and secret storage")} | ||||
|                 </AccessibleButton> | ||||
|             </div>; | ||||
|         } | ||||
| 
 | ||||
|         return ( | ||||
|  |  | |||
|  | @ -558,6 +558,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 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", | ||||
|  | @ -1435,6 +1436,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?", | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Zoe
						Zoe