Add device verification
parent
f9e48b4e3b
commit
0057f57db9
|
@ -5,19 +5,42 @@
|
||||||
* Please see LICENSE files in the repository root for full details.
|
* Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { JSX, useState } from "react";
|
import React, { JSX, useCallback, useEffect, useState } from "react";
|
||||||
|
import { Button, InlineSpinner } from "@vector-im/compound-web";
|
||||||
|
import ComputerIcon from "@vector-im/compound-design-tokens/assets/web/icons/computer";
|
||||||
|
|
||||||
import SettingsTab from "../SettingsTab";
|
import SettingsTab from "../SettingsTab";
|
||||||
import { RecoveryPanel } from "../../encryption/RecoveryPanel";
|
import { RecoveryPanel } from "../../encryption/RecoveryPanel";
|
||||||
import { ChangeRecoveryKey } from "../../encryption/ChangeRecoveryKey";
|
import { ChangeRecoveryKey } from "../../encryption/ChangeRecoveryKey";
|
||||||
|
import { useMatrixClientContext } from "../../../../../contexts/MatrixClientContext";
|
||||||
|
import { _t } from "../../../../../languageHandler";
|
||||||
|
import Modal from "../../../../../Modal";
|
||||||
|
import SetupEncryptionDialog from "../../../dialogs/security/SetupEncryptionDialog";
|
||||||
|
import { SettingsSection } from "../../shared/SettingsSection";
|
||||||
|
import { SettingsSubheader } from "../../SettingsSubheader";
|
||||||
|
|
||||||
type Panel = "main" | "change_recovery_key" | "set_recovery_key";
|
/**
|
||||||
|
* The panel to show in the encryption settings tab.
|
||||||
|
* - "loading": We are checking if the device is verified.
|
||||||
|
* - "main": The main panel with all the sections (Key storage, recovery, advanced).
|
||||||
|
* - "verification_required": The panel to show when the user needs to verify their session.
|
||||||
|
* - "change_recovery_key": The panel to show when the user is changing their recovery key.
|
||||||
|
* - "set_recovery_key": The panel to show when the user is setting up their recovery key.
|
||||||
|
*/
|
||||||
|
type Panel = "loading" | "main" | "verification_required" | "change_recovery_key" | "set_recovery_key";
|
||||||
|
|
||||||
export function EncryptionUserSettingsTab(): JSX.Element {
|
export function EncryptionUserSettingsTab(): JSX.Element {
|
||||||
const [panel, setPanel] = useState<Panel>("main");
|
const [panel, setPanel] = useState<Panel>("loading");
|
||||||
|
const checkVerificationRequired = useVerificationRequired(setPanel);
|
||||||
|
|
||||||
let content: JSX.Element;
|
let content: JSX.Element;
|
||||||
switch (panel) {
|
switch (panel) {
|
||||||
|
case "loading":
|
||||||
|
content = <InlineSpinner />;
|
||||||
|
break;
|
||||||
|
case "verification_required":
|
||||||
|
content = <VerifySessionPanel onFinish={checkVerificationRequired} />;
|
||||||
|
break;
|
||||||
case "main":
|
case "main":
|
||||||
content = (
|
content = (
|
||||||
<RecoveryPanel
|
<RecoveryPanel
|
||||||
|
@ -48,3 +71,61 @@ export function EncryptionUserSettingsTab(): JSX.Element {
|
||||||
|
|
||||||
return <SettingsTab className="mx_EncryptionUserSettingsTab">{content}</SettingsTab>;
|
return <SettingsTab className="mx_EncryptionUserSettingsTab">{content}</SettingsTab>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to check if the user needs to verify their session.
|
||||||
|
* If the user needs to verify their session, the panel will be set to "verification_required".
|
||||||
|
* If the user doesn't need to verify their session, the panel will be set to "main".
|
||||||
|
* @param setPanel
|
||||||
|
*/
|
||||||
|
function useVerificationRequired(setPanel: (panel: Panel) => void): () => Promise<void> {
|
||||||
|
const matrixClient = useMatrixClientContext();
|
||||||
|
|
||||||
|
const checkVerificationRequired = useCallback(async () => {
|
||||||
|
const crypto = matrixClient.getCrypto();
|
||||||
|
if (!crypto) return;
|
||||||
|
|
||||||
|
const isCrossSigningReady = await crypto.isCrossSigningReady();
|
||||||
|
if (isCrossSigningReady) setPanel("main");
|
||||||
|
else setPanel("verification_required");
|
||||||
|
}, [matrixClient, setPanel]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
checkVerificationRequired();
|
||||||
|
}, [checkVerificationRequired]);
|
||||||
|
|
||||||
|
return checkVerificationRequired;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface VerifySessionPanelProps {
|
||||||
|
/**
|
||||||
|
* Callback to call when the user has finished verifying their session.
|
||||||
|
*/
|
||||||
|
onFinish: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Panel to show when the user needs to verify their session.
|
||||||
|
*/
|
||||||
|
function VerifySessionPanel({ onFinish }: VerifySessionPanelProps): JSX.Element {
|
||||||
|
return (
|
||||||
|
<SettingsSection
|
||||||
|
legacy={false}
|
||||||
|
heading={_t("settings|encryption|device_not_verified_title")}
|
||||||
|
subHeading={
|
||||||
|
<SettingsSubheader
|
||||||
|
stateMessage={_t("settings|encryption|device_not_verified_description")}
|
||||||
|
state="error"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
Icon={ComputerIcon}
|
||||||
|
onClick={() => Modal.createDialog(SetupEncryptionDialog, { onFinished: onFinish })}
|
||||||
|
>
|
||||||
|
{_t("settings|encryption|device_not_verified_button")}
|
||||||
|
</Button>
|
||||||
|
</SettingsSection>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -2463,6 +2463,9 @@
|
||||||
"enable_markdown": "Enable Markdown",
|
"enable_markdown": "Enable Markdown",
|
||||||
"enable_markdown_description": "Start messages with <code>/plain</code> to send without markdown.",
|
"enable_markdown_description": "Start messages with <code>/plain</code> to send without markdown.",
|
||||||
"encryption": {
|
"encryption": {
|
||||||
|
"device_not_verified_button": "Verify this device",
|
||||||
|
"device_not_verified_description": "You need to verify this device in order to view your encryption settings.",
|
||||||
|
"device_not_verified_title": "Device not verified",
|
||||||
"dialog_title": "<strong>Settings:</strong> Encryption",
|
"dialog_title": "<strong>Settings:</strong> Encryption",
|
||||||
"recovery": {
|
"recovery": {
|
||||||
"change_recovery_key": "Change recovery key",
|
"change_recovery_key": "Change recovery key",
|
||||||
|
|
Loading…
Reference in New Issue