"allDeclaredFields":true,
"allDeclaredMethods":true}
,
+{
+ "name":"com.google.protobuf.GeneratedMessageLite",
+ "fields":[{"name":"unknownFields"}]}
+,
{
"name":"com.google.protobuf.Internal$LongList",
"allDeclaredMethods":true}
"allDeclaredConstructors":true}
,
{
- "name":"org.asamk.signal.manager.configuration.ConfigurationStore$Storage",
+ "name":"org.asamk.signal.manager.api.PhoneNumberSharingMode",
+ "allDeclaredFields":true,
+ "queryAllDeclaredMethods":true}
+,
+{
+ "name":"org.asamk.signal.manager.storage.configuration.ConfigurationStore$Storage",
"allDeclaredFields":true,
"queryAllDeclaredMethods":true,
"queryAllDeclaredConstructors":true,
"methods":[
- {"name":"<init>","parameterTypes":["java.lang.Boolean","java.lang.Boolean","java.lang.Boolean","java.lang.Boolean"] },
+ {"name":"<init>","parameterTypes":["java.lang.Boolean","java.lang.Boolean","java.lang.Boolean","java.lang.Boolean","org.asamk.signal.manager.api.PhoneNumberSharingMode"] },
{"name":"linkPreviews","parameterTypes":[] },
+ {"name":"phoneNumberSharingMode","parameterTypes":[] },
{"name":"readReceipts","parameterTypes":[] },
{"name":"typingIndicators","parameterTypes":[] },
{"name":"unidentifiedDeliveryIndicators","parameterTypes":[] }
{"name":"metadata_"}
]}
,
+{
+ "name":"org.whispersystems.signalservice.internal.storage.protos.AccountRecord",
+ "allDeclaredFields":true}
+,
+{
+ "name":"org.whispersystems.signalservice.internal.storage.protos.AccountRecord$PinnedConversation",
+ "fields":[
+ {"name":"identifierCase_"},
+ {"name":"identifier_"}
+ ]}
+,
+{
+ "name":"org.whispersystems.signalservice.internal.storage.protos.AccountRecord$PinnedConversation$Contact",
+ "fields":[
+ {"name":"e164_"},
+ {"name":"uuid_"}
+ ]}
+,
+{
+ "name":"org.whispersystems.signalservice.internal.storage.protos.ContactRecord",
+ "allDeclaredFields":true}
+,
+{
+ "name":"org.whispersystems.signalservice.internal.storage.protos.GroupV2Record",
+ "allDeclaredFields":true}
+,
+{
+ "name":"org.whispersystems.signalservice.internal.storage.protos.ManifestRecord",
+ "fields":[
+ {"name":"identifiers_"},
+ {"name":"version_"}
+ ]}
+,
+{
+ "name":"org.whispersystems.signalservice.internal.storage.protos.ManifestRecord$Identifier",
+ "fields":[
+ {"name":"raw_"},
+ {"name":"type_"}
+ ]}
+,
+{
+ "name":"org.whispersystems.signalservice.internal.storage.protos.Payments",
+ "allDeclaredFields":true}
+,
+{
+ "name":"org.whispersystems.signalservice.internal.storage.protos.ReadOperation",
+ "fields":[{"name":"readKey_"}]}
+,
+{
+ "name":"org.whispersystems.signalservice.internal.storage.protos.StorageItem",
+ "fields":[
+ {"name":"key_"},
+ {"name":"value_"}
+ ]}
+,
+{
+ "name":"org.whispersystems.signalservice.internal.storage.protos.StorageItems",
+ "fields":[{"name":"items_"}]}
+,
+{
+ "name":"org.whispersystems.signalservice.internal.storage.protos.StorageManifest",
+ "fields":[
+ {"name":"value_"},
+ {"name":"version_"}
+ ]}
+,
+{
+ "name":"org.whispersystems.signalservice.internal.storage.protos.StorageRecord",
+ "fields":[
+ {"name":"recordCase_"},
+ {"name":"record_"}
+ ]}
+,
{
"name":"org.whispersystems.signalservice.internal.util.JsonUtil$AciDeserializer",
"methods":[{"name":"<init>","parameterTypes":[] }]}
--- /dev/null
+package org.asamk.signal.manager.api;
+
+public enum PhoneNumberSharingMode {
+ EVERYBODY,
+ CONTACTS,
+ NOBODY,
+}
import org.asamk.signal.manager.SignalDependencies;
import org.asamk.signal.manager.TrustLevel;
+import org.asamk.signal.manager.api.PhoneNumberSharingMode;
import org.asamk.signal.manager.groups.GroupId;
import org.asamk.signal.manager.storage.SignalAccount;
import org.asamk.signal.manager.storage.recipients.Contact;
import org.whispersystems.signalservice.api.storage.SignalStorageManifest;
import org.whispersystems.signalservice.api.storage.SignalStorageRecord;
import org.whispersystems.signalservice.api.storage.StorageId;
+import org.whispersystems.signalservice.internal.storage.protos.AccountRecord;
import org.whispersystems.signalservice.internal.storage.protos.ManifestRecord;
import java.io.IOException;
account.getConfigurationStore()
.setUnidentifiedDeliveryIndicators(accountRecord.isSealedSenderIndicatorsEnabled());
account.getConfigurationStore().setLinkPreviews(accountRecord.isLinkPreviewsEnabled());
+ if (accountRecord.getPhoneNumberSharingMode() != AccountRecord.PhoneNumberSharingMode.UNRECOGNIZED) {
+ account.getConfigurationStore()
+ .setPhoneNumberSharingMode(switch (accountRecord.getPhoneNumberSharingMode()) {
+ case EVERYBODY -> PhoneNumberSharingMode.EVERYBODY;
+ case NOBODY -> PhoneNumberSharingMode.NOBODY;
+ default -> PhoneNumberSharingMode.CONTACTS;
+ });
+ }
if (accountRecord.getProfileKey().isPresent()) {
ProfileKey profileKey;
package org.asamk.signal.manager.helper;
import org.asamk.signal.manager.SignalDependencies;
+import org.asamk.signal.manager.api.PhoneNumberSharingMode;
import org.asamk.signal.manager.storage.SignalAccount;
import org.asamk.signal.manager.storage.recipients.RecipientId;
import org.signal.libsignal.metadata.certificate.InvalidCertificateException;
this.profileProvider = profileProvider;
}
- private byte[] getSenderCertificate() {
- byte[] certificate;
+ private byte[] getSenderCertificateFor(final RecipientId recipientId) {
+ final var sharingMode = account.getConfigurationStore().getPhoneNumberSharingMode();
+ if (sharingMode == PhoneNumberSharingMode.EVERYBODY || (
+ sharingMode == PhoneNumberSharingMode.CONTACTS
+ && account.getContactStore().getContact(recipientId) != null
+ )) {
+ logger.debug("Using normal sender certificate for message to {}", recipientId);
+ return getSenderCertificate();
+ } else {
+ logger.debug("Using phone number privacy sender certificate for message to {}", recipientId);
+ return getSenderCertificateForPhoneNumberPrivacy();
+ }
+ }
+
+ private byte[] getSenderCertificateForPhoneNumberPrivacy() {
+ // TODO cache for a day
try {
- if (account.isPhoneNumberShared()) {
- certificate = dependencies.getAccountManager().getSenderCertificate();
- } else {
- certificate = dependencies.getAccountManager().getSenderCertificateForPhoneNumberPrivacy();
- }
+ return dependencies.getAccountManager().getSenderCertificateForPhoneNumberPrivacy();
} catch (IOException e) {
logger.warn("Failed to get sender certificate, ignoring: {}", e.getMessage());
return null;
}
+ }
+
+ private byte[] getSenderCertificate() {
// TODO cache for a day
- return certificate;
+ try {
+ return dependencies.getAccountManager().getSenderCertificate();
+ } catch (IOException e) {
+ logger.warn("Failed to get sender certificate, ignoring: {}", e.getMessage());
+ return null;
+ }
}
private byte[] getSelfUnidentifiedAccessKey() {
public Optional<UnidentifiedAccessPair> getAccessFor(RecipientId recipient) {
var recipientUnidentifiedAccessKey = getTargetUnidentifiedAccessKey(recipient);
var selfUnidentifiedAccessKey = getSelfUnidentifiedAccessKey();
- var selfUnidentifiedAccessCertificate = getSenderCertificate();
+ var selfUnidentifiedAccessCertificate = getSenderCertificateFor(recipient);
if (recipientUnidentifiedAccessKey == null
|| selfUnidentifiedAccessKey == null
import org.asamk.signal.manager.TrustLevel;
import org.asamk.signal.manager.api.Pair;
-import org.asamk.signal.manager.configuration.ConfigurationStore;
import org.asamk.signal.manager.groups.GroupId;
+import org.asamk.signal.manager.storage.configuration.ConfigurationStore;
import org.asamk.signal.manager.storage.contacts.ContactsStore;
import org.asamk.signal.manager.storage.contacts.LegacyJsonContactsStore;
import org.asamk.signal.manager.storage.groups.GroupInfoV1;
return true;
}
- public boolean isPhoneNumberShared() {
- // TODO make configurable
- return true;
- }
-
public void finishRegistration(final ACI aci, final MasterKey masterKey, final String pin) {
this.pinMasterKey = masterKey;
this.storageManifestVersion = -1;
-package org.asamk.signal.manager.configuration;
+package org.asamk.signal.manager.storage.configuration;
+
+import org.asamk.signal.manager.api.PhoneNumberSharingMode;
public class ConfigurationStore {
private Boolean unidentifiedDeliveryIndicators;
private Boolean typingIndicators;
private Boolean linkPreviews;
+ private PhoneNumberSharingMode phoneNumberSharingMode;
public ConfigurationStore(final Saver saver) {
this.saver = saver;
store.unidentifiedDeliveryIndicators = storage.unidentifiedDeliveryIndicators;
store.typingIndicators = storage.typingIndicators;
store.linkPreviews = storage.linkPreviews;
+ store.phoneNumberSharingMode = storage.phoneNumberSharingMode;
return store;
}
saver.save(toStorage());
}
+ public PhoneNumberSharingMode getPhoneNumberSharingMode() {
+ return phoneNumberSharingMode;
+ }
+
+ public void setPhoneNumberSharingMode(final PhoneNumberSharingMode phoneNumberSharingMode) {
+ this.phoneNumberSharingMode = phoneNumberSharingMode;
+ saver.save(toStorage());
+ }
+
private Storage toStorage() {
- return new Storage(readReceipts, unidentifiedDeliveryIndicators, typingIndicators, linkPreviews);
+ return new Storage(readReceipts,
+ unidentifiedDeliveryIndicators,
+ typingIndicators,
+ linkPreviews,
+ phoneNumberSharingMode);
}
public record Storage(
- Boolean readReceipts, Boolean unidentifiedDeliveryIndicators, Boolean typingIndicators, Boolean linkPreviews
+ Boolean readReceipts,
+ Boolean unidentifiedDeliveryIndicators,
+ Boolean typingIndicators,
+ Boolean linkPreviews,
+ PhoneNumberSharingMode phoneNumberSharingMode
) {}
public interface Saver {