diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientTableTest_applyStorageSyncContactUpdate.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientTableTest_applyStorageSyncContactUpdate.kt index 0c208e2c29..9acfd64b5a 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientTableTest_applyStorageSyncContactUpdate.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/database/RecipientTableTest_applyStorageSyncContactUpdate.kt @@ -50,7 +50,7 @@ class RecipientTableTest_applyStorageSyncContactUpdate { // WHEN val oldVerifiedStatus: IdentityTable.VerifiedStatus = identities.getIdentityRecord(other.id).get().verifiedStatus - SignalDatabase.recipients.applyStorageSyncContactUpdate(update) + SignalDatabase.recipients.applyStorageSyncContactUpdate(update, true) val newVerifiedStatus: IdentityTable.VerifiedStatus = identities.getIdentityRecord(other.id).get().verifiedStatus // THEN diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientTable.kt index b2239c98f9..2817a9beaf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientTable.kt @@ -860,7 +860,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da } } - fun applyStorageSyncContactInsert(insert: SignalContactRecord) { + fun applyStorageSyncContactInsert(insert: SignalContactRecord, rotateProfileKeyOnBlock: Boolean): Boolean { val db = writableDatabase val threadDatabase = threads val values = getValuesForStorageContact(insert, true) @@ -877,6 +877,12 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da recipientId = RecipientId.from(id) } + val profileKeyRotated = if (insert.proto.blocked) { + RecipientUtil.updateProfileSharingAfterBlock(Recipient.resolved(recipientId), rotateProfileKeyOnBlock) + } else { + false + } + if (insert.proto.identityKey.isNotEmpty() && (insert.proto.signalAci != null || insert.proto.signalPni != null)) { try { val serviceId: ServiceId = insert.proto.signalAci ?: insert.proto.signalPni!! @@ -892,9 +898,11 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da } threadDatabase.applyStorageSyncUpdate(recipientId, insert) + + return profileKeyRotated } - fun applyStorageSyncContactUpdate(update: StorageRecordUpdate) { + fun applyStorageSyncContactUpdate(update: StorageRecordUpdate, rotateProfileKeyOnBlock: Boolean): Boolean { val db = writableDatabase val identityStore = AppDependencies.protocolStore.aci().identities() val values = getValuesForStorageContact(update.new, false) @@ -925,6 +933,12 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da db.update(TABLE_NAME, clearValues, ID_WHERE, SqlUtil.buildArgs(recipientId)) } + val profileKeyRotated = if (update.new.proto.blocked && !update.old.proto.blocked) { + RecipientUtil.updateProfileSharingAfterBlock(Recipient.resolved(recipientId), rotateProfileKeyOnBlock) + } else { + false + } + try { val oldIdentityRecord = identityStore.getIdentityRecord(recipientId) if (update.new.proto.identityKey.isNotEmpty() && update.new.proto.signalAci != null) { @@ -948,6 +962,8 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da threads.applyStorageSyncUpdate(recipientId, update.new) AppDependencies.databaseObserver.notifyRecipientChanged(recipientId) + + return profileKeyRotated } private fun resolvePotentialUsernameConflicts(username: String?, recipientId: RecipientId) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt index 2d051cf4b7..50523ba2a4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/SyncMessageProcessor.kt @@ -90,6 +90,7 @@ import org.thoughtcrime.securesms.payments.MobileCoinPublicAddress import org.thoughtcrime.securesms.ratelimit.RateLimitUtil import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.recipients.RecipientId +import org.thoughtcrime.securesms.recipients.RecipientUtil import org.thoughtcrime.securesms.service.webrtc.links.CallLinkCredentials import org.thoughtcrime.securesms.service.webrtc.links.CallLinkRoomId import org.thoughtcrime.securesms.service.webrtc.links.SignalCallLinkState @@ -1170,7 +1171,7 @@ object SyncMessageProcessor { } MessageRequestResponse.Type.BLOCK -> { SignalDatabase.recipients.setBlocked(recipient.id, true) - SignalDatabase.recipients.setProfileSharing(recipient.id, false) + RecipientUtil.updateProfileSharingAfterBlock(recipient, true) SignalDatabase.messages.insertMessageOutbox( message = OutgoingMessage.blockedMessage(recipient, System.currentTimeMillis(), TimeUnit.SECONDS.toMillis(recipient.expiresInSeconds.toLong())), threadId = threadId @@ -1178,7 +1179,7 @@ object SyncMessageProcessor { } MessageRequestResponse.Type.BLOCK_AND_DELETE -> { SignalDatabase.recipients.setBlocked(recipient.id, true) - SignalDatabase.recipients.setProfileSharing(recipient.id, false) + RecipientUtil.updateProfileSharingAfterBlock(recipient, true) if (threadId > 0) { SignalDatabase.threads.deleteConversation(threadId, syncThreadDelete = false) } @@ -1191,7 +1192,7 @@ object SyncMessageProcessor { } MessageRequestResponse.Type.BLOCK_AND_SPAM -> { SignalDatabase.recipients.setBlocked(recipient.id, true) - SignalDatabase.recipients.setProfileSharing(recipient.id, false) + RecipientUtil.updateProfileSharingAfterBlock(recipient, true) SignalDatabase.messages.insertMessageOutbox( message = OutgoingMessage.reportSpamMessage(recipient, System.currentTimeMillis(), TimeUnit.SECONDS.toMillis(recipient.expiresInSeconds.toLong())), threadId = threadId diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java index ab592705e1..1e6d47b4fd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java @@ -176,18 +176,30 @@ public class RecipientUtil { SignalDatabase.recipients().setBlocked(recipient.getId(), true); insertBlockedUpdate(recipient, SignalDatabase.threads().getOrCreateThreadIdFor(recipient)); - if (recipient.isSystemContact() || recipient.isProfileSharing() || isProfileSharedViaGroup(recipient)) { - SignalDatabase.recipients().setProfileSharing(recipient.getId(), false); - - AppDependencies.getJobManager().startChain(new RefreshOwnProfileJob()) - .then(new RotateProfileKeyJob()) - .enqueue(); - } + RecipientUtil.updateProfileSharingAfterBlock(recipient, true); AppDependencies.getJobManager().add(new MultiDeviceBlockedUpdateJob()); StorageSyncHelper.scheduleSyncForDataChange(); } + @WorkerThread + public static boolean updateProfileSharingAfterBlock(@NonNull Recipient recipient, boolean rotateProfileKeyOnBlock) { + if (recipient.isSystemContact() || recipient.isProfileSharing() || isProfileSharedViaGroup(recipient)) { + SignalDatabase.recipients().setProfileSharing(recipient.getId(), false); + + if (rotateProfileKeyOnBlock) { + Log.i(TAG, "Rotating profile key"); + AppDependencies.getJobManager().startChain(new RefreshOwnProfileJob()) + .then(new RotateProfileKeyJob()) + .enqueue(); + + return true; + } + } + + return false; + } + @WorkerThread public static void unblock(@NonNull Recipient recipient) { if (!isBlockable(recipient)) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.kt b/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.kt index 15d683be0c..a4f11f8663 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.kt @@ -48,6 +48,8 @@ class ContactRecordProcessor( } } + private var rotateProfileKeyOnBlock = true + constructor() : this( selfAci = SignalStore.account.aci, selfPni = SignalStore.account.pni, @@ -247,11 +249,17 @@ class ContactRecordProcessor( } override fun insertLocal(record: SignalContactRecord) { - recipientTable.applyStorageSyncContactInsert(record) + val profileKeyRotated = recipientTable.applyStorageSyncContactInsert(record, rotateProfileKeyOnBlock) + if (profileKeyRotated) { + rotateProfileKeyOnBlock = false + } } override fun updateLocal(update: StorageRecordUpdate) { - recipientTable.applyStorageSyncContactUpdate(update) + val profileKeyRotated = recipientTable.applyStorageSyncContactUpdate(update, rotateProfileKeyOnBlock) + if (profileKeyRotated) { + rotateProfileKeyOnBlock = false + } } override fun compare(lhs: SignalContactRecord, rhs: SignalContactRecord): Int {