mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 10:30:38 +00:00
Store messages in cache by recipient id
This commit is contained in:
parent
8a0c6cae15
commit
2ef59d692a
4 changed files with 86 additions and 13 deletions
|
@ -1629,6 +1629,15 @@ public class Manager implements Closeable {
|
||||||
try {
|
try {
|
||||||
content = decryptMessage(envelope);
|
content = decryptMessage(envelope);
|
||||||
} catch (org.whispersystems.libsignal.UntrustedIdentityException e) {
|
} 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;
|
return;
|
||||||
} catch (Exception er) {
|
} catch (Exception er) {
|
||||||
// All other errors are not recoverable, so delete the cached message
|
// All other errors are not recoverable, so delete the cached message
|
||||||
|
@ -1671,8 +1680,11 @@ public class Manager implements Closeable {
|
||||||
final CachedMessage[] cachedMessage = {null};
|
final CachedMessage[] cachedMessage = {null};
|
||||||
try {
|
try {
|
||||||
var result = messagePipe.readOrEmpty(timeout, unit, envelope1 -> {
|
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
|
// 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()) {
|
if (result.isPresent()) {
|
||||||
envelope = result.get();
|
envelope = result.get();
|
||||||
|
@ -1703,8 +1715,7 @@ public class Manager implements Closeable {
|
||||||
|
|
||||||
if (envelope.hasSource()) {
|
if (envelope.hasSource()) {
|
||||||
// Store uuid if we don't have it already
|
// Store uuid if we don't have it already
|
||||||
var source = envelope.getSourceAddress();
|
resolveRecipientTrusted(envelope.getSourceAddress());
|
||||||
resolveSignalServiceAddress(source);
|
|
||||||
}
|
}
|
||||||
if (!envelope.isReceipt()) {
|
if (!envelope.isReceipt()) {
|
||||||
try {
|
try {
|
||||||
|
@ -1736,8 +1747,19 @@ public class Manager implements Closeable {
|
||||||
} else {
|
} else {
|
||||||
handler.handleMessage(envelope, content, exception);
|
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();
|
cachedMessage[0].delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2461,7 +2483,12 @@ public class Manager implements Closeable {
|
||||||
var canonicalizedNumber = UuidUtil.isUuid(identifier)
|
var canonicalizedNumber = UuidUtil.isUuid(identifier)
|
||||||
? identifier
|
? identifier
|
||||||
: PhoneNumberFormatter.formatNumber(identifier, account.getUsername());
|
: 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);
|
return resolveRecipient(address);
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,6 +244,7 @@ public class SignalAccount implements Closeable {
|
||||||
private void mergeRecipients(RecipientId recipientId, RecipientId toBeMergedRecipientId) {
|
private void mergeRecipients(RecipientId recipientId, RecipientId toBeMergedRecipientId) {
|
||||||
sessionStore.mergeRecipients(recipientId, toBeMergedRecipientId);
|
sessionStore.mergeRecipients(recipientId, toBeMergedRecipientId);
|
||||||
identityKeyStore.mergeRecipients(recipientId, toBeMergedRecipientId);
|
identityKeyStore.mergeRecipients(recipientId, toBeMergedRecipientId);
|
||||||
|
messageCache.mergeRecipients(recipientId, toBeMergedRecipientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File getFileName(File dataPath, String username) {
|
public static File getFileName(File dataPath, String username) {
|
||||||
|
|
|
@ -19,6 +19,10 @@ public final class CachedMessage {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File getFile() {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
public SignalServiceEnvelope loadEnvelope() {
|
public SignalServiceEnvelope loadEnvelope() {
|
||||||
try {
|
try {
|
||||||
return MessageCacheUtils.loadEnvelope(file);
|
return MessageCacheUtils.loadEnvelope(file);
|
||||||
|
@ -34,5 +38,10 @@ public final class CachedMessage {
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("Failed to delete cached message file “{}”, ignoring: {}", file, e.getMessage());
|
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) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.asamk.signal.manager.storage.messageCache;
|
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.IOUtils;
|
||||||
import org.asamk.signal.manager.util.MessageCacheUtils;
|
import org.asamk.signal.manager.util.MessageCacheUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -49,12 +50,11 @@ public class MessageCache {
|
||||||
}).map(CachedMessage::new).collect(Collectors.toList());
|
}).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 now = new Date().getTime();
|
||||||
final var source = envelope.hasSource() ? envelope.getSourceAddress().getLegacyIdentifier() : "";
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var cacheFile = getMessageCacheFile(source, now, envelope.getTimestamp());
|
var cacheFile = getMessageCacheFile(recipientId, now, envelope.getTimestamp());
|
||||||
MessageCacheUtils.storeEnvelope(envelope, cacheFile);
|
MessageCacheUtils.storeEnvelope(envelope, cacheFile);
|
||||||
return new CachedMessage(cacheFile);
|
return new CachedMessage(cacheFile);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -63,17 +63,53 @@ public class MessageCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private File getMessageCachePath(String sender) {
|
public CachedMessage replaceSender(CachedMessage cachedMessage, RecipientId sender) throws IOException {
|
||||||
if (sender == null || sender.isEmpty()) {
|
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;
|
return messageCachePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sender = String.valueOf(recipientId.getId());
|
||||||
return new File(messageCachePath, sender.replace("/", "_"));
|
return new File(messageCachePath, sender.replace("/", "_"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private File getMessageCacheFile(String sender, long now, long timestamp) throws IOException {
|
private File getMessageCacheFile(RecipientId recipientId, String filename) throws IOException {
|
||||||
var cachePath = getMessageCachePath(sender);
|
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);
|
IOUtils.createPrivateDirectories(cachePath);
|
||||||
return new File(cachePath, now + "_" + timestamp);
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue