mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 18:40:39 +00:00
Rotate profile key after blocking a contact/group
This commit is contained in:
parent
b1e56faab2
commit
cf1626ea31
12 changed files with 218 additions and 19 deletions
|
@ -694,27 +694,48 @@ class ManagerImpl implements Manager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final var recipientIds = context.getRecipientHelper().resolveRecipients(recipients);
|
final var recipientIds = context.getRecipientHelper().resolveRecipients(recipients);
|
||||||
|
final var selfRecipientId = account.getSelfRecipientId();
|
||||||
|
boolean shouldRotateProfileKey = false;
|
||||||
for (final var recipientId : recipientIds) {
|
for (final var recipientId : recipientIds) {
|
||||||
|
if (context.getContactHelper().isContactBlocked(recipientId) == blocked) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
context.getContactHelper().setContactBlocked(recipientId, blocked);
|
context.getContactHelper().setContactBlocked(recipientId, blocked);
|
||||||
|
// if we don't have a common group with the blocked contact we need to rotate the profile key
|
||||||
|
shouldRotateProfileKey = blocked && (
|
||||||
|
shouldRotateProfileKey || account.getGroupStore()
|
||||||
|
.getGroups()
|
||||||
|
.stream()
|
||||||
|
.noneMatch(g -> g.isMember(selfRecipientId) && g.isMember(recipientId))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (shouldRotateProfileKey) {
|
||||||
|
context.getProfileHelper().rotateProfileKey();
|
||||||
}
|
}
|
||||||
// TODO cycle our profile key, if we're not together in a group with recipient
|
|
||||||
context.getSyncHelper().sendBlockedList();
|
context.getSyncHelper().sendBlockedList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setGroupsBlocked(
|
public void setGroupsBlocked(
|
||||||
final Collection<GroupId> groupIds, final boolean blocked
|
final Collection<GroupId> groupIds, final boolean blocked
|
||||||
) throws GroupNotFoundException, NotMasterDeviceException {
|
) throws GroupNotFoundException, NotMasterDeviceException, IOException {
|
||||||
if (!account.isMasterDevice()) {
|
if (!account.isMasterDevice()) {
|
||||||
throw new NotMasterDeviceException();
|
throw new NotMasterDeviceException();
|
||||||
}
|
}
|
||||||
if (groupIds.size() == 0) {
|
if (groupIds.size() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
boolean shouldRotateProfileKey = false;
|
||||||
for (final var groupId : groupIds) {
|
for (final var groupId : groupIds) {
|
||||||
|
if (context.getGroupHelper().isGroupBlocked(groupId) == blocked) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
context.getGroupHelper().setGroupBlocked(groupId, blocked);
|
context.getGroupHelper().setGroupBlocked(groupId, blocked);
|
||||||
|
shouldRotateProfileKey = blocked;
|
||||||
|
}
|
||||||
|
if (shouldRotateProfileKey) {
|
||||||
|
context.getProfileHelper().rotateProfileKey();
|
||||||
}
|
}
|
||||||
// TODO cycle our profile key
|
|
||||||
context.getSyncHelper().sendBlockedList();
|
context.getSyncHelper().sendBlockedList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package org.asamk.signal.manager.actions;
|
||||||
|
|
||||||
|
import org.asamk.signal.manager.helper.Context;
|
||||||
|
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class SendProfileKeyAction implements HandleAction {
|
||||||
|
|
||||||
|
private final RecipientId recipientId;
|
||||||
|
|
||||||
|
public SendProfileKeyAction(final RecipientId recipientId) {
|
||||||
|
this.recipientId = recipientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Context context) throws Throwable {
|
||||||
|
context.getSendHelper().sendProfileKey(recipientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
final SendProfileKeyAction that = (SendProfileKeyAction) o;
|
||||||
|
return recipientId.equals(that.recipientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(recipientId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package org.asamk.signal.manager.actions;
|
||||||
|
|
||||||
|
import org.asamk.signal.manager.helper.Context;
|
||||||
|
|
||||||
|
public class UpdateAccountAttributesAction implements HandleAction {
|
||||||
|
|
||||||
|
private static final UpdateAccountAttributesAction INSTANCE = new UpdateAccountAttributesAction();
|
||||||
|
|
||||||
|
private UpdateAccountAttributesAction() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UpdateAccountAttributesAction create() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Context context) throws Throwable {
|
||||||
|
context.getAccountHelper().updateAccountAttributes();
|
||||||
|
}
|
||||||
|
}
|
|
@ -254,6 +254,24 @@ public class GroupHelper {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateGroupProfileKey(GroupIdV2 groupId) throws GroupNotFoundException, NotAGroupMemberException, IOException {
|
||||||
|
var group = getGroupForUpdating(groupId);
|
||||||
|
|
||||||
|
if (group instanceof GroupInfoV2 groupInfoV2) {
|
||||||
|
Pair<DecryptedGroup, GroupChange> groupChangePair;
|
||||||
|
try {
|
||||||
|
groupChangePair = context.getGroupV2Helper().updateSelfProfileKey(groupInfoV2);
|
||||||
|
} catch (ConflictException e) {
|
||||||
|
// Detected conflicting update, refreshing group and trying again
|
||||||
|
groupInfoV2 = (GroupInfoV2) getGroup(groupId, true);
|
||||||
|
groupChangePair = context.getGroupV2Helper().updateSelfProfileKey(groupInfoV2);
|
||||||
|
}
|
||||||
|
if (groupChangePair != null) {
|
||||||
|
sendUpdateGroupV2Message(groupInfoV2, groupChangePair.first(), groupChangePair.second());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Pair<GroupId, SendGroupMessageResults> joinGroup(
|
public Pair<GroupId, SendGroupMessageResults> joinGroup(
|
||||||
GroupInviteLinkUrl inviteLinkUrl
|
GroupInviteLinkUrl inviteLinkUrl
|
||||||
) throws IOException, InactiveGroupLinkException {
|
) throws IOException, InactiveGroupLinkException {
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.signal.storageservice.protos.groups.Member;
|
||||||
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
||||||
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
|
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
|
||||||
import org.signal.storageservice.protos.groups.local.DecryptedGroupJoinInfo;
|
import org.signal.storageservice.protos.groups.local.DecryptedGroupJoinInfo;
|
||||||
|
import org.signal.storageservice.protos.groups.local.DecryptedMember;
|
||||||
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
|
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -45,6 +46,7 @@ import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -340,6 +342,36 @@ class GroupV2Helper {
|
||||||
return commitChange(groupInfoV2, change);
|
return commitChange(groupInfoV2, change);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pair<DecryptedGroup, GroupChange> updateSelfProfileKey(GroupInfoV2 groupInfoV2) throws IOException {
|
||||||
|
Optional<DecryptedMember> selfInGroup = groupInfoV2.getGroup() == null
|
||||||
|
? Optional.empty()
|
||||||
|
: DecryptedGroupUtil.findMemberByUuid(groupInfoV2.getGroup().getMembersList(), getSelfAci().uuid());
|
||||||
|
if (selfInGroup.isEmpty()) {
|
||||||
|
logger.trace("Not updating group, self not in group " + groupInfoV2.getGroupId().toBase64());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final var profileKey = context.getAccount().getProfileKey();
|
||||||
|
if (Arrays.equals(profileKey.serialize(), selfInGroup.get().getProfileKey().toByteArray())) {
|
||||||
|
logger.trace("Not updating group, own Profile Key is already up to date in group "
|
||||||
|
+ groupInfoV2.getGroupId().toBase64());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
logger.debug("Updating own profile key in group " + groupInfoV2.getGroupId().toBase64());
|
||||||
|
|
||||||
|
final var selfRecipientId = context.getAccount().getSelfRecipientId();
|
||||||
|
final var profileKeyCredential = context.getProfileHelper().getRecipientProfileKeyCredential(selfRecipientId);
|
||||||
|
if (profileKeyCredential == null) {
|
||||||
|
logger.trace("Cannot update profile key as self does not have a versioned profile");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
|
||||||
|
final var change = groupOperations.createUpdateProfileKeyCredentialChange(profileKeyCredential);
|
||||||
|
change.setSourceUuid(getSelfAci().toByteString());
|
||||||
|
return commitChange(groupInfoV2, change);
|
||||||
|
}
|
||||||
|
|
||||||
GroupChange joinGroup(
|
GroupChange joinGroup(
|
||||||
GroupMasterKey groupMasterKey,
|
GroupMasterKey groupMasterKey,
|
||||||
GroupLinkPassword groupLinkPassword,
|
GroupLinkPassword groupLinkPassword,
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.asamk.signal.manager.actions.RetrieveStorageDataAction;
|
||||||
import org.asamk.signal.manager.actions.SendGroupInfoAction;
|
import org.asamk.signal.manager.actions.SendGroupInfoAction;
|
||||||
import org.asamk.signal.manager.actions.SendGroupInfoRequestAction;
|
import org.asamk.signal.manager.actions.SendGroupInfoRequestAction;
|
||||||
import org.asamk.signal.manager.actions.SendPniIdentityKeyAction;
|
import org.asamk.signal.manager.actions.SendPniIdentityKeyAction;
|
||||||
|
import org.asamk.signal.manager.actions.SendProfileKeyAction;
|
||||||
import org.asamk.signal.manager.actions.SendReceiptAction;
|
import org.asamk.signal.manager.actions.SendReceiptAction;
|
||||||
import org.asamk.signal.manager.actions.SendRetryMessageRequestAction;
|
import org.asamk.signal.manager.actions.SendRetryMessageRequestAction;
|
||||||
import org.asamk.signal.manager.actions.SendSyncBlockedListAction;
|
import org.asamk.signal.manager.actions.SendSyncBlockedListAction;
|
||||||
|
@ -18,6 +19,7 @@ import org.asamk.signal.manager.actions.SendSyncConfigurationAction;
|
||||||
import org.asamk.signal.manager.actions.SendSyncContactsAction;
|
import org.asamk.signal.manager.actions.SendSyncContactsAction;
|
||||||
import org.asamk.signal.manager.actions.SendSyncGroupsAction;
|
import org.asamk.signal.manager.actions.SendSyncGroupsAction;
|
||||||
import org.asamk.signal.manager.actions.SendSyncKeysAction;
|
import org.asamk.signal.manager.actions.SendSyncKeysAction;
|
||||||
|
import org.asamk.signal.manager.actions.UpdateAccountAttributesAction;
|
||||||
import org.asamk.signal.manager.api.MessageEnvelope;
|
import org.asamk.signal.manager.api.MessageEnvelope;
|
||||||
import org.asamk.signal.manager.api.Pair;
|
import org.asamk.signal.manager.api.Pair;
|
||||||
import org.asamk.signal.manager.api.StickerPackId;
|
import org.asamk.signal.manager.api.StickerPackId;
|
||||||
|
@ -246,6 +248,13 @@ public final class IncomingMessageHandler {
|
||||||
|
|
||||||
if (content.isNeedsReceipt()) {
|
if (content.isNeedsReceipt()) {
|
||||||
actions.add(new SendReceiptAction(sender, message.getTimestamp()));
|
actions.add(new SendReceiptAction(sender, message.getTimestamp()));
|
||||||
|
} else {
|
||||||
|
// Message wasn't sent as unidentified sender message
|
||||||
|
final var contact = context.getAccount().getContactStore().getContact(sender);
|
||||||
|
if (contact != null && !contact.isBlocked() && contact.isProfileSharingEnabled()) {
|
||||||
|
actions.add(UpdateAccountAttributesAction.create());
|
||||||
|
actions.add(new SendProfileKeyAction(sender));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
actions.addAll(handleSignalServiceDataMessage(message,
|
actions.addAll(handleSignalServiceDataMessage(message,
|
||||||
|
|
|
@ -4,11 +4,15 @@ import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
|
|
||||||
import org.asamk.signal.manager.SignalDependencies;
|
import org.asamk.signal.manager.SignalDependencies;
|
||||||
import org.asamk.signal.manager.config.ServiceConfig;
|
import org.asamk.signal.manager.config.ServiceConfig;
|
||||||
|
import org.asamk.signal.manager.groups.GroupNotFoundException;
|
||||||
|
import org.asamk.signal.manager.groups.NotAGroupMemberException;
|
||||||
import org.asamk.signal.manager.storage.SignalAccount;
|
import org.asamk.signal.manager.storage.SignalAccount;
|
||||||
|
import org.asamk.signal.manager.storage.groups.GroupInfoV2;
|
||||||
import org.asamk.signal.manager.storage.recipients.Profile;
|
import org.asamk.signal.manager.storage.recipients.Profile;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
|
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
||||||
import org.asamk.signal.manager.util.IOUtils;
|
import org.asamk.signal.manager.util.IOUtils;
|
||||||
|
import org.asamk.signal.manager.util.KeyUtils;
|
||||||
import org.asamk.signal.manager.util.ProfileUtils;
|
import org.asamk.signal.manager.util.ProfileUtils;
|
||||||
import org.asamk.signal.manager.util.Utils;
|
import org.asamk.signal.manager.util.Utils;
|
||||||
import org.signal.libsignal.protocol.IdentityKey;
|
import org.signal.libsignal.protocol.IdentityKey;
|
||||||
|
@ -57,6 +61,35 @@ public final class ProfileHelper {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void rotateProfileKey() throws IOException {
|
||||||
|
var profileKey = KeyUtils.createProfileKey();
|
||||||
|
account.setProfileKey(profileKey);
|
||||||
|
context.getAccountHelper().updateAccountAttributes();
|
||||||
|
setProfile(true, true, null, null, null, null, null);
|
||||||
|
// TODO update profile key in storage
|
||||||
|
|
||||||
|
final var recipientIds = account.getRecipientStore().getRecipientIdsWithEnabledProfileSharing();
|
||||||
|
for (final var recipientId : recipientIds) {
|
||||||
|
context.getSendHelper().sendProfileKey(recipientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
final var selfRecipientId = account.getSelfRecipientId();
|
||||||
|
final var activeGroupIds = account.getGroupStore()
|
||||||
|
.getGroups()
|
||||||
|
.stream()
|
||||||
|
.filter(g -> g instanceof GroupInfoV2 && g.isMember(selfRecipientId))
|
||||||
|
.map(g -> (GroupInfoV2) g)
|
||||||
|
.map(GroupInfoV2::getGroupId)
|
||||||
|
.toList();
|
||||||
|
for (final var groupId : activeGroupIds) {
|
||||||
|
try {
|
||||||
|
context.getGroupHelper().updateGroupProfileKey(groupId);
|
||||||
|
} catch (GroupNotFoundException | NotAGroupMemberException | IOException e) {
|
||||||
|
logger.warn("Failed to update group profile key: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Profile getRecipientProfile(RecipientId recipientId) {
|
public Profile getRecipientProfile(RecipientId recipientId) {
|
||||||
return getRecipientProfile(recipientId, false);
|
return getRecipientProfile(recipientId, false);
|
||||||
}
|
}
|
||||||
|
@ -106,11 +139,12 @@ public final class ProfileHelper {
|
||||||
public void setProfile(
|
public void setProfile(
|
||||||
String givenName, final String familyName, String about, String aboutEmoji, Optional<File> avatar
|
String givenName, final String familyName, String about, String aboutEmoji, Optional<File> avatar
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
setProfile(true, givenName, familyName, about, aboutEmoji, avatar);
|
setProfile(true, false, givenName, familyName, about, aboutEmoji, avatar);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProfile(
|
public void setProfile(
|
||||||
boolean uploadProfile,
|
boolean uploadProfile,
|
||||||
|
boolean forceUploadAvatar,
|
||||||
String givenName,
|
String givenName,
|
||||||
final String familyName,
|
final String familyName,
|
||||||
String about,
|
String about,
|
||||||
|
@ -134,13 +168,14 @@ public final class ProfileHelper {
|
||||||
var newProfile = builder.build();
|
var newProfile = builder.build();
|
||||||
|
|
||||||
if (uploadProfile) {
|
if (uploadProfile) {
|
||||||
try (final var streamDetails = avatar != null && avatar.isPresent() ? Utils.createStreamDetailsFromFile(
|
final var streamDetails = avatar != null && avatar.isPresent()
|
||||||
avatar.get()) : null) {
|
? Utils.createStreamDetailsFromFile(avatar.get())
|
||||||
final var avatarUploadParams = avatar == null
|
: forceUploadAvatar && avatar == null ? context.getAvatarStore()
|
||||||
? AvatarUploadParams.unchanged(true)
|
.retrieveProfileAvatar(account.getSelfRecipientAddress()) : null;
|
||||||
: avatar.isPresent()
|
try (streamDetails) {
|
||||||
? AvatarUploadParams.forAvatar(streamDetails)
|
final var avatarUploadParams = streamDetails != null
|
||||||
: AvatarUploadParams.unchanged(false);
|
? AvatarUploadParams.forAvatar(streamDetails)
|
||||||
|
: avatar == null ? AvatarUploadParams.unchanged(true) : AvatarUploadParams.unchanged(false);
|
||||||
final var paymentsAddress = Optional.ofNullable(newProfile.getPaymentAddress()).map(data -> {
|
final var paymentsAddress = Optional.ofNullable(newProfile.getPaymentAddress()).map(data -> {
|
||||||
try {
|
try {
|
||||||
return SignalServiceProtos.PaymentAddress.parseFrom(data);
|
return SignalServiceProtos.PaymentAddress.parseFrom(data);
|
||||||
|
@ -148,6 +183,7 @@ public final class ProfileHelper {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
logger.debug("Uploading new profile");
|
||||||
final var avatarPath = dependencies.getAccountManager()
|
final var avatarPath = dependencies.getAccountManager()
|
||||||
.setVersionedProfile(account.getAci(),
|
.setVersionedProfile(account.getAci(),
|
||||||
account.getProfileKey(),
|
account.getProfileKey(),
|
||||||
|
@ -156,7 +192,7 @@ public final class ProfileHelper {
|
||||||
newProfile.getAboutEmoji() == null ? "" : newProfile.getAboutEmoji(),
|
newProfile.getAboutEmoji() == null ? "" : newProfile.getAboutEmoji(),
|
||||||
paymentsAddress,
|
paymentsAddress,
|
||||||
avatarUploadParams,
|
avatarUploadParams,
|
||||||
List.of(/* TODO */));
|
List.of(/* TODO implement support for badges */));
|
||||||
if (!avatarUploadParams.keepTheSame) {
|
if (!avatarUploadParams.keepTheSame) {
|
||||||
builder.withAvatarUrlPath(avatarPath.orElse(null));
|
builder.withAvatarUrlPath(avatarPath.orElse(null));
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,6 +139,21 @@ public class SendHelper {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SendMessageResult sendProfileKey(RecipientId recipientId) {
|
||||||
|
logger.debug("Sending updated profile key to recipient: {}", recipientId);
|
||||||
|
final var profileKey = account.getProfileKey().serialize();
|
||||||
|
final var message = SignalServiceDataMessage.newBuilder()
|
||||||
|
.asProfileKeyUpdate(true)
|
||||||
|
.withProfileKey(profileKey)
|
||||||
|
.build();
|
||||||
|
return handleSendMessage(recipientId,
|
||||||
|
(messageSender, address, unidentifiedAccess) -> messageSender.sendDataMessage(address,
|
||||||
|
unidentifiedAccess,
|
||||||
|
ContentHint.IMPLICIT,
|
||||||
|
message,
|
||||||
|
SignalServiceMessageSender.IndividualSendEvents.EMPTY));
|
||||||
|
}
|
||||||
|
|
||||||
public SendMessageResult sendRetryReceipt(
|
public SendMessageResult sendRetryReceipt(
|
||||||
DecryptionErrorMessage errorMessage, RecipientId recipientId, Optional<GroupId> groupId
|
DecryptionErrorMessage errorMessage, RecipientId recipientId, Optional<GroupId> groupId
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -229,6 +229,7 @@ public class StorageHelper {
|
||||||
|
|
||||||
context.getProfileHelper()
|
context.getProfileHelper()
|
||||||
.setProfile(false,
|
.setProfile(false,
|
||||||
|
false,
|
||||||
accountRecord.getGivenName().orElse(null),
|
accountRecord.getGivenName().orElse(null),
|
||||||
accountRecord.getFamilyName().orElse(null),
|
accountRecord.getFamilyName().orElse(null),
|
||||||
null,
|
null,
|
||||||
|
|
|
@ -373,7 +373,7 @@ public class SignalAccount implements Closeable {
|
||||||
setProfileKey(KeyUtils.createProfileKey());
|
setProfileKey(KeyUtils.createProfileKey());
|
||||||
}
|
}
|
||||||
// Ensure our profile key is stored in profile store
|
// Ensure our profile key is stored in profile store
|
||||||
getProfileStore().storeProfileKey(getSelfRecipientId(), getProfileKey());
|
getProfileStore().storeSelfProfileKey(getSelfRecipientId(), getProfileKey());
|
||||||
if (previousStorageVersion < 3) {
|
if (previousStorageVersion < 3) {
|
||||||
for (final var group : groupStore.getGroups()) {
|
for (final var group : groupStore.getGroups()) {
|
||||||
if (group instanceof GroupInfoV2 && group.getDistributionId() == null) {
|
if (group instanceof GroupInfoV2 && group.getDistributionId() == null) {
|
||||||
|
@ -1266,6 +1266,7 @@ public class SignalAccount implements Closeable {
|
||||||
}
|
}
|
||||||
this.profileKey = profileKey;
|
this.profileKey = profileKey;
|
||||||
save();
|
save();
|
||||||
|
getProfileStore().storeSelfProfileKey(getSelfRecipientId(), getProfileKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getSelfUnidentifiedAccessKey() {
|
public byte[] getSelfUnidentifiedAccessKey() {
|
||||||
|
|
|
@ -15,6 +15,8 @@ public interface ProfileStore {
|
||||||
|
|
||||||
void storeProfile(RecipientId recipientId, Profile profile);
|
void storeProfile(RecipientId recipientId, Profile profile);
|
||||||
|
|
||||||
|
void storeSelfProfileKey(RecipientId recipientId, ProfileKey profileKey);
|
||||||
|
|
||||||
void storeProfileKey(RecipientId recipientId, ProfileKey profileKey);
|
void storeProfileKey(RecipientId recipientId, ProfileKey profileKey);
|
||||||
|
|
||||||
void storeProfileKeyCredential(RecipientId recipientId, ProfileKeyCredential profileKeyCredential);
|
void storeProfileKeyCredential(RecipientId recipientId, ProfileKeyCredential profileKeyCredential);
|
||||||
|
|
|
@ -325,8 +325,17 @@ public class RecipientStore implements RecipientResolver, ContactsStore, Profile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void storeSelfProfileKey(final RecipientId recipientId, final ProfileKey profileKey) {
|
||||||
|
storeProfileKey(recipientId, profileKey, false);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void storeProfileKey(RecipientId recipientId, final ProfileKey profileKey) {
|
public void storeProfileKey(RecipientId recipientId, final ProfileKey profileKey) {
|
||||||
|
storeProfileKey(recipientId, profileKey, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void storeProfileKey(RecipientId recipientId, final ProfileKey profileKey, boolean resetProfile) {
|
||||||
synchronized (recipients) {
|
synchronized (recipients) {
|
||||||
final var recipient = recipients.get(recipientId);
|
final var recipient = recipients.get(recipientId);
|
||||||
if (profileKey != null && profileKey.equals(recipient.getProfileKey()) && (
|
if (profileKey != null && profileKey.equals(recipient.getProfileKey()) && (
|
||||||
|
@ -339,13 +348,15 @@ public class RecipientStore implements RecipientResolver, ContactsStore, Profile
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final var newRecipient = Recipient.newBuilder(recipient)
|
final var builder = Recipient.newBuilder(recipient)
|
||||||
.withProfileKey(profileKey)
|
.withProfileKey(profileKey)
|
||||||
.withProfileKeyCredential(null)
|
.withProfileKeyCredential(null);
|
||||||
.withProfile(recipient.getProfile() == null
|
if (resetProfile) {
|
||||||
? null
|
builder.withProfile(recipient.getProfile() == null
|
||||||
: Profile.newBuilder(recipient.getProfile()).withLastUpdateTimestamp(0).build())
|
? null
|
||||||
.build();
|
: Profile.newBuilder(recipient.getProfile()).withLastUpdateTimestamp(0).build());
|
||||||
|
}
|
||||||
|
final var newRecipient = builder.build();
|
||||||
storeRecipientLocked(recipientId, newRecipient);
|
storeRecipientLocked(recipientId, newRecipient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue