mirror of
https://github.com/oxen-io/session-android.git
synced 2025-08-11 20:37:39 +00:00
feat: add self sending syncTarget messages
This commit is contained in:
@@ -686,6 +686,15 @@ public class SmsDatabase extends MessagingDatabase {
|
||||
return insertMessageInbox(message, Types.BASE_INBOX_TYPE, serverTimestamp);
|
||||
}
|
||||
|
||||
public Optional<InsertResult> insertMessageOutbox(long threadId, OutgoingTextMessage message, long serverTimestamp) {
|
||||
long messageId = insertMessageOutbox(threadId, message, false, serverTimestamp, null);
|
||||
if (messageId == -1) {
|
||||
return Optional.absent();
|
||||
}
|
||||
markAsSent(messageId, true);
|
||||
return Optional.fromNullable(new InsertResult(messageId, threadId));
|
||||
}
|
||||
|
||||
public long insertMessageOutbox(long threadId, OutgoingTextMessage message,
|
||||
boolean forceSms, long date, InsertListener insertListener)
|
||||
{
|
||||
@@ -716,9 +725,17 @@ public class SmsDatabase extends MessagingDatabase {
|
||||
contentValues.put(DELIVERY_RECEIPT_COUNT, Stream.of(earlyDeliveryReceipts.values()).mapToLong(Long::longValue).sum());
|
||||
contentValues.put(READ_RECEIPT_COUNT, Stream.of(earlyReadReceipts.values()).mapToLong(Long::longValue).sum());
|
||||
|
||||
SQLiteDatabase readDb = databaseHelper.getReadableDatabase();
|
||||
Cursor existingRecord = readDb.query(TABLE_NAME, null, String.format("%s = ? AND %s = ? AND %s = ?",ADDRESS, THREAD_ID, DATE_SENT),
|
||||
new String[] { address.serialize(), Long.toString(threadId), Long.toString(date) }, null, null, null);
|
||||
int existingRecordCount = existingRecord.getCount();
|
||||
if (existingRecordCount > 0) {
|
||||
// return -1 because record exists from Address to ThreadID with the same date sent (probably sent from us)
|
||||
return -1;
|
||||
}
|
||||
|
||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||
long messageId = db.insert(TABLE_NAME, ADDRESS, contentValues);
|
||||
|
||||
if (insertListener != null) {
|
||||
insertListener.onComplete();
|
||||
}
|
||||
|
@@ -28,6 +28,7 @@ import org.session.libsignal.metadata.ProtocolNoSessionException;
|
||||
import org.session.libsignal.metadata.ProtocolUntrustedIdentityException;
|
||||
import org.session.libsignal.metadata.SelfSendException;
|
||||
import org.session.libsignal.service.loki.api.crypto.SessionProtocol;
|
||||
import org.session.libsignal.service.loki.utilities.HexEncodingKt;
|
||||
import org.session.libsignal.utilities.PromiseUtilities;
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
|
||||
@@ -568,6 +569,8 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
{
|
||||
Recipient originalRecipient = getMessageDestination(content, message);
|
||||
Recipient masterRecipient = getMessageMasterDestination(content.getSender());
|
||||
String syncTarget = message.getSyncTarget().orNull();
|
||||
|
||||
|
||||
notifyTypingStoppedFromIncomingMessage(masterRecipient, content.getSender(), content.getSenderDevice());
|
||||
|
||||
@@ -582,75 +585,79 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
masterAddress = getMessageMasterDestination(content.getSender()).getAddress();
|
||||
}
|
||||
|
||||
IncomingMediaMessage mediaMessage = new IncomingMediaMessage(masterAddress, message.getTimestamp(), -1,
|
||||
message.getExpiresInSeconds() * 1000L, false, content.isNeedsReceipt(), message.getBody(), message.getGroupInfo(), message.getAttachments(),
|
||||
quote, sharedContacts, linkPreviews, sticker);
|
||||
if (syncTarget != null && !syncTarget.isEmpty()) {
|
||||
// OutgoingMediaMessage mediaMessage = new OutgoingMediaMessage(masterAddress, message.getTimestamp(), -1,
|
||||
// message.getExpiresInSeconds() * 1000L, false, )
|
||||
} else {
|
||||
IncomingMediaMessage mediaMessage = new IncomingMediaMessage(masterAddress, message.getTimestamp(), -1,
|
||||
message.getExpiresInSeconds() * 1000L, false, content.isNeedsReceipt(), message.getBody(), message.getGroupInfo(), message.getAttachments(),
|
||||
quote, sharedContacts, linkPreviews, sticker);
|
||||
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
||||
database.beginTransaction();
|
||||
|
||||
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
|
||||
database.beginTransaction();
|
||||
// Ignore message if it has no body and no attachments
|
||||
if (mediaMessage.getBody().isEmpty() && mediaMessage.getAttachments().isEmpty() && mediaMessage.getLinkPreviews().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore message if it has no body and no attachments
|
||||
if (mediaMessage.getBody().isEmpty() && mediaMessage.getAttachments().isEmpty() && mediaMessage.getLinkPreviews().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Optional<InsertResult> insertResult;
|
||||
|
||||
Optional<InsertResult> insertResult;
|
||||
try {
|
||||
if (message.isGroupMessage()) {
|
||||
insertResult = database.insertSecureDecryptedMessageInbox(mediaMessage, -1, content.getTimestamp());
|
||||
} else {
|
||||
insertResult = database.insertSecureDecryptedMessageInbox(mediaMessage, -1);
|
||||
}
|
||||
|
||||
try {
|
||||
if (message.isGroupMessage()) {
|
||||
insertResult = database.insertSecureDecryptedMessageInbox(mediaMessage, -1, content.getTimestamp());
|
||||
} else {
|
||||
insertResult = database.insertSecureDecryptedMessageInbox(mediaMessage, -1);
|
||||
if (insertResult.isPresent()) {
|
||||
List<DatabaseAttachment> allAttachments = DatabaseFactory.getAttachmentDatabase(context).getAttachmentsForMessage(insertResult.get().getMessageId());
|
||||
List<DatabaseAttachment> stickerAttachments = Stream.of(allAttachments).filter(Attachment::isSticker).toList();
|
||||
List<DatabaseAttachment> attachments = Stream.of(allAttachments).filterNot(Attachment::isSticker).toList();
|
||||
|
||||
forceStickerDownloadIfNecessary(stickerAttachments);
|
||||
|
||||
for (DatabaseAttachment attachment : attachments) {
|
||||
ApplicationContext.getInstance(context).getJobManager().add(new AttachmentDownloadJob(insertResult.get().getMessageId(), attachment.getAttachmentId(), false));
|
||||
}
|
||||
|
||||
if (smsMessageId.isPresent()) {
|
||||
DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get());
|
||||
}
|
||||
|
||||
database.setTransactionSuccessful();
|
||||
}
|
||||
} catch (MmsException e) {
|
||||
throw new StorageFailedException(e, content.getSender(), content.getSenderDevice());
|
||||
} finally {
|
||||
database.endTransaction();
|
||||
}
|
||||
|
||||
if (insertResult.isPresent()) {
|
||||
List<DatabaseAttachment> allAttachments = DatabaseFactory.getAttachmentDatabase(context).getAttachmentsForMessage(insertResult.get().getMessageId());
|
||||
List<DatabaseAttachment> stickerAttachments = Stream.of(allAttachments).filter(Attachment::isSticker).toList();
|
||||
List<DatabaseAttachment> attachments = Stream.of(allAttachments).filterNot(Attachment::isSticker).toList();
|
||||
|
||||
forceStickerDownloadIfNecessary(stickerAttachments);
|
||||
|
||||
for (DatabaseAttachment attachment : attachments) {
|
||||
ApplicationContext.getInstance(context).getJobManager().add(new AttachmentDownloadJob(insertResult.get().getMessageId(), attachment.getAttachmentId(), false));
|
||||
}
|
||||
|
||||
if (smsMessageId.isPresent()) {
|
||||
DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get());
|
||||
}
|
||||
|
||||
database.setTransactionSuccessful();
|
||||
}
|
||||
} catch (MmsException e) {
|
||||
throw new StorageFailedException(e, content.getSender(), content.getSenderDevice());
|
||||
} finally {
|
||||
database.endTransaction();
|
||||
}
|
||||
|
||||
if (insertResult.isPresent()) {
|
||||
messageNotifier.updateNotification(context, insertResult.get().getThreadId());
|
||||
}
|
||||
|
||||
if (insertResult.isPresent()) {
|
||||
InsertResult result = insertResult.get();
|
||||
|
||||
// Loki - Cache the user hex encoded public key (for mentions)
|
||||
MentionManagerUtilities.INSTANCE.populateUserPublicKeyCacheIfNeeded(result.getThreadId(), context);
|
||||
MentionsManager.shared.cache(content.getSender(), result.getThreadId());
|
||||
|
||||
// Loki - Store message open group server ID if needed
|
||||
if (messageServerIDOrNull.isPresent()) {
|
||||
long messageID = result.getMessageId();
|
||||
long messageServerID = messageServerIDOrNull.get();
|
||||
LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context);
|
||||
lokiMessageDatabase.setServerID(messageID, messageServerID);
|
||||
messageNotifier.updateNotification(context, insertResult.get().getThreadId());
|
||||
}
|
||||
|
||||
// Loki - Update mapping of message ID to original thread ID
|
||||
if (result.getMessageId() > -1) {
|
||||
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
|
||||
LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context);
|
||||
long originalThreadId = threadDatabase.getOrCreateThreadIdFor(originalRecipient);
|
||||
lokiMessageDatabase.setOriginalThreadID(result.getMessageId(), originalThreadId);
|
||||
if (insertResult.isPresent()) {
|
||||
InsertResult result = insertResult.get();
|
||||
|
||||
// Loki - Cache the user hex encoded public key (for mentions)
|
||||
MentionManagerUtilities.INSTANCE.populateUserPublicKeyCacheIfNeeded(result.getThreadId(), context);
|
||||
MentionsManager.shared.cache(content.getSender(), result.getThreadId());
|
||||
|
||||
// Loki - Store message open group server ID if needed
|
||||
if (messageServerIDOrNull.isPresent()) {
|
||||
long messageID = result.getMessageId();
|
||||
long messageServerID = messageServerIDOrNull.get();
|
||||
LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context);
|
||||
lokiMessageDatabase.setServerID(messageID, messageServerID);
|
||||
}
|
||||
|
||||
// Loki - Update mapping of message ID to original thread ID
|
||||
if (result.getMessageId() > -1) {
|
||||
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
|
||||
LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context);
|
||||
long originalThreadId = threadDatabase.getOrCreateThreadIdFor(originalRecipient);
|
||||
lokiMessageDatabase.setOriginalThreadID(result.getMessageId(), originalThreadId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -769,6 +776,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
String body = message.getBody().isPresent() ? message.getBody().get() : "";
|
||||
Recipient originalRecipient = getMessageDestination(content, message);
|
||||
Recipient masterRecipient = getMessageMasterDestination(content.getSender());
|
||||
String syncTarget = message.getSyncTarget().orNull();
|
||||
|
||||
if (message.getExpiresInSeconds() != originalRecipient.getExpireMessages()) {
|
||||
handleExpirationUpdate(content, message, Optional.absent());
|
||||
@@ -778,15 +786,46 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
|
||||
if (smsMessageId.isPresent() && !message.getGroupInfo().isPresent()) {
|
||||
threadId = database.updateBundleMessageBody(smsMessageId.get(), body).second;
|
||||
} else if (syncTarget != null && !syncTarget.isEmpty()) {
|
||||
Address targetAddress = Address.fromSerialized(syncTarget);
|
||||
|
||||
OutgoingTextMessage tm = new OutgoingTextMessage(Recipient.from(context, targetAddress, false),
|
||||
body, message.getExpiresInSeconds(), -1);
|
||||
|
||||
// Ignore the message if it has no body
|
||||
if (tm.getMessageBody().length() == 0) { return; }
|
||||
|
||||
// Check if we have the thread already
|
||||
long threadID = DatabaseFactory.getLokiThreadDatabase(context).getThreadID(syncTarget);
|
||||
|
||||
|
||||
// Insert the message into the database
|
||||
Optional<InsertResult> insertResult;
|
||||
insertResult = database.insertMessageOutbox(threadID, tm, content.getTimestamp());
|
||||
|
||||
if (insertResult.isPresent()) {
|
||||
threadId = insertResult.get().getThreadId();
|
||||
}
|
||||
|
||||
if (smsMessageId.isPresent()) database.deleteMessage(smsMessageId.get());
|
||||
|
||||
if (threadId != null) {
|
||||
messageNotifier.updateNotification(context, threadId);
|
||||
}
|
||||
|
||||
if (insertResult.isPresent()) {
|
||||
InsertResult result = insertResult.get();
|
||||
|
||||
// Loki - Cache the user hex encoded public key (for mentions)
|
||||
MentionManagerUtilities.INSTANCE.populateUserPublicKeyCacheIfNeeded(result.getThreadId(), context);
|
||||
MentionsManager.shared.cache(content.getSender(), result.getThreadId());
|
||||
}
|
||||
|
||||
} else {
|
||||
notifyTypingStoppedFromIncomingMessage(masterRecipient, content.getSender(), content.getSenderDevice());
|
||||
|
||||
Address masterAddress = masterRecipient.getAddress();
|
||||
|
||||
if (message.isGroupMessage()) {
|
||||
masterAddress = getMessageMasterDestination(content.getSender()).getAddress();
|
||||
}
|
||||
|
||||
IncomingTextMessage tm = new IncomingTextMessage(masterAddress,
|
||||
content.getSenderDevice(),
|
||||
message.getTimestamp(), body,
|
||||
|
@@ -15,6 +15,7 @@ import org.session.libsession.messaging.threads.recipients.Recipient;
|
||||
import org.session.libsession.messaging.threads.Address;
|
||||
import org.session.libsession.utilities.GroupUtil;
|
||||
|
||||
import org.session.libsession.utilities.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
@@ -143,6 +144,9 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
|
||||
List<NetworkFailure> existingNetworkFailures = message.getNetworkFailures();
|
||||
List<IdentityKeyMismatch> existingIdentityMismatches = message.getIdentityKeyMismatches();
|
||||
|
||||
String userPublicKey = TextSecurePreferences.getLocalNumber(context);
|
||||
SignalServiceAddress localAddress = new SignalServiceAddress(userPublicKey);
|
||||
|
||||
if (database.isSent(messageId)) {
|
||||
log(TAG, "Message " + messageId + " was already sent. Ignoring.");
|
||||
return;
|
||||
@@ -190,6 +194,22 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
|
||||
}
|
||||
|
||||
if (existingNetworkFailures.isEmpty() && networkFailures.isEmpty() && identityMismatches.isEmpty() && existingIdentityMismatches.isEmpty()) {
|
||||
Address address = message.getRecipient().getAddress();
|
||||
if (!address.isOpenGroup()) {
|
||||
try {
|
||||
SignalServiceDataMessage selfSend = getDataMessage(address, message)
|
||||
.withSyncTarget(address.toGroupString())
|
||||
.build();
|
||||
// send to ourselves to sync multi-device
|
||||
Optional<UnidentifiedAccessPair> syncAccess = UnidentifiedAccessUtil.getAccessForSync(context);
|
||||
SendMessageResult selfSendResult = messageSender.sendMessage(messageId, localAddress, syncAccess, selfSend);
|
||||
if (selfSendResult.getLokiAPIError() != null) {
|
||||
throw selfSendResult.getLokiAPIError();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e("Loki", "Error sending message to ourselves", e);
|
||||
}
|
||||
}
|
||||
database.markAsSent(messageId, true);
|
||||
|
||||
markAttachmentsUploaded(messageId, message.getAttachments());
|
||||
@@ -238,25 +258,18 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
|
||||
// return results;
|
||||
// }
|
||||
|
||||
String groupId = address.toGroupString();
|
||||
Optional<byte[]> profileKey = getProfileKey(message.getRecipient());
|
||||
Optional<Quote> quote = getQuoteFor(message);
|
||||
Optional<SignalServiceDataMessage.Sticker> sticker = getStickerFor(message);
|
||||
List<SharedContact> sharedContacts = getSharedContactsFor(message);
|
||||
List<Preview> previews = getPreviewsFor(message);
|
||||
List<SignalServiceAddress> addresses = Stream.of(destinations).map(this::getPushAddress).toList();
|
||||
List<Attachment> attachments = Stream.of(message.getAttachments()).filterNot(Attachment::isSticker).toList();
|
||||
List<SignalServiceAttachment> attachmentPointers = getAttachmentPointersFor(attachments);
|
||||
|
||||
List<Optional<UnidentifiedAccessPair>> unidentifiedAccess = Stream.of(addresses)
|
||||
.map(a -> Address.Companion.fromSerialized(a.getNumber()))
|
||||
.map(a -> Recipient.from(context, a, false))
|
||||
.map(recipient -> UnidentifiedAccessUtil.getAccessFor(context, recipient))
|
||||
.toList();
|
||||
|
||||
SignalServiceGroup.GroupType groupType = address.isOpenGroup() ? SignalServiceGroup.GroupType.PUBLIC_CHAT : SignalServiceGroup.GroupType.SIGNAL;
|
||||
|
||||
if (message.isGroup() && address.isClosedGroup()) {
|
||||
SignalServiceGroup.GroupType groupType = address.isOpenGroup() ? SignalServiceGroup.GroupType.PUBLIC_CHAT : SignalServiceGroup.GroupType.SIGNAL;
|
||||
String groupId = address.toGroupString();
|
||||
List<Attachment> attachments = Stream.of(message.getAttachments()).filterNot(Attachment::isSticker).toList();
|
||||
List<SignalServiceAttachment> attachmentPointers = getAttachmentPointersFor(attachments);
|
||||
// Loki - Only send GroupUpdate or GroupQuit messages to closed groups
|
||||
OutgoingGroupMediaMessage groupMessage = (OutgoingGroupMediaMessage) message;
|
||||
GroupContext groupContext = groupMessage.getGroupContext();
|
||||
@@ -271,25 +284,40 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
|
||||
|
||||
return messageSender.sendMessage(messageId, addresses, unidentifiedAccess, groupDataMessage);
|
||||
} else {
|
||||
SignalServiceGroup group = new SignalServiceGroup(GroupUtil.getDecodedGroupIDAsData(groupId), groupType);
|
||||
SignalServiceDataMessage groupMessage = SignalServiceDataMessage.newBuilder()
|
||||
.withTimestamp(message.getSentTimeMillis())
|
||||
.asGroupMessage(group)
|
||||
.withAttachments(attachmentPointers)
|
||||
.withBody(message.getBody())
|
||||
.withExpiration((int)(message.getExpiresIn() / 1000))
|
||||
.asExpirationUpdate(message.isExpirationUpdate())
|
||||
.withProfileKey(profileKey.orNull())
|
||||
.withQuote(quote.orNull())
|
||||
.withSticker(sticker.orNull())
|
||||
.withSharedContacts(sharedContacts)
|
||||
.withPreviews(previews)
|
||||
.build();
|
||||
SignalServiceDataMessage groupMessage = getDataMessage(address, message).build();
|
||||
|
||||
return messageSender.sendMessage(messageId, addresses, unidentifiedAccess, groupMessage);
|
||||
}
|
||||
}
|
||||
|
||||
public SignalServiceDataMessage.Builder getDataMessage(Address address, OutgoingMediaMessage message) {
|
||||
|
||||
SignalServiceGroup.GroupType groupType = address.isOpenGroup() ? SignalServiceGroup.GroupType.PUBLIC_CHAT : SignalServiceGroup.GroupType.SIGNAL;
|
||||
|
||||
String groupId = address.toGroupString();
|
||||
Optional<byte[]> profileKey = getProfileKey(message.getRecipient());
|
||||
Optional<Quote> quote = getQuoteFor(message);
|
||||
Optional<SignalServiceDataMessage.Sticker> sticker = getStickerFor(message);
|
||||
List<SharedContact> sharedContacts = getSharedContactsFor(message);
|
||||
List<Preview> previews = getPreviewsFor(message);
|
||||
List<Attachment> attachments = Stream.of(message.getAttachments()).filterNot(Attachment::isSticker).toList();
|
||||
List<SignalServiceAttachment> attachmentPointers = getAttachmentPointersFor(attachments);
|
||||
|
||||
SignalServiceGroup group = new SignalServiceGroup(GroupUtil.getDecodedGroupIDAsData(groupId), groupType);
|
||||
return SignalServiceDataMessage.newBuilder()
|
||||
.withTimestamp(message.getSentTimeMillis())
|
||||
.asGroupMessage(group)
|
||||
.withAttachments(attachmentPointers)
|
||||
.withBody(message.getBody())
|
||||
.withExpiration((int)(message.getExpiresIn() / 1000))
|
||||
.asExpirationUpdate(message.isExpirationUpdate())
|
||||
.withProfileKey(profileKey.orNull())
|
||||
.withQuote(quote.orNull())
|
||||
.withSticker(sticker.orNull())
|
||||
.withSharedContacts(sharedContacts)
|
||||
.withPreviews(previews);
|
||||
}
|
||||
|
||||
public static class Factory implements Job.Factory<PushGroupSendJob> {
|
||||
@Override
|
||||
public @NonNull PushGroupSendJob create(@NonNull Parameters parameters, @NonNull Data data) {
|
||||
|
@@ -245,7 +245,9 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
|
||||
{
|
||||
try {
|
||||
Recipient recipient = Recipient.from(context, destination, false);
|
||||
String userPublicKey = TextSecurePreferences.getLocalNumber(context);
|
||||
SignalServiceAddress address = getPushAddress(recipient.getAddress());
|
||||
SignalServiceAddress localAddress = new SignalServiceAddress(userPublicKey);
|
||||
List<Attachment> attachments = Stream.of(message.getAttachments()).filterNot(Attachment::isSticker).toList();
|
||||
List<SignalServiceAttachment> serviceAttachments = getAttachmentPointersFor(attachments);
|
||||
Optional<byte[]> profileKey = getProfileKey(message.getRecipient());
|
||||
@@ -254,6 +256,8 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
|
||||
List<SharedContact> sharedContacts = getSharedContactsFor(message);
|
||||
List<Preview> previews = getPreviewsFor(message);
|
||||
|
||||
Optional<UnidentifiedAccessPair> unidentifiedAccessPair = UnidentifiedAccessUtil.getAccessFor(context, recipient);
|
||||
|
||||
SignalServiceDataMessage mediaMessage = SignalServiceDataMessage.newBuilder()
|
||||
.withBody(message.getBody())
|
||||
.withAttachments(serviceAttachments)
|
||||
@@ -267,6 +271,20 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
|
||||
.asExpirationUpdate(message.isExpirationUpdate())
|
||||
.build();
|
||||
|
||||
SignalServiceDataMessage mediaSelfSendMessage = SignalServiceDataMessage.newBuilder()
|
||||
.withBody(message.getBody())
|
||||
.withAttachments(serviceAttachments)
|
||||
.withTimestamp(message.getSentTimeMillis())
|
||||
.withSyncTarget(destination.serialize())
|
||||
.withExpiration((int)(message.getExpiresIn() / 1000))
|
||||
.withProfileKey(profileKey.orNull())
|
||||
.withQuote(quote.orNull())
|
||||
.withSticker(sticker.orNull())
|
||||
.withSharedContacts(sharedContacts)
|
||||
.withPreviews(previews)
|
||||
.asExpirationUpdate(message.isExpirationUpdate())
|
||||
.build();
|
||||
|
||||
if (SessionMetaProtocol.shared.isNoteToSelf(address.getNumber())) {
|
||||
// Loki - Device link messages don't go through here
|
||||
Optional<UnidentifiedAccessPair> syncAccess = UnidentifiedAccessUtil.getAccessForSync(context);
|
||||
@@ -275,11 +293,24 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType {
|
||||
messageSender.sendMessage(syncMessage, syncAccess);
|
||||
return syncAccess.isPresent();
|
||||
} else {
|
||||
SendMessageResult result = messageSender.sendMessage(messageId, address, UnidentifiedAccessUtil.getAccessFor(context, recipient), mediaMessage);
|
||||
SendMessageResult result = messageSender.sendMessage(messageId, address, unidentifiedAccessPair, mediaMessage);
|
||||
if (result.getLokiAPIError() != null) {
|
||||
throw result.getLokiAPIError();
|
||||
} else {
|
||||
return result.getSuccess().isUnidentified();
|
||||
boolean isUnidentified = result.getSuccess().isUnidentified();
|
||||
|
||||
try {
|
||||
// send to ourselves to sync multi-device
|
||||
Optional<UnidentifiedAccessPair> syncAccess = UnidentifiedAccessUtil.getAccessForSync(context);
|
||||
SendMessageResult selfSendResult = messageSender.sendMessage(messageId, localAddress, syncAccess, mediaSelfSendMessage);
|
||||
if (selfSendResult.getLokiAPIError() != null) {
|
||||
throw selfSendResult.getLokiAPIError();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e("Loki", "Error sending message to ourselves", e);
|
||||
}
|
||||
|
||||
return isUnidentified;
|
||||
}
|
||||
}
|
||||
} catch (UnregisteredUserException e) {
|
||||
|
@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.jobs;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.session.libsession.messaging.jobs.Data;
|
||||
import org.session.libsignal.service.api.crypto.UnidentifiedAccess;
|
||||
import org.session.libsignal.utilities.logging.Log;
|
||||
|
||||
import org.session.libsession.messaging.threads.Address;
|
||||
@@ -192,8 +193,10 @@ public class PushTextSendJob extends PushSendJob implements InjectableType {
|
||||
throws UntrustedIdentityException, InsecureFallbackApprovalException, RetryLaterException, SnodeAPI.Error
|
||||
{
|
||||
try {
|
||||
String userPublicKey = TextSecurePreferences.getLocalNumber(context);
|
||||
Recipient recipient = Recipient.from(context, destination, false);
|
||||
SignalServiceAddress address = getPushAddress(recipient.getAddress());
|
||||
SignalServiceAddress localAddress = new SignalServiceAddress(userPublicKey);
|
||||
Optional<byte[]> profileKey = getProfileKey(recipient);
|
||||
Optional<UnidentifiedAccessPair> unidentifiedAccess = UnidentifiedAccessUtil.getAccessFor(context, recipient);
|
||||
|
||||
@@ -205,13 +208,21 @@ public class PushTextSendJob extends PushSendJob implements InjectableType {
|
||||
// }
|
||||
|
||||
SignalServiceDataMessage textSecureMessage = SignalServiceDataMessage.newBuilder()
|
||||
.withTimestamp(message.getDateSent())
|
||||
.withBody(message.getBody())
|
||||
.withExpiration((int)(message.getExpiresIn() / 1000))
|
||||
.withProfileKey(profileKey.orNull())
|
||||
// .withPreKeyBundle(preKeyBundle)
|
||||
.asEndSessionMessage(message.isEndSession())
|
||||
.build();
|
||||
.withTimestamp(message.getDateSent())
|
||||
.withBody(message.getBody())
|
||||
.withExpiration((int)(message.getExpiresIn() / 1000))
|
||||
.withProfileKey(profileKey.orNull())
|
||||
.asEndSessionMessage(message.isEndSession())
|
||||
.build();
|
||||
|
||||
SignalServiceDataMessage textSecureSelfSendMessage = SignalServiceDataMessage.newBuilder()
|
||||
.withTimestamp(message.getDateSent())
|
||||
.withBody(message.getBody())
|
||||
.withSyncTarget(destination.serialize())
|
||||
.withExpiration((int)(message.getExpiresIn() / 1000))
|
||||
.withProfileKey(profileKey.orNull())
|
||||
.asEndSessionMessage(message.isEndSession())
|
||||
.build();
|
||||
|
||||
if (SessionMetaProtocol.shared.isNoteToSelf(address.getNumber())) {
|
||||
// Loki - Device link messages don't go through here
|
||||
@@ -225,7 +236,19 @@ public class PushTextSendJob extends PushSendJob implements InjectableType {
|
||||
if (result.getLokiAPIError() != null) {
|
||||
throw result.getLokiAPIError();
|
||||
} else {
|
||||
return result.getSuccess().isUnidentified();
|
||||
boolean isUnidentified = result.getSuccess().isUnidentified();
|
||||
|
||||
try {
|
||||
// send to ourselves to sync multi-device
|
||||
Optional<UnidentifiedAccessPair> syncAccess = UnidentifiedAccessUtil.getAccessForSync(context);
|
||||
SendMessageResult selfSendResult = messageSender.sendMessage(messageId, localAddress, syncAccess, textSecureSelfSendMessage);
|
||||
if (selfSendResult.getLokiAPIError() != null) {
|
||||
throw selfSendResult.getLokiAPIError();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e("Loki", "Error sending message to ourselves", e);
|
||||
}
|
||||
return isUnidentified;
|
||||
}
|
||||
}
|
||||
} catch (UnregisteredUserException e) {
|
||||
|
@@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.loki.protocol
|
||||
|
||||
import com.google.protobuf.ByteString
|
||||
import org.session.libsession.messaging.jobs.Data
|
||||
import org.session.libsignal.libsignal.util.guava.Optional
|
||||
import org.thoughtcrime.securesms.ApplicationContext
|
||||
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil
|
||||
import org.thoughtcrime.securesms.jobmanager.Job
|
||||
@@ -128,7 +129,7 @@ class ClosedGroupUpdateMessageSendJob private constructor(parameters: Parameters
|
||||
// isClosedGroup can always be false as it's only used in the context of legacy closed groups
|
||||
messageSender.sendMessage(0, address, udAccess.get().targetUnidentifiedAccess,
|
||||
Date().time, serializedContentMessage, false, ttl, false,
|
||||
useFallbackEncryption, false, false, false)
|
||||
useFallbackEncryption, false, false, Optional.absent())
|
||||
} catch (e: Exception) {
|
||||
Log.d("Loki", "Failed to send closed group update message to: $destination due to error: $e.")
|
||||
}
|
||||
|
@@ -9,6 +9,7 @@ import org.session.libsession.messaging.jobs.Data
|
||||
import org.session.libsignal.libsignal.ecc.DjbECPrivateKey
|
||||
import org.session.libsignal.libsignal.ecc.DjbECPublicKey
|
||||
import org.session.libsignal.libsignal.ecc.ECKeyPair
|
||||
import org.session.libsignal.libsignal.util.guava.Optional
|
||||
import org.session.libsignal.service.api.push.SignalServiceAddress
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||
import org.session.libsignal.service.loki.protocol.meta.TTLUtilities
|
||||
@@ -221,7 +222,7 @@ class ClosedGroupUpdateMessageSendJobV2 private constructor(parameters: Paramete
|
||||
// isClosedGroup can always be false as it's only used in the context of legacy closed groups
|
||||
messageSender.sendMessage(0, address, udAccess.get().targetUnidentifiedAccess,
|
||||
Date().time, serializedContentMessage, false, ttl, false,
|
||||
true, false, false, false)
|
||||
true, false, false, Optional.absent())
|
||||
} catch (e: Exception) {
|
||||
Log.d("Loki", "Failed to send closed group update message to: $destination due to error: $e.")
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint
|
||||
import org.thoughtcrime.securesms.jobs.BaseJob
|
||||
import org.session.libsignal.utilities.logging.Log
|
||||
import org.session.libsession.messaging.threads.recipients.Recipient
|
||||
import org.session.libsignal.libsignal.util.guava.Optional
|
||||
import org.session.libsignal.service.api.push.SignalServiceAddress
|
||||
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||
import org.session.libsignal.service.loki.protocol.meta.TTLUtilities
|
||||
@@ -56,7 +57,7 @@ class NullMessageSendJob private constructor(parameters: Parameters, private val
|
||||
try {
|
||||
messageSender.sendMessage(0, address, udAccess.get().targetUnidentifiedAccess,
|
||||
Date().time, serializedContentMessage, false, ttl, false,
|
||||
false, false, false, false)
|
||||
false, false, false, Optional.absent())
|
||||
} catch (e: Exception) {
|
||||
Log.d("Loki", "Failed to send null message to: $publicKey due to error: $e.")
|
||||
throw e
|
||||
|
@@ -6,12 +6,7 @@ public class IncomingEncryptedMessage extends IncomingTextMessage {
|
||||
super(base, newBody);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IncomingTextMessage withMessageBody(String body) {
|
||||
return new IncomingEncryptedMessage(this, body);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public boolean isSecureMessage() {
|
||||
return true;
|
||||
}
|
||||
|
@@ -10,12 +10,7 @@ public class IncomingEndSessionMessage extends IncomingTextMessage {
|
||||
super(base, newBody);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IncomingEndSessionMessage withMessageBody(String messageBody) {
|
||||
return new IncomingEndSessionMessage(this, messageBody);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public boolean isEndSession() {
|
||||
return true;
|
||||
}
|
||||
|
@@ -11,12 +11,7 @@ public class IncomingGroupMessage extends IncomingTextMessage {
|
||||
this.groupContext = groupContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IncomingGroupMessage withMessageBody(String body) {
|
||||
return new IncomingGroupMessage(this, groupContext, body);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public boolean isGroup() {
|
||||
return true;
|
||||
}
|
||||
|
@@ -9,12 +9,7 @@ public class IncomingPreKeyBundleMessage extends IncomingTextMessage {
|
||||
this.legacy = legacy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IncomingPreKeyBundleMessage withMessageBody(String messageBody) {
|
||||
return new IncomingPreKeyBundleMessage(this, messageBody, legacy);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public boolean isLegacyPreKeyBundle() {
|
||||
return legacy;
|
||||
}
|
||||
|
@@ -175,10 +175,6 @@ public class IncomingTextMessage implements Parcelable {
|
||||
return message;
|
||||
}
|
||||
|
||||
public IncomingTextMessage withMessageBody(String message) {
|
||||
return new IncomingTextMessage(this, message);
|
||||
}
|
||||
|
||||
public Address getSender() {
|
||||
return sender;
|
||||
}
|
||||
@@ -250,7 +246,6 @@ public class IncomingTextMessage implements Parcelable {
|
||||
public boolean isUnidentified() {
|
||||
return unidentified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user