Merge branch 'develop' into midhun/fix-spotlight-1
This commit is contained in:
commit
ec96d33ed7
215 changed files with 3574 additions and 2704 deletions
|
@ -12,6 +12,7 @@ import { Room, EventType } from "matrix-js-sdk/src/matrix";
|
|||
import { KnownMembership } from "matrix-js-sdk/src/types";
|
||||
import { sleep } from "matrix-js-sdk/src/utils";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { ErrorIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import { _t, _td, TranslationKey } from "../../../languageHandler";
|
||||
import BaseDialog from "./BaseDialog";
|
||||
|
@ -34,7 +35,6 @@ import LazyRenderList from "../elements/LazyRenderList";
|
|||
import { useSettingValue } from "../../../hooks/useSettings";
|
||||
import { filterBoolean } from "../../../utils/arrays";
|
||||
import { NonEmptyArray } from "../../../@types/common";
|
||||
import WarningBadgeSvg from "../../../../res/img/element-icons/warning-badge.svg";
|
||||
|
||||
// These values match CSS
|
||||
const ROW_HEIGHT = 32 + 12;
|
||||
|
@ -229,7 +229,7 @@ export const AddExistingToSpace: React.FC<IAddExistingToSpaceProps> = ({
|
|||
if (error) {
|
||||
footer = (
|
||||
<>
|
||||
<img src={WarningBadgeSvg} height="24" width="24" alt="" />
|
||||
<ErrorIcon height="24px" width="24px" />
|
||||
|
||||
<span className="mx_AddExistingToSpaceDialog_error">
|
||||
<div className="mx_AddExistingToSpaceDialog_errorHeading">
|
||||
|
|
|
@ -7,12 +7,10 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
|||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import React, { lazy } from "react";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import type CreateKeyBackupDialog from "../../../async-components/views/dialogs/security/CreateKeyBackupDialog";
|
||||
import type ExportE2eKeysDialog from "../../../async-components/views/dialogs/security/ExportE2eKeysDialog";
|
||||
import Modal from "../../../Modal";
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
import { _t } from "../../../languageHandler";
|
||||
|
@ -116,10 +114,8 @@ export default class LogoutDialog extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
private onExportE2eKeysClicked = (): void => {
|
||||
Modal.createDialogAsync(
|
||||
import("../../../async-components/views/dialogs/security/ExportE2eKeysDialog") as unknown as Promise<
|
||||
typeof ExportE2eKeysDialog
|
||||
>,
|
||||
Modal.createDialog(
|
||||
lazy(() => import("../../../async-components/views/dialogs/security/ExportE2eKeysDialog")),
|
||||
{
|
||||
matrixClient: MatrixClientPeg.safeGet(),
|
||||
},
|
||||
|
@ -147,10 +143,8 @@ export default class LogoutDialog extends React.Component<IProps, IState> {
|
|||
/* static = */ true,
|
||||
);
|
||||
} else {
|
||||
Modal.createDialogAsync(
|
||||
import("../../../async-components/views/dialogs/security/CreateKeyBackupDialog") as unknown as Promise<
|
||||
typeof CreateKeyBackupDialog
|
||||
>,
|
||||
Modal.createDialog(
|
||||
lazy(() => import("../../../async-components/views/dialogs/security/CreateKeyBackupDialog")),
|
||||
undefined,
|
||||
undefined,
|
||||
/* priority = */ false,
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
WidgetApiFromWidgetAction,
|
||||
WidgetKind,
|
||||
} from "matrix-widget-api";
|
||||
import { ErrorIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
|
||||
|
||||
import BaseDialog from "./BaseDialog";
|
||||
import { _t, getUserLanguage } from "../../../languageHandler";
|
||||
|
@ -33,7 +34,6 @@ import { arrayFastClone } from "../../../utils/arrays";
|
|||
import { ElementWidget } from "../../../stores/widgets/StopGapWidget";
|
||||
import { ELEMENT_CLIENT_ID } from "../../../identifiers";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import WarningBadgeSvg from "../../../../res/img/element-icons/warning-badge.svg";
|
||||
|
||||
interface IProps {
|
||||
widgetDefinition: IModalWidgetOpenRequestData;
|
||||
|
@ -186,7 +186,7 @@ export default class ModalWidgetDialog extends React.PureComponent<IProps, IStat
|
|||
onFinished={this.props.onFinished}
|
||||
>
|
||||
<div className="mx_ModalWidgetDialog_warning">
|
||||
<img src={WarningBadgeSvg} height="16" width="16" alt="" />
|
||||
<ErrorIcon width="16px" height="16px" />
|
||||
{_t("widget|modal_data_warning", {
|
||||
widgetDomain: parsed.hostname,
|
||||
})}
|
||||
|
|
|
@ -21,7 +21,7 @@ import { SpacePreferenceTab } from "../../../dispatcher/payloads/OpenSpacePrefer
|
|||
import { NonEmptyArray } from "../../../@types/common";
|
||||
import SettingsTab from "../settings/tabs/SettingsTab";
|
||||
import { SettingsSection } from "../settings/shared/SettingsSection";
|
||||
import SettingsSubsection, { SettingsSubsectionText } from "../settings/shared/SettingsSubsection";
|
||||
import { SettingsSubsection, SettingsSubsectionText } from "../settings/shared/SettingsSubsection";
|
||||
|
||||
interface IProps {
|
||||
space: Room;
|
||||
|
|
|
@ -8,9 +8,8 @@ Please see LICENSE files in the repository root for full details.
|
|||
*/
|
||||
|
||||
import React, { ChangeEvent } from "react";
|
||||
import { MatrixClient, MatrixError, SecretStorage } from "matrix-js-sdk/src/matrix";
|
||||
import { decodeRecoveryKey, KeyBackupInfo } from "matrix-js-sdk/src/crypto-api";
|
||||
import { IKeyBackupRestoreResult } from "matrix-js-sdk/src/crypto/keybackup";
|
||||
import { MatrixClient, MatrixError } from "matrix-js-sdk/src/matrix";
|
||||
import { decodeRecoveryKey, KeyBackupInfo, KeyBackupRestoreResult } from "matrix-js-sdk/src/crypto-api";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
import { MatrixClientPeg } from "../../../../MatrixClientPeg";
|
||||
|
@ -42,12 +41,11 @@ interface IProps {
|
|||
|
||||
interface IState {
|
||||
backupInfo: KeyBackupInfo | null;
|
||||
backupKeyStored: Record<string, SecretStorage.SecretStorageKeyDescription> | null;
|
||||
loading: boolean;
|
||||
loadError: boolean | null;
|
||||
restoreError: unknown | null;
|
||||
recoveryKey: string;
|
||||
recoverInfo: IKeyBackupRestoreResult | null;
|
||||
recoverInfo: KeyBackupRestoreResult | null;
|
||||
recoveryKeyValid: boolean;
|
||||
forceRecoveryKey: boolean;
|
||||
passPhrase: string;
|
||||
|
@ -72,7 +70,6 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
super(props);
|
||||
this.state = {
|
||||
backupInfo: null,
|
||||
backupKeyStored: null,
|
||||
loading: false,
|
||||
loadError: null,
|
||||
restoreError: null,
|
||||
|
@ -137,7 +134,8 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
};
|
||||
|
||||
private onPassPhraseNext = async (): Promise<void> => {
|
||||
if (!this.state.backupInfo) return;
|
||||
const crypto = MatrixClientPeg.safeGet().getCrypto();
|
||||
if (!crypto) return;
|
||||
this.setState({
|
||||
loading: true,
|
||||
restoreError: null,
|
||||
|
@ -146,13 +144,9 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
try {
|
||||
// We do still restore the key backup: we must ensure that the key backup key
|
||||
// is the right one and restoring it is currently the only way we can do this.
|
||||
const recoverInfo = await MatrixClientPeg.safeGet().restoreKeyBackupWithPassword(
|
||||
this.state.passPhrase,
|
||||
undefined,
|
||||
undefined,
|
||||
this.state.backupInfo,
|
||||
{ progressCallback: this.progressCallback },
|
||||
);
|
||||
const recoverInfo = await crypto.restoreKeyBackupWithPassphrase(this.state.passPhrase, {
|
||||
progressCallback: this.progressCallback,
|
||||
});
|
||||
|
||||
if (!this.props.showSummary) {
|
||||
this.props.onFinished(true);
|
||||
|
@ -172,7 +166,8 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
};
|
||||
|
||||
private onRecoveryKeyNext = async (): Promise<void> => {
|
||||
if (!this.state.recoveryKeyValid || !this.state.backupInfo) return;
|
||||
const crypto = MatrixClientPeg.safeGet().getCrypto();
|
||||
if (!this.state.recoveryKeyValid || !this.state.backupInfo?.version || !crypto) return;
|
||||
|
||||
this.setState({
|
||||
loading: true,
|
||||
|
@ -180,13 +175,14 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
restoreType: RestoreType.RecoveryKey,
|
||||
});
|
||||
try {
|
||||
const recoverInfo = await MatrixClientPeg.safeGet().restoreKeyBackupWithRecoveryKey(
|
||||
this.state.recoveryKey,
|
||||
undefined,
|
||||
undefined,
|
||||
this.state.backupInfo,
|
||||
{ progressCallback: this.progressCallback },
|
||||
await crypto.storeSessionBackupPrivateKey(
|
||||
decodeRecoveryKey(this.state.recoveryKey),
|
||||
this.state.backupInfo.version,
|
||||
);
|
||||
const recoverInfo = await crypto.restoreKeyBackup({
|
||||
progressCallback: this.progressCallback,
|
||||
});
|
||||
|
||||
if (!this.props.showSummary) {
|
||||
this.props.onFinished(true);
|
||||
return;
|
||||
|
@ -210,44 +206,41 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
});
|
||||
};
|
||||
|
||||
private async restoreWithSecretStorage(): Promise<void> {
|
||||
private async restoreWithSecretStorage(): Promise<boolean> {
|
||||
const crypto = MatrixClientPeg.safeGet().getCrypto();
|
||||
if (!crypto) return false;
|
||||
|
||||
this.setState({
|
||||
loading: true,
|
||||
restoreError: null,
|
||||
restoreType: RestoreType.SecretStorage,
|
||||
});
|
||||
try {
|
||||
let recoverInfo: KeyBackupRestoreResult | null = null;
|
||||
// `accessSecretStorage` may prompt for storage access as needed.
|
||||
await accessSecretStorage(async (): Promise<void> => {
|
||||
if (!this.state.backupInfo) return;
|
||||
await MatrixClientPeg.safeGet().restoreKeyBackupWithSecretStorage(
|
||||
this.state.backupInfo,
|
||||
undefined,
|
||||
undefined,
|
||||
{ progressCallback: this.progressCallback },
|
||||
);
|
||||
await crypto.loadSessionBackupPrivateKeyFromSecretStorage();
|
||||
recoverInfo = await crypto.restoreKeyBackup({ progressCallback: this.progressCallback });
|
||||
});
|
||||
this.setState({
|
||||
loading: false,
|
||||
recoverInfo,
|
||||
});
|
||||
return true;
|
||||
} catch (e) {
|
||||
logger.log("Error restoring backup", e);
|
||||
logger.log("restoreWithSecretStorage failed:", e);
|
||||
this.setState({
|
||||
restoreError: e,
|
||||
loading: false,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private async restoreWithCachedKey(backupInfo: KeyBackupInfo | null): Promise<boolean> {
|
||||
if (!backupInfo) return false;
|
||||
const crypto = MatrixClientPeg.safeGet().getCrypto();
|
||||
if (!crypto) return false;
|
||||
try {
|
||||
const recoverInfo = await MatrixClientPeg.safeGet().restoreKeyBackupWithCache(
|
||||
undefined /* targetRoomId */,
|
||||
undefined /* targetSessionId */,
|
||||
backupInfo,
|
||||
{ progressCallback: this.progressCallback },
|
||||
);
|
||||
const recoverInfo = await crypto.restoreKeyBackup({ progressCallback: this.progressCallback });
|
||||
this.setState({
|
||||
recoverInfo,
|
||||
});
|
||||
|
@ -270,7 +263,6 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
const backupKeyStored = has4S ? await cli.isKeyBackupKeyStored() : null;
|
||||
this.setState({
|
||||
backupInfo,
|
||||
backupKeyStored,
|
||||
});
|
||||
|
||||
const gotCache = await this.restoreWithCachedKey(backupInfo);
|
||||
|
@ -282,9 +274,13 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
return;
|
||||
}
|
||||
|
||||
// If the backup key is stored, we can proceed directly to restore.
|
||||
if (backupKeyStored) {
|
||||
return this.restoreWithSecretStorage();
|
||||
const hasBackupFromSS = backupKeyStored && (await this.restoreWithSecretStorage());
|
||||
if (hasBackupFromSS) {
|
||||
logger.log("RestoreKeyBackupDialog: found backup key in secret storage");
|
||||
this.setState({
|
||||
loading: false,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
|
@ -398,6 +394,7 @@ export default class RestoreKeyBackupDialog extends React.PureComponent<IProps,
|
|||
|
||||
<form className="mx_RestoreKeyBackupDialog_primaryContainer">
|
||||
<input
|
||||
data-testid="passphraseInput"
|
||||
type="password"
|
||||
className="mx_RestoreKeyBackupDialog_passPhraseInput"
|
||||
onChange={this.onPassPhraseChange}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue