Skip to content

Commit

Permalink
Add key storage delete confirm screen
Browse files Browse the repository at this point in the history
  • Loading branch information
dbkr committed Feb 5, 2025
1 parent b7b2ea3 commit e408715
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 8 deletions.
74 changes: 74 additions & 0 deletions src/components/views/settings/encryption/DeleteKeyStoragePanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/

import { Breadcrumb, Button, VisualList, VisualListItem } from "@vector-im/compound-web";
import CrossIcon from "@vector-im/compound-design-tokens/assets/web/icons/close";
import ErrorIcon from "@vector-im/compound-design-tokens/assets/web/icons/error";
import React, { useCallback, useState } from "react";

import { _t } from "../../../../languageHandler";
import { EncryptionCard } from "./EncryptionCard";
import { useKeyStoragePanelViewModel } from "../../../viewmodels/settings/encryption/KeyStoragePanelViewModel";

interface ResetIdentityPanelProps {
onFinish: () => void;
}

/**
* Confirms that the user really wants to turn off and delete their key storage
*/
export function DeleteKeyStoragePanel({ onFinish }: ResetIdentityPanelProps): JSX.Element {
const { setEnabled } = useKeyStoragePanelViewModel();
const [busy, setBusy] = useState(false);

const onDeleteClick = useCallback(async () => {
setBusy(true);
try {
await setEnabled(false);
} finally {
setBusy(false);
}
onFinish();
}, [setEnabled, onFinish]);

return (
<>
<Breadcrumb
backLabel={_t("action|back")}
onBackClick={onFinish}
pages={[_t("settings|encryption|title"), _t("settings|encryption|delete_key_storage|breadcrumb_page")]}
onPageClick={onFinish}
/>
<EncryptionCard
Icon={ErrorIcon}
destructive={true}
title={_t("settings|encryption|delete_key_storage|title")}
className="mx_ResetIdentityPanel"
>
<div className="mx_ResetIdentityPanel_content">
{_t("settings|encryption|delete_key_storage|description")}
<VisualList>
<VisualListItem Icon={CrossIcon} destructive={true}>
{_t("settings|encryption|delete_key_storage|list_first")}
</VisualListItem>
<VisualListItem Icon={CrossIcon} destructive={true}>
{_t("settings|encryption|delete_key_storage|list_second")}
</VisualListItem>
</VisualList>
</div>
<div className="mx_ResetIdentityPanel_footer">
<Button destructive={true} onClick={onDeleteClick} disabled={busy}>
{_t("settings|encryption|delete_key_storage|confirm")}
</Button>
<Button kind="tertiary" onClick={onFinish}>
{_t("action|cancel")}
</Button>
</div>
</EncryptionCard>
</>
);
}
18 changes: 13 additions & 5 deletions src/components/views/settings/encryption/KeyStoragePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,33 @@
* Please see LICENSE files in the repository root for full details.
*/

import React, { FormEvent, JSX, useCallback } from "react";
import React, { FormEvent, useCallback } from "react";
import { InlineField, InlineSpinner, Label, Root, ToggleControl } from "@vector-im/compound-web";

import { SettingsSection } from "../shared/SettingsSection";
import { _t } from "../../../../languageHandler";
import { SettingsHeader } from "../SettingsHeader";
import { useKeyStoragePanelViewModel } from "../../../viewmodels/settings/encryption/KeyStoragePanelViewModel";

interface Props {
onKeyStorageDisableClick: () => void;
}

/**
* This component allows the user to set up or change their recovery key.
*/
export function KeyBackupPanel(): JSX.Element {
export const KeyStoragePanel: React.FC<Props> = ({ onKeyStorageDisableClick }) => {
const { isEnabled, setEnabled, loading, busy } = useKeyStoragePanelViewModel();

const onKeyBackupChange = useCallback(
(e: FormEvent<HTMLInputElement>) => {
setEnabled(e.currentTarget.checked);
if (e.currentTarget.checked) {
setEnabled(true);
} else {
onKeyStorageDisableClick();
}
},
[setEnabled],
[setEnabled, onKeyStorageDisableClick],
);

if (loading) {
Expand Down Expand Up @@ -58,4 +66,4 @@ export function KeyBackupPanel(): JSX.Element {
</Root>
</SettingsSection>
);
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ import { ResetIdentityPanel } from "../../encryption/ResetIdentityPanel";
import { RecoveryPanelOutOfSync } from "../../encryption/RecoveryPanelOutOfSync";
import Spinner from "../../../elements/Spinner";
import { useEventEmitter } from "../../../../../hooks/useEventEmitter";
import { KeyBackupPanel } from "../../encryption/KeyStoragePanel";
import { KeyStoragePanel } from "../../encryption/KeyStoragePanel";
import { DeleteKeyStoragePanel } from "../../encryption/DeleteKeyStoragePanel";

/**
* The state in the encryption settings tab.
Expand All @@ -49,7 +50,8 @@ export type State =
| "set_recovery_key"
| "reset_identity_compromised"
| "reset_identity_forgot"
| "secrets_not_cached";
| "secrets_not_cached"
| "key_storage_delete";

interface EncryptionUserSettingsTabProps {
/**
Expand Down Expand Up @@ -113,7 +115,7 @@ export function EncryptionUserSettingsTab({ initialState = "loading" }: Encrypti
case "main":
content = (
<>
<KeyBackupPanel />
<KeyStoragePanel onKeyStorageDisableClick={() => setState("key_storage_delete")} />
{keyBackupIsEnabled && (
<>
<RecoveryPanel
Expand Down Expand Up @@ -158,6 +160,9 @@ export function EncryptionUserSettingsTab({ initialState = "loading" }: Encrypti
/>
);
break;
case "key_storage_delete":
content = <DeleteKeyStoragePanel onFinish={() => setState("main")} />;
break;
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -2482,6 +2482,14 @@
"session_key": "Session key:",
"title": "Advanced"
},
"delete_key_storage": {
"breadcrumb_page": "Delete key storage",
"confirm": "Delete key storage",
"description": "Deleting key storage will remove your cryptographic identity and message keys from the server and turn off the following security features:",
"list_first": "You will not have encrypted message history on new devices",
"list_second": "You will lose access to your encrypted messages if you are signed out of Element everywhere",
"title": "Are you sure you want to turn off key storage and delete it?"
},
"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",
Expand Down

0 comments on commit e408715

Please sign in to comment.