mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-23 18:15:22 +00:00
fix: closed groups now propagate properly without self-sends
This commit is contained in:
parent
e62eb819c9
commit
fd0596f9ea
@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.jobs.AvatarDownloadJob;
|
||||
import org.thoughtcrime.securesms.jobs.PushGroupUpdateJob;
|
||||
import org.session.libsignal.utilities.logging.Log;
|
||||
@ -123,11 +124,19 @@ public class GroupMessageProcessor {
|
||||
{
|
||||
|
||||
GroupDatabase database = DatabaseFactory.getGroupDatabase(context);
|
||||
ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context);
|
||||
String id = GroupUtil.getEncodedId(group);
|
||||
Address address = Address.Companion.fromExternal(context, GroupUtil.getEncodedId(group));
|
||||
Recipient recipient = Recipient.from(context, address, false);
|
||||
|
||||
String userMasterDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context);
|
||||
if (userMasterDevice == null) { userMasterDevice = TextSecurePreferences.getLocalNumber(context); }
|
||||
|
||||
if (content.getSender().equals(userMasterDevice)) {
|
||||
long threadId = threadDatabase.getThreadIdIfExistsFor(recipient);
|
||||
return threadId == -1 ? null : threadId;
|
||||
}
|
||||
|
||||
if (group.getGroupType() == SignalServiceGroup.GroupType.SIGNAL) {
|
||||
// Loki - Only update the group if the group admin sent the message
|
||||
String masterDevice = MultiDeviceProtocol.shared.getMasterDevice(content.getSender());
|
||||
|
@ -586,11 +586,15 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
}
|
||||
|
||||
// Handle sync message from ourselves
|
||||
if (syncTarget != null && !syncTarget.isEmpty()) {
|
||||
if (syncTarget != null && !syncTarget.isEmpty() || TextSecurePreferences.getLocalNumber(context).equals(content.getSender())) {
|
||||
Address targetAddress = masterRecipient.getAddress();
|
||||
if (message.getGroupInfo().isPresent()) {
|
||||
targetAddress = Address.Companion.fromSerialized(GroupUtil.getEncodedId(message.getGroupInfo().get()));
|
||||
} else if (syncTarget != null && !syncTarget.isEmpty()) {
|
||||
targetAddress = Address.fromSerialized(syncTarget);
|
||||
}
|
||||
List<Attachment> attachments = PointerAttachment.forPointers(message.getAttachments());
|
||||
|
||||
Address targetAddress = Address.fromSerialized(syncTarget);
|
||||
|
||||
OutgoingMediaMessage mediaMessage = new OutgoingMediaMessage(masterRecipient, message.getBody().orNull(),
|
||||
attachments,
|
||||
message.getTimestamp(), -1,
|
||||
@ -618,7 +622,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
try {
|
||||
|
||||
// Check if we have the thread already
|
||||
long threadID = DatabaseFactory.getLokiThreadDatabase(context).getThreadID(syncTarget);
|
||||
long threadID = DatabaseFactory.getLokiThreadDatabase(context).getThreadID(targetAddress.serialize());
|
||||
|
||||
insertResult = database.insertSecureDecryptedMessageOutbox(mediaMessage, threadID, content.getTimestamp());
|
||||
|
||||
@ -843,8 +847,13 @@ 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() || TextSecurePreferences.getLocalNumber(context).equals(content.getSender())) {
|
||||
Address targetAddress = masterRecipient.getAddress();
|
||||
if (message.getGroupInfo().isPresent()) {
|
||||
targetAddress = Address.Companion.fromSerialized(GroupUtil.getEncodedId(message.getGroupInfo().get()));
|
||||
} else if (syncTarget != null && !syncTarget.isEmpty()) {
|
||||
Address targetAddress = Address.fromSerialized(syncTarget);
|
||||
targetAddress = Address.fromSerialized(syncTarget);
|
||||
}
|
||||
|
||||
if (DatabaseFactory.getMmsSmsDatabase(context).getMessageFor(message.getTimestamp(), targetAddress) != null) {
|
||||
Log.d("Loki","Message already exists, don't insert again");
|
||||
@ -858,7 +867,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
if (tm.getMessageBody().length() == 0) { return; }
|
||||
|
||||
// Check if we have the thread already
|
||||
long threadID = DatabaseFactory.getLokiThreadDatabase(context).getThreadID(syncTarget);
|
||||
long threadID = DatabaseFactory.getLokiThreadDatabase(context).getThreadID(targetAddress.serialize());
|
||||
|
||||
|
||||
// Insert the message into the database
|
||||
|
@ -194,22 +194,6 @@ 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());
|
||||
@ -290,7 +274,7 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
|
||||
}
|
||||
}
|
||||
|
||||
public SignalServiceDataMessage.Builder getDataMessage(Address address, OutgoingMediaMessage message) {
|
||||
public SignalServiceDataMessage.Builder getDataMessage(Address address, OutgoingMediaMessage message) throws IOException {
|
||||
|
||||
SignalServiceGroup.GroupType groupType = address.isOpenGroup() ? SignalServiceGroup.GroupType.PUBLIC_CHAT : SignalServiceGroup.GroupType.SIGNAL;
|
||||
|
||||
|
@ -18,10 +18,11 @@ import org.thoughtcrime.securesms.loki.utilities.KeyPairUtilities
|
||||
|
||||
class SessionProtocolImpl(private val context: Context) : SessionProtocol {
|
||||
|
||||
private val sodium by lazy { LazySodiumAndroid(SodiumAndroid()) }
|
||||
|
||||
override fun encrypt(plaintext: ByteArray, recipientHexEncodedX25519PublicKey: String): ByteArray {
|
||||
val userED25519KeyPair = KeyPairUtilities.getUserED25519KeyPair(context) ?: throw SessionProtocol.Exception.NoUserED25519KeyPair
|
||||
val recipientX25519PublicKey = Hex.fromStringCondensed(recipientHexEncodedX25519PublicKey.removing05PrefixIfNeeded())
|
||||
val sodium = LazySodiumAndroid(SodiumAndroid())
|
||||
|
||||
val verificationData = plaintext + userED25519KeyPair.publicKey.asBytes + recipientX25519PublicKey
|
||||
val signature = ByteArray(Sign.BYTES)
|
||||
@ -47,7 +48,6 @@ class SessionProtocolImpl(private val context: Context) : SessionProtocol {
|
||||
val recipientX25519PrivateKey = x25519KeyPair.privateKey.serialize()
|
||||
val recipientX25519PublicKey = Hex.fromStringCondensed(x25519KeyPair.hexEncodedPublicKey.removing05PrefixIfNeeded())
|
||||
Log.d("Test", "recipientX25519PublicKey: $recipientX25519PublicKey")
|
||||
val sodium = LazySodiumAndroid(SodiumAndroid())
|
||||
val signatureSize = Sign.BYTES
|
||||
val ed25519PublicKeySize = Sign.PUBLICKEYBYTES
|
||||
|
||||
|
@ -70,7 +70,6 @@ object ClosedGroupsProtocolV2 {
|
||||
// Send a closed group update message to all members individually
|
||||
val closedGroupUpdateKind = ClosedGroupUpdateMessageSendJobV2.Kind.New(Hex.fromStringCondensed(groupPublicKey), name, encryptionKeyPair, membersAsData, adminsAsData)
|
||||
for (member in members) {
|
||||
if (member == userPublicKey) { continue }
|
||||
val job = ClosedGroupUpdateMessageSendJobV2(member, closedGroupUpdateKind)
|
||||
job.setContext(context)
|
||||
job.onRun() // Run the job immediately to make all of this sync
|
||||
|
@ -14,7 +14,7 @@ import org.session.libsignal.libsignal.ecc.ECKeyPair
|
||||
|
||||
object KeyPairUtilities {
|
||||
|
||||
private val sodium = LazySodiumAndroid(SodiumAndroid())
|
||||
private val sodium by lazy { LazySodiumAndroid(SodiumAndroid()) }
|
||||
|
||||
fun generate(): KeyPairGenerationResult {
|
||||
val seed = sodium.randomBytesBuf(16)
|
||||
|
@ -13,7 +13,7 @@ import org.session.libsignal.service.api.crypto.UnidentifiedAccessPair
|
||||
|
||||
object UnidentifiedAccessUtil {
|
||||
private val TAG = UnidentifiedAccessUtil::class.simpleName
|
||||
private val sodium = LazySodiumAndroid(SodiumAndroid())
|
||||
private val sodium by lazy { LazySodiumAndroid(SodiumAndroid()) }
|
||||
|
||||
fun getAccessFor(recipientPublicKey: String): UnidentifiedAccessPair? {
|
||||
try {
|
||||
|
@ -331,7 +331,6 @@ public class SignalServiceCipher {
|
||||
kotlin.Pair<byte[], String> plaintextAndSenderPublicKey = SessionProtocolUtilities.INSTANCE.decryptClosedGroupCiphertext(ciphertext, groupPublicKey, apiDB, sessionProtocolImpl);
|
||||
paddedMessage = plaintextAndSenderPublicKey.getFirst();
|
||||
String senderPublicKey = plaintextAndSenderPublicKey.getSecond();
|
||||
if (senderPublicKey.equals(localAddress.getNumber())) { throw new SelfSendException(); } // Will be caught and ignored in PushDecryptJob
|
||||
metadata = new Metadata(senderPublicKey, 1, envelope.getTimestamp(), false);
|
||||
sessionVersion = sessionCipher.getSessionVersion();
|
||||
} else if (envelope.isPreKeySignalMessage()) {
|
||||
|
Loading…
Reference in New Issue
Block a user