Perform zk check in check job.

This commit is contained in:
Alex Hart
2025-08-08 15:33:32 -03:00
committed by Greyson Parrelli
parent 75df8c0e2a
commit 308f4c817f
2 changed files with 51 additions and 4 deletions

View File

@@ -1425,9 +1425,33 @@ object BackupRepository {
}
}
/**
* Grabs the backup tier we think the user is on without performing any kind of authentication clearing
* on a 403 error. Ensures we can check without rolling the user back during the BackupSubscriptionCheckJob.
*/
fun getBackupTierWithoutDowngrade(): NetworkResult<MessageBackupTier> {
return if (SignalStore.backup.areBackupsEnabled) {
getArchiveServiceAccessPair()
.then { credential ->
val zkCredential = SignalNetwork.archive.getZkCredential(Recipient.self().requireAci(), credential.messageBackupAccess)
val tier = if (zkCredential.backupLevel == BackupLevel.PAID) {
MessageBackupTier.PAID
} else {
MessageBackupTier.FREE
}
NetworkResult.Success(tier)
}
} else {
NetworkResult.StatusCodeError(NonSuccessfulResponseCodeException(404))
}
}
/**
* If backups are enabled, sync with the network. Otherwise, return a 404.
* Used in instrumentation tests.
*
* Note that this will set the user's backup tier to FREE if they are not on PAID, so avoid this method if you don't intend that to be the case.
*/
fun getBackupTier(): NetworkResult<MessageBackupTier> {
return if (SignalStore.backup.areBackupsEnabled) {

View File

@@ -29,6 +29,7 @@ import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.net.SignalNetwork
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.RemoteConfig
import org.whispersystems.signalservice.api.NetworkResult
import org.whispersystems.signalservice.api.storage.IAPSubscriptionId
import org.whispersystems.signalservice.api.subscriptions.ActiveSubscription
import org.whispersystems.signalservice.internal.push.SubscriptionsConfiguration
@@ -139,10 +140,7 @@ class BackupSubscriptionCheckJob private constructor(parameters: Parameters) : C
val isSignalSubscriptionFailedOrCanceled = activeSubscription?.isFailedPayment == true || activeSubscription?.isCanceled == true
if (hasActiveSignalSubscription && !isSignalSubscriptionFailedOrCanceled) {
Log.i(TAG, "Detected an active, non-failed, non-canceled signal subscription. Synchronizing backup tier with value from server.", true)
BackupRepository.getBackupTier().runIfSuccessful {
SignalStore.backup.backupTier = it
}
checkAndSynchronizeZkCredentialTierWithStoredLocalTier()
}
val hasActivePaidBackupTier = SignalStore.backup.backupTier == MessageBackupTier.PAID
@@ -188,6 +186,31 @@ class BackupSubscriptionCheckJob private constructor(parameters: Parameters) : C
}
}
/**
* If we detect that we have an active subscription, we want to check to make sure our ZK credentials are good. If they aren't, we should clear them.
* This will also synchronize our backup tier value with whatever the refreshed Zk tier thinks we are on, if necessary.
*/
private fun checkAndSynchronizeZkCredentialTierWithStoredLocalTier() {
Log.i(TAG, "Detected an active, non-failed, non-canceled signal subscription. Synchronizing backup tier with value from server.", true)
val zkTier: MessageBackupTier? = when (val result = BackupRepository.getBackupTierWithoutDowngrade()) {
is NetworkResult.Success -> result.result
else -> null
}
if (zkTier == SignalStore.backup.backupTier) {
Log.i(TAG, "ZK credential tier is in sync with our stored backup tier.", true)
} else {
Log.w(TAG, "ZK credential tier is not in sync with our stored backup tier, flushing credentials and retrying.", true)
BackupRepository.resetInitializedStateAndAuthCredentials()
BackupRepository.getBackupTier().runIfSuccessful {
Log.i(TAG, "Refreshed credentials. Synchronizing stored backup tier with ZK result.")
SignalStore.backup.backupTier = it
}
}
}
/**
* Checks for a payment failure / subscription cancellation. If either of these things occur, we will mark when to display
* the "download your data" notifier sheet.