mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 10:30:38 +00:00
Retrieve profile to get latest identity key
This commit is contained in:
parent
2ef59d692a
commit
deb4ecd04f
2 changed files with 88 additions and 21 deletions
|
@ -157,3 +157,32 @@ class SendGroupInfoAction implements HandleAction {
|
|||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
class RetrieveProfileAction implements HandleAction {
|
||||
|
||||
private final SignalServiceAddress address;
|
||||
|
||||
public RetrieveProfileAction(final SignalServiceAddress address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Manager m) throws Throwable {
|
||||
m.getRecipientProfile(address, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
final RetrieveProfileAction that = (RetrieveProfileAction) o;
|
||||
|
||||
return address.equals(that.address);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return address.hashCode();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,6 +146,7 @@ import java.nio.file.Files;
|
|||
import java.security.SignatureException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
|
@ -532,11 +533,13 @@ public class Manager implements Closeable {
|
|||
return getRecipientProfile(address, false);
|
||||
}
|
||||
|
||||
private SignalProfile getRecipientProfile(
|
||||
SignalProfile getRecipientProfile(
|
||||
SignalServiceAddress address, boolean force
|
||||
) {
|
||||
var profileEntry = account.getProfileStore().getProfileEntry(address);
|
||||
if (profileEntry == null) {
|
||||
// retrieve profile to get identity key
|
||||
retrieveEncryptedProfile(address);
|
||||
return null;
|
||||
}
|
||||
var now = new Date().getTime();
|
||||
|
@ -549,14 +552,13 @@ public class Manager implements Closeable {
|
|||
profileEntry.setRequestPending(true);
|
||||
final SignalServiceProfile encryptedProfile;
|
||||
try {
|
||||
encryptedProfile = profileHelper.retrieveProfileSync(address, SignalServiceProfile.RequestType.PROFILE)
|
||||
.getProfile();
|
||||
} catch (IOException e) {
|
||||
logger.warn("Failed to retrieve profile, ignoring: {}", e.getMessage());
|
||||
return null;
|
||||
encryptedProfile = retrieveEncryptedProfile(address);
|
||||
} finally {
|
||||
profileEntry.setRequestPending(false);
|
||||
}
|
||||
if (encryptedProfile == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final var profileKey = profileEntry.getProfileKey();
|
||||
final var profile = decryptProfileAndDownloadAvatar(address, profileKey, encryptedProfile);
|
||||
|
@ -567,6 +569,25 @@ public class Manager implements Closeable {
|
|||
return profileEntry.getProfile();
|
||||
}
|
||||
|
||||
private SignalServiceProfile retrieveEncryptedProfile(SignalServiceAddress address) {
|
||||
try {
|
||||
final var profile = profileHelper.retrieveProfileSync(address, SignalServiceProfile.RequestType.PROFILE)
|
||||
.getProfile();
|
||||
try {
|
||||
account.getIdentityKeyStore()
|
||||
.saveIdentity(resolveRecipient(address),
|
||||
new IdentityKey(Base64.getDecoder().decode(profile.getIdentityKey())),
|
||||
new Date());
|
||||
} catch (InvalidKeyException ignored) {
|
||||
logger.warn("Got invalid identity key in profile for {}", address.getLegacyIdentifier());
|
||||
}
|
||||
return profile;
|
||||
} catch (IOException e) {
|
||||
logger.warn("Failed to retrieve profile, ignoring: {}", e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private ProfileKeyCredential getRecipientProfileKeyCredential(SignalServiceAddress address) {
|
||||
var profileEntry = account.getProfileStore().getProfileEntry(address);
|
||||
if (profileEntry == null) {
|
||||
|
@ -1292,6 +1313,16 @@ public class Manager implements Closeable {
|
|||
unidentifiedAccessHelper.getAccessFor(recipients),
|
||||
isRecipientUpdate,
|
||||
message);
|
||||
|
||||
for (var r : result) {
|
||||
if (r.getIdentityFailure() != null) {
|
||||
account.getIdentityKeyStore().
|
||||
saveIdentity(resolveRecipient(r.getAddress()),
|
||||
r.getIdentityFailure().getIdentityKey(),
|
||||
new Date());
|
||||
}
|
||||
}
|
||||
|
||||
return new Pair<>(timestamp, result);
|
||||
} catch (UntrustedIdentityException e) {
|
||||
return new Pair<>(timestamp, List.of());
|
||||
|
@ -1612,19 +1643,31 @@ public class Manager implements Closeable {
|
|||
}
|
||||
|
||||
private void retryFailedReceivedMessages(ReceiveMessageHandler handler, boolean ignoreAttachments) {
|
||||
Set<HandleAction> queuedActions = new HashSet<>();
|
||||
for (var cachedMessage : account.getMessageCache().getCachedMessages()) {
|
||||
retryFailedReceivedMessage(handler, ignoreAttachments, cachedMessage);
|
||||
var actions = retryFailedReceivedMessage(handler, ignoreAttachments, cachedMessage);
|
||||
if (actions != null) {
|
||||
queuedActions.addAll(actions);
|
||||
}
|
||||
}
|
||||
for (var action : queuedActions) {
|
||||
try {
|
||||
action.execute(this);
|
||||
} catch (Throwable e) {
|
||||
logger.warn("Message action failed.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void retryFailedReceivedMessage(
|
||||
private List<HandleAction> retryFailedReceivedMessage(
|
||||
final ReceiveMessageHandler handler, final boolean ignoreAttachments, final CachedMessage cachedMessage
|
||||
) {
|
||||
var envelope = cachedMessage.loadEnvelope();
|
||||
if (envelope == null) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
SignalServiceContent content = null;
|
||||
List<HandleAction> actions = null;
|
||||
if (!envelope.isReceipt()) {
|
||||
try {
|
||||
content = decryptMessage(envelope);
|
||||
|
@ -1638,24 +1681,18 @@ public class Manager implements Closeable {
|
|||
logger.warn("Failed to move cached message to recipient folder: {}", ioException.getMessage());
|
||||
}
|
||||
}
|
||||
return;
|
||||
return null;
|
||||
} catch (Exception er) {
|
||||
// All other errors are not recoverable, so delete the cached message
|
||||
cachedMessage.delete();
|
||||
return;
|
||||
}
|
||||
var actions = handleMessage(envelope, content, ignoreAttachments);
|
||||
for (var action : actions) {
|
||||
try {
|
||||
action.execute(this);
|
||||
} catch (Throwable e) {
|
||||
logger.warn("Message action failed.", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
actions = handleMessage(envelope, content, ignoreAttachments);
|
||||
}
|
||||
account.save();
|
||||
handler.handleMessage(envelope, content, null);
|
||||
cachedMessage.delete();
|
||||
return actions;
|
||||
}
|
||||
|
||||
public void receiveMessages(
|
||||
|
@ -1749,9 +1786,10 @@ public class Manager implements Closeable {
|
|||
}
|
||||
if (cachedMessage[0] != null) {
|
||||
if (exception instanceof org.whispersystems.libsignal.UntrustedIdentityException) {
|
||||
if (!envelope.hasSource()) {
|
||||
final var recipientId = resolveRecipient(((org.whispersystems.libsignal.UntrustedIdentityException) exception)
|
||||
.getName());
|
||||
queuedActions.add(new RetrieveProfileAction(resolveSignalServiceAddress(recipientId)));
|
||||
if (!envelope.hasSource()) {
|
||||
try {
|
||||
cachedMessage[0] = account.getMessageCache().replaceSender(cachedMessage[0], recipientId);
|
||||
} catch (IOException ioException) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue