Fix linked device changing discoverability bug.

This commit is contained in:
Cody Henthorne
2026-07-17 15:56:53 -04:00
parent c50757880e
commit 9a8e0dd64f
4 changed files with 33 additions and 1 deletions
@@ -108,8 +108,10 @@ public class RefreshAttributesJob extends BaseJob {
if (SignalStore.account().isPrimaryDevice()) {
setPrimaryDeviceAttributes(svrValues, capabilities);
} else {
Log.i(TAG, "Linked device, refreshing device capabilities only. Capabilities: " + capabilities);
boolean phoneNumberDiscoverable = SignalStore.phoneNumberPrivacy().getPhoneNumberDiscoverabilityMode() == PhoneNumberDiscoverabilityMode.DISCOVERABLE;
Log.i(TAG, "Linked device, refreshing device capabilities and phone number discoverability. Capabilities: " + capabilities + ", discoverable: " + phoneNumberDiscoverable);
RequestResultUtil.successOrThrow(SignalNetwork.account().setCapabilities(capabilities));
RequestResultUtil.successOrThrow(SignalNetwork.account().setPhoneNumberDiscoverability(phoneNumberDiscoverable));
}
hasRefreshedThisAppCycle = true;
@@ -22,6 +22,7 @@ import org.thoughtcrime.securesms.database.model.KeyTransparencyStore
import org.thoughtcrime.securesms.database.model.RecipientRecord
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.dependencies.KeyTransparencyApi
import org.thoughtcrime.securesms.jobs.RefreshAttributesJob
import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob
import org.thoughtcrime.securesms.jobs.StorageSyncJob
import org.thoughtcrime.securesms.keyvalue.AccountValues
@@ -263,6 +264,11 @@ object StorageSyncHelper {
SignalStore.story.userHasSeenGroupStoryEducationSheet = update.new.proto.hasSeenGroupStoryEducationSheet
SignalStore.uiHints.setHasCompletedUsernameOnboarding(update.new.proto.hasCompletedUsernameOnboarding)
if (update.new.proto.unlistedPhoneNumber != update.old.proto.unlistedPhoneNumber && SignalStore.account.isPrimaryDevice) {
Log.i(TAG, "Phone number discoverability changed via storage service. Refreshing attributes to push the change to the server.")
AppDependencies.jobManager.add(RefreshAttributesJob())
}
if (SignalStore.settings.automaticVerificationEnabled && update.new.proto.automaticKeyVerificationDisabled) {
SignalDatabase.recipients.clearAllKeyTransparencyData()
}
@@ -22,6 +22,7 @@ import org.whispersystems.signalservice.api.websocket.SignalWebSocket
import org.whispersystems.signalservice.internal.push.ConfirmUsernameRequest
import org.whispersystems.signalservice.internal.push.ConfirmUsernameResponse
import org.whispersystems.signalservice.internal.push.GcmRegistrationId
import org.whispersystems.signalservice.internal.push.PhoneNumberDiscoverabilityRequest
import org.whispersystems.signalservice.internal.push.PushServiceSocket
import org.whispersystems.signalservice.internal.push.ReserveUsernameRequest
import org.whispersystems.signalservice.internal.push.ReserveUsernameResponse
@@ -90,6 +91,18 @@ class AccountApi(private val authWebSocket: SignalWebSocket.AuthenticatedWebSock
return authWebSocket.fromWebSocketRequest(request, Unit::class)
}
/**
* Set whether this account is discoverable by phone number. Unlike [setAccountAttributes], this
* dedicated endpoint can be called from a linked device.
*
* PUT /v2/accounts/phone_number_discoverability
* - 204: Success
*/
fun setPhoneNumberDiscoverability(discoverable: Boolean): RequestResult<Unit, RestStatusCodeError> {
val request = WebSocketRequestMessage.put("/v2/accounts/phone_number_discoverability", PhoneNumberDiscoverabilityRequest(discoverable))
return authWebSocket.fromWebSocketRequest(request, Unit::class)
}
/**
* PUT /v1/accounts/registration_lock
* - 204: Success
@@ -0,0 +1,11 @@
/*
* Copyright 2026 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.signalservice.internal.push
import com.fasterxml.jackson.annotation.JsonProperty
data class PhoneNumberDiscoverabilityRequest(
@JsonProperty val discoverableByPhoneNumber: Boolean
)