Very early WIP of rejigged e2e error toast code

dbkr/e2e_toasts
David Baker 2025-01-08 17:22:15 +00:00
parent 1c00502e6b
commit d9d752804c
3 changed files with 43 additions and 30 deletions

View File

@ -283,7 +283,19 @@ export default class DeviceListener {
const crossSigningReady = await crypto.isCrossSigningReady();
const secretStorageReady = await crypto.isSecretStorageReady();
const allSystemsReady = crossSigningReady && secretStorageReady;
const crossSigningStatus = await crypto.getCrossSigningStatus();
const allCrossSigningSecretsCached =
crossSigningStatus.privateKeysCachedLocally.masterKey &&
crossSigningStatus.privateKeysCachedLocally.selfSigningKey &&
crossSigningStatus.privateKeysCachedLocally.userSigningKey;
const isCurrentDeviceTrusted =
crossSigningReady &&
Boolean(
(await crypto.getDeviceVerificationStatus(cli.getSafeUserId(), cli.deviceId!))?.crossSigningVerified,
);
const allSystemsReady = crossSigningReady && secretStorageReady && allCrossSigningSecretsCached;
await this.reportCryptoSessionStateToAnalytics(cli);
if (this.dismissedThisDeviceToast || allSystemsReady) {
@ -294,31 +306,22 @@ export default class DeviceListener {
// make sure our keys are finished downloading
await crypto.getUserDeviceInfo([cli.getSafeUserId()]);
// cross signing isn't enabled - nag to enable it
// There are 3 different toasts for:
if (!(await crypto.getCrossSigningKeyId()) && (await crypto.userHasCrossSigningKeys())) {
// Toast 1. Cross-signing on account but this device doesn't trust the master key (verify this session)
if (!crossSigningReady) {
// This account is legacy and doesn't have cross-signing set up at all.
// Prompt the user to set it up.
showSetupEncryptionToast(SetupKind.SET_UP_ENCRYPTION);
} else if (!isCurrentDeviceTrusted) {
// cross signing is ready but the current device is not trusted: prompt the user to verify
showSetupEncryptionToast(SetupKind.VERIFY_THIS_SESSION);
this.checkKeyBackupStatus();
} else if (!allCrossSigningSecretsCached) {
// cross signing ready & device trusted, but we are missing secrets from our local cached.
// prompt the user to enter their recovery key.
showSetupEncryptionToast(SetupKind.KEY_STORAGE_OUT_OF_SYNC);
} else if ((await cli.secretStorage.getDefaultKeyId()) === null) {
// the user just hasn't set up 4S yet: prompt them to do so
showSetupEncryptionToast(SetupKind.SET_UP_RECOVERY);
} else {
const backupInfo = await this.getKeyBackupInfo();
if (backupInfo) {
// Toast 2: Key backup is enabled but recovery (4S) is not set up: prompt user to set up recovery.
// Since we now enable key backup at registration time, this will be the common case for
// new users.
showSetupEncryptionToast(SetupKind.SET_UP_RECOVERY);
} else {
// Toast 3: No cross-signing or key backup on account (set up encryption)
await cli.waitForClientWellKnown();
if (isSecureBackupRequired(cli) && isLoggedIn()) {
// If we're meant to set up, and Secure Backup is required,
// trigger the flow directly without a toast once logged in.
hideSetupEncryptionToast();
accessSecretStorage();
} else {
showSetupEncryptionToast(SetupKind.SET_UP_ENCRYPTION);
}
}
// some other condition... yikes!
}
}
@ -334,12 +337,6 @@ export default class DeviceListener {
// Unverified devices that have appeared since then
const newUnverifiedDeviceIds = new Set<string>();
const isCurrentDeviceTrusted =
crossSigningReady &&
Boolean(
(await crypto.getDeviceVerificationStatus(cli.getSafeUserId(), cli.deviceId!))?.crossSigningVerified,
);
// as long as cross-signing isn't ready,
// you can't see or dismiss any device toasts
if (crossSigningReady) {

View File

@ -882,14 +882,18 @@
"title": "Destroy cross-signing keys?",
"warning": "Deleting cross-signing keys is permanent. Anyone you have verified with will see security alerts. You almost certainly don't want to do this, unless you've lost every device you can cross-sign from."
},
"enter_recovery_key": "Enter recovery key",
"event_shield_reason_authenticity_not_guaranteed": "The authenticity of this encrypted message can't be guaranteed on this device.",
"event_shield_reason_mismatched_sender_key": "Encrypted by an unverified session",
"event_shield_reason_unknown_device": "Encrypted by an unknown or deleted device.",
"event_shield_reason_unsigned_device": "Encrypted by a device not verified by its owner.",
"event_shield_reason_unverified_identity": "Encrypted by an unverified user.",
"export_unsupported": "Your browser does not support the required cryptography extensions",
"forgot_recovery_key": "Forgot recovery key?",
"import_invalid_keyfile": "Not a valid %(brand)s keyfile",
"import_invalid_passphrase": "Authentication check failed: incorrect password?",
"key_storage_out_of_sync": "Your key storage is out of sync.",
"key_storage_out_of_sync_description": "Confirm your recovery key to maintain access to your key storage and message history.",
"messages_not_secure": {
"cause_1": "Your homeserver",
"cause_2": "The homeserver the user you're verifying is connected to",

View File

@ -27,6 +27,8 @@ const getTitle = (kind: Kind): string => {
return _t("encryption|set_up_recovery");
case Kind.VERIFY_THIS_SESSION:
return _t("encryption|verify_toast_title");
case Kind.KEY_STORAGE_OUT_OF_SYNC:
return _t("encryption|key_storage_out_of_sync");
}
};
@ -49,6 +51,8 @@ const getSetupCaption = (kind: Kind): string => {
return _t("action|continue");
case Kind.VERIFY_THIS_SESSION:
return _t("action|verify");
case Kind.KEY_STORAGE_OUT_OF_SYNC:
return _t("encryption|enter_recovery_key");
}
};
@ -59,6 +63,8 @@ const getSecondaryButtonLabel = (kind: Kind): string => {
case Kind.SET_UP_ENCRYPTION:
case Kind.VERIFY_THIS_SESSION:
return _t("encryption|verification|unverified_sessions_toast_reject");
case Kind.KEY_STORAGE_OUT_OF_SYNC:
return _t("encryption|forgot_recovery_key");
}
};
@ -70,6 +76,8 @@ const getDescription = (kind: Kind): string => {
return _t("encryption|set_up_recovery_toast_description");
case Kind.VERIFY_THIS_SESSION:
return _t("encryption|verify_toast_description");
case Kind.KEY_STORAGE_OUT_OF_SYNC:
return _t("encryption|key_storage_out_of_sync_description");
}
};
@ -89,6 +97,10 @@ export enum Kind {
* Prompt the user to verify this session
*/
VERIFY_THIS_SESSION = "verify_this_session",
/**
* Prompt the user to enter their recovery key
*/
KEY_STORAGE_OUT_OF_SYNC = "key_storage_out_of_sync",
}
const onReject = (): void => {