/* Copyright 2024 New Vector Ltd. Copyright 2021 The Matrix.org Foundation C.I.C. 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 { logger } from "matrix-js-sdk/src/logger"; import type ExportE2eKeysDialog from "../../../async-components/views/dialogs/security/ExportE2eKeysDialog"; import type ImportE2eKeysDialog from "../../../async-components/views/dialogs/security/ImportE2eKeysDialog"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import { _t } from "../../../languageHandler"; import Modal from "../../../Modal"; import AccessibleButton from "../elements/AccessibleButton"; import * as FormattingUtils from "../../../utils/FormattingUtils"; import SettingsStore from "../../../settings/SettingsStore"; import SettingsFlag from "../elements/SettingsFlag"; import { SettingLevel } from "../../../settings/SettingLevel"; import SettingsSubsection, { SettingsSubsectionText } from "./shared/SettingsSubsection"; interface IProps {} interface IState { /** The device's base64-encoded Ed25519 identity key, or: * * * `undefined`: not yet loaded * * `null`: encryption is not supported (or the crypto stack was not correctly initialized) */ deviceIdentityKey: string | undefined | null; } export default class CryptographyPanel extends React.Component { public constructor(props: IProps) { super(props); const client = MatrixClientPeg.safeGet(); const crypto = client.getCrypto(); if (!crypto) { this.state = { deviceIdentityKey: null }; } else { this.state = { deviceIdentityKey: undefined }; crypto .getOwnDeviceKeys() .then((keys) => { this.setState({ deviceIdentityKey: keys.ed25519 }); }) .catch((e) => { logger.error(`CryptographyPanel: Error fetching own device keys: ${e}`); this.setState({ deviceIdentityKey: null }); }); } } public render(): React.ReactNode { const client = MatrixClientPeg.safeGet(); const deviceId = client.deviceId; let identityKey = this.state.deviceIdentityKey; if (identityKey === undefined) { // Should show a spinner here really, but since this will be very transitional, I can't be doing with the // necessary styling. identityKey = "..."; } else if (identityKey === null) { identityKey = _t("encryption|not_supported"); } else { identityKey = FormattingUtils.formatCryptoKey(identityKey); } let importExportButtons: JSX.Element | undefined; if (client.getCrypto()) { importExportButtons = (
{_t("settings|security|export_megolm_keys")} {_t("settings|security|import_megolm_keys")}
); } let noSendUnverifiedSetting: JSX.Element | undefined; if (SettingsStore.canSetValue("blacklistUnverifiedDevices", null, SettingLevel.DEVICE)) { noSendUnverifiedSetting = ( ); } return (
{_t("settings|security|session_id")} {deviceId}
{_t("settings|security|session_key")} {identityKey}
{importExportButtons} {noSendUnverifiedSetting}
); } private onExportE2eKeysClicked = (): void => { Modal.createDialogAsync( import("../../../async-components/views/dialogs/security/ExportE2eKeysDialog") as unknown as Promise< typeof ExportE2eKeysDialog >, { matrixClient: MatrixClientPeg.safeGet() }, ); }; private onImportE2eKeysClicked = (): void => { Modal.createDialogAsync( import("../../../async-components/views/dialogs/security/ImportE2eKeysDialog") as unknown as Promise< typeof ImportE2eKeysDialog >, { matrixClient: MatrixClientPeg.safeGet() }, ); }; private updateBlacklistDevicesFlag = (checked: boolean): void => { MatrixClientPeg.safeGet().setGlobalBlacklistUnverifiedDevices(checked); }; }