Simplify DeviceListener recheck logic using a failedCheck method (#32982)

* Extract the logic for a failed recheck into a method

This will allow us to simplify the logic that calls it.

* Remove unneeded log items

These are already known at the time of logging due to the surrounding
logic.

* Remove now-unneeded initial 'all is ok' check in DeviceListener
This commit is contained in:
Andy Balaam
2026-05-22 22:10:13 +00:00
committed by GitHub
parent 53631faffc
commit db92f80e90
@@ -180,64 +180,45 @@ export class DeviceListenerCurrentDevice {
const keyBackupDownloadIsOk = const keyBackupDownloadIsOk =
!keyBackupUploadActive || backupDisabled || (await crypto.getSessionBackupPrivateKey()) !== null; !keyBackupUploadActive || backupDisabled || (await crypto.getSessionBackupPrivateKey()) !== null;
const allSystemsReady =
isCurrentDeviceTrusted &&
allCrossSigningSecretsCached &&
keyBackupUploadIsOk &&
recoveryIsOk &&
keyBackupDownloadIsOk;
if (allSystemsReady) {
logSpan.info("No toast needed");
await this.setDeviceState("ok", logSpan);
} else {
// make sure our keys are finished downloading
await crypto.getUserDeviceInfo([this.client.getSafeUserId()]);
if (!isCurrentDeviceTrusted) { if (!isCurrentDeviceTrusted) {
// the current device is not trusted: prompt the user to verify // The current device is not trusted: prompt the user to verify
logSpan.info("Current device not verified: setting state to VERIFY_THIS_SESSION"); await this.failedCheck("verify_this_session", logSpan, "info", "Current device not verified");
await this.setDeviceState("verify_this_session", logSpan);
} else if (!allCrossSigningSecretsCached) { } else if (!allCrossSigningSecretsCached) {
// cross signing ready & device trusted, but we are missing secrets from our local cache. // cross signing ready & device trusted, but we are missing secrets from our local cache.
// prompt the user to enter their recovery key. // prompt the user to enter their recovery key.
logSpan.info( const newState = crossSigningStatus.privateKeysInSecretStorage
"Some secrets not cached: setting state to KEY_STORAGE_OUT_OF_SYNC", ? "key_storage_out_of_sync"
: "identity_needs_reset";
await this.failedCheck(
newState,
logSpan,
"info",
"Some secrets not cached",
crossSigningStatus.privateKeysCachedLocally, crossSigningStatus.privateKeysCachedLocally,
crossSigningStatus.privateKeysInSecretStorage, crossSigningStatus.privateKeysInSecretStorage,
); );
await this.setDeviceState(
crossSigningStatus.privateKeysInSecretStorage ? "key_storage_out_of_sync" : "identity_needs_reset",
logSpan,
);
} else if (!keyBackupUploadIsOk) { } else if (!keyBackupUploadIsOk) {
logSpan.info("Key backup upload is unexpectedly turned off: setting state to TURN_ON_KEY_STORAGE"); await this.failedCheck(
await this.setDeviceState("turn_on_key_storage", logSpan); "turn_on_key_storage",
logSpan,
"info",
"Key backup upload is unexpectedly turned off",
);
} else if (!recoveryIsOk) { } else if (!recoveryIsOk) {
if (secretStorageStatus.defaultKeyId === null) { if (secretStorageStatus.defaultKeyId === null) {
logSpan.info("No default 4S key: setting state to SET_UP_RECOVERY"); await this.failedCheck("set_up_recovery", logSpan, "info", "No default 4S key");
await this.setDeviceState("set_up_recovery", logSpan);
} else { } else {
logSpan.warn("4S is missing secrets: setting state to KEY_STORAGE_OUT_OF_SYNC", { await this.failedCheck("key_storage_out_of_sync", logSpan, "warn", "4S is missing secrets", {
secretStorageStatus, secretStorageStatus,
allCrossSigningSecretsCached,
isCurrentDeviceTrusted,
keyBackupDownloadIsOk,
}); });
await this.setDeviceState("key_storage_out_of_sync", logSpan);
} }
} else if (!keyBackupDownloadIsOk) { } else if (!keyBackupDownloadIsOk) {
logSpan.warn("Backup key is not cached locally: setting state to KEY_STORAGE_OUT_OF_SYNC", { await this.failedCheck("key_storage_out_of_sync", logSpan, "warn", "Backup key is not cached locally");
secretStorageStatus,
allCrossSigningSecretsCached,
isCurrentDeviceTrusted,
keyBackupDownloadIsOk,
});
await this.setDeviceState("key_storage_out_of_sync", logSpan);
} else { } else {
// We should not get here // Everything is OK - no need to show a toast
logSpan.error("DeviceListenerCurrentDevice: allSystemsReady was false, but no case matched."); logSpan.info("No toast needed");
} await this.setDeviceState("ok", logSpan);
} }
} }
@@ -250,6 +231,30 @@ export class DeviceListenerCurrentDevice {
return this.deviceState; return this.deviceState;
} }
/**
* recheck failed - update our local device keys, log a message and set the
* state to display to the user.
*/
private async failedCheck(
newState: DeviceState,
logSpan: LogSpan,
level: "info" | "warn",
message: string,
...logItems: Array<any>
): Promise<void> {
// Make sure our keys are finished downloading
await this.client.getCrypto()?.getUserDeviceInfo([this.client.getSafeUserId()]);
const fullMessage = `${message}: setting state to ${newState.toLowerCase()}`;
if (level === "info") {
logSpan.info(fullMessage, ...logItems);
} else {
logSpan.warn(fullMessage, ...logItems);
}
await this.setDeviceState(newState, logSpan);
}
/** /**
* Set the state of the device, and perform any actions necessary in * Set the state of the device, and perform any actions necessary in
* response to the state changing. * response to the state changing.