mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-03-02 07:23:38 +00:00
Update to the standard SignalService.proto
This commit is contained in:
@@ -258,7 +258,7 @@ object MessageContentFuzzer {
|
||||
authorServiceId = Recipient.resolved(message.first).requireAci().toString(),
|
||||
sentTimestamp = message.second
|
||||
),
|
||||
uuid = uuid?.let { UuidUtil.toByteString(it) },
|
||||
clientUuid = uuid?.let { UuidUtil.toByteString(it) },
|
||||
fallbackDigest = digest?.toByteString(),
|
||||
fallbackPlaintextHash = plainTextHash?.let { Base64.decodeOrNull(it)?.toByteString() }
|
||||
)
|
||||
|
||||
@@ -1525,7 +1525,7 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl
|
||||
@JvmStatic
|
||||
fun from(event: CallEvent.Event?): Event? {
|
||||
return when (event) {
|
||||
null, CallEvent.Event.UNKNOWN_ACTION, CallEvent.Event.OBSERVED -> null
|
||||
null, CallEvent.Event.UNKNOWN_EVENT, CallEvent.Event.OBSERVED -> null
|
||||
CallEvent.Event.ACCEPTED -> ACCEPTED
|
||||
CallEvent.Event.NOT_ACCEPTED -> NOT_ACCEPTED
|
||||
CallEvent.Event.DELETE -> DELETE
|
||||
|
||||
@@ -70,7 +70,7 @@ class CallLinkUpdateSendJob private constructor(
|
||||
|
||||
val callLinkUpdate = CallLinkUpdate(
|
||||
rootKey = callLink.credentials.linkKeyBytes.toByteString(),
|
||||
adminPassKey = callLink.credentials.adminPassBytes?.toByteString(),
|
||||
adminPasskey = callLink.credentials.adminPassBytes?.toByteString(),
|
||||
type = callLinkUpdateType
|
||||
)
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ class MultiDeviceCallLinkSyncJob private constructor(
|
||||
.build(),
|
||||
CallLinkUpdate(
|
||||
rootKey = credentials.linkKeyBytes.toByteString(),
|
||||
adminPassKey = credentials.adminPassBytes!!.toByteString()
|
||||
adminPasskey = credentials.adminPassBytes!!.toByteString()
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.jobs
|
||||
import org.signal.core.util.isAbsent
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.libsignal.protocol.InvalidMessageException
|
||||
import org.thoughtcrime.securesms.database.IdentityTable.VerifiedStatus
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.jobmanager.Job
|
||||
@@ -16,7 +15,6 @@ import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContact
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContactsInputStream
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage.VerifiedState
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress
|
||||
import org.whispersystems.signalservice.api.push.exceptions.MissingConfigurationException
|
||||
import org.whispersystems.signalservice.api.util.AttachmentPointerUtil
|
||||
@@ -103,42 +101,6 @@ class MultiDeviceContactSyncJob(parameters: Parameters, private val attachmentPo
|
||||
}
|
||||
}
|
||||
|
||||
if (contact.profileKey.isPresent) {
|
||||
val profileKey = contact.profileKey.get()
|
||||
recipients.setProfileKey(recipient.id, profileKey)
|
||||
}
|
||||
|
||||
if (contact.verified.isPresent) {
|
||||
val verifiedStatus: VerifiedStatus = when (contact.verified.get().verified) {
|
||||
VerifiedState.VERIFIED -> VerifiedStatus.VERIFIED
|
||||
VerifiedState.UNVERIFIED -> VerifiedStatus.UNVERIFIED
|
||||
else -> VerifiedStatus.DEFAULT
|
||||
}
|
||||
|
||||
if (recipient.serviceId.isPresent) {
|
||||
AppDependencies.protocolStore.aci().identities().saveIdentityWithoutSideEffects(
|
||||
recipient.id,
|
||||
recipient.serviceId.get(),
|
||||
contact.verified.get().identityKey,
|
||||
verifiedStatus,
|
||||
false,
|
||||
contact.verified.get().timestamp,
|
||||
true
|
||||
)
|
||||
} else {
|
||||
Log.w(TAG, "Missing serviceId for ${recipient.id} -- cannot save identity!")
|
||||
}
|
||||
}
|
||||
|
||||
val threadRecord = threads.getThreadRecord(threads.getThreadIdFor(recipient.id))
|
||||
if (threadRecord != null && contact.isArchived != threadRecord.isArchived) {
|
||||
if (contact.isArchived) {
|
||||
threads.archiveConversation(threadRecord.threadId)
|
||||
} else {
|
||||
threads.unarchiveConversation(threadRecord.threadId)
|
||||
}
|
||||
}
|
||||
|
||||
if (contact.avatar.isPresent) {
|
||||
try {
|
||||
AvatarHelper.setSyncAvatar(context, recipient.id, contact.avatar.get().inputStream)
|
||||
|
||||
@@ -157,8 +157,6 @@ public class MultiDeviceContactUpdateJob extends BaseJob {
|
||||
return;
|
||||
}
|
||||
|
||||
Optional<IdentityRecord> identityRecord = AppDependencies.getProtocolStore().aci().identities().getIdentityRecord(recipient.getId());
|
||||
Optional<VerifiedMessage> verifiedMessage = getVerifiedMessage(recipient, identityRecord);
|
||||
Map<RecipientId, Integer> inboxPositions = SignalDatabase.threads().getInboxPositions();
|
||||
Set<RecipientId> archived = SignalDatabase.threads().getArchivedRecipients();
|
||||
|
||||
@@ -166,14 +164,10 @@ public class MultiDeviceContactUpdateJob extends BaseJob {
|
||||
recipient.getE164(),
|
||||
Optional.ofNullable(recipient.isGroup() || recipient.isSystemContact() ? recipient.getDisplayName(context) : null),
|
||||
getSystemAvatar(recipient.getContactUri()),
|
||||
Optional.of(ChatColorsMapper.getMaterialColor(recipient.getChatColors()).serialize()),
|
||||
verifiedMessage,
|
||||
ProfileKeyUtil.profileKeyOptional(recipient.getProfileKey()),
|
||||
recipient.getExpiresInSeconds() > 0 ? Optional.of(recipient.getExpiresInSeconds())
|
||||
: Optional.empty(),
|
||||
Optional.of(recipient.getExpireTimerVersion()),
|
||||
Optional.ofNullable(inboxPositions.get(recipientId)),
|
||||
archived.contains(recipientId)));
|
||||
Optional.ofNullable(inboxPositions.get(recipientId))));
|
||||
|
||||
out.close();
|
||||
updateUri = writeDetails.getUri();
|
||||
@@ -185,7 +179,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob {
|
||||
length,
|
||||
false);
|
||||
|
||||
} catch(InvalidNumberException | InterruptedException e) {
|
||||
} catch(InterruptedException e) {
|
||||
Log.w(TAG, e);
|
||||
} finally {
|
||||
if (updateUri != null) {
|
||||
@@ -222,10 +216,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob {
|
||||
|
||||
for (Recipient recipient : recipients) {
|
||||
Optional<IdentityRecord> identity = AppDependencies.getProtocolStore().aci().identities().getIdentityRecord(recipient.getId());
|
||||
Optional<VerifiedMessage> verified = getVerifiedMessage(recipient, identity);
|
||||
Optional<String> name = Optional.ofNullable(recipient.isSystemContact() ? recipient.getDisplayName(context) : recipient.getGroupName(context));
|
||||
Optional<ProfileKey> profileKey = ProfileKeyUtil.profileKeyOptional(recipient.getProfileKey());
|
||||
boolean blocked = recipient.isBlocked();
|
||||
Optional<Integer> expireTimer = recipient.getExpiresInSeconds() > 0 ? Optional.of(recipient.getExpiresInSeconds()) : Optional.empty();
|
||||
Optional<Integer> expireTimerVersion = Optional.of(recipient.getExpireTimerVersion());
|
||||
Optional<Integer> inboxPosition = Optional.ofNullable(inboxPositions.get(recipient.getId()));
|
||||
@@ -234,13 +225,9 @@ public class MultiDeviceContactUpdateJob extends BaseJob {
|
||||
recipient.getE164(),
|
||||
name,
|
||||
getSystemAvatar(recipient.getContactUri()),
|
||||
Optional.of(ChatColorsMapper.getMaterialColor(recipient.getChatColors()).serialize()),
|
||||
verified,
|
||||
profileKey,
|
||||
expireTimer,
|
||||
expireTimerVersion,
|
||||
inboxPosition,
|
||||
archived.contains(recipient.getId())));
|
||||
inboxPosition));
|
||||
}
|
||||
|
||||
|
||||
@@ -252,13 +239,9 @@ public class MultiDeviceContactUpdateJob extends BaseJob {
|
||||
Optional.of(SignalStore.account().getE164()),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.of(ChatColorsMapper.getMaterialColor(self.getChatColors()).serialize()),
|
||||
Optional.empty(),
|
||||
ProfileKeyUtil.profileKeyOptionalOrThrow(self.getProfileKey()),
|
||||
self.getExpiresInSeconds() > 0 ? Optional.of(self.getExpiresInSeconds()) : Optional.empty(),
|
||||
Optional.of(self.getExpireTimerVersion()),
|
||||
Optional.ofNullable(inboxPositions.get(self.getId())),
|
||||
archived.contains(self.getId())));
|
||||
Optional.ofNullable(inboxPositions.get(self.getId()))));
|
||||
}
|
||||
|
||||
out.close();
|
||||
@@ -271,7 +254,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob {
|
||||
BlobProvider.getInstance().getStream(context, updateUri),
|
||||
length,
|
||||
true);
|
||||
} catch(InvalidNumberException | InterruptedException e) {
|
||||
} catch(InterruptedException e) {
|
||||
Log.w(TAG, e);
|
||||
} finally {
|
||||
if (updateUri != null) {
|
||||
|
||||
@@ -316,7 +316,7 @@ class MultiDeviceDeleteSyncJob private constructor(
|
||||
DeleteForMe.AttachmentDelete(
|
||||
conversation = conversation,
|
||||
targetMessage = targetMessage,
|
||||
uuid = it.uuid,
|
||||
clientUuid = it.uuid,
|
||||
fallbackDigest = it.digest,
|
||||
fallbackPlaintextHash = it.plaintextHash
|
||||
)
|
||||
|
||||
@@ -81,11 +81,7 @@ public class MultiDeviceProfileKeyUpdateJob extends BaseJob {
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
profileKey,
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
Optional.empty(),
|
||||
false));
|
||||
Optional.empty()));
|
||||
|
||||
out.close();
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class RefreshCallLinkDetailsJob private constructor(
|
||||
val manager: SignalCallLinkManager = AppDependencies.signalCallManager.callLinkManager
|
||||
val credentials = CallLinkCredentials(
|
||||
linkKeyBytes = callLinkUpdate.rootKey!!.toByteArray(),
|
||||
adminPassBytes = callLinkUpdate.adminPassKey?.toByteArray()
|
||||
adminPassBytes = callLinkUpdate.adminPasskey?.toByteArray()
|
||||
)
|
||||
|
||||
when (val result = manager.readCallLink(credentials).safeBlockingGet()) {
|
||||
|
||||
@@ -274,7 +274,7 @@ class IncomingMessageObserver(private val context: Application, private val sign
|
||||
@VisibleForTesting
|
||||
fun processEnvelope(bufferedProtocolStore: BufferedProtocolStore, envelope: Envelope, serverDeliveredTimestamp: Long): List<FollowUpOperation>? {
|
||||
return when (envelope.type) {
|
||||
Envelope.Type.RECEIPT -> {
|
||||
Envelope.Type.SERVER_DELIVERY_RECEIPT -> {
|
||||
processReceipt(envelope)
|
||||
null
|
||||
}
|
||||
|
||||
@@ -197,9 +197,9 @@ object MessageDecryptor {
|
||||
}
|
||||
|
||||
// TODO We can move this to the "message processing" stage once we give it access to the envelope. But for now it'll stay here.
|
||||
if (envelope.reportingToken != null && envelope.reportingToken!!.size > 0) {
|
||||
if (envelope.report_spam_token != null && envelope.report_spam_token!!.size > 0) {
|
||||
val sender = RecipientId.from(cipherResult.metadata.sourceServiceId)
|
||||
SignalDatabase.recipients.setReportingToken(sender, envelope.reportingToken!!.toByteArray())
|
||||
SignalDatabase.recipients.setReportingToken(sender, envelope.report_spam_token!!.toByteArray())
|
||||
}
|
||||
|
||||
Result.Success(envelope, serverDeliveredTimestamp, cipherResult.content, cipherResult.metadata, followUpOperations.toUnmodifiableList())
|
||||
|
||||
@@ -157,7 +157,6 @@ object SyncMessageProcessor {
|
||||
syncMessage.fetchLatest?.type != null -> handleSynchronizeFetchMessage(syncMessage.fetchLatest!!.type!!, envelope.timestamp!!)
|
||||
syncMessage.messageRequestResponse != null -> handleSynchronizeMessageRequestResponse(syncMessage.messageRequestResponse!!, envelope.timestamp!!)
|
||||
syncMessage.outgoingPayment != null -> handleSynchronizeOutgoingPayment(syncMessage.outgoingPayment!!, envelope.timestamp!!)
|
||||
syncMessage.keys?.storageService != null -> handleSynchronizeKeys(syncMessage.keys!!.storageService!!, envelope.timestamp!!)
|
||||
syncMessage.contacts != null -> handleSynchronizeContacts(syncMessage.contacts!!, envelope.timestamp!!)
|
||||
syncMessage.callEvent != null -> handleSynchronizeCallEvent(syncMessage.callEvent!!, envelope.timestamp!!)
|
||||
syncMessage.callLinkUpdate != null -> handleSynchronizeCallLink(syncMessage.callLinkUpdate!!, envelope.timestamp!!)
|
||||
@@ -262,7 +261,7 @@ object SyncMessageProcessor {
|
||||
|
||||
private fun handlePniIdentityKeys(envelope: Envelope, sent: Sent) {
|
||||
for (status in sent.unidentifiedStatus) {
|
||||
if (status.destinationIdentityKey == null) {
|
||||
if (status.destinationPniIdentityKey == null) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -280,7 +279,7 @@ object SyncMessageProcessor {
|
||||
|
||||
try {
|
||||
log(envelope.timestamp!!, "Saving identity from sent transcript for $pni")
|
||||
val identityKey = IdentityKey(status.destinationIdentityKey!!.toByteArray())
|
||||
val identityKey = IdentityKey(status.destinationPniIdentityKey!!.toByteArray())
|
||||
AppDependencies.protocolStore.aci().identities().saveIdentity(address, identityKey)
|
||||
} catch (e: InvalidKeyException) {
|
||||
warn(envelope.timestamp!!, "Failed to deserialize identity key for $pni")
|
||||
@@ -1262,7 +1261,7 @@ object SyncMessageProcessor {
|
||||
}
|
||||
|
||||
private fun handleSynchronizeCallEvent(callEvent: SyncMessage.CallEvent, envelopeTimestamp: Long) {
|
||||
if (callEvent.id == null) {
|
||||
if (callEvent.callId == null) {
|
||||
log(envelopeTimestamp, "Synchronize call event missing call id, ignoring. type: ${callEvent.type}")
|
||||
return
|
||||
}
|
||||
@@ -1346,7 +1345,7 @@ object SyncMessageProcessor {
|
||||
roomId,
|
||||
CallLinkCredentials(
|
||||
callLinkUpdate.rootKey!!.toByteArray(),
|
||||
callLinkUpdate.adminPassKey?.toByteArray()
|
||||
callLinkUpdate.adminPasskey?.toByteArray()
|
||||
)
|
||||
)
|
||||
} else {
|
||||
@@ -1357,7 +1356,7 @@ object SyncMessageProcessor {
|
||||
roomId = roomId,
|
||||
credentials = CallLinkCredentials(
|
||||
linkKeyBytes = callLinkRootKey.keyBytes,
|
||||
adminPassBytes = callLinkUpdate.adminPassKey?.toByteArray()
|
||||
adminPassBytes = callLinkUpdate.adminPasskey?.toByteArray()
|
||||
),
|
||||
state = SignalCallLinkState(),
|
||||
deletionTimestamp = 0L
|
||||
@@ -1371,7 +1370,7 @@ object SyncMessageProcessor {
|
||||
}
|
||||
|
||||
private fun handleSynchronizeOneToOneCallEvent(callEvent: SyncMessage.CallEvent, envelopeTimestamp: Long) {
|
||||
val callId: Long = callEvent.id!!
|
||||
val callId: Long = callEvent.callId!!
|
||||
val timestamp: Long = callEvent.timestamp ?: 0L
|
||||
val type: CallTable.Type? = CallTable.Type.from(callEvent.type)
|
||||
val direction: CallTable.Direction? = CallTable.Direction.from(callEvent.direction)
|
||||
@@ -1410,7 +1409,7 @@ object SyncMessageProcessor {
|
||||
|
||||
@Throws(BadGroupIdException::class)
|
||||
private fun handleSynchronizeGroupOrAdHocCallEvent(callEvent: SyncMessage.CallEvent, envelopeTimestamp: Long) {
|
||||
val callId: Long = callEvent.id!!
|
||||
val callId: Long = callEvent.callId!!
|
||||
val timestamp: Long = callEvent.timestamp ?: 0L
|
||||
val type: CallTable.Type? = CallTable.Type.from(callEvent.type)
|
||||
val direction: CallTable.Direction? = CallTable.Direction.from(callEvent.direction)
|
||||
@@ -1491,11 +1490,11 @@ object SyncMessageProcessor {
|
||||
}
|
||||
} else {
|
||||
when (event) {
|
||||
CallTable.Event.DELETE -> SignalDatabase.calls.insertDeletedCallFromSyncEvent(callEvent.id!!, recipient.id, type, direction, timestamp)
|
||||
CallTable.Event.ACCEPTED -> SignalDatabase.calls.insertAcceptedGroupCall(callEvent.id!!, recipient.id, direction, timestamp)
|
||||
CallTable.Event.DELETE -> SignalDatabase.calls.insertDeletedCallFromSyncEvent(callEvent.callId!!, recipient.id, type, direction, timestamp)
|
||||
CallTable.Event.ACCEPTED -> SignalDatabase.calls.insertAcceptedGroupCall(callEvent.callId!!, recipient.id, direction, timestamp)
|
||||
CallTable.Event.NOT_ACCEPTED -> {
|
||||
if (callEvent.direction == SyncMessage.CallEvent.Direction.INCOMING) {
|
||||
SignalDatabase.calls.insertDeclinedGroupCall(callEvent.id!!, recipient.id, timestamp)
|
||||
SignalDatabase.calls.insertDeclinedGroupCall(callEvent.callId!!, recipient.id, timestamp)
|
||||
} else {
|
||||
warn(envelopeTimestamp, "Invalid direction OUTGOING for event NOT_ACCEPTED for non-existing call")
|
||||
}
|
||||
@@ -1677,7 +1676,7 @@ object SyncMessageProcessor {
|
||||
}
|
||||
|
||||
private fun SyncMessage.DeleteForMe.AttachmentDelete.toSyncAttachmentId(syncMessageId: MessageTable.SyncMessageId?, envelopeTimestamp: Long): AttachmentTable.SyncAttachmentId? {
|
||||
val uuid = UuidUtil.fromByteStringOrNull(uuid)
|
||||
val uuid = UuidUtil.fromByteStringOrNull(clientUuid)
|
||||
val digest = fallbackDigest?.toByteArray()
|
||||
val plaintextHash = fallbackPlaintextHash?.let { Base64.encodeWithPadding(it.toByteArray()) }
|
||||
|
||||
|
||||
@@ -61,12 +61,6 @@ public final class MessageGroupContext {
|
||||
}
|
||||
}
|
||||
|
||||
public MessageGroupContext(@NonNull GroupContext group) {
|
||||
this.groupV1 = new GroupV1Properties(group);
|
||||
this.groupV2 = null;
|
||||
this.group = groupV1;
|
||||
}
|
||||
|
||||
public MessageGroupContext(@NonNull DecryptedGroupV2Context group) {
|
||||
this.groupV1 = null;
|
||||
this.groupV2 = new GroupV2Properties(group);
|
||||
|
||||
@@ -21,10 +21,10 @@ public final class MobileCoinPublicAddressProfileUtil {
|
||||
byte[] signature = identityKeyPair.getPrivateKey().calculateSignature(publicAddressBytes);
|
||||
|
||||
return new PaymentAddress.Builder()
|
||||
.mobileCoinAddress(new PaymentAddress.MobileCoinAddress.Builder()
|
||||
.address(ByteString.of(publicAddressBytes))
|
||||
.signature(ByteString.of(signature))
|
||||
.build())
|
||||
.mobileCoin(new PaymentAddress.MobileCoin.Builder()
|
||||
.publicAddress(ByteString.of(publicAddressBytes))
|
||||
.signature(ByteString.of(signature))
|
||||
.build())
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -37,16 +37,16 @@ public final class MobileCoinPublicAddressProfileUtil {
|
||||
@NonNull IdentityKey identityKey)
|
||||
throws PaymentsAddressException
|
||||
{
|
||||
if (paymentAddress.mobileCoinAddress == null) {
|
||||
if (paymentAddress.mobileCoin == null) {
|
||||
throw new PaymentsAddressException(PaymentsAddressException.Code.NO_ADDRESS);
|
||||
}
|
||||
|
||||
if (paymentAddress.mobileCoinAddress.address == null || paymentAddress.mobileCoinAddress.signature == null) {
|
||||
if (paymentAddress.mobileCoin.publicAddress == null || paymentAddress.mobileCoin.signature == null) {
|
||||
throw new PaymentsAddressException(PaymentsAddressException.Code.INVALID_ADDRESS_SIGNATURE);
|
||||
}
|
||||
|
||||
byte[] bytes = paymentAddress.mobileCoinAddress.address.toByteArray();
|
||||
byte[] signature = paymentAddress.mobileCoinAddress.signature.toByteArray();
|
||||
byte[] bytes = paymentAddress.mobileCoin.publicAddress.toByteArray();
|
||||
byte[] signature = paymentAddress.mobileCoin.signature.toByteArray();
|
||||
|
||||
if (signature.length != 64 || !identityKey.getPublicKey().verifySignature(bytes, signature)) {
|
||||
throw new PaymentsAddressException(PaymentsAddressException.Code.INVALID_ADDRESS_SIGNATURE);
|
||||
|
||||
@@ -83,7 +83,7 @@ object CallEventSyncMessageUtil {
|
||||
|
||||
return CallEvent(
|
||||
conversationId = conversationId,
|
||||
id = callId,
|
||||
callId = callId,
|
||||
timestamp = timestamp,
|
||||
type = callType,
|
||||
direction = if (isOutgoing) CallEvent.Direction.OUTGOING else CallEvent.Direction.INCOMING,
|
||||
|
||||
@@ -12,6 +12,7 @@ option java_package = "org.thoughtcrime.securesms.database.model.database
|
||||
option java_multiple_files = true;
|
||||
|
||||
import Backup.proto;
|
||||
import SignalServiceLegacy.proto;
|
||||
|
||||
// DEPRECATED -- only here for database migrations
|
||||
message ReactionList {
|
||||
|
||||
@@ -46,12 +46,12 @@ class MobileCoinPublicAddressProfileUtilTest {
|
||||
val identityKeyPair = IdentityKeyUtil.generateIdentityKeyPair()
|
||||
val address = Util.getSecretBytes(100)
|
||||
val signedPaymentAddress = MobileCoinPublicAddressProfileUtil.signPaymentsAddress(address, identityKeyPair)
|
||||
val mobileCoinAddress = signedPaymentAddress.mobileCoinAddress!!
|
||||
val mobileCoinAddress = signedPaymentAddress.mobileCoin!!
|
||||
|
||||
val signature = mobileCoinAddress.signature!!.toByteArray()
|
||||
signature[0] = (signature[0].toInt() xor 0x01).toByte()
|
||||
val tamperedSignature = signedPaymentAddress.newBuilder()
|
||||
.mobileCoinAddress(
|
||||
.mobileCoin(
|
||||
mobileCoinAddress
|
||||
.newBuilder()
|
||||
.signature(ByteString.of(*signature))
|
||||
@@ -69,15 +69,15 @@ class MobileCoinPublicAddressProfileUtilTest {
|
||||
val identityKeyPair = IdentityKeyUtil.generateIdentityKeyPair()
|
||||
val addressBytes = Util.getSecretBytes(100)
|
||||
val signedPaymentAddress = MobileCoinPublicAddressProfileUtil.signPaymentsAddress(addressBytes, identityKeyPair)
|
||||
val mobileCoinAddress = signedPaymentAddress.mobileCoinAddress!!
|
||||
val mobileCoinAddress = signedPaymentAddress.mobileCoin!!
|
||||
|
||||
val address = mobileCoinAddress.address!!.toByteArray()
|
||||
val address = mobileCoinAddress.publicAddress!!.toByteArray()
|
||||
address[0] = (address[0].toInt() xor 0x01).toByte()
|
||||
val tamperedAddress = signedPaymentAddress.newBuilder()
|
||||
.mobileCoinAddress(
|
||||
.mobileCoin(
|
||||
mobileCoinAddress
|
||||
.newBuilder()
|
||||
.address(ByteString.of(*address))
|
||||
.publicAddress(ByteString.of(*address))
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
@@ -94,8 +94,8 @@ class MobileCoinPublicAddressProfileUtilTest {
|
||||
val signedPaymentAddress = MobileCoinPublicAddressProfileUtil.signPaymentsAddress(address, identityKeyPair)
|
||||
|
||||
val removedSignature = signedPaymentAddress.newBuilder()
|
||||
.mobileCoinAddress(
|
||||
signedPaymentAddress.mobileCoinAddress!!
|
||||
.mobileCoin(
|
||||
signedPaymentAddress.mobileCoin!!
|
||||
.newBuilder()
|
||||
.signature(null)
|
||||
.build()
|
||||
@@ -114,10 +114,10 @@ class MobileCoinPublicAddressProfileUtilTest {
|
||||
val signedPaymentAddress = MobileCoinPublicAddressProfileUtil.signPaymentsAddress(address, identityKeyPair)
|
||||
|
||||
val removedAddress = signedPaymentAddress.newBuilder()
|
||||
.mobileCoinAddress(
|
||||
signedPaymentAddress.mobileCoinAddress!!
|
||||
.mobileCoin(
|
||||
signedPaymentAddress.mobileCoin!!
|
||||
.newBuilder()
|
||||
.address(null)
|
||||
.publicAddress(null)
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
|
||||
@@ -1391,7 +1391,7 @@ public class SignalServiceMessageSender {
|
||||
unidentifiedDeliveryStatuses.add(new SyncMessage.Sent.UnidentifiedDeliveryStatus.Builder()
|
||||
.destinationServiceId(result.getAddress().getServiceId().toString())
|
||||
.unidentified(false)
|
||||
.destinationIdentityKey(identity)
|
||||
.destinationPniIdentityKey(identity)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
@@ -1665,10 +1665,6 @@ public class SignalServiceMessageSender {
|
||||
SyncMessage.Builder syncMessage = createSyncMessageBuilder();
|
||||
SyncMessage.Keys.Builder builder = new SyncMessage.Keys.Builder();
|
||||
|
||||
if (keysMessage.getStorageService() != null) {
|
||||
builder.storageService(ByteString.of(keysMessage.getStorageService().serialize()));
|
||||
}
|
||||
|
||||
if (keysMessage.getMaster() != null) {
|
||||
builder.master(ByteString.of(keysMessage.getMaster().serialize()));
|
||||
}
|
||||
|
||||
@@ -17,25 +17,17 @@ public class DeviceContact {
|
||||
private final Optional<String> e164;
|
||||
private final Optional<String> name;
|
||||
private final Optional<DeviceContactAvatar> avatar;
|
||||
private final Optional<String> color;
|
||||
private final Optional<VerifiedMessage> verified;
|
||||
private final Optional<ProfileKey> profileKey;
|
||||
private final Optional<Integer> expirationTimer;
|
||||
private final Optional<Integer> expirationTimerVersion;
|
||||
private final Optional<Integer> inboxPosition;
|
||||
private final boolean archived;
|
||||
|
||||
public DeviceContact(Optional<ACI> aci,
|
||||
Optional<String> e164,
|
||||
Optional<String> name,
|
||||
Optional<DeviceContactAvatar> avatar,
|
||||
Optional<String> color,
|
||||
Optional<VerifiedMessage> verified,
|
||||
Optional<ProfileKey> profileKey,
|
||||
Optional<Integer> expirationTimer,
|
||||
Optional<Integer> expirationTimerVersion,
|
||||
Optional<Integer> inboxPosition,
|
||||
boolean archived)
|
||||
Optional<Integer> inboxPosition)
|
||||
{
|
||||
if (aci.isEmpty() && e164.isEmpty()) {
|
||||
throw new IllegalArgumentException("Must have either ACI or E164");
|
||||
@@ -45,13 +37,9 @@ public class DeviceContact {
|
||||
this.e164 = e164;
|
||||
this.name = name;
|
||||
this.avatar = avatar;
|
||||
this.color = color;
|
||||
this.verified = verified;
|
||||
this.profileKey = profileKey;
|
||||
this.expirationTimer = expirationTimer;
|
||||
this.expirationTimerVersion = expirationTimerVersion;
|
||||
this.inboxPosition = inboxPosition;
|
||||
this.archived = archived;
|
||||
}
|
||||
|
||||
public Optional<DeviceContactAvatar> getAvatar() {
|
||||
@@ -70,18 +58,6 @@ public class DeviceContact {
|
||||
return e164;
|
||||
}
|
||||
|
||||
public Optional<String> getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public Optional<VerifiedMessage> getVerified() {
|
||||
return verified;
|
||||
}
|
||||
|
||||
public Optional<ProfileKey> getProfileKey() {
|
||||
return profileKey;
|
||||
}
|
||||
|
||||
public Optional<Integer> getExpirationTimer() {
|
||||
return expirationTimer;
|
||||
}
|
||||
@@ -93,8 +69,4 @@ public class DeviceContact {
|
||||
public Optional<Integer> getInboxPosition() {
|
||||
return inboxPosition;
|
||||
}
|
||||
|
||||
public boolean isArchived() {
|
||||
return archived;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,13 +50,9 @@ public class DeviceContactsInputStream extends ChunkedInputStream {
|
||||
Optional<String> e164 = Optional.ofNullable(details.number);
|
||||
Optional<String> name = Optional.ofNullable(details.name);
|
||||
Optional<DeviceContactAvatar> avatar = Optional.empty();
|
||||
Optional<String> color = details.color != null ? Optional.of(details.color) : Optional.empty();
|
||||
Optional<VerifiedMessage> verified = Optional.empty();
|
||||
Optional<ProfileKey> profileKey = Optional.empty();
|
||||
Optional<Integer> expireTimer = Optional.empty();
|
||||
Optional<Integer> expireTimerVersion = Optional.empty();
|
||||
Optional<Integer> inboxPosition = Optional.empty();
|
||||
boolean archived = false;
|
||||
|
||||
if (details.avatar != null && details.avatar.length != null) {
|
||||
long avatarLength = details.avatar.length;
|
||||
@@ -66,39 +62,6 @@ public class DeviceContactsInputStream extends ChunkedInputStream {
|
||||
avatar = Optional.of(new DeviceContactAvatar(avatarStream, avatarLength, avatarContentType));
|
||||
}
|
||||
|
||||
if (details.verified != null) {
|
||||
try {
|
||||
if (!SignalServiceAddress.isValidAddress(details.verified.destinationAci, null)) {
|
||||
throw new InvalidMessageException("Missing Verified address!");
|
||||
}
|
||||
|
||||
IdentityKey identityKey = new IdentityKey(details.verified.identityKey.toByteArray(), 0);
|
||||
SignalServiceAddress destination = new SignalServiceAddress(ServiceId.parseOrThrow(details.verified.destinationAci));
|
||||
|
||||
VerifiedMessage.VerifiedState state;
|
||||
|
||||
switch (details.verified.state) {
|
||||
case VERIFIED: state = VerifiedMessage.VerifiedState.VERIFIED; break;
|
||||
case UNVERIFIED:state = VerifiedMessage.VerifiedState.UNVERIFIED; break;
|
||||
case DEFAULT: state = VerifiedMessage.VerifiedState.DEFAULT; break;
|
||||
default: throw new InvalidMessageException("Unknown state: " + details.verified.state);
|
||||
}
|
||||
|
||||
verified = Optional.of(new VerifiedMessage(destination, identityKey, state, System.currentTimeMillis()));
|
||||
} catch (InvalidKeyException | InvalidMessageException e) {
|
||||
Log.w(TAG, e);
|
||||
verified = Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
if (details.profileKey != null) {
|
||||
try {
|
||||
profileKey = Optional.ofNullable(new ProfileKey(details.profileKey.toByteArray()));
|
||||
} catch (InvalidInputException e) {
|
||||
Log.w(TAG, "Invalid profile key ignored", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (details.expireTimer != null && details.expireTimer > 0) {
|
||||
expireTimer = Optional.of(details.expireTimer);
|
||||
}
|
||||
@@ -111,9 +74,7 @@ public class DeviceContactsInputStream extends ChunkedInputStream {
|
||||
inboxPosition = Optional.of(details.inboxPosition);
|
||||
}
|
||||
|
||||
archived = details.archived;
|
||||
|
||||
return new DeviceContact(aci, e164, name, avatar, color, verified, profileKey, expireTimer, expireTimerVersion, inboxPosition, archived);
|
||||
return new DeviceContact(aci, e164, name, avatar, expireTimer, expireTimerVersion, inboxPosition);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -57,34 +57,6 @@ public class DeviceContactsOutputStream extends ChunkedOutputStream {
|
||||
contactDetails.avatar(avatarBuilder.build());
|
||||
}
|
||||
|
||||
if (contact.getColor().isPresent()) {
|
||||
contactDetails.color(contact.getColor().get());
|
||||
}
|
||||
|
||||
if (contact.getVerified().isPresent()) {
|
||||
Verified.State state;
|
||||
|
||||
switch (contact.getVerified().get().getVerified()) {
|
||||
case VERIFIED:
|
||||
state = Verified.State.VERIFIED; break;
|
||||
case UNVERIFIED:
|
||||
state = Verified.State.UNVERIFIED; break;
|
||||
default:
|
||||
state = Verified.State.DEFAULT; break;
|
||||
}
|
||||
|
||||
Verified.Builder verifiedBuilder = new Verified.Builder()
|
||||
.identityKey(ByteString.of(contact.getVerified().get().getIdentityKey().serialize()))
|
||||
.destinationAci(contact.getVerified().get().getDestination().getServiceId().toString())
|
||||
.state(state);
|
||||
|
||||
contactDetails.verified(verifiedBuilder.build());
|
||||
}
|
||||
|
||||
if (contact.getProfileKey().isPresent()) {
|
||||
contactDetails.profileKey(ByteString.of(contact.getProfileKey().get().serialize()));
|
||||
}
|
||||
|
||||
if (contact.getExpirationTimer().isPresent()) {
|
||||
contactDetails.expireTimer(contact.getExpirationTimer().get());
|
||||
}
|
||||
@@ -93,8 +65,6 @@ public class DeviceContactsOutputStream extends ChunkedOutputStream {
|
||||
contactDetails.inboxPosition(contact.getInboxPosition().get());
|
||||
}
|
||||
|
||||
contactDetails.archived(contact.isArchived());
|
||||
|
||||
byte[] serializedContactDetails = contactDetails.build().encode();
|
||||
|
||||
writeVarint32(serializedContactDetails.length);
|
||||
|
||||
@@ -40,11 +40,7 @@ public class RequestMessage {
|
||||
return request.type == Request.Type.KEYS;
|
||||
}
|
||||
|
||||
public boolean isPniIdentityRequest() {
|
||||
return request.type == Request.Type.PNI_IDENTITY;
|
||||
}
|
||||
|
||||
public boolean isUrgent() {
|
||||
return isContactsRequest() || isKeysRequest() || isPniIdentityRequest();
|
||||
return isContactsRequest() || isKeysRequest();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public final class AttachmentPointerUtil {
|
||||
pointer.height != null ? pointer.height : 0,
|
||||
pointer.digest != null ? Optional.of(pointer.digest.toByteArray()) : Optional.empty(),
|
||||
pointer.incrementalMac != null ? Optional.of(pointer.incrementalMac.toByteArray()) : Optional.empty(),
|
||||
pointer.incrementalMacChunkSize != null ? pointer.incrementalMacChunkSize : 0,
|
||||
pointer.chunkSize != null ? pointer.chunkSize : 0,
|
||||
pointer.fileName != null ? Optional.of(pointer.fileName) : Optional.empty(),
|
||||
((pointer.flags != null ? pointer.flags : 0) & FlagUtil.toBinaryFlag(AttachmentPointer.Flags.VOICE_MESSAGE.getValue())) != 0,
|
||||
((pointer.flags != null ? pointer.flags : 0) & FlagUtil.toBinaryFlag(AttachmentPointer.Flags.BORDERLESS.getValue())) != 0,
|
||||
@@ -36,7 +36,7 @@ public final class AttachmentPointerUtil {
|
||||
pointer.caption != null ? Optional.of(pointer.caption) : Optional.empty(),
|
||||
pointer.blurHash != null ? Optional.of(pointer.blurHash) : Optional.empty(),
|
||||
pointer.uploadTimestamp != null ? pointer.uploadTimestamp : 0,
|
||||
UuidUtil.fromByteStringOrNull(pointer.uuid));
|
||||
UuidUtil.fromByteStringOrNull(pointer.clientUuid));
|
||||
}
|
||||
|
||||
public static AttachmentPointer createAttachmentPointer(SignalServiceAttachmentPointer attachment) {
|
||||
@@ -53,7 +53,7 @@ public final class AttachmentPointerUtil {
|
||||
}
|
||||
|
||||
if (attachment.getIncrementalMacChunkSize() > 0) {
|
||||
builder.incrementalMacChunkSize(attachment.getIncrementalMacChunkSize());
|
||||
builder.chunkSize(attachment.getIncrementalMacChunkSize());
|
||||
}
|
||||
|
||||
if (attachment.getRemoteId() instanceof SignalServiceAttachmentRemoteId.V2) {
|
||||
@@ -105,7 +105,7 @@ public final class AttachmentPointerUtil {
|
||||
}
|
||||
|
||||
if (attachment.getUuid() != null) {
|
||||
builder.uuid(UuidUtil.toByteString(attachment.getUuid()));
|
||||
builder.clientUuid(UuidUtil.toByteString(attachment.getUuid()));
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2020-2022 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file contains protos that were removed from SignalService.proto, but are still needed by our application,
|
||||
* typically for serialization purposes.
|
||||
*/
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package signalservice;
|
||||
|
||||
option java_package = "org.whispersystems.signalservice.internal.push";
|
||||
option java_outer_classname = "SignalServiceProtos";
|
||||
|
||||
import SignalService.proto;
|
||||
|
||||
message GroupContext {
|
||||
enum Type {
|
||||
UNKNOWN = 0;
|
||||
UPDATE = 1;
|
||||
DELIVER = 2;
|
||||
QUIT = 3;
|
||||
REQUEST_INFO = 4;
|
||||
}
|
||||
|
||||
message Member {
|
||||
reserved /* uuid */ 1; // removed
|
||||
optional string e164 = 2;
|
||||
}
|
||||
|
||||
optional bytes id = 1;
|
||||
optional Type type = 2;
|
||||
optional string name = 3;
|
||||
repeated string membersE164 = 4;
|
||||
repeated Member members = 6;
|
||||
optional signalservice.AttachmentPointer avatar = 5;
|
||||
}
|
||||
@@ -35,13 +35,9 @@ public class DeviceContactsInputStreamTest {
|
||||
e164First,
|
||||
Optional.of("Teal'c"),
|
||||
Optional.empty(),
|
||||
Optional.of("ultramarine"),
|
||||
Optional.of(new VerifiedMessage(new SignalServiceAddress(aciFirst.get(), e164First), generateIdentityKey(), VerifiedMessage.VerifiedState.DEFAULT, System.currentTimeMillis())),
|
||||
Optional.of(generateProfileKey()),
|
||||
Optional.of(0),
|
||||
Optional.of(0),
|
||||
Optional.of(0),
|
||||
false
|
||||
Optional.of(0)
|
||||
);
|
||||
|
||||
DeviceContact second = new DeviceContact(
|
||||
@@ -49,13 +45,9 @@ public class DeviceContactsInputStreamTest {
|
||||
e164Second,
|
||||
Optional.of("Bra'tac"),
|
||||
Optional.empty(),
|
||||
Optional.of("ultramarine"),
|
||||
Optional.of(new VerifiedMessage(new SignalServiceAddress(aciSecond.get(), e164Second), generateIdentityKey(), VerifiedMessage.VerifiedState.DEFAULT, System.currentTimeMillis())),
|
||||
Optional.of(generateProfileKey()),
|
||||
Optional.of(0),
|
||||
Optional.of(0),
|
||||
Optional.of(0),
|
||||
false
|
||||
Optional.of(0)
|
||||
);
|
||||
|
||||
output.write(first);
|
||||
@@ -72,24 +64,9 @@ public class DeviceContactsInputStreamTest {
|
||||
assertEquals(first.getAci(), readFirst.getAci());
|
||||
assertEquals(first.getE164(), readFirst.getE164());
|
||||
assertEquals(first.getName(), readFirst.getName());
|
||||
assertEquals(first.getColor(), readFirst.getColor());
|
||||
assertEquals(first.getVerified().get().getIdentityKey(), readFirst.getVerified().get().getIdentityKey());
|
||||
assertEquals(first.isArchived(), readFirst.isArchived());
|
||||
|
||||
assertEquals(second.getAci(), readSecond.getAci());
|
||||
assertEquals(second.getE164(), readSecond.getE164());
|
||||
assertEquals(second.getName(), readSecond.getName());
|
||||
assertEquals(second.getColor(), readSecond.getColor());
|
||||
assertEquals(second.getVerified().get().getIdentityKey(), readSecond.getVerified().get().getIdentityKey());
|
||||
assertEquals(second.isArchived(), readSecond.isArchived());
|
||||
}
|
||||
|
||||
private static IdentityKey generateIdentityKey() {
|
||||
ECKeyPair djbKeyPair = Curve.generateKeyPair();
|
||||
return new IdentityKey(djbKeyPair.getPublicKey());
|
||||
}
|
||||
|
||||
private static ProfileKey generateProfileKey() throws InvalidInputException {
|
||||
return new ProfileKey(Util.getSecretBytes(32));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user