From c93457402c37b5bd8e98db9b2c49805a25143a45 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Mon, 6 Dec 2021 12:18:42 -0500 Subject: [PATCH] Store your own PNI. --- .../InternalConversationSettingsFragment.kt | 16 ++- .../securesms/database/RecipientDatabase.kt | 17 +++- .../helpers/SignalDatabaseMigrations.kt | 8 +- .../database/model/RecipientRecord.kt | 2 + .../securesms/jobs/JobManagerFactories.java | 2 + .../migrations/ApplicationMigrations.java | 7 +- .../securesms/migrations/PniMigrationJob.java | 74 ++++++++++++++ .../migrations/UuidMigrationJob.java | 6 +- .../securesms/recipients/Recipient.java | 14 ++- .../recipients/RecipientDetails.java | 98 ++++++++++--------- .../registration/RegistrationRepository.java | 4 + .../database/RecipientDatabaseTestUtils.kt | 1 + .../api/SignalServiceAccountManager.java | 4 - .../signalservice/api/push/ACI.java | 4 +- .../signalservice/api/push/PNI.java | 9 ++ .../internal/push/PushServiceSocket.java | 14 +-- .../internal/push/VerifyAccountResponse.java | 7 ++ 17 files changed, 208 insertions(+), 79 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/migrations/PniMigrationJob.java diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/InternalConversationSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/InternalConversationSettingsFragment.kt index 7594e8456..c9fd5d17b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/InternalConversationSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/InternalConversationSettingsFragment.kt @@ -27,6 +27,7 @@ import org.thoughtcrime.securesms.util.SpanUtil import org.thoughtcrime.securesms.util.Util import org.thoughtcrime.securesms.util.livedata.Store import org.whispersystems.signalservice.api.push.ACI +import org.whispersystems.signalservice.api.push.PNI import java.util.Objects /** @@ -60,11 +61,18 @@ class InternalConversationSettingsFragment : DSLSettingsFragment( ) if (!recipient.isGroup) { - val uuid = recipient.aci.transform(ACI::toString).or("null") + val aci = recipient.aci.transform(ACI::toString).or("null") longClickPref( - title = DSLSettingsText.from("UUID"), - summary = DSLSettingsText.from(uuid), - onLongClick = { copyToClipboard(uuid) } + title = DSLSettingsText.from("ACI"), + summary = DSLSettingsText.from(aci), + onLongClick = { copyToClipboard(aci) } + ) + + val pni = recipient.pni.transform(PNI::toString).or("null") + longClickPref( + title = DSLSettingsText.from("PNI"), + summary = DSLSettingsText.from(pni), + onLongClick = { copyToClipboard(pni) } ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.kt index f5bd8d0c7..0bfa3e456 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.kt @@ -77,6 +77,7 @@ import org.whispersystems.libsignal.util.Pair import org.whispersystems.libsignal.util.guava.Optional import org.whispersystems.signalservice.api.profiles.SignalServiceProfile import org.whispersystems.signalservice.api.push.ACI +import org.whispersystems.signalservice.api.push.PNI import org.whispersystems.signalservice.api.push.SignalServiceAddress import org.whispersystems.signalservice.api.storage.SignalAccountRecord import org.whispersystems.signalservice.api.storage.SignalContactRecord @@ -108,6 +109,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) : const val ID = "_id" private const val ACI_COLUMN = "uuid" + private const val PNI_COLUMN = "pni" private const val USERNAME = "username" const val PHONE = "phone" const val EMAIL = "email" @@ -216,17 +218,20 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) : $GROUPS_IN_COMMON INTEGER DEFAULT 0, $CHAT_COLORS BLOB DEFAULT NULL, $CUSTOM_CHAT_COLORS_ID INTEGER DEFAULT 0, - $BADGES BLOB DEFAULT NULL + $BADGES BLOB DEFAULT NULL, + $PNI_COLUMN TEXT DEFAULT NULL ) """.trimIndent() val CREATE_INDEXS = arrayOf( - "CREATE INDEX IF NOT EXISTS recipient_group_type_index ON $TABLE_NAME ($GROUP_TYPE);" + "CREATE INDEX IF NOT EXISTS recipient_group_type_index ON $TABLE_NAME ($GROUP_TYPE);", + "CREATE UNIQUE INDEX IF NOT EXISTS recipient_pni_index ON $TABLE_NAME ($PNI_COLUMN)" ) private val RECIPIENT_PROJECTION: Array = arrayOf( ID, ACI_COLUMN, + PNI_COLUMN, USERNAME, PHONE, EMAIL, @@ -1807,6 +1812,13 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) : return results } + fun setPni(id: RecipientId, pni: PNI) { + val values = ContentValues().apply { + put(PNI_COLUMN, pni.toString()) + } + writableDatabase.update(TABLE_NAME, values, ID_WHERE, SqlUtil.buildArgs(id)) + } + /** * @return True if setting the UUID resulted in changed recipientId, otherwise false. */ @@ -2777,6 +2789,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) : return RecipientRecord( id = recipientId, aci = ACI.parseOrNull(cursor.requireString(ACI_COLUMN)), + pni = PNI.parseOrNull(cursor.requireString(PNI_COLUMN)), username = cursor.requireString(USERNAME), e164 = cursor.requireString(PHONE), email = cursor.requireString(EMAIL), diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt index e311182b3..da6bab14e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt @@ -178,8 +178,9 @@ object SignalDatabaseMigrations { private const val SENDER_KEY_UUID = 119 private const val SENDER_KEY_SHARED_TIMESTAMP = 120 private const val REACTION_REFACTOR = 121 + private const val PNI = 122 - const val DATABASE_VERSION = 121 + const val DATABASE_VERSION = 122 @JvmStatic fun migrate(context: Context, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { @@ -2170,6 +2171,11 @@ object SignalDatabaseMigrations { db.execSQL("UPDATE sms SET reactions = NULL WHERE reactions NOT NULL") db.execSQL("UPDATE mms SET reactions = NULL WHERE reactions NOT NULL") } + + if (oldVersion < PNI) { + db.execSQL("ALTER TABLE recipient ADD COLUMN pni TEXT DEFAULT NULL") + db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS recipient_pni_index ON recipient (pni)") + } } @JvmStatic diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/RecipientRecord.kt b/app/src/main/java/org/thoughtcrime/securesms/database/model/RecipientRecord.kt index 536d550a4..839c34d5c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/RecipientRecord.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/RecipientRecord.kt @@ -21,6 +21,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.wallpaper.ChatWallpaper import org.whispersystems.libsignal.util.guava.Optional import org.whispersystems.signalservice.api.push.ACI +import org.whispersystems.signalservice.api.push.PNI /** * Database model for [RecipientDatabase]. @@ -28,6 +29,7 @@ import org.whispersystems.signalservice.api.push.ACI data class RecipientRecord( val id: RecipientId, val aci: ACI?, + val pni: PNI?, val username: String?, val e164: String?, val email: String?, diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java index d93f2e04b..977e7f4ad 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -47,6 +47,7 @@ import org.thoughtcrime.securesms.migrations.MigrationCompleteJob; import org.thoughtcrime.securesms.migrations.PassingMigrationJob; import org.thoughtcrime.securesms.migrations.PinOptOutMigration; import org.thoughtcrime.securesms.migrations.PinReminderMigrationJob; +import org.thoughtcrime.securesms.migrations.PniMigrationJob; import org.thoughtcrime.securesms.migrations.ProfileMigrationJob; import org.thoughtcrime.securesms.migrations.ProfileSharingUpdateMigrationJob; import org.thoughtcrime.securesms.migrations.RecipientSearchMigrationJob; @@ -191,6 +192,7 @@ public final class JobManagerFactories { put(MigrationCompleteJob.KEY, new MigrationCompleteJob.Factory()); put(PinOptOutMigration.KEY, new PinOptOutMigration.Factory()); put(PinReminderMigrationJob.KEY, new PinReminderMigrationJob.Factory()); + put(PniMigrationJob.KEY, new PniMigrationJob.Factory()); put(ProfileMigrationJob.KEY, new ProfileMigrationJob.Factory()); put(ProfileSharingUpdateMigrationJob.KEY, new ProfileSharingUpdateMigrationJob.Factory()); put(RecipientSearchMigrationJob.KEY, new RecipientSearchMigrationJob.Factory()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java index 05663811d..8c5e3c3c6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java @@ -91,9 +91,10 @@ public class ApplicationMigrations { static final int DEFAULT_REACTIONS_SYNC = 47; static final int DB_REACTIONS_MIGRATION = 48; //static final int CHANGE_NUMBER_CAPABILITY_3 = 49; + static final int PNI = 50; } - public static final int CURRENT_VERSION = 49; + public static final int CURRENT_VERSION = 50; /** * This *must* be called after the {@link JobManager} has been instantiated, but *before* the call @@ -395,6 +396,10 @@ public class ApplicationMigrations { jobs.put(Version.DB_REACTIONS_MIGRATION, new DatabaseMigrationJob()); } + if (lastSeenVersion < Version.PNI) { + jobs.put(Version.PNI, new PniMigrationJob()); + } + return jobs; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/PniMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/PniMigrationJob.java new file mode 100644 index 000000000..3cc674b05 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/PniMigrationJob.java @@ -0,0 +1,74 @@ +package org.thoughtcrime.securesms.migrations; + +import androidx.annotation.NonNull; + +import org.signal.core.util.logging.Log; +import org.thoughtcrime.securesms.database.SignalDatabase; +import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; +import org.thoughtcrime.securesms.jobmanager.Data; +import org.thoughtcrime.securesms.jobmanager.Job; +import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; +import org.thoughtcrime.securesms.keyvalue.SignalStore; +import org.thoughtcrime.securesms.recipients.Recipient; +import org.thoughtcrime.securesms.recipients.RecipientId; +import org.whispersystems.signalservice.api.push.PNI; + +import java.io.IOException; + +/** + * Migration to fetch our own PNI from the service. + */ +public class PniMigrationJob extends MigrationJob { + + public static final String KEY = "PniMigrationJob"; + + private static final String TAG = Log.tag(PniMigrationJob.class); + + PniMigrationJob() { + this(new Parameters.Builder().addConstraint(NetworkConstraint.KEY).build()); + } + + private PniMigrationJob(@NonNull Parameters parameters) { + super(parameters); + } + + @Override + public @NonNull String getFactoryKey() { + return KEY; + } + + @Override + boolean isUiBlocking() { + return false; + } + + @Override + void performMigration() throws Exception { + if (!SignalStore.account().isRegistered() || SignalStore.account().getAci() == null) { + Log.w(TAG, "Not registered! Skipping migration, as it wouldn't do anything."); + return; + } + + RecipientId self = Recipient.self().getId(); + PNI pni = PNI.parseOrNull(ApplicationDependencies.getSignalServiceAccountManager().getWhoAmI().getPni()); + + if (pni == null) { + throw new IOException("Invalid PNI!"); + } + + SignalDatabase.recipients().setPni(self, pni); + SignalStore.account().setPni(pni); + } + + @Override + boolean shouldRetry(@NonNull Exception e) { + return e instanceof IOException; + } + + public static class Factory implements Job.Factory { + @Override + public @NonNull PniMigrationJob create(@NonNull Parameters parameters, @NonNull Data data) { + return new PniMigrationJob(parameters); + } + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/UuidMigrationJob.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/UuidMigrationJob.java index f3cc69a28..dadcc40b4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/UuidMigrationJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/UuidMigrationJob.java @@ -71,7 +71,11 @@ public class UuidMigrationJob extends MigrationJob { private static void fetchOwnUuid(@NonNull Context context) throws IOException { RecipientId self = Recipient.self().getId(); - ACI localUuid = ApplicationDependencies.getSignalServiceAccountManager().getOwnAci(); + ACI localUuid = ACI.parseOrNull(ApplicationDependencies.getSignalServiceAccountManager().getWhoAmI().getAci()); + + if (localUuid == null) { + throw new IOException("Invalid UUID!"); + } SignalDatabase.recipients().markRegisteredOrThrow(self, localUuid); SignalStore.account().setAci(localUuid); diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java index d9456c02b..cdaa31dce 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java @@ -49,6 +49,7 @@ import org.thoughtcrime.securesms.wallpaper.ChatWallpaper; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.libsignal.util.guava.Preconditions; import org.whispersystems.signalservice.api.push.ACI; +import org.whispersystems.signalservice.api.push.PNI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.util.UuidUtil; @@ -78,6 +79,7 @@ public class Recipient { private final RecipientId id; private final boolean resolving; private final ACI aci; + private final PNI pni; private final String username; private final String e164; private final String email; @@ -329,9 +331,10 @@ public class Recipient { Recipient(@NonNull RecipientId id) { this.id = id; - this.resolving = true; - this.aci = null; - this.username = null; + this.resolving = true; + this.aci = null; + this.pni = null; + this.username = null; this.e164 = null; this.email = null; this.groupId = null; @@ -385,6 +388,7 @@ public class Recipient { this.id = id; this.resolving = !resolved; this.aci = details.aci; + this.pni = details.pni; this.username = details.username; this.e164 = details.e164; this.email = details.email; @@ -607,6 +611,10 @@ public class Recipient { return Optional.fromNullable(aci); } + public @NonNull Optional getPni() { + return Optional.fromNullable(pni); + } + public @NonNull Optional getUsername() { if (FeatureFlags.usernames()) { return Optional.fromNullable(username); diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java index 22db549da..dd480da9b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientDetails.java @@ -24,6 +24,7 @@ import org.thoughtcrime.securesms.util.Util; import org.thoughtcrime.securesms.wallpaper.ChatWallpaper; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.push.ACI; +import org.whispersystems.signalservice.api.push.PNI; import java.util.Collections; import java.util.LinkedList; @@ -32,6 +33,7 @@ import java.util.List; public class RecipientDetails { final ACI aci; + final PNI pni; final String username; final String e164; final String email; @@ -88,59 +90,60 @@ public class RecipientDetails { boolean systemContact, boolean isSelf, @NonNull RegisteredState registeredState, - @NonNull RecipientRecord settings, + @NonNull RecipientRecord record, @Nullable List participants) { this.groupAvatarId = groupAvatarId; - this.systemContactPhoto = Util.uri(settings.getSystemContactPhotoUri()); - this.customLabel = settings.getSystemPhoneLabel(); - this.contactUri = Util.uri(settings.getSystemContactUri()); - this.aci = settings.getAci(); - this.username = settings.getUsername(); - this.e164 = settings.getE164(); - this.email = settings.getEmail(); - this.groupId = settings.getGroupId(); - this.messageRingtone = settings.getMessageRingtone(); - this.callRingtone = settings.getCallRingtone(); - this.mutedUntil = settings.getMuteUntil(); - this.messageVibrateState = settings.getMessageVibrateState(); - this.callVibrateState = settings.getCallVibrateState(); - this.blocked = settings.isBlocked(); - this.expireMessages = settings.getExpireMessages(); + this.systemContactPhoto = Util.uri(record.getSystemContactPhotoUri()); + this.customLabel = record.getSystemPhoneLabel(); + this.contactUri = Util.uri(record.getSystemContactUri()); + this.aci = record.getAci(); + this.pni = record.getPni(); + this.username = record.getUsername(); + this.e164 = record.getE164(); + this.email = record.getEmail(); + this.groupId = record.getGroupId(); + this.messageRingtone = record.getMessageRingtone(); + this.callRingtone = record.getCallRingtone(); + this.mutedUntil = record.getMuteUntil(); + this.messageVibrateState = record.getMessageVibrateState(); + this.callVibrateState = record.getCallVibrateState(); + this.blocked = record.isBlocked(); + this.expireMessages = record.getExpireMessages(); this.participants = participants == null ? new LinkedList<>() : participants; - this.profileName = settings.getProfileName(); - this.defaultSubscriptionId = settings.getDefaultSubscriptionId(); + this.profileName = record.getProfileName(); + this.defaultSubscriptionId = record.getDefaultSubscriptionId(); this.registered = registeredState; - this.profileKey = settings.getProfileKey(); - this.profileKeyCredential = settings.getProfileKeyCredential(); - this.profileAvatar = settings.getProfileAvatar(); - this.hasProfileImage = settings.hasProfileImage(); - this.profileSharing = settings.isProfileSharing(); - this.lastProfileFetch = settings.getLastProfileFetch(); + this.profileKey = record.getProfileKey(); + this.profileKeyCredential = record.getProfileKeyCredential(); + this.profileAvatar = record.getProfileAvatar(); + this.hasProfileImage = record.hasProfileImage(); + this.profileSharing = record.isProfileSharing(); + this.lastProfileFetch = record.getLastProfileFetch(); this.systemContact = systemContact; this.isSelf = isSelf; - this.notificationChannel = settings.getNotificationChannel(); - this.unidentifiedAccessMode = settings.getUnidentifiedAccessMode(); - this.forceSmsSelection = settings.isForceSmsSelection(); - this.groupsV2Capability = settings.getGroupsV2Capability(); - this.groupsV1MigrationCapability = settings.getGroupsV1MigrationCapability(); - this.senderKeyCapability = settings.getSenderKeyCapability(); - this.announcementGroupCapability = settings.getAnnouncementGroupCapability(); - this.changeNumberCapability = settings.getChangeNumberCapability(); - this.insightsBannerTier = settings.getInsightsBannerTier(); - this.storageId = settings.getStorageId(); - this.mentionSetting = settings.getMentionSetting(); - this.wallpaper = settings.getWallpaper(); - this.chatColors = settings.getChatColors(); - this.avatarColor = settings.getAvatarColor(); - this.about = settings.getAbout(); - this.aboutEmoji = settings.getAboutEmoji(); - this.systemProfileName = settings.getSystemProfileName(); + this.notificationChannel = record.getNotificationChannel(); + this.unidentifiedAccessMode = record.getUnidentifiedAccessMode(); + this.forceSmsSelection = record.isForceSmsSelection(); + this.groupsV2Capability = record.getGroupsV2Capability(); + this.groupsV1MigrationCapability = record.getGroupsV1MigrationCapability(); + this.senderKeyCapability = record.getSenderKeyCapability(); + this.announcementGroupCapability = record.getAnnouncementGroupCapability(); + this.changeNumberCapability = record.getChangeNumberCapability(); + this.insightsBannerTier = record.getInsightsBannerTier(); + this.storageId = record.getStorageId(); + this.mentionSetting = record.getMentionSetting(); + this.wallpaper = record.getWallpaper(); + this.chatColors = record.getChatColors(); + this.avatarColor = record.getAvatarColor(); + this.about = record.getAbout(); + this.aboutEmoji = record.getAboutEmoji(); + this.systemProfileName = record.getSystemProfileName(); this.groupName = groupName; this.systemContactName = systemContactName; - this.extras = Optional.fromNullable(settings.getExtras()); - this.hasGroupsInCommon = settings.hasGroupsInCommon(); - this.badges = settings.getBadges(); + this.extras = Optional.fromNullable(record.getExtras()); + this.hasGroupsInCommon = record.hasGroupsInCommon(); + this.badges = record.getBadges(); } /** @@ -150,9 +153,10 @@ public class RecipientDetails { this.groupAvatarId = null; this.systemContactPhoto = null; this.customLabel = null; - this.contactUri = null; - this.aci = null; - this.username = null; + this.contactUri = null; + this.aci = null; + this.pni = null; + this.username = null; this.e164 = null; this.email = null; this.groupId = null; diff --git a/app/src/main/java/org/thoughtcrime/securesms/registration/RegistrationRepository.java b/app/src/main/java/org/thoughtcrime/securesms/registration/RegistrationRepository.java index 8b75d2fcc..7c9a15867 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/registration/RegistrationRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/registration/RegistrationRepository.java @@ -38,6 +38,7 @@ import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.KbsPinData; import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.push.ACI; +import org.whispersystems.signalservice.api.push.PNI; import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.internal.ServiceResponse; import org.whispersystems.signalservice.internal.push.VerifyAccountResponse; @@ -130,6 +131,7 @@ public final class RegistrationRepository { SenderKeyUtil.clearAllState(context); ACI aci = ACI.parseOrThrow(response.getUuid()); + PNI pni = PNI.parseOrThrow(response.getPni()); boolean hasPin = response.isStorageCapable(); IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(context); @@ -148,9 +150,11 @@ public final class RegistrationRepository { recipientDatabase.setProfileSharing(selfId, true); recipientDatabase.markRegisteredOrThrow(selfId, aci); + recipientDatabase.setPni(selfId, pni); SignalStore.account().setE164(registrationData.getE164()); SignalStore.account().setAci(aci); + SignalStore.account().setPni(pni); recipientDatabase.setProfileKey(selfId, registrationData.getProfileKey()); ApplicationDependencies.getRecipientCache().clearSelf(); diff --git a/app/src/test/java/org/thoughtcrime/securesms/database/RecipientDatabaseTestUtils.kt b/app/src/test/java/org/thoughtcrime/securesms/database/RecipientDatabaseTestUtils.kt index 1c2ba5fa1..8618a08d1 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/database/RecipientDatabaseTestUtils.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/database/RecipientDatabaseTestUtils.kt @@ -93,6 +93,7 @@ object RecipientDatabaseTestUtils { RecipientRecord( recipientId, aci, + null, username, e164, email, diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java index c656c9053..0bcf38728 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java @@ -176,10 +176,6 @@ public class SignalServiceAccountManager { this.pushServiceSocket.removeRegistrationLockV1(); } - public ACI getOwnAci() throws IOException { - return this.pushServiceSocket.getOwnAci(); - } - public WhoAmIResponse getWhoAmI() throws IOException { return this.pushServiceSocket.getWhoAmI(); } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/ACI.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/ACI.java index 2e4e27197..f6164ba84 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/ACI.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/ACI.java @@ -10,8 +10,6 @@ import java.util.List; import java.util.UUID; import java.util.stream.Collectors; -import io.reactivex.rxjava3.annotations.NonNull; - /** * An ACI is an "Account Identity". They're just UUIDs, but given multiple different things could be UUIDs, this wrapper exists to give us type safety around * this *specific type* of UUID. @@ -65,7 +63,7 @@ public final class ACI extends AccountIdentifier { return uuid != null ? uuid : UNKNOWN; } - public static List filterKnown(@NonNull Collection acis) { + public static List filterKnown(Collection acis) { return acis.stream().filter(aci -> !aci.equals(UNKNOWN)).collect(Collectors.toList()); } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/PNI.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/PNI.java index 11862ba12..9ce11caf6 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/PNI.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/PNI.java @@ -19,6 +19,10 @@ public final class PNI extends AccountIdentifier { return uuid != null ? from(uuid) : null; } + public static PNI parseOrThrow(String raw) { + return from(UUID.fromString(raw)); + } + private PNI(UUID uuid) { super(uuid); } @@ -36,4 +40,9 @@ public final class PNI extends AccountIdentifier { return false; } } + + @Override + public String toString() { + return uuid.toString(); + } } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java index 7cc5c9835..b99b31372 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java @@ -327,18 +327,6 @@ public class PushServiceSocket { makeServiceRequest(path, "GET", null, headers, new VerificationCodeResponseHandler()); } - public ACI getOwnAci() throws IOException { - String body = makeServiceRequest(WHO_AM_I, "GET", null); - WhoAmIResponse response = JsonUtil.fromJson(body, WhoAmIResponse.class); - Optional aci = ACI.parse(response.getAci()); - - if (aci.isPresent()) { - return aci.get(); - } else { - throw new IOException("Invalid UUID!"); - } - } - public WhoAmIResponse getWhoAmI() throws IOException { return JsonUtil.fromJson(makeServiceRequest(WHO_AM_I, "GET", null), WhoAmIResponse.class); } @@ -580,7 +568,7 @@ public class PushServiceSocket { signedPreKey.getKeyPair().getPublicKey(), signedPreKey.getSignature()); - makeServiceRequest(String.format(PREKEY_PATH, ""), "PUT", + String response = makeServiceRequest(String.format(PREKEY_PATH, ""), "PUT", JsonUtil.toJson(new PreKeyState(entities, signedPreKeyEntity, identityKey))); } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/VerifyAccountResponse.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/VerifyAccountResponse.java index 67867b2b7..b075d0e79 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/VerifyAccountResponse.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/VerifyAccountResponse.java @@ -6,6 +6,9 @@ public class VerifyAccountResponse { @JsonProperty private String uuid; + @JsonProperty + private String pni; + @JsonProperty private boolean storageCapable; @@ -16,4 +19,8 @@ public class VerifyAccountResponse { public boolean isStorageCapable() { return storageCapable; } + + public String getPni() { + return pni; + } }