Move security-related dialogs to a common directory

This commit is contained in:
J. Ryan Stinnett 2020-09-10 13:56:07 +01:00
parent f4f94e31d1
commit 7bd5e3fa31
28 changed files with 42 additions and 43 deletions

View file

@ -91,11 +91,11 @@
@import "./views/dialogs/_UploadConfirmDialog.scss"; @import "./views/dialogs/_UploadConfirmDialog.scss";
@import "./views/dialogs/_UserSettingsDialog.scss"; @import "./views/dialogs/_UserSettingsDialog.scss";
@import "./views/dialogs/_WidgetOpenIDPermissionsDialog.scss"; @import "./views/dialogs/_WidgetOpenIDPermissionsDialog.scss";
@import "./views/dialogs/keybackup/_CreateKeyBackupDialog.scss"; @import "./views/dialogs/security/_AccessSecretStorageDialog.scss";
@import "./views/dialogs/keybackup/_KeyBackupFailedDialog.scss"; @import "./views/dialogs/security/_CreateKeyBackupDialog.scss";
@import "./views/dialogs/keybackup/_RestoreKeyBackupDialog.scss"; @import "./views/dialogs/security/_CreateSecretStorageDialog.scss";
@import "./views/dialogs/secretstorage/_AccessSecretStorageDialog.scss"; @import "./views/dialogs/security/_KeyBackupFailedDialog.scss";
@import "./views/dialogs/secretstorage/_CreateSecretStorageDialog.scss"; @import "./views/dialogs/security/_RestoreKeyBackupDialog.scss";
@import "./views/directory/_NetworkDropdown.scss"; @import "./views/directory/_NetworkDropdown.scss";
@import "./views/elements/_AccessibleButton.scss"; @import "./views/elements/_AccessibleButton.scss";
@import "./views/elements/_AddressSelector.scss"; @import "./views/elements/_AddressSelector.scss";

View file

@ -22,6 +22,8 @@ import { decodeRecoveryKey } from 'matrix-js-sdk/src/crypto/recoverykey';
import { _t } from './languageHandler'; import { _t } from './languageHandler';
import {encodeBase64} from "matrix-js-sdk/src/crypto/olmlib"; import {encodeBase64} from "matrix-js-sdk/src/crypto/olmlib";
import { isSecureBackupRequired } from './utils/WellKnownUtils'; import { isSecureBackupRequired } from './utils/WellKnownUtils';
import AccessSecretStorageDialog from './components/views/dialogs/security/AccessSecretStorageDialog';
import RestoreKeyBackupDialog from './components/views/dialogs/security/RestoreKeyBackupDialog';
// This stores the secret storage private keys in memory for the JS SDK. This is // This stores the secret storage private keys in memory for the JS SDK. This is
// only meant to act as a cache to avoid prompting the user multiple times // only meant to act as a cache to avoid prompting the user multiple times
@ -87,8 +89,6 @@ async function getSecretStorageKey({ keys: keyInfos }, ssssItemName) {
return decodeRecoveryKey(recoveryKey); return decodeRecoveryKey(recoveryKey);
} }
}; };
const AccessSecretStorageDialog =
sdk.getComponent("dialogs.secretstorage.AccessSecretStorageDialog");
const { finished } = Modal.createTrackedDialog("Access Secret Storage dialog", "", const { finished } = Modal.createTrackedDialog("Access Secret Storage dialog", "",
AccessSecretStorageDialog, AccessSecretStorageDialog,
/* props= */ /* props= */
@ -181,7 +181,6 @@ export const crossSigningCallbacks = {
export async function promptForBackupPassphrase() { export async function promptForBackupPassphrase() {
let key; let key;
const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog');
const { finished } = Modal.createTrackedDialog('Restore Backup', '', RestoreKeyBackupDialog, { const { finished } = Modal.createTrackedDialog('Restore Backup', '', RestoreKeyBackupDialog, {
showSummary: false, keyCallback: k => key = k, showSummary: false, keyCallback: k => key = k,
}, null, /* priority = */ false, /* static = */ true); }, null, /* priority = */ false, /* static = */ true);
@ -221,7 +220,7 @@ export async function accessSecretStorage(func = async () => { }, forceReset = f
// This dialog calls bootstrap itself after guiding the user through // This dialog calls bootstrap itself after guiding the user through
// passphrase creation. // passphrase creation.
const { finished } = Modal.createTrackedDialogAsync('Create Secret Storage dialog', '', const { finished } = Modal.createTrackedDialogAsync('Create Secret Storage dialog', '',
import("./async-components/views/dialogs/secretstorage/CreateSecretStorageDialog"), import("./async-components/views/dialogs/security/CreateSecretStorageDialog"),
{ {
forceReset, forceReset,
}, },

View file

@ -30,6 +30,7 @@ import StyledRadioButton from '../../../../components/views/elements/StyledRadio
import AccessibleButton from "../../../../components/views/elements/AccessibleButton"; import AccessibleButton from "../../../../components/views/elements/AccessibleButton";
import DialogButtons from "../../../../components/views/elements/DialogButtons"; import DialogButtons from "../../../../components/views/elements/DialogButtons";
import InlineSpinner from "../../../../components/views/elements/InlineSpinner"; import InlineSpinner from "../../../../components/views/elements/InlineSpinner";
import RestoreKeyBackupDialog from "../../../../components/views/dialogs/security/RestoreKeyBackupDialog";
import { isSecureBackupRequired } from '../../../../utils/WellKnownUtils'; import { isSecureBackupRequired } from '../../../../utils/WellKnownUtils';
const PHASE_LOADING = 0; const PHASE_LOADING = 0;
@ -341,7 +342,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
// so let's stash it here, rather than prompting for it twice. // so let's stash it here, rather than prompting for it twice.
const keyCallback = k => this._backupKey = k; const keyCallback = k => this._backupKey = k;
const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog');
const { finished } = Modal.createTrackedDialog( const { finished } = Modal.createTrackedDialog(
'Restore Backup', '', RestoreKeyBackupDialog, 'Restore Backup', '', RestoreKeyBackupDialog,
{ {

View file

@ -17,11 +17,11 @@ limitations under the License.
import FileSaver from 'file-saver'; import FileSaver from 'file-saver';
import React, {createRef} from 'react'; import React, {createRef} from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { _t } from '../../../languageHandler'; import { _t } from '../../../../languageHandler';
import { MatrixClient } from 'matrix-js-sdk'; import { MatrixClient } from 'matrix-js-sdk';
import * as MegolmExportEncryption from '../../../utils/MegolmExportEncryption'; import * as MegolmExportEncryption from '../../../../utils/MegolmExportEncryption';
import * as sdk from '../../../index'; import * as sdk from '../../../../index';
const PHASE_EDIT = 1; const PHASE_EDIT = 1;
const PHASE_EXPORTING = 2; const PHASE_EXPORTING = 2;

View file

@ -18,9 +18,9 @@ import React, {createRef} from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { MatrixClient } from 'matrix-js-sdk'; import { MatrixClient } from 'matrix-js-sdk';
import * as MegolmExportEncryption from '../../../utils/MegolmExportEncryption'; import * as MegolmExportEncryption from '../../../../utils/MegolmExportEncryption';
import * as sdk from '../../../index'; import * as sdk from '../../../../index';
import { _t } from '../../../languageHandler'; import { _t } from '../../../../languageHandler';
function readFileAsArrayBuffer(file) { function readFileAsArrayBuffer(file) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {

View file

@ -22,6 +22,7 @@ import {MatrixClientPeg} from '../../../../MatrixClientPeg';
import dis from "../../../../dispatcher/dispatcher"; import dis from "../../../../dispatcher/dispatcher";
import { _t } from "../../../../languageHandler"; import { _t } from "../../../../languageHandler";
import Modal from "../../../../Modal"; import Modal from "../../../../Modal";
import RestoreKeyBackupDialog from "../../../../components/views/dialogs/security/RestoreKeyBackupDialog";
import {Action} from "../../../../dispatcher/actions"; import {Action} from "../../../../dispatcher/actions";
export default class NewRecoveryMethodDialog extends React.PureComponent { export default class NewRecoveryMethodDialog extends React.PureComponent {
@ -41,7 +42,6 @@ export default class NewRecoveryMethodDialog extends React.PureComponent {
} }
onSetupClick = async () => { onSetupClick = async () => {
const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog');
Modal.createTrackedDialog( Modal.createTrackedDialog(
'Restore Backup', '', RestoreKeyBackupDialog, { 'Restore Backup', '', RestoreKeyBackupDialog, {
onFinished: this.props.onFinished, onFinished: this.props.onFinished,

View file

@ -1496,12 +1496,12 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
if (haveNewVersion) { if (haveNewVersion) {
Modal.createTrackedDialogAsync('New Recovery Method', 'New Recovery Method', Modal.createTrackedDialogAsync('New Recovery Method', 'New Recovery Method',
import('../../async-components/views/dialogs/keybackup/NewRecoveryMethodDialog'), import('../../async-components/views/dialogs/security/NewRecoveryMethodDialog'),
{ newVersionInfo }, { newVersionInfo },
); );
} else { } else {
Modal.createTrackedDialogAsync('Recovery Method Removed', 'Recovery Method Removed', Modal.createTrackedDialogAsync('Recovery Method Removed', 'Recovery Method Removed',
import('../../async-components/views/dialogs/keybackup/RecoveryMethodRemovedDialog'), import('../../async-components/views/dialogs/security/RecoveryMethodRemovedDialog'),
); );
} }
}); });

View file

@ -29,7 +29,7 @@ export default class E2eSetup extends React.Component {
super(); super();
// awkwardly indented because https://github.com/eslint/eslint/issues/11310 // awkwardly indented because https://github.com/eslint/eslint/issues/11310
this._createStorageDialogPromise = this._createStorageDialogPromise =
import("../../../async-components/views/dialogs/secretstorage/CreateSecretStorageDialog"); import("../../../async-components/views/dialogs/security/CreateSecretStorageDialog");
} }
render() { render() {

View file

@ -20,7 +20,8 @@ import Modal from '../../../Modal';
import * as sdk from '../../../index'; import * as sdk from '../../../index';
import dis from '../../../dispatcher/dispatcher'; import dis from '../../../dispatcher/dispatcher';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import {MatrixClientPeg} from '../../../MatrixClientPeg'; import { MatrixClientPeg } from '../../../MatrixClientPeg';
import RestoreKeyBackupDialog from './security/RestoreKeyBackupDialog';
export default class LogoutDialog extends React.Component { export default class LogoutDialog extends React.Component {
defaultProps = { defaultProps = {
@ -73,7 +74,7 @@ export default class LogoutDialog extends React.Component {
_onExportE2eKeysClicked() { _onExportE2eKeysClicked() {
Modal.createTrackedDialogAsync('Export E2E Keys', '', Modal.createTrackedDialogAsync('Export E2E Keys', '',
import('../../../async-components/views/dialogs/ExportE2eKeysDialog'), import('../../../async-components/views/dialogs/security/ExportE2eKeysDialog'),
{ {
matrixClient: MatrixClientPeg.get(), matrixClient: MatrixClientPeg.get(),
}, },
@ -93,14 +94,13 @@ export default class LogoutDialog extends React.Component {
// A key backup exists for this account, but the creating device is not // A key backup exists for this account, but the creating device is not
// verified, so restore the backup which will give us the keys from it and // verified, so restore the backup which will give us the keys from it and
// allow us to trust it (ie. upload keys to it) // allow us to trust it (ie. upload keys to it)
const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog');
Modal.createTrackedDialog( Modal.createTrackedDialog(
'Restore Backup', '', RestoreKeyBackupDialog, null, null, 'Restore Backup', '', RestoreKeyBackupDialog, null, null,
/* priority = */ false, /* static = */ true, /* priority = */ false, /* static = */ true,
); );
} else { } else {
Modal.createTrackedDialogAsync("Key Backup", "Key Backup", Modal.createTrackedDialogAsync("Key Backup", "Key Backup",
import("../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog"), import("../../../async-components/views/dialogs/security/CreateKeyBackupDialog"),
null, null, /* priority = */ false, /* static = */ true, null, null, /* priority = */ false, /* static = */ true,
); );
} }

View file

@ -16,8 +16,8 @@ limitations under the License.
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import {_t} from "../../../languageHandler"; import {_t} from "../../../../languageHandler";
import * as sdk from "../../../index"; import * as sdk from "../../../../index";
export default class ConfirmDestroyCrossSigningDialog extends React.Component { export default class ConfirmDestroyCrossSigningDialog extends React.Component {
static propTypes = { static propTypes = {

View file

@ -16,16 +16,16 @@ limitations under the License.
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import SetupEncryptionBody from '../../structures/auth/SetupEncryptionBody'; import SetupEncryptionBody from '../../../structures/auth/SetupEncryptionBody';
import BaseDialog from './BaseDialog'; import BaseDialog from '../BaseDialog';
import { _t } from '../../../languageHandler'; import { _t } from '../../../../languageHandler';
import { SetupEncryptionStore, PHASE_DONE } from '../../../stores/SetupEncryptionStore'; import { SetupEncryptionStore, PHASE_DONE } from '../../../../stores/SetupEncryptionStore';
function iconFromPhase(phase) { function iconFromPhase(phase) {
if (phase === PHASE_DONE) { if (phase === PHASE_DONE) {
return require("../../../../res/img/e2e/verified.svg"); return require("../../../../../res/img/e2e/verified.svg");
} else { } else {
return require("../../../../res/img/e2e/warning.svg"); return require("../../../../../res/img/e2e/warning.svg");
} }
} }

View file

@ -23,6 +23,7 @@ import Modal from "../../../Modal";
import {MatrixClientPeg} from "../../../MatrixClientPeg"; import {MatrixClientPeg} from "../../../MatrixClientPeg";
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import {SettingLevel} from "../../../settings/SettingLevel"; import {SettingLevel} from "../../../settings/SettingLevel";
import RestoreKeyBackupDialog from "../dialogs/security/RestoreKeyBackupDialog";
export default class RoomRecoveryReminder extends React.PureComponent { export default class RoomRecoveryReminder extends React.PureComponent {
static propTypes = { static propTypes = {
@ -70,14 +71,13 @@ export default class RoomRecoveryReminder extends React.PureComponent {
// A key backup exists for this account, but the creating device is not // A key backup exists for this account, but the creating device is not
// verified, so restore the backup which will give us the keys from it and // verified, so restore the backup which will give us the keys from it and
// allow us to trust it (ie. upload keys to it) // allow us to trust it (ie. upload keys to it)
const RestoreKeyBackupDialog = sdk.getComponent('dialogs.keybackup.RestoreKeyBackupDialog');
Modal.createTrackedDialog( Modal.createTrackedDialog(
'Restore Backup', '', RestoreKeyBackupDialog, null, null, 'Restore Backup', '', RestoreKeyBackupDialog, null, null,
/* priority = */ false, /* static = */ true, /* priority = */ false, /* static = */ true,
); );
} else { } else {
Modal.createTrackedDialogAsync("Key Backup", "Key Backup", Modal.createTrackedDialogAsync("Key Backup", "Key Backup",
import("../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog"), import("../../../async-components/views/dialogs/security/CreateKeyBackupDialog"),
null, null, /* priority = */ false, /* static = */ true, null, null, /* priority = */ false, /* static = */ true,
); );
} }
@ -91,7 +91,7 @@ export default class RoomRecoveryReminder extends React.PureComponent {
// When you choose "Don't ask again" from the room reminder, we show a // When you choose "Don't ask again" from the room reminder, we show a
// dialog to confirm the choice. // dialog to confirm the choice.
Modal.createTrackedDialogAsync("Ignore Recovery Reminder", "Ignore Recovery Reminder", Modal.createTrackedDialogAsync("Ignore Recovery Reminder", "Ignore Recovery Reminder",
import("../../../async-components/views/dialogs/keybackup/IgnoreRecoveryReminderDialog"), import("../../../async-components/views/dialogs/security/IgnoreRecoveryReminderDialog"),
{ {
onDontAskAgain: async () => { onDontAskAgain: async () => {
await SettingsStore.setValue( await SettingsStore.setValue(

View file

@ -184,7 +184,7 @@ export default class ChangePassword extends React.Component {
_onExportE2eKeysClicked = () => { _onExportE2eKeysClicked = () => {
Modal.createTrackedDialogAsync('Export E2E Keys', 'Change Password', Modal.createTrackedDialogAsync('Export E2E Keys', 'Change Password',
import('../../../async-components/views/dialogs/ExportE2eKeysDialog'), import('../../../async-components/views/dialogs/security/ExportE2eKeysDialog'),
{ {
matrixClient: MatrixClientPeg.get(), matrixClient: MatrixClientPeg.get(),
}, },

View file

@ -22,6 +22,7 @@ import * as sdk from '../../../index';
import Modal from '../../../Modal'; import Modal from '../../../Modal';
import Spinner from '../elements/Spinner'; import Spinner from '../elements/Spinner';
import InteractiveAuthDialog from '../dialogs/InteractiveAuthDialog'; import InteractiveAuthDialog from '../dialogs/InteractiveAuthDialog';
import ConfirmDestroyCrossSigningDialog from '../dialogs/security/ConfirmDestroyCrossSigningDialog';
export default class CrossSigningPanel extends React.PureComponent { export default class CrossSigningPanel extends React.PureComponent {
constructor(props) { constructor(props) {
@ -137,7 +138,6 @@ export default class CrossSigningPanel extends React.PureComponent {
} }
_resetCrossSigning = () => { _resetCrossSigning = () => {
const ConfirmDestroyCrossSigningDialog = sdk.getComponent("dialogs.ConfirmDestroyCrossSigningDialog");
Modal.createDialog(ConfirmDestroyCrossSigningDialog, { Modal.createDialog(ConfirmDestroyCrossSigningDialog, {
onFinished: (act) => { onFinished: (act) => {
if (!act) return; if (!act) return;

View file

@ -24,7 +24,7 @@ import { isSecureBackupRequired } from '../../../utils/WellKnownUtils';
import Spinner from '../elements/Spinner'; import Spinner from '../elements/Spinner';
import AccessibleButton from '../elements/AccessibleButton'; import AccessibleButton from '../elements/AccessibleButton';
import QuestionDialog from '../dialogs/QuestionDialog'; import QuestionDialog from '../dialogs/QuestionDialog';
import RestoreKeyBackupDialog from '../dialogs/keybackup/RestoreKeyBackupDialog'; import RestoreKeyBackupDialog from '../dialogs/security/RestoreKeyBackupDialog';
import { accessSecretStorage } from '../../../SecurityManager'; import { accessSecretStorage } from '../../../SecurityManager';
export default class SecureBackupPanel extends React.PureComponent { export default class SecureBackupPanel extends React.PureComponent {
@ -150,7 +150,7 @@ export default class SecureBackupPanel extends React.PureComponent {
_startNewBackup = () => { _startNewBackup = () => {
Modal.createTrackedDialogAsync('Key Backup', 'Key Backup', Modal.createTrackedDialogAsync('Key Backup', 'Key Backup',
import('../../../async-components/views/dialogs/keybackup/CreateKeyBackupDialog'), import('../../../async-components/views/dialogs/security/CreateKeyBackupDialog'),
{ {
onFinished: () => { onFinished: () => {
this._loadBackupStatus(); this._loadBackupStatus();

View file

@ -103,14 +103,14 @@ export default class SecurityUserSettingsTab extends React.Component {
_onExportE2eKeysClicked = () => { _onExportE2eKeysClicked = () => {
Modal.createTrackedDialogAsync('Export E2E Keys', '', Modal.createTrackedDialogAsync('Export E2E Keys', '',
import('../../../../../async-components/views/dialogs/ExportE2eKeysDialog'), import('../../../../../async-components/views/dialogs/security/ExportE2eKeysDialog'),
{matrixClient: MatrixClientPeg.get()}, {matrixClient: MatrixClientPeg.get()},
); );
}; };
_onImportE2eKeysClicked = () => { _onImportE2eKeysClicked = () => {
Modal.createTrackedDialogAsync('Import E2E Keys', '', Modal.createTrackedDialogAsync('Import E2E Keys', '',
import('../../../../../async-components/views/dialogs/ImportE2eKeysDialog'), import('../../../../../async-components/views/dialogs/security/ImportE2eKeysDialog'),
{matrixClient: MatrixClientPeg.get()}, {matrixClient: MatrixClientPeg.get()},
); );
}; };

View file

@ -18,7 +18,7 @@ import Modal from "../Modal";
import * as sdk from "../index"; import * as sdk from "../index";
import { _t } from "../languageHandler"; import { _t } from "../languageHandler";
import DeviceListener from "../DeviceListener"; import DeviceListener from "../DeviceListener";
import SetupEncryptionDialog from "../components/views/dialogs/SetupEncryptionDialog"; import SetupEncryptionDialog from "../components/views/dialogs/security/SetupEncryptionDialog";
import { accessSecretStorage } from "../SecurityManager"; import { accessSecretStorage } from "../SecurityManager";
import ToastStore from "../stores/ToastStore"; import ToastStore from "../stores/ToastStore";
import GenericToast from "../components/views/toasts/GenericToast"; import GenericToast from "../components/views/toasts/GenericToast";

View file

@ -20,7 +20,7 @@ import sdk from '../../../skinned-sdk';
import {MatrixClientPeg} from '../../../../src/MatrixClientPeg'; import {MatrixClientPeg} from '../../../../src/MatrixClientPeg';
import { stubClient } from '../../../test-utils'; import { stubClient } from '../../../test-utils';
const AccessSecretStorageDialog = sdk.getComponent("dialogs.secretstorage.AccessSecretStorageDialog"); const AccessSecretStorageDialog = sdk.getComponent("dialogs.security.AccessSecretStorageDialog");
describe("AccessSecretStorageDialog", function() { describe("AccessSecretStorageDialog", function() {
it("Closes the dialog if _onRecoveryKeyNext is called with a valid key", (done) => { it("Closes the dialog if _onRecoveryKeyNext is called with a valid key", (done) => {