Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Recovery section in the new user settings Encryption tab #28673

Merged
merged 44 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
3e77b3d
Refine `SettingsSection` & `SettingsTab`
florianduros Dec 4, 2024
ae623f8
Add encryption tab
florianduros Dec 4, 2024
f9e48b4
Add recovery section
florianduros Dec 6, 2024
0057f57
Add device verification
florianduros Dec 12, 2024
bb507b0
Rename `Panel` into `State`
florianduros Dec 13, 2024
1aace3f
Update & add tests to user settings common
florianduros Dec 13, 2024
70c084e
Add tests to `RecoveryPanel`
florianduros Dec 18, 2024
7193998
Add tests to `ChangeRecoveryKey`
florianduros Dec 18, 2024
fec324e
Update CreateSecretStorageDialog-test snapshot
florianduros Dec 16, 2024
44c6bce
Add tests to `EncryptionUserSettingsTab`
florianduros Dec 16, 2024
075f6dc
Update existing screenshots of e2e tests
florianduros Dec 16, 2024
895ad88
Add new encryption tab ownership to `@element-hq/element-crypto-web-r…
florianduros Dec 17, 2024
ba032a7
Add e2e tests
florianduros Dec 18, 2024
7909ac9
Fix monospace font and add figma link to hardcoded value
florianduros Dec 19, 2024
618557c
Add unit to Icon
florianduros Dec 19, 2024
c805cd8
Merge branch 'develop' into florianduros/encryption-tab
florianduros Dec 19, 2024
7a372f7
Merge branch 'develop' into florianduros/encryption-tab
florianduros Dec 23, 2024
b20579d
Improve e2e doc
florianduros Dec 23, 2024
24c537c
Assert that the crypto module is defined
florianduros Jan 6, 2025
72adfa5
Add classname doc
florianduros Jan 6, 2025
36c7e0e
Fix typo
florianduros Jan 6, 2025
52076f1
Use `good` state instead of default
florianduros Jan 6, 2025
a0d904e
Rename `ChangeRecoveryKey.isSetupFlow` into `ChangeRecoveryKey.userHa…
florianduros Jan 6, 2025
1a0e6dc
Move `deleteCachedSecrets` fixture in `recovery.spec.ts`
florianduros Jan 6, 2025
0b254e5
Use one callback instead of two in `RecoveryPanel`
florianduros Jan 6, 2025
6f236bd
Fix docs and naming of `utils.createBot`
florianduros Jan 8, 2025
82bf2cc
Fix typo in `RecoveryPanel`
florianduros Jan 8, 2025
84d11f8
Add more doc to the state of the `EncryptionUserSettingsTab`
florianduros Jan 8, 2025
2fe5555
Rename `verification_required` into `set_up_encryption`
florianduros Jan 8, 2025
4b365ba
Merge branch 'develop' into florianduros/encryption-tab
florianduros Jan 8, 2025
8a9291a
Update test
florianduros Jan 8, 2025
1c00502
ADd new license
florianduros Jan 8, 2025
dc940f5
Update comments and doc
florianduros Jan 9, 2025
521cebf
Assert that `recoveryKey.encodedPrivateKey` is always defined
florianduros Jan 9, 2025
7af44cc
Add comments to explain how the secrets could be uncached
florianduros Jan 9, 2025
8bd5d6a
Use `matrixClient.secretStorage.getDefaultKeyId` instead of `matrixCl…
florianduros Jan 9, 2025
086f28e
Merge branch 'develop' into florianduros/encryption-tab
florianduros Jan 9, 2025
0c18708
Update existing screenshot to add encryption tab.
florianduros Jan 9, 2025
0a52b7c
Update tests
florianduros Jan 9, 2025
e5dea48
Use new labels when changing the recovery key
florianduros Jan 10, 2025
f78c27a
Fix docs
florianduros Jan 13, 2025
bef3165
Don't reset key backup when creating a recovery key
florianduros Jan 13, 2025
ae163d1
Fix doc
florianduros Jan 15, 2025
ee4f3a8
Merge branch 'develop' into florianduros/encryption-tab
florianduros Jan 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion playwright/e2e/settings/encryption-user-tab/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class Helpers {
}

/**
* Set the default key id of the secret storage at null
* Set the default key id of the secret storage to `null`
*/
async removeSecretStorageDefaultKeyId() {
const client = await this.app.client.prepareClient();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,13 @@ test.describe("Recovery section in Encryption tab", () => {

await app.closeDialog();
// Check that the current device is connected to key backup and the backup version is the expected one
await checkDeviceIsConnectedKeyBackup(page, "2", true);
await checkDeviceIsConnectedKeyBackup(page, "1", true);
});

// This case shouldn't happen but we have seen cases where the secrets gossiping failed or shared partial secrets when verified with another device.
// To simulate this case, we need to delete the cached secrets in the indexedDB
// Test what happens if the cross-signing secrets are in secret storage but are not cached in the local DB.
//
// This can happen if we verified another device and secret-gossiping failed, or the other device itself lacked the secrets.
// We simulate this case by deleting the cached secrets in the indexedDB.
test(
"should enter the recovery key when the secrets are not cached",
{ tag: "@screenshot" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export function ChangeRecoveryKey({
break;
case "confirm_key_setup_flow":
case "confirm_key_change_flow":
// Ask the user to enter the recovery key they just save to confirm it.
// Ask the user to enter the recovery key they just saved to confirm it.
content = (
<KeyForm
// encodedPrivateKey is always defined, the optional typing is incorrect
Expand All @@ -123,7 +123,6 @@ export function ChangeRecoveryKey({
// when we will try to access the secret storage during the bootstrap
await withSecretStorageKeyCache(() =>
crypto.bootstrapSecretStorage({
setupNewKeyBackup: !userHasRecoveryKey,
setupNewSecretStorage: true,
createSecretStorageKey: async () => recoveryKey,
}),
Expand Down
9 changes: 6 additions & 3 deletions src/components/views/settings/encryption/RecoveryPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,17 @@ import { SettingsSubheader } from "../SettingsSubheader";
* - `loading`: We are checking the recovery key and the secrets.
* - `missing_recovery_key`: The user has no recovery key.
* - `secrets_not_cached`: The user has a backup but the secrets are not cached.
florianduros marked this conversation as resolved.
Show resolved Hide resolved
* This shouldn't happen but we have seen cases where the secrets gossiping failed or shared partial secrets when verified with another device.
* - `good`: The user has a backup and the secrets are cached.
* This can happen if we verified another device and secret-gossiping failed, or the other device itself lacked the secrets.
Copy link
Member

@richvdh richvdh Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's worth noting that this indentation is lost if/when the tsdoc is rendered to HTML, and is inconsistent with our style elsewhere.

But, not a big problem. Something to consider for the future.

* - `good`: The user has a recovery key and the secrets are cached.
*/
type State = "loading" | "missing_recovery_key" | "secrets_not_cached" | "good";

interface RecoveryPanelProps {
/**
* Callback for when the user wants to set up or change their recovery key.
*
* @param setupNewKeyis set if the user does not already have a recovery key (and has therefore clicked on
* "Set up recovery" rather than "Change recovery key").
florianduros marked this conversation as resolved.
Show resolved Hide resolved
*/
onChangeRecoveryKeyClick: (setupNewKey: boolean) => void;
}
Expand All @@ -45,7 +48,7 @@ export function RecoveryPanel({ onChangeRecoveryKeyClick }: RecoveryPanelProps):
const checkEncryption = useCallback(async () => {
const crypto = matrixClient.getCrypto()!;

// Check if the user has a backup
// Check if the user has a recovery key
const hasRecoveryKey = Boolean(await matrixClient.secretStorage.getDefaultKeyId());
if (!hasRecoveryKey) return setState("missing_recovery_key");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { SettingsSubheader } from "../../SettingsSubheader";
* - "change_recovery_key": The panel to show when the user is changing their recovery key.
* This happens when the user has a key backup and the user clicks on "Change recovery key" button of the RecoveryPanel.
florianduros marked this conversation as resolved.
Show resolved Hide resolved
* - "set_recovery_key": The panel to show when the user is setting up their recovery key.
* This happens when the user doesn't have a key backup and the user clicks on "Set up recovery key" button of the RecoveryPanel.
* This happens when the user doesn't have a key a recovery key and the user clicks on "Set up recovery key" button of the RecoveryPanel.
*/
type State = "loading" | "main" | "set_up_encryption" | "change_recovery_key" | "set_recovery_key";

Expand Down
Loading