diff --git a/libsignal-service/protobuf/Groups.proto b/libsignal-service/protobuf/Groups.proto index e462536f2..bad55e4a1 100644 --- a/libsignal-service/protobuf/Groups.proto +++ b/libsignal-service/protobuf/Groups.proto @@ -182,7 +182,7 @@ message GroupChange { bool announcementsOnly = 1; } - bytes sourceUuid = 1; + bytes sourceServiceId = 1; uint32 revision = 2; repeated AddMemberAction addMembers = 3; repeated DeleteMemberAction deleteMembers = 4; diff --git a/libsignal-service/protobuf/SignalService.proto b/libsignal-service/protobuf/SignalService.proto index 27677636e..de9b4ea8d 100644 --- a/libsignal-service/protobuf/SignalService.proto +++ b/libsignal-service/protobuf/SignalService.proto @@ -22,21 +22,22 @@ message Envelope { PLAINTEXT_CONTENT = 8; } - optional Type type = 1; - reserved /*sourceE164*/ 2; - optional string sourceUuid = 11; - optional uint32 sourceDevice = 7; - optional string destinationUuid = 13; - reserved /*relay*/ 3; - optional uint64 timestamp = 5; - reserved /*legacyMessage*/ 6; - optional bytes content = 8; // Contains an encrypted Content - optional string serverGuid = 9; - optional uint64 serverTimestamp = 10; - optional bool urgent = 14 [default = true]; - reserved /*updatedPni*/ 15; // Not used presently, may be used in the future - optional bool story = 16; - // NEXT ID: 17 + optional Type type = 1; + reserved /*sourceE164*/ 2; + optional string sourceServiceId = 11; + optional uint32 sourceDevice = 7; + optional string destinationServiceId = 13; + reserved /*relay*/ 3; + optional uint64 timestamp = 5; + reserved /*legacyMessage*/ 6; + optional bytes content = 8; // Contains an encrypted Content + optional string serverGuid = 9; + optional uint64 serverTimestamp = 10; + optional bool urgent = 14 [default = true]; + reserved /*updatedPni*/ 15; // Not used presently, may be used in the future + optional bool story = 16; + optional bytes reportingToken = 17; + // NEXT ID: 18 } message Content { @@ -50,6 +51,7 @@ message Content { optional bytes decryptionErrorMessage = 8; optional StoryMessage storyMessage = 9; optional PniSignatureMessage pniSignatureMessage = 10; + optional EditMessage editMessage = 11; } message CallMessage { @@ -120,7 +122,7 @@ message CallMessage { optional Busy busy = 5; reserved /* profileKey */ 6; optional Hangup hangup = 7; - optional bool multiRing = 8; + reserved /* multiRing */ 8; optional uint32 destinationDeviceId = 9; optional Opaque opaque = 10; } @@ -139,8 +141,8 @@ message BodyRange { optional uint32 length = 2; oneof associatedValue { - string mentionUuid = 3; - Style style = 4; + string mentionAci = 3; + Style style = 4; } } @@ -165,7 +167,7 @@ message DataMessage { optional uint64 id = 1; reserved /*authorE164*/ 2; - optional string authorUuid = 5; + optional string authorAci = 5; optional string text = 3; repeated QuotedAttachment attachments = 4; repeated BodyRange bodyRanges = 6; @@ -251,7 +253,7 @@ message DataMessage { optional string emoji = 1; optional bool remove = 2; reserved /*targetAuthorE164*/ 3; - optional string targetAuthorUuid = 4; + optional string targetAuthorAci = 4; optional uint64 targetSentTimestamp = 5; } @@ -264,22 +266,11 @@ message DataMessage { } message StoryContext { - optional string authorUuid = 1; + optional string authorAci = 1; optional uint64 sentTimestamp = 2; } message Payment { - - message Address { - message MobileCoin { - optional bytes address = 1; - } - - oneof Address { - MobileCoin mobileCoin = 1; - } - } - message Amount { message MobileCoin { optional uint64 picoMob = 1; @@ -300,6 +291,7 @@ message DataMessage { } optional string note = 2; + reserved /*requestId*/ 1003; } message Activation { @@ -315,6 +307,9 @@ message DataMessage { Notification notification = 1; Activation activation = 2; } + + reserved /*request*/ 1002; + reserved /*cancellation*/ 1003; } message GiftBadge { @@ -440,7 +435,7 @@ message Verified { } reserved /*destinationE164*/ 1; - optional string destinationUuid = 5; + optional string destinationAci = 5; optional bytes identityKey = 2; optional State state = 3; optional bytes nullMessage = 4; @@ -450,18 +445,18 @@ message SyncMessage { message Sent { message UnidentifiedDeliveryStatus { reserved /*destinationE164*/ 1; - optional string destinationUuid = 3; - optional bool unidentified = 2; + optional string destinationServiceId = 3; + optional bool unidentified = 2; } message StoryMessageRecipient { - optional string destinationUuid = 1; - repeated string distributionListIds = 2; - optional bool isAllowedToReply = 3; + optional string destinationServiceId = 1; + repeated string distributionListIds = 2; + optional bool isAllowedToReply = 3; } optional string destinationE164 = 1; - optional string destinationUuid = 7; + optional string destinationServiceId = 7; optional uint64 timestamp = 2; optional DataMessage message = 3; optional uint64 expirationStartTimestamp = 4; @@ -469,6 +464,7 @@ message SyncMessage { optional bool isRecipientUpdate = 6 [default = false]; optional StoryMessage storyMessage = 8; repeated StoryMessageRecipient storyMessageRecipients = 9; + optional EditMessage editMessage = 10; } message Contacts { @@ -476,13 +472,9 @@ message SyncMessage { optional bool complete = 2 [default = false]; } - message Groups { - optional AttachmentPointer blob = 1; - } - message Blocked { repeated string numbers = 1; - repeated string uuids = 3; + repeated string acis = 3; repeated bytes groupIds = 2; } @@ -490,7 +482,7 @@ message SyncMessage { enum Type { UNKNOWN = 0; CONTACTS = 1; - GROUPS = 2; +// GROUPS = 2; BLOCKED = 3; CONFIGURATION = 4; KEYS = 5; @@ -502,13 +494,13 @@ message SyncMessage { message Read { reserved /*senderE164*/ 1; - optional string senderUuid = 3; + optional string senderAci = 3; optional uint64 timestamp = 2; } message Viewed { reserved /*senderE164*/ 1; - optional string senderUuid = 3; + optional string senderAci = 3; optional uint64 timestamp = 2; } @@ -534,7 +526,7 @@ message SyncMessage { message ViewOnceOpen { reserved /*senderE164*/ 1; - optional string senderUuid = 3; + optional string senderAci = 3; optional uint64 timestamp = 2; } @@ -553,11 +545,6 @@ message SyncMessage { optional bytes storageService = 1; } - message PniIdentity { - optional bytes publicKey = 1; - optional bytes privateKey = 2; - } - message MessageRequestResponse { enum Type { UNKNOWN = 0; @@ -568,7 +555,7 @@ message SyncMessage { } reserved /*threadE164*/ 1; - optional string threadUuid = 2; + optional string threadAci = 2; optional bytes groupId = 3; optional Type type = 4; } @@ -587,8 +574,8 @@ message SyncMessage { repeated bytes spentKeyImages = 7; repeated bytes outputPublicKeys = 8; } - optional string recipientUuid = 1; - optional string note = 2; + optional string recipientServiceId = 1; + optional string note = 2; oneof paymentDetail { MobileCoin mobileCoin = 3; @@ -596,9 +583,12 @@ message SyncMessage { } message PniChangeNumber { - optional bytes identityKeyPair = 1; // Serialized libsignal-client IdentityKeyPair - optional bytes signedPreKey = 2; // Serialized libsignal-client SignedPreKeyRecord - optional uint32 registrationId = 3; + optional bytes identityKeyPair = 1; // Serialized libsignal-client IdentityKeyPair + optional bytes signedPreKey = 2; // Serialized libsignal-client SignedPreKeyRecord + optional bytes lastResortKyberPreKey = 5; // Serialized libsignal-client KyberPreKeyRecord + optional uint32 registrationId = 3; + optional string newE164 = 4; // The e164 we have changed our number to + // Next ID: 6 } message CallEvent { @@ -606,6 +596,8 @@ message SyncMessage { UNKNOWN_TYPE = 0; AUDIO_CALL = 1; VIDEO_CALL = 2; + GROUP_CALL = 3; + AD_HOC_CALL = 4; } enum Direction { @@ -618,19 +610,34 @@ message SyncMessage { UNKNOWN_ACTION = 0; ACCEPTED = 1; NOT_ACCEPTED = 2; + DELETE = 3; } - optional bytes peerUuid = 1; - optional uint64 id = 2; - optional uint64 timestamp = 3; - optional Type type = 4; - optional Direction direction = 5; - optional Event event = 6; + optional bytes conversationId = 1; + optional uint64 id = 2; + optional uint64 timestamp = 3; + optional Type type = 4; + optional Direction direction = 5; + optional Event event = 6; + } + + message CallLinkUpdate { + optional bytes rootKey = 1; + optional bytes adminPassKey = 2; + } + + message CallLogEvent { + enum Type { + CLEAR = 0; + } + + optional Type type = 1; + optional uint64 timestamp = 2; } optional Sent sent = 1; optional Contacts contacts = 2; - optional Groups groups = 3; + reserved /*groups*/ 3; optional Request request = 4; repeated Read read = 5; optional Blocked blocked = 6; @@ -644,9 +651,11 @@ message SyncMessage { optional MessageRequestResponse messageRequestResponse = 14; optional OutgoingPayment outgoingPayment = 15; repeated Viewed viewed = 16; - optional PniIdentity pniIdentity = 17; + reserved /*pniIdentity*/ 17; optional PniChangeNumber pniChangeNumber = 18; optional CallEvent callEvent = 19; + optional CallLinkUpdate callLinkUpdate = 20; + optional CallLogEvent callLogEvent = 21; } message AttachmentPointer { @@ -661,20 +670,22 @@ message AttachmentPointer { fixed64 cdnId = 1; string cdnKey = 15; } - optional string contentType = 2; - optional bytes key = 3; - optional uint32 size = 4; - optional bytes thumbnail = 5; - optional bytes digest = 6; - optional string fileName = 7; - optional uint32 flags = 8; - optional uint32 width = 9; - optional uint32 height = 10; - optional string caption = 11; - optional string blurHash = 12; - optional uint64 uploadTimestamp = 13; - optional uint32 cdnNumber = 14; - // Next ID: 16 + optional string contentType = 2; + optional bytes key = 3; + optional uint32 size = 4; + optional bytes thumbnail = 5; + optional bytes digest = 6; + optional bytes incrementalDigest = 16; + optional uint32 incrementalMacChunkSize = 17; + optional string fileName = 7; + optional uint32 flags = 8; + optional uint32 width = 9; + optional uint32 height = 10; + optional string caption = 11; + optional string blurHash = 12; + optional uint64 uploadTimestamp = 13; + optional uint32 cdnNumber = 14; + // Next ID: 18 } message GroupContext { @@ -712,7 +723,7 @@ message ContactDetails { } optional string number = 1; - optional string uuid = 9; + optional string aci = 9; optional string name = 2; optional Avatar avatar = 3; optional string color = 4; @@ -768,4 +779,9 @@ message DecryptionErrorMessage { message PniSignatureMessage { optional bytes pni = 1; optional bytes signature = 2; +} + +message EditMessage { + optional uint64 targetSentTimestamp = 1; + optional DataMessage dataMessage = 2; } \ No newline at end of file diff --git a/libsignal-service/protobuf/update-protos.sh b/libsignal-service/protobuf/update-protos.sh index 411a2ec59..477d143b2 100755 --- a/libsignal-service/protobuf/update-protos.sh +++ b/libsignal-service/protobuf/update-protos.sh @@ -1,14 +1,16 @@ #!/bin/bash set -euo pipefail -GIT_REVISION=${1:-7275b95b583b64144fc7f935144b0a17c45244e7} - update_proto() { case "$1" in - Signal-Android) prefix="libsignal/service/src/main/proto/";; - Signal-Desktop) prefix="protos/";; + Signal-Android) + git_revision="0cdd56e0accfe59e39a312f32bb1463f551dee33" + prefix="libsignal/service/src/main/protowire/";; + Signal-Desktop) + git_revision="0e194975a23669263d053b03a42ac52ad38c5d87" + prefix="protos/";; esac - curl -sLOf https://raw.githubusercontent.com/signalapp/${1}/${GIT_REVISION}/${prefix}${2} + curl -LOf https://raw.githubusercontent.com/signalapp/${1}/${git_revision}/${prefix}${2} } update_proto Signal-Android Groups.proto diff --git a/libsignal-service/src/cipher.rs b/libsignal-service/src/cipher.rs index 33064d5ed..8154cad54 100644 --- a/libsignal-service/src/cipher.rs +++ b/libsignal-service/src/cipher.rs @@ -228,7 +228,7 @@ where })?, }; - let needs_receipt = if envelope.source_uuid.is_some() { + let needs_receipt = if envelope.source_service_id.is_some() { log::warn!("Received an unidentified delivery over an identified channel. Marking needs_receipt=false"); false } else { diff --git a/libsignal-service/src/content.rs b/libsignal-service/src/content.rs index 81da1c1d7..6b4d1dcf8 100644 --- a/libsignal-service/src/content.rs +++ b/libsignal-service/src/content.rs @@ -1,13 +1,13 @@ use libsignal_protocol::ProtocolAddress; -use crate::proto::PniSignatureMessage; pub use crate::{ proto::{ attachment_pointer::Flags as AttachmentPointerFlags, data_message::Flags as DataMessageFlags, data_message::Reaction, group_context::Type as GroupType, sync_message, AttachmentPointer, - CallMessage, DataMessage, GroupContext, GroupContextV2, NullMessage, - ReceiptMessage, StoryMessage, SyncMessage, TypingMessage, + CallMessage, DataMessage, EditMessage, GroupContext, GroupContextV2, + NullMessage, PniSignatureMessage, ReceiptMessage, StoryMessage, + SyncMessage, TypingMessage, }, push_service::ServiceError, }; @@ -92,6 +92,7 @@ pub enum ContentBody { // DecryptionErrorMessage(DecryptionErrorMessage), StoryMessage(StoryMessage), PniSignatureMessage(PniSignatureMessage), + EditMessage(EditMessage), } impl ContentBody { @@ -139,6 +140,10 @@ impl ContentBody { pni_signature_message: Some(msg), ..Default::default() }, + Self::EditMessage(msg) => crate::proto::Content { + edit_message: Some(msg), + ..Default::default() + }, } } } @@ -165,3 +170,4 @@ impl_from_for_content_body!(TypingMessage(TypingMessage)); // impl_from_for_content_body!(DecryptionErrorMessage(DecryptionErrorMessage)); impl_from_for_content_body!(StoryMessage(StoryMessage)); impl_from_for_content_body!(PniSignatureMessage(PniSignatureMessage)); +impl_from_for_content_body!(EditMessage(EditMessage)); diff --git a/libsignal-service/src/envelope.rs b/libsignal-service/src/envelope.rs index fd7a63b71..8e9d7be00 100644 --- a/libsignal-service/src/envelope.rs +++ b/libsignal-service/src/envelope.rs @@ -98,7 +98,7 @@ impl Envelope { source_device: Some(entity.source_device), timestamp: Some(entity.timestamp), server_timestamp: Some(entity.server_timestamp), - source_uuid: Some(source.uuid.to_string()), + source_service_id: Some(source.uuid.to_string()), content: entity.content, ..Default::default() } @@ -131,7 +131,7 @@ impl Envelope { pub fn source_address(&self) -> ServiceAddress { let uuid = self - .source_uuid + .source_service_id .as_deref() .and_then(|u| Uuid::parse_str(u).ok()) .expect("valid uuid checked in constructor"); diff --git a/libsignal-service/src/groups_v2/operations.rs b/libsignal-service/src/groups_v2/operations.rs index a7384594e..7f53b4b8e 100644 --- a/libsignal-service/src/groups_v2/operations.rs +++ b/libsignal-service/src/groups_v2/operations.rs @@ -270,7 +270,7 @@ impl GroupOperations { let actions: proto::group_change::Actions = Message::decode(Bytes::from(group_change.actions))?; - let aci = self.decrypt_aci(&actions.source_uuid)?; + let aci = self.decrypt_aci(&actions.source_service_id)?; let new_members = actions.add_members.into_iter().filter_map(|m| m.added).map( diff --git a/libsignal-service/src/models.rs b/libsignal-service/src/models.rs index b3602a0e7..57f0a362c 100644 --- a/libsignal-service/src/models.rs +++ b/libsignal-service/src/models.rs @@ -57,7 +57,7 @@ impl Contact { ) -> Result { Ok(Self { uuid: contact_details - .uuid + .aci .as_ref() .ok_or(ParseContactError::MissingUuid)? .parse()?, diff --git a/libsignal-service/src/push_service.rs b/libsignal-service/src/push_service.rs index 095433d33..2fdfbf7b0 100644 --- a/libsignal-service/src/push_service.rs +++ b/libsignal-service/src/push_service.rs @@ -173,6 +173,8 @@ pub struct DeviceCapabilities { pub stories: bool, #[serde(default)] pub gift_badges: bool, + #[serde(default)] + pub pnp: bool, } #[derive(Debug, Serialize, Deserialize)] diff --git a/libsignal-service/src/sender.rs b/libsignal-service/src/sender.rs index eeb25ca7f..9e0185c7a 100644 --- a/libsignal-service/src/sender.rs +++ b/libsignal-service/src/sender.rs @@ -234,40 +234,6 @@ where }) } - /// Upload group details to the CDN - /// - /// Returns attachment ID and the attachment digest - async fn upload_group_details( - &mut self, - groups: Groups, - ) -> Result - where - Groups: IntoIterator, - { - use prost::Message; - let mut out = Vec::new(); - for group in groups { - group - .encode_length_delimited(&mut out) - .expect("infallible encoding"); - // XXX add avatar here - } - - let spec = AttachmentSpec { - content_type: "application/octet-stream".into(), - length: out.len(), - file_name: None, - preview: None, - voice_note: None, - borderless: None, - width: None, - height: None, - caption: None, - blur_hash: None, - }; - self.upload_attachment(spec, out).await - } - /// Upload contact details to the CDN /// /// Returns attachment ID and the attachment digest @@ -597,39 +563,6 @@ where Err(MessageSenderError::MaximumRetriesLimitExceeded) } - /// Upload group details to the CDN and send a sync message - pub async fn send_groups_details( - &mut self, - recipient: &ServiceAddress, - unidentified_access: Option, - // XXX It may be interesting to use an intermediary type, - // instead of GroupDetails directly, - // because it allows us to add the avatar content. - groups: Groups, - online: bool, - ) -> Result<(), MessageSenderError> - where - Groups: IntoIterator, - { - let ptr = self.upload_group_details(groups).await?; - - let msg = SyncMessage { - groups: Some(sync_message::Groups { blob: Some(ptr) }), - ..Default::default() - }; - - self.send_message( - recipient, - unidentified_access, - msg, - Utc::now().timestamp_millis() as u64, - online, - ) - .await?; - - Ok(()) - } - /// Upload contact details to the CDN and send a sync message pub async fn send_contact_details( &mut self, @@ -829,14 +762,16 @@ where .. } = sent; UnidentifiedDeliveryStatus { - destination_uuid: Some(recipient.uuid.to_string()), + destination_service_id: Some( + recipient.uuid.to_string(), + ), unidentified: Some(*unidentified), } }) .collect(); ContentBody::SynchronizeMessage(SyncMessage { sent: Some(sync_message::Sent { - destination_uuid: recipient.map(|r| r.uuid.to_string()), + destination_service_id: recipient.map(|r| r.uuid.to_string()), destination_e164: None, expiration_start_timestamp: if data_message .as_ref()