try {
content = decryptMessage(envelope);
} catch (org.whispersystems.libsignal.UntrustedIdentityException e) {
+ if (!envelope.hasSource()) {
+ final var recipientId = resolveRecipient(((org.whispersystems.libsignal.UntrustedIdentityException) e)
+ .getName());
+ try {
+ account.getMessageCache().replaceSender(cachedMessage, recipientId);
+ } catch (IOException ioException) {
+ logger.warn("Failed to move cached message to recipient folder: {}", ioException.getMessage());
+ }
+ }
return;
} catch (Exception er) {
// All other errors are not recoverable, so delete the cached message
final CachedMessage[] cachedMessage = {null};
try {
var result = messagePipe.readOrEmpty(timeout, unit, envelope1 -> {
+ final var recipientId = envelope1.hasSource()
+ ? resolveRecipient(envelope1.getSourceIdentifier())
+ : null;
// store message on disk, before acknowledging receipt to the server
- cachedMessage[0] = account.getMessageCache().cacheMessage(envelope1);
+ cachedMessage[0] = account.getMessageCache().cacheMessage(envelope1, recipientId);
});
if (result.isPresent()) {
envelope = result.get();
if (envelope.hasSource()) {
// Store uuid if we don't have it already
- var source = envelope.getSourceAddress();
- resolveSignalServiceAddress(source);
+ resolveRecipientTrusted(envelope.getSourceAddress());
}
if (!envelope.isReceipt()) {
try {
} else {
handler.handleMessage(envelope, content, exception);
}
- if (!(exception instanceof org.whispersystems.libsignal.UntrustedIdentityException)) {
- if (cachedMessage[0] != null) {
+ if (cachedMessage[0] != null) {
+ if (exception instanceof org.whispersystems.libsignal.UntrustedIdentityException) {
+ if (!envelope.hasSource()) {
+ final var recipientId = resolveRecipient(((org.whispersystems.libsignal.UntrustedIdentityException) exception)
+ .getName());
+ try {
+ cachedMessage[0] = account.getMessageCache().replaceSender(cachedMessage[0], recipientId);
+ } catch (IOException ioException) {
+ logger.warn("Failed to move cached message to recipient folder: {}",
+ ioException.getMessage());
+ }
+ }
+ } else {
cachedMessage[0].delete();
}
}
var canonicalizedNumber = UuidUtil.isUuid(identifier)
? identifier
: PhoneNumberFormatter.formatNumber(identifier, account.getUsername());
- var address = Utils.getSignalServiceAddressFromIdentifier(canonicalizedNumber);
+
+ return resolveRecipient(canonicalizedNumber);
+ }
+
+ private RecipientId resolveRecipient(final String identifier) {
+ var address = Utils.getSignalServiceAddressFromIdentifier(identifier);
return resolveRecipient(address);
}
private void mergeRecipients(RecipientId recipientId, RecipientId toBeMergedRecipientId) {
sessionStore.mergeRecipients(recipientId, toBeMergedRecipientId);
identityKeyStore.mergeRecipients(recipientId, toBeMergedRecipientId);
+ messageCache.mergeRecipients(recipientId, toBeMergedRecipientId);
}
public static File getFileName(File dataPath, String username) {
this.file = file;
}
+ File getFile() {
+ return file;
+ }
+
public SignalServiceEnvelope loadEnvelope() {
try {
return MessageCacheUtils.loadEnvelope(file);
} catch (IOException e) {
logger.warn("Failed to delete cached message file “{}”, ignoring: {}", file, e.getMessage());
}
+ // Delete parent directory, if empty
+ try {
+ Files.delete(file.toPath().getParent());
+ } catch (IOException ignored) {
+ }
}
}
package org.asamk.signal.manager.storage.messageCache;
+import org.asamk.signal.manager.storage.recipients.RecipientId;
import org.asamk.signal.manager.util.IOUtils;
import org.asamk.signal.manager.util.MessageCacheUtils;
import org.slf4j.Logger;
}).map(CachedMessage::new).collect(Collectors.toList());
}
- public CachedMessage cacheMessage(SignalServiceEnvelope envelope) {
+ public CachedMessage cacheMessage(SignalServiceEnvelope envelope, RecipientId recipientId) {
final var now = new Date().getTime();
- final var source = envelope.hasSource() ? envelope.getSourceAddress().getLegacyIdentifier() : "";
try {
- var cacheFile = getMessageCacheFile(source, now, envelope.getTimestamp());
+ var cacheFile = getMessageCacheFile(recipientId, now, envelope.getTimestamp());
MessageCacheUtils.storeEnvelope(envelope, cacheFile);
return new CachedMessage(cacheFile);
} catch (IOException e) {
}
}
- private File getMessageCachePath(String sender) {
- if (sender == null || sender.isEmpty()) {
+ public CachedMessage replaceSender(CachedMessage cachedMessage, RecipientId sender) throws IOException {
+ final var cacheFile = getMessageCacheFile(sender, cachedMessage.getFile().getName());
+ if (cacheFile.equals(cachedMessage.getFile())) {
+ return cachedMessage;
+ }
+ Files.move(cachedMessage.getFile().toPath(), cacheFile.toPath());
+ return new CachedMessage(cacheFile);
+ }
+
+ private File getMessageCachePath(RecipientId recipientId) {
+ if (recipientId == null) {
return messageCachePath;
}
+ var sender = String.valueOf(recipientId.getId());
return new File(messageCachePath, sender.replace("/", "_"));
}
- private File getMessageCacheFile(String sender, long now, long timestamp) throws IOException {
- var cachePath = getMessageCachePath(sender);
+ private File getMessageCacheFile(RecipientId recipientId, String filename) throws IOException {
+ var cachePath = getMessageCachePath(recipientId);
+ IOUtils.createPrivateDirectories(cachePath);
+ return new File(cachePath, filename);
+ }
+
+ private File getMessageCacheFile(RecipientId recipientId, long now, long timestamp) throws IOException {
+ var cachePath = getMessageCachePath(recipientId);
IOUtils.createPrivateDirectories(cachePath);
return new File(cachePath, now + "_" + timestamp);
}
+
+ public void mergeRecipients(final RecipientId recipientId, final RecipientId toBeMergedRecipientId) {
+ final var toBeMergedMessageCachePath = getMessageCachePath(toBeMergedRecipientId);
+ if (!toBeMergedMessageCachePath.exists()) {
+ return;
+ }
+
+ for (var file : Objects.requireNonNull(toBeMergedMessageCachePath.listFiles())) {
+ if (!file.isFile()) {
+ continue;
+ }
+
+ try {
+ final var cacheFile = getMessageCacheFile(recipientId, file.getName());
+ Files.move(file.toPath(), cacheFile.toPath());
+ } catch (IOException e) {
+ logger.warn("Failed to move cache file “{}”, ignoring: {}", file, e.getMessage());
+ }
+ }
+ }
}