1 package org
.asamk
.signal
.manager
.syncStorage
;
3 import org
.asamk
.signal
.manager
.api
.PhoneNumberSharingMode
;
4 import org
.asamk
.signal
.manager
.api
.TrustLevel
;
5 import org
.asamk
.signal
.manager
.storage
.configuration
.ConfigurationStore
;
6 import org
.asamk
.signal
.manager
.storage
.groups
.GroupInfoV1
;
7 import org
.asamk
.signal
.manager
.storage
.groups
.GroupInfoV2
;
8 import org
.asamk
.signal
.manager
.storage
.identities
.IdentityInfo
;
9 import org
.asamk
.signal
.manager
.storage
.recipients
.Recipient
;
10 import org
.whispersystems
.signalservice
.api
.push
.UsernameLinkComponents
;
11 import org
.whispersystems
.signalservice
.api
.storage
.SignalAccountRecord
;
12 import org
.whispersystems
.signalservice
.api
.storage
.SignalContactRecord
;
13 import org
.whispersystems
.signalservice
.api
.storage
.SignalGroupV1Record
;
14 import org
.whispersystems
.signalservice
.api
.storage
.SignalGroupV2Record
;
15 import org
.whispersystems
.signalservice
.api
.storage
.SignalStorageRecord
;
16 import org
.whispersystems
.signalservice
.api
.util
.UuidUtil
;
17 import org
.whispersystems
.signalservice
.internal
.storage
.protos
.AccountRecord
;
18 import org
.whispersystems
.signalservice
.internal
.storage
.protos
.AccountRecord
.UsernameLink
;
19 import org
.whispersystems
.signalservice
.internal
.storage
.protos
.ContactRecord
;
20 import org
.whispersystems
.signalservice
.internal
.storage
.protos
.ContactRecord
.IdentityState
;
22 import java
.util
.Optional
;
24 import okio
.ByteString
;
26 public final class StorageSyncModels
{
28 private StorageSyncModels() {
31 public static AccountRecord
.PhoneNumberSharingMode
localToRemote(PhoneNumberSharingMode phoneNumberPhoneNumberSharingMode
) {
32 return switch (phoneNumberPhoneNumberSharingMode
) {
33 case EVERYBODY
-> AccountRecord
.PhoneNumberSharingMode
.EVERYBODY
;
34 case CONTACTS
, NOBODY
-> AccountRecord
.PhoneNumberSharingMode
.NOBODY
;
38 public static PhoneNumberSharingMode
remoteToLocal(AccountRecord
.PhoneNumberSharingMode phoneNumberPhoneNumberSharingMode
) {
39 return switch (phoneNumberPhoneNumberSharingMode
) {
40 case EVERYBODY
-> PhoneNumberSharingMode
.EVERYBODY
;
41 case UNKNOWN
, NOBODY
-> PhoneNumberSharingMode
.NOBODY
;
45 public static SignalStorageRecord
localToRemoteRecord(
46 ConfigurationStore configStore
,
48 UsernameLinkComponents usernameLinkComponents
,
51 final var builder
= new SignalAccountRecord
.Builder(rawStorageId
, self
.getStorageRecord());
52 if (self
.getProfileKey() != null) {
53 builder
.setProfileKey(self
.getProfileKey().serialize());
55 if (self
.getProfile() != null) {
56 builder
.setGivenName(self
.getProfile().getGivenName())
57 .setFamilyName(self
.getProfile().getFamilyName())
58 .setAvatarUrlPath(self
.getProfile().getAvatarUrlPath());
60 builder
.setTypingIndicatorsEnabled(Optional
.ofNullable(configStore
.getTypingIndicators()).orElse(true))
61 .setReadReceiptsEnabled(Optional
.ofNullable(configStore
.getReadReceipts()).orElse(true))
62 .setSealedSenderIndicatorsEnabled(Optional
.ofNullable(configStore
.getUnidentifiedDeliveryIndicators())
64 .setLinkPreviewsEnabled(Optional
.ofNullable(configStore
.getLinkPreviews()).orElse(true))
65 .setUnlistedPhoneNumber(Optional
.ofNullable(configStore
.getPhoneNumberUnlisted()).orElse(false))
66 .setPhoneNumberSharingMode(localToRemote(Optional
.ofNullable(configStore
.getPhoneNumberSharingMode())
67 .orElse(PhoneNumberSharingMode
.EVERYBODY
)))
68 .setE164(self
.getAddress().number().orElse(""))
69 .setUsername(self
.getAddress().username().orElse(null));
70 if (usernameLinkComponents
!= null) {
71 final var linkColor
= configStore
.getUsernameLinkColor();
72 builder
.setUsernameLink(new UsernameLink
.Builder().entropy(ByteString
.of(usernameLinkComponents
.getEntropy()))
73 .serverId(UuidUtil
.toByteString(usernameLinkComponents
.getServerId()))
74 .color(linkColor
== null ? UsernameLink
.Color
.UNKNOWN
: UsernameLink
.Color
.valueOf(linkColor
))
78 return SignalStorageRecord
.forAccount(builder
.build());
81 public static SignalStorageRecord
localToRemoteRecord(
82 Recipient recipient
, IdentityInfo identity
, byte[] rawStorageId
84 final var address
= recipient
.getAddress();
85 final var builder
= new SignalContactRecord
.Builder(rawStorageId
,
86 address
.aci().orElse(null),
87 recipient
.getStorageRecord()).setE164(address
.number().orElse(null))
88 .setPni(address
.pni().orElse(null))
89 .setUsername(address
.username().orElse(null))
90 .setProfileKey(recipient
.getProfileKey() == null ?
null : recipient
.getProfileKey().serialize());
91 if (recipient
.getProfile() != null) {
92 builder
.setProfileGivenName(recipient
.getProfile().getGivenName())
93 .setProfileFamilyName(recipient
.getProfile().getFamilyName());
95 if (recipient
.getContact() != null) {
96 builder
.setSystemGivenName(recipient
.getContact().givenName())
97 .setSystemFamilyName(recipient
.getContact().familyName())
98 .setSystemNickname(recipient
.getContact().nickName())
99 .setBlocked(recipient
.getContact().isBlocked())
100 .setProfileSharingEnabled(recipient
.getContact().isProfileSharingEnabled())
101 .setMuteUntil(recipient
.getContact().muteUntil())
102 .setHideStory(recipient
.getContact().hideStory())
103 .setUnregisteredTimestamp(recipient
.getContact().unregisteredTimestamp() == null
105 : recipient
.getContact().unregisteredTimestamp())
106 .setArchived(recipient
.getContact().isArchived())
107 .setHidden(recipient
.getContact().isHidden());
109 if (identity
!= null) {
110 builder
.setIdentityKey(identity
.getIdentityKey().serialize())
111 .setIdentityState(localToRemote(identity
.getTrustLevel()));
113 return SignalStorageRecord
.forContact(builder
.build());
116 public static SignalStorageRecord
localToRemoteRecord(
117 GroupInfoV1 group
, byte[] rawStorageId
119 final var builder
= new SignalGroupV1Record
.Builder(rawStorageId
,
120 group
.getGroupId().serialize(),
121 group
.getStorageRecord());
122 builder
.setBlocked(group
.isBlocked());
123 builder
.setArchived(group
.archived
);
124 builder
.setProfileSharingEnabled(true);
125 return SignalStorageRecord
.forGroupV1(builder
.build());
128 public static SignalStorageRecord
localToRemoteRecord(
129 GroupInfoV2 group
, byte[] rawStorageId
131 final var builder
= new SignalGroupV2Record
.Builder(rawStorageId
,
132 group
.getMasterKey(),
133 group
.getStorageRecord());
134 builder
.setBlocked(group
.isBlocked());
135 builder
.setProfileSharingEnabled(group
.isProfileSharingEnabled());
136 return SignalStorageRecord
.forGroupV2(builder
.build());
139 public static TrustLevel
remoteToLocal(ContactRecord
.IdentityState identityState
) {
140 return switch (identityState
) {
141 case DEFAULT
-> TrustLevel
.TRUSTED_UNVERIFIED
;
142 case UNVERIFIED
-> TrustLevel
.UNTRUSTED
;
143 case VERIFIED
-> TrustLevel
.TRUSTED_VERIFIED
;
147 private static IdentityState
localToRemote(TrustLevel local
) {
148 return switch (local
) {
149 case TRUSTED_VERIFIED
-> IdentityState
.VERIFIED
;
150 case UNTRUSTED
-> IdentityState
.UNVERIFIED
;
151 default -> IdentityState
.DEFAULT
;