diff --git a/package.json b/package.json index 99f2589eb..c6b3022a2 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "get-expire-time": "node ts/scripts/get-expire-time.js", "copy-components": "node ts/scripts/copy.js", "sass": "sass stylesheets/manifest.scss:stylesheets/manifest.css stylesheets/manifest_bridge.scss:stylesheets/manifest_bridge.css", - "build-module-protobuf": "pbjs --target static-module --force-long --no-typeurl --no-verify --no-create --no-convert --wrap commonjs --out ts/protobuf/compiled.js protos/*.proto && pbts --no-comments --out ts/protobuf/compiled.d.ts ts/protobuf/compiled.js", + "build-module-protobuf": "pbjs --root='signal-desktop' --target static-module --force-long --no-typeurl --no-verify --no-create --no-convert --wrap commonjs --out ts/protobuf/compiled.js protos/*.proto && pbts --no-comments --out ts/protobuf/compiled.d.ts ts/protobuf/compiled.js", "clean-module-protobuf": "rm -f ts/protobuf/compiled.d.ts ts/protobuf/compiled.js", "build-protobuf": "npm run build-module-protobuf", "clean-protobuf": "npm run clean-module-protobuf", diff --git a/protos/SignalService.proto b/protos/SignalService.proto index 492df9959..6e10e6d50 100644 --- a/protos/SignalService.proto +++ b/protos/SignalService.proto @@ -1,131 +1,132 @@ -// Copyright 2014 Signal Messenger, LLC -// SPDX-License-Identifier: AGPL-3.0-only +/* + * Copyright 2020-2022 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ -// Source: https://github.com/signalapp/libsignal-service-java/blob/4684a49b2ed8f32be619e0d0eea423626b6cb2cb/protobuf/SignalService.proto package signalservice; option java_package = "org.whispersystems.signalservice.internal.push"; option java_outer_classname = "SignalServiceProtos"; message Envelope { + // Our parser does not handle reserved in enums: DESKTOP-1569 enum Type { - UNKNOWN = 0; - CIPHERTEXT = 1; - KEY_EXCHANGE = 2; - PREKEY_BUNDLE = 3; - RECEIPT = 5; - UNIDENTIFIED_SENDER = 6; - - // Our parser does not handle reserved in enums: DESKTOP-1569 - // reserved 7; - - PLAINTEXT_CONTENT = 8; + UNKNOWN = 0; + CIPHERTEXT = 1; // content => (version byte | SignalMessage{Content}) + // reserved 2; + // reserved "KEY_EXCHANGE"; + PREKEY_BUNDLE = 3; // content => (version byte | PreKeySignalMessage{Content}) + SERVER_DELIVERY_RECEIPT = 5; // legacyMessage => [] AND content => [] + UNIDENTIFIED_SENDER = 6; // legacyMessage => [] AND content => ((version byte | UnidentifiedSenderMessage) OR (version byte | Multi-Recipient Sealed Sender Format)) + SENDERKEY_MESSAGE = 7; // legacyMessage => [] AND content => (version byte | SenderKeyMessage) + PLAINTEXT_CONTENT = 8; // legacyMessage => [] AND content => (marker byte | Content) } - optional Type type = 1; + optional Type type = 1; + reserved 2; // formerly optional string sourceE164 = 2; optional string sourceServiceId = 11; - optional uint32 sourceDevice = 7; + optional uint32 sourceDevice = 7; optional string destinationServiceId = 13; - // reserved 3; // formerly optional string relay = 3; - optional uint64 timestamp = 5; - // reserved 6; // formerly optional bytes legacyMessage = 6; - optional bytes content = 8; // Contains an encrypted Content - optional string serverGuid = 9; + reserved 3; // formerly optional string relay = 3; + optional uint64 timestamp = 5; + reserved 6; // formerly optional bytes legacyMessage = 6; // Contains an encrypted DataMessage; this field could have been set historically for type 1 or 3 messages; no longer in use + optional bytes content = 8; // Contains an encrypted Content + optional string serverGuid = 9; optional uint64 serverTimestamp = 10; optional bool ephemeral = 12; // indicates that the message should not be persisted if the recipient is offline - optional bool urgent = 14 [default=true]; // indicates that the content is considered timely by the sender; defaults to true so senders have to opt-out to say something isn't time critical - optional string updated_pni = 15; + optional bool urgent = 14 [default = true]; // indicates that the content is considered timely by the sender; defaults to true so senders have to opt-out to say something isn't time critical + optional string updatedPni = 15; // for number-change synchronization messages, provides the new server-assigned phone number identifier associated with the changed number optional bool story = 16; // indicates that the content is a story. - optional bytes reporting_token = 17; - // next: 18 + optional bytes report_spam_token = 17; // token sent when reporting spam + reserved 18; // internal server use + // next: 19 } message Content { - optional DataMessage dataMessage = 1; - optional SyncMessage syncMessage = 2; - optional CallingMessage callingMessage = 3; - optional NullMessage nullMessage = 4; - optional ReceiptMessage receiptMessage = 5; - optional TypingMessage typingMessage = 6; - optional bytes senderKeyDistributionMessage = 7; - optional bytes decryptionErrorMessage = 8; - optional StoryMessage storyMessage = 9; - optional PniSignatureMessage pniSignatureMessage = 10; + optional DataMessage dataMessage = 1; + optional SyncMessage syncMessage = 2; + optional CallMessage callMessage = 3; + optional NullMessage nullMessage = 4; + optional ReceiptMessage receiptMessage = 5; + optional TypingMessage typingMessage = 6; + optional bytes /* SenderKeyDistributionMessage */ senderKeyDistributionMessage = 7; + optional bytes /* DecryptionErrorMessage */ decryptionErrorMessage = 8; + optional StoryMessage storyMessage = 9; + optional PniSignatureMessage pniSignatureMessage = 10; optional EditMessage editMessage = 11; } -message CallingMessage { +message CallMessage { message Offer { enum Type { OFFER_AUDIO_CALL = 0; OFFER_VIDEO_CALL = 1; + reserved /* OFFER_NEED_PERMISSION */ 2; // removed } - - optional uint64 callId = 1; - reserved /* sdp */ 2; - optional Type type = 3; - optional bytes opaque = 4; + optional uint64 id = 1; + reserved /* sdp */ 2; + optional Type type = 3; + optional bytes opaque = 4; } message Answer { - optional uint64 callId = 1; - reserved /* sdp */ 2; - optional bytes opaque = 3; + optional uint64 id = 1; + reserved /* sdp */ 2; + optional bytes opaque = 3; } - message IceCandidate { - optional uint64 callId = 1; - reserved /* mid */ 2; - reserved /* line */ 3; - reserved /* sdp */ 4; - optional bytes opaque = 5; + message IceUpdate { + optional uint64 id = 1; + reserved /* mid */ 2; + reserved /* line */ 3; + reserved /* sdp */ 4; + optional bytes opaque = 5; } message Busy { - optional uint64 callId = 1; + optional uint64 id = 1; } message Hangup { enum Type { - HANGUP_NORMAL = 0; - HANGUP_ACCEPTED = 1; - HANGUP_DECLINED = 2; - HANGUP_BUSY = 3; + HANGUP_NORMAL = 0; + HANGUP_ACCEPTED = 1; + HANGUP_DECLINED = 2; + HANGUP_BUSY = 3; HANGUP_NEED_PERMISSION = 4; } - - optional uint64 callId = 1; - optional Type type = 2; + optional uint64 id = 1; + optional Type type = 2; optional uint32 deviceId = 3; } message Opaque { enum Urgency { - DROPPABLE = 0; + DROPPABLE = 0; HANDLE_IMMEDIATELY = 1; } - - optional bytes data = 1; - optional Urgency urgency = 2; + optional bytes data = 1; + optional Urgency urgency = 2; // If missing, treat as DROPPABLE. } - optional Offer offer = 1; - optional Answer answer = 2; - repeated IceCandidate iceCandidates = 3; - reserved /* legacyHangup */ 4; - optional Busy busy = 5; - reserved /* profileKey */ 6; - optional Hangup hangup = 7; - reserved /* multiRing */ 8; - optional uint32 destinationDeviceId = 9; - optional Opaque opaque = 10; + optional Offer offer = 1; + optional Answer answer = 2; + repeated IceUpdate iceUpdate = 3; + reserved /* legacyHangup */ 4; + optional Busy busy = 5; + reserved /* profileKey */ 6; + optional Hangup hangup = 7; + reserved /* multiRing */ 8; + optional uint32 destinationDeviceId = 9; + optional Opaque opaque = 10; } message DataMessage { enum Flags { - END_SESSION = 1; + END_SESSION = 1; EXPIRATION_TIMER_UPDATE = 2; - PROFILE_KEY_UPDATE = 4; + PROFILE_KEY_UPDATE = 4; + FORWARD = 8; } message Payment { @@ -139,19 +140,9 @@ message DataMessage { } } - message RequestId { - optional string uuid = 1; - } - - message Request { - optional RequestId requestId = 1; - optional Amount amount = 2; - optional string note = 3; - } - message Notification { message MobileCoin { - optional bytes receipt = 1; + optional bytes receipt = 1; } oneof Transaction { @@ -159,12 +150,8 @@ message DataMessage { } // Optional, Refers to the PaymentRequest message, if any. - optional string note = 2; - optional RequestId requestId = 1003; - } - - message Cancellation { - optional RequestId requestId = 1; + optional string note = 2; + reserved /*requestId*/ 1003; } message Activation { @@ -179,9 +166,10 @@ message DataMessage { oneof Item { Notification notification = 1; Activation activation = 2; - Request request = 1002; - Cancellation cancellation = 1003; } + + reserved /*request*/ 1002; + reserved /*cancellation*/ 1003; } message Quote { @@ -191,135 +179,108 @@ message DataMessage { } message QuotedAttachment { - optional string contentType = 1; - optional string fileName = 2; - optional AttachmentPointer thumbnail = 3; + optional string contentType = 1; + optional string fileName = 2; + optional AttachmentPointer thumbnail = 3; } - optional uint64 id = 1; - reserved /* author */ 2; // removed - optional string authorAci = 5; - optional string text = 3; + optional uint64 id = 1; + reserved /*authorE164*/ 2; + optional string authorAci = 5; + optional string text = 3; repeated QuotedAttachment attachments = 4; - repeated BodyRange bodyRanges = 6; - optional Type type = 7; + repeated BodyRange bodyRanges = 6; + optional Type type = 7; } message Contact { message Name { - optional string givenName = 1; - optional string familyName = 2; - optional string prefix = 3; - optional string suffix = 4; - optional string middleName = 5; - reserved /* displayName */ 6; + optional string givenName = 1; + optional string familyName = 2; + optional string prefix = 3; + optional string suffix = 4; + optional string middleName = 5; + reserved /*displayName*/ 6; optional string nickname = 7; } message Phone { enum Type { - HOME = 1; + HOME = 1; MOBILE = 2; - WORK = 3; + WORK = 3; CUSTOM = 4; } optional string value = 1; - optional Type type = 2; + optional Type type = 2; optional string label = 3; } message Email { enum Type { - HOME = 1; + HOME = 1; MOBILE = 2; - WORK = 3; + WORK = 3; CUSTOM = 4; } optional string value = 1; - optional Type type = 2; + optional Type type = 2; optional string label = 3; } message PostalAddress { enum Type { - HOME = 1; - WORK = 2; + HOME = 1; + WORK = 2; CUSTOM = 3; } - optional Type type = 1; - optional string label = 2; - optional string street = 3; - optional string pobox = 4; + optional Type type = 1; + optional string label = 2; + optional string street = 3; + optional string pobox = 4; optional string neighborhood = 5; - optional string city = 6; - optional string region = 7; - optional string postcode = 8; - optional string country = 9; + optional string city = 6; + optional string region = 7; + optional string postcode = 8; + optional string country = 9; } message Avatar { - optional AttachmentPointer avatar = 1; - optional bool isProfile = 2; + optional AttachmentPointer avatar = 1; + optional bool isProfile = 2; } - optional Name name = 1; - repeated Phone number = 3; - repeated Email email = 4; - repeated PostalAddress address = 5; - optional Avatar avatar = 6; - optional string organization = 7; - } - - message Preview { - optional string url = 1; - optional string title = 2; - optional AttachmentPointer image = 3; - optional string description = 4; - optional uint64 date = 5; + optional Name name = 1; + repeated Phone number = 3; + repeated Email email = 4; + repeated PostalAddress address = 5; + optional Avatar avatar = 6; + optional string organization = 7; } message Sticker { - optional bytes packId = 1; - optional bytes packKey = 2; - optional uint32 stickerId = 3; - optional AttachmentPointer data = 4; - optional string emoji = 5; + optional bytes packId = 1; + optional bytes packKey = 2; + optional uint32 stickerId = 3; + optional AttachmentPointer data = 4; + optional string emoji = 5; } message Reaction { - optional string emoji = 1; - optional bool remove = 2; - reserved /* targetAuthorE164 */ 3; // removed + optional string emoji = 1; + optional bool remove = 2; + reserved /* targetAuthorE164 */ 3; optional string targetAuthorAci = 4; - optional uint64 targetTimestamp = 5; + optional uint64 targetSentTimestamp = 5; } message Delete { optional uint64 targetSentTimestamp = 1; } - message BodyRange { - enum Style { - NONE = 0; - BOLD = 1; - ITALIC = 2; - SPOILER = 3; - STRIKETHROUGH = 4; - MONOSPACE = 5; - } - - optional uint32 start = 1; // Starting index in UTF-16 code units/raw string representation - optional uint32 length = 2; // Length of range in UTF-16 code units/raw string representation - - oneof associatedValue { - string mentionAci = 3; - Style style = 4; - } - } - message GroupCallUpdate { optional string eraId = 1; } @@ -347,28 +308,29 @@ message DataMessage { optional bytes receiptCredentialPresentation = 1; } - optional string body = 1; - repeated AttachmentPointer attachments = 2; + optional string body = 1; + repeated AttachmentPointer attachments = 2; reserved /*groupV1*/ 3; - optional GroupContextV2 groupV2 = 15; - optional uint32 flags = 4; - optional uint32 expireTimer = 5; - optional uint32 expireTimerVersion = 23; - optional bytes profileKey = 6; - optional uint64 timestamp = 7; - optional Quote quote = 8; - repeated Contact contact = 9; - repeated Preview preview = 10; - optional Sticker sticker = 11; - optional uint32 requiredProtocolVersion = 12; - optional bool isViewOnce = 14; - optional Reaction reaction = 16; - optional Delete delete = 17; - repeated BodyRange bodyRanges = 18; - optional GroupCallUpdate groupCallUpdate = 19; - optional Payment payment = 20; - optional StoryContext storyContext = 21; - optional GiftBadge giftBadge = 22; + optional GroupContextV2 groupV2 = 15; + optional uint32 flags = 4; + optional uint32 expireTimer = 5; + optional uint32 expireTimerVersion = 23; + optional bytes profileKey = 6; + optional uint64 timestamp = 7; + optional Quote quote = 8; + repeated Contact contact = 9; + repeated Preview preview = 10; + optional Sticker sticker = 11; + optional uint32 requiredProtocolVersion = 12; + optional bool isViewOnce = 14; + optional Reaction reaction = 16; + optional Delete delete = 17; + repeated BodyRange bodyRanges = 18; + optional GroupCallUpdate groupCallUpdate = 19; + optional Payment payment = 20; + optional StoryContext storyContext = 21; + optional GiftBadge giftBadge = 22; + // NEXT ID: 24 } message NullMessage { @@ -378,23 +340,23 @@ message NullMessage { message ReceiptMessage { enum Type { DELIVERY = 0; - READ = 1; - VIEWED = 2; + READ = 1; + VIEWED = 2; } - optional Type type = 1; + optional Type type = 1; repeated uint64 timestamp = 2; } message TypingMessage { - enum Action { - STARTED = 0; - STOPPED = 1; - } + enum Action { + STARTED = 0; + STOPPED = 1; + } - optional uint64 timestamp = 1; - optional Action action = 2; - optional bytes groupId = 3; + optional uint64 timestamp = 1; + optional Action action = 2; + optional bytes groupId = 3; } message StoryMessage { @@ -408,6 +370,14 @@ message StoryMessage { repeated BodyRange bodyRanges = 6; } +message Preview { + optional string url = 1; + optional string title = 2; + optional AttachmentPointer image = 3; + optional string description = 4; + optional uint64 date = 5; +} + message TextAttachment { enum Style { DEFAULT = 0; @@ -439,25 +409,25 @@ message TextAttachment { message Verified { enum State { - DEFAULT = 0; - VERIFIED = 1; + DEFAULT = 0; + VERIFIED = 1; UNVERIFIED = 2; } - optional string destination = 1; - optional string destinationAci = 5; - optional bytes identityKey = 2; - optional State state = 3; - optional bytes nullMessage = 4; + reserved /*destinationE164*/ 1; + optional string destinationAci = 5; + optional bytes identityKey = 2; + optional State state = 3; + optional bytes nullMessage = 4; } message SyncMessage { message Sent { message UnidentifiedDeliveryStatus { - optional string destination = 1; + reserved /*destinationE164*/ 1; optional string destinationServiceId = 3; optional bool unidentified = 2; - reserved /* destinationPni */ 4; + reserved /*destinationPni */ 4; optional bytes destinationPniIdentityKey = 5; // Only set for PNI destinations } @@ -465,121 +435,129 @@ message SyncMessage { optional string destinationServiceId = 1; repeated string distributionListIds = 2; optional bool isAllowedToReply = 3; + reserved /*destinationPni */ 4; } - optional string destination = 1; - optional string destinationServiceId = 7; - optional uint64 timestamp = 2; - optional DataMessage message = 3; - optional uint64 expirationStartTimestamp = 4; - repeated UnidentifiedDeliveryStatus unidentifiedStatus = 5; - optional bool isRecipientUpdate = 6 [default = false]; + optional string destinationE164 = 1; + optional string destinationServiceId = 7; + optional uint64 timestamp = 2; + optional DataMessage message = 3; + optional uint64 expirationStartTimestamp = 4; + repeated UnidentifiedDeliveryStatus unidentifiedStatus = 5; + optional bool isRecipientUpdate = 6 [default = false]; optional StoryMessage storyMessage = 8; repeated StoryMessageRecipient storyMessageRecipients = 9; optional EditMessage editMessage = 10; + reserved /*destinationPni */ 11; + // Next ID: 12 } message Contacts { - optional AttachmentPointer blob = 1; - optional bool complete = 2 [default = false]; + optional AttachmentPointer blob = 1; + optional bool complete = 2 [default = false]; } message Blocked { - repeated string numbers = 1; - repeated string acis = 3; - repeated bytes groupIds = 2; + repeated string numbers = 1; + repeated string acis = 3; + repeated bytes groupIds = 2; } message Request { enum Type { - UNKNOWN = 0; - CONTACTS = 1; - reserved /* GROUPS */ 2; - BLOCKED = 3; + UNKNOWN = 0; + CONTACTS = 1; + reserved /*GROUPS*/ 2; + BLOCKED = 3; CONFIGURATION = 4; - KEYS = 5; - reserved /* PNI_IDENTITY */ 6; + KEYS = 5; + reserved /*PNI_IDENTITY*/ 6; } optional Type type = 1; } - message Keys { - reserved /* storageService */ 1; // deprecated: this field will be removed in a future release. - optional bytes master = 2; // deprecated: this field will be removed in a future release. - optional string accountEntropyPool = 3; - optional bytes mediaRootBackupKey = 4; - } - message Read { - optional string sender = 1; - optional string senderAci = 3; - optional uint64 timestamp = 2; + reserved /*senderE164*/ 1; + optional string senderAci = 3; + optional uint64 timestamp = 2; } message Viewed { - optional string senderE164 = 1; + reserved /*senderE164*/ 1; optional string senderAci = 3; optional uint64 timestamp = 2; } message Configuration { - optional bool readReceipts = 1; - optional bool unidentifiedDeliveryIndicators = 2; - optional bool typingIndicators = 3; - reserved 4; - optional uint32 provisioningVersion = 5; - optional bool linkPreviews = 6; + optional bool readReceipts = 1; + optional bool unidentifiedDeliveryIndicators = 2; + optional bool typingIndicators = 3; + reserved /* linkPreviews */ 4; + optional uint32 provisioningVersion = 5; + optional bool linkPreviews = 6; } message StickerPackOperation { enum Type { INSTALL = 0; - REMOVE = 1; + REMOVE = 1; } - optional bytes packId = 1; + optional bytes packId = 1; optional bytes packKey = 2; - optional Type type = 3; + optional Type type = 3; } message ViewOnceOpen { - optional string sender = 1; - optional string senderAci = 3; - optional uint64 timestamp = 2; - } - - message MessageRequestResponse { - enum Type { - UNKNOWN = 0; - ACCEPT = 1; - DELETE = 2; - BLOCK = 3; - BLOCK_AND_DELETE = 4; - SPAM = 5; - BLOCK_AND_SPAM = 6; - } - - optional string threadE164 = 1; - optional string threadAci = 2; - optional bytes groupId = 3; - optional Type type = 4; + reserved /*senderE164*/ 1; + optional string senderAci = 3; + optional uint64 timestamp = 2; } message FetchLatest { enum Type { - UNKNOWN = 0; - LOCAL_PROFILE = 1; - STORAGE_MANIFEST = 2; + UNKNOWN = 0; + LOCAL_PROFILE = 1; + STORAGE_MANIFEST = 2; SUBSCRIPTION_STATUS = 3; } optional Type type = 1; } + message Keys { + reserved /* storageService */ 1; + optional bytes master = 2; // deprecated: this field will be removed in a future release. + optional string accountEntropyPool = 3; + optional bytes mediaRootBackupKey = 4; + } + + message PniIdentity { + optional bytes publicKey = 1; + optional bytes privateKey = 2; + } + + message MessageRequestResponse { + enum Type { + UNKNOWN = 0; + ACCEPT = 1; + DELETE = 2; + BLOCK = 3; + BLOCK_AND_DELETE = 4; + SPAM = 5; + BLOCK_AND_SPAM = 6; + } + + reserved /*threadE164*/ 1; + optional string threadAci = 2; + optional bytes groupId = 3; + optional Type type = 4; + } + message PniChangeNumber { optional bytes identityKeyPair = 1; // Serialized libsignal-client IdentityKeyPair - optional bytes signedPreKey = 2; // Serialized libsignal-client SignedPreKeyRecord + 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 @@ -588,38 +566,38 @@ message SyncMessage { message CallEvent { enum Type { - UNKNOWN = 0; - AUDIO_CALL = 1; - VIDEO_CALL = 2; - GROUP_CALL = 3; + UNKNOWN_TYPE = 0; + AUDIO_CALL = 1; + VIDEO_CALL = 2; + GROUP_CALL = 3; AD_HOC_CALL = 4; } enum Direction { - UNKNOWN = 0; + UNKNOWN_DIRECTION = 0; INCOMING = 1; OUTGOING = 2; } enum Event { - UNKNOWN = 0; - ACCEPTED = 1; + UNKNOWN_EVENT = 0; + ACCEPTED = 1; NOT_ACCEPTED = 2; - DELETE = 3; - OBSERVED = 4; + DELETE = 3; + OBSERVED = 4; } /* Data identifying a conversation. The service ID for 1:1, the group ID for * group, or the room ID for an ad-hoc call. See also * `CallLogEvent/peerId`. */ - optional bytes peerId = 1; + optional bytes peerId = 1; /* An identifier for a call. Generated directly for 1:1, or derived from * the era ID for group and ad-hoc calls. See also `CallLogEvent/callId`. */ - optional uint64 callId = 2; - optional uint64 timestamp = 3; - optional Type type = 4; + optional uint64 callId = 2; + optional uint64 timestamp = 3; + optional Type type = 4; optional Direction direction = 5; - optional Event event = 6; + optional Event event = 6; } message CallLinkUpdate { @@ -628,9 +606,9 @@ message SyncMessage { reserved 1; // was DELETE, superseded by storage service } - optional bytes rootKey = 1; + optional bytes rootKey = 1; optional bytes adminPasskey = 2; - optional Type type = 3; // defaults to UPDATE + optional Type type = 3; // defaults to UPDATE } message CallLogEvent { @@ -638,17 +616,18 @@ message SyncMessage { CLEAR = 0; MARKED_AS_READ = 1; MARKED_AS_READ_IN_CONVERSATION = 2; + CLEAR_IN_CONVERSATION = 3; } - optional Type type = 1; + optional Type type = 1; optional uint64 timestamp = 2; /* Data identifying a conversation. The service ID for 1:1, the group ID for * group, or the room ID for an ad-hoc call. See also * `CallEvent/peerId`. */ - optional bytes peerId = 3; - /* An identifier for a call. Generated directly for 1:1, or derived from - * the era ID for group and ad-hoc calls. See also `CallEvent/callId`. */ - optional uint64 callId = 4; + optional bytes peerId = 3; + /* An identifier for a call. Generated directly for 1:1, or derived from + * the era ID for group and ad-hoc calls. See also `CallEvent/callId`. */ + optional uint64 callId = 4; } message DeleteForMe { @@ -700,42 +679,41 @@ message SyncMessage { repeated LocalOnlyConversationDelete localOnlyConversationDeletes = 3; repeated AttachmentDelete attachmentDeletes = 4; } - + message DeviceNameChange { reserved /*name*/ 1; optional uint32 deviceId = 2; } - optional Sent sent = 1; - optional Contacts contacts = 2; - reserved /* groups */ 3; - optional Request request = 4; - repeated Read read = 5; - optional Blocked blocked = 6; - optional Verified verified = 7; - optional Configuration configuration = 9; - optional bytes padding = 8; - repeated StickerPackOperation stickerPackOperation = 10; - optional ViewOnceOpen viewOnceOpen = 11; - optional FetchLatest fetchLatest = 12; - optional Keys keys = 13; + optional Sent sent = 1; + optional Contacts contacts = 2; + reserved /*groups*/ 3; + optional Request request = 4; + repeated Read read = 5; + optional Blocked blocked = 6; + optional Verified verified = 7; + optional Configuration configuration = 9; + optional bytes padding = 8; + repeated StickerPackOperation stickerPackOperation = 10; + optional ViewOnceOpen viewOnceOpen = 11; + optional FetchLatest fetchLatest = 12; + optional Keys keys = 13; optional MessageRequestResponse messageRequestResponse = 14; - reserved 15; // not yet added - repeated Viewed viewed = 16; - reserved 17; // pniIdentity - optional PniChangeNumber pniChangeNumber = 18; - optional CallEvent callEvent = 19; - optional CallLinkUpdate callLinkUpdate = 20; - optional CallLogEvent callLogEvent = 21; - optional DeleteForMe deleteForMe = 22; - optional DeviceNameChange deviceNameChange = 23; + repeated Viewed viewed = 16; + reserved /*pniIdentity*/ 17; + optional PniChangeNumber pniChangeNumber = 18; + optional CallEvent callEvent = 19; + optional CallLinkUpdate callLinkUpdate = 20; + optional CallLogEvent callLogEvent = 21; + optional DeleteForMe deleteForMe = 22; + optional DeviceNameChange deviceNameChange = 23; } message AttachmentPointer { + // Our parser does not handle reserved in enums: DESKTOP-1569 enum Flags { VOICE_MESSAGE = 1; BORDERLESS = 2; - // Our parser does not handle reserved in enums: DESKTOP-1569 // reserved 4; GIF = 8; } @@ -768,28 +746,36 @@ message AttachmentPointer { } message GroupContextV2 { - optional bytes masterKey = 1; - optional uint32 revision = 2; - optional bytes groupChange = 3; + optional bytes masterKey = 1; + optional uint32 revision = 2; + optional bytes groupChange = 3; } message ContactDetails { message Avatar { optional string contentType = 1; - optional uint32 length = 2; + optional uint32 length = 2; } optional string number = 1; optional string aci = 9; optional string name = 2; optional Avatar avatar = 3; - // reserved 4; // formerly color - // reserved 5; // formerly verified - // reserved 6; // formerly profileKey - // reserved 7; // formerly blocked + reserved /* color */ 4; + reserved /* verified */ 5; + reserved /* profileKey */ 6; + reserved /* blocked */ 7; optional uint32 expireTimer = 8; optional uint32 expireTimerVersion = 12; optional uint32 inboxPosition = 10; + reserved /* archived */ 11; + // NEXT ID: 13 +} + +message DecryptionErrorMessage { + optional bytes ratchetKey = 1; // set to the public ratchet key from the SignalMessage if a 1-1 payload fails to decrypt + optional uint64 timestamp = 2; + optional uint32 deviceId = 3; } message PniSignatureMessage { @@ -802,3 +788,22 @@ message EditMessage { optional uint64 targetSentTimestamp = 1; optional DataMessage dataMessage = 2; } + +message BodyRange { + enum Style { + NONE = 0; + BOLD = 1; + ITALIC = 2; + SPOILER = 3; + STRIKETHROUGH = 4; + MONOSPACE = 5; + } + + optional uint32 start = 1; // Starting index in UTF-16 code units/raw string representation + optional uint32 length = 2; // Length of range in UTF-16 code units/raw string representation + + oneof associatedValue { + string mentionAci = 3; + Style style = 4; + } +} diff --git a/ts/background.ts b/ts/background.ts index df78ef14f..0fa6d47d6 100644 --- a/ts/background.ts +++ b/ts/background.ts @@ -2476,7 +2476,7 @@ export async function startApp(): Promise { const messageDescriptor = getMessageDescriptor({ // 'message' event: for 1:1 converations, the conversation is same as sender - destination: data.source, + destinationE164: data.source, destinationServiceId: data.sourceAci, envelopeId: data.envelopeId, message: data.message, @@ -2736,12 +2736,10 @@ export async function startApp(): Promise { for (const { destinationServiceId, - destination, isAllowedToReplyToStory, } of unidentifiedStatus) { - const conversation = window.ConversationController.get( - destinationServiceId || destination - ); + const conversation = + window.ConversationController.get(destinationServiceId); if (!conversation || conversation.id === ourId) { continue; } @@ -2788,7 +2786,7 @@ export async function startApp(): Promise { if (unidentifiedStatus.length) { unidentifiedDeliveries = unidentifiedStatus .filter(item => Boolean(item.unidentified)) - .map(item => item.destinationServiceId || item.destination) + .map(item => item.destinationServiceId) .filter(isNotNil); } @@ -2823,14 +2821,14 @@ export async function startApp(): Promise { // Works with 'sent' and 'message' data sent from MessageReceiver const getMessageDescriptor = ({ - destination, + destinationE164, destinationServiceId, envelopeId, message, source, sourceDevice, }: { - destination?: string; + destinationE164?: string; destinationServiceId?: ServiceIdString; envelopeId: string; message: ProcessedDataMessage; @@ -2877,7 +2875,7 @@ export async function startApp(): Promise { }; } - const id = destinationServiceId || destination; + const id = destinationServiceId || destinationE164; strictAssert( id, `${logId}: We need some sort of destination for the conversation` @@ -2910,7 +2908,7 @@ export async function startApp(): Promise { ) { const { mergePromises } = window.ConversationController.maybeMergeContacts({ - e164: data.destination, + e164: data.destinationE164, aci: isAciString(data.destinationServiceId) ? data.destinationServiceId : undefined, @@ -3241,14 +3239,13 @@ export async function startApp(): Promise { } function onViewOnceOpenSync(ev: ViewOnceOpenSyncEvent): void { - const { source, sourceAci, timestamp } = ev; - log.info(`view once open sync ${source} ${timestamp}`); + const { sourceAci, timestamp } = ev; + log.info(`view once open sync ${sourceAci} ${timestamp}`); strictAssert(sourceAci, 'ViewOnceOpen without sourceAci'); strictAssert(timestamp, 'ViewOnceOpen without timestamp'); const attributes: ViewOnceOpenSyncAttributesType = { removeFromMessageReceiverCache: ev.confirm, - source, sourceAci, timestamp, }; @@ -3379,10 +3376,9 @@ export async function startApp(): Promise { } function onMessageRequestResponse(ev: MessageRequestResponseEvent): void { - const { threadE164, threadAci, groupV2Id, messageRequestResponseType } = ev; + const { threadAci, groupV2Id, messageRequestResponseType } = ev; log.info('onMessageRequestResponse', { - threadE164, threadAci, groupV2Id: `groupv2(${groupV2Id})`, messageRequestResponseType, @@ -3398,7 +3394,6 @@ export async function startApp(): Promise { const attributes: MessageRequestAttributesType = { envelopeId: ev.envelopeId, removeFromMessageReceiverCache: ev.confirm, - threadE164, threadAci, groupV2Id, type: messageRequestResponseType, diff --git a/ts/jobs/helpers/sendCallingMessage.ts b/ts/jobs/helpers/sendCallingMessage.ts index e02322b64..75a000ac1 100644 --- a/ts/jobs/helpers/sendCallingMessage.ts +++ b/ts/jobs/helpers/sendCallingMessage.ts @@ -90,9 +90,7 @@ export async function sendCallingMessage( groupId, }); - const callingMessage = Proto.CallingMessage.decode( - Bytes.fromBase64(protoBase64) - ); + const callMessage = Proto.CallMessage.decode(Bytes.fromBase64(protoBase64)); const { ContentHint } = Proto.UnidentifiedSenderMessage.Message; @@ -101,7 +99,7 @@ export async function sendCallingMessage( await handleMessageSend( sendContentMessageToGroup({ contentHint: ContentHint.DEFAULT, - contentMessage: new Proto.Content({ callingMessage }), + contentMessage: new Proto.Content({ callMessage }), isPartialSend, messageId: undefined, recipients, @@ -122,7 +120,7 @@ export async function sendCallingMessage( await handleMessageSend( messaging.sendCallingMessage( sendTarget, - callingMessage, + callMessage, timestamp, urgent, sendOptions diff --git a/ts/jobs/helpers/sendDeleteForEveryone.ts b/ts/jobs/helpers/sendDeleteForEveryone.ts index 1d45730ad..ce306f166 100644 --- a/ts/jobs/helpers/sendDeleteForEveryone.ts +++ b/ts/jobs/helpers/sendDeleteForEveryone.ts @@ -144,7 +144,7 @@ export async function sendDeleteForEveryone( encodedDataMessage: Proto.DataMessage.encode( proto.dataMessage ).finish(), - destination: conversation.get('e164'), + destinationE164: conversation.get('e164'), destinationServiceId: conversation.getServiceId(), expirationStartTimestamp: null, options: sendOptions, diff --git a/ts/jobs/helpers/sendDeleteStoryForEveryone.ts b/ts/jobs/helpers/sendDeleteStoryForEveryone.ts index 03c4c0d73..f9b186e71 100644 --- a/ts/jobs/helpers/sendDeleteStoryForEveryone.ts +++ b/ts/jobs/helpers/sendDeleteStoryForEveryone.ts @@ -241,7 +241,7 @@ export async function sendDeleteStoryForEveryone( // Sync message for other devices await handleMessageSend( messaging.sendSyncMessage({ - destination: undefined, + destinationE164: undefined, destinationServiceId, storyMessageRecipients: updatedStoryRecipients?.map( ({ destinationServiceId: legacyDestinationUuid, ...rest }) => { diff --git a/ts/jobs/helpers/sendDirectExpirationTimerUpdate.ts b/ts/jobs/helpers/sendDirectExpirationTimerUpdate.ts index ebbe8e941..d1c471456 100644 --- a/ts/jobs/helpers/sendDirectExpirationTimerUpdate.ts +++ b/ts/jobs/helpers/sendDirectExpirationTimerUpdate.ts @@ -105,7 +105,7 @@ export async function sendDirectExpirationTimerUpdate( encodedDataMessage: Proto.DataMessage.encode( proto.dataMessage ).finish(), - destination: conversation.get('e164'), + destinationE164: conversation.get('e164'), destinationServiceId: conversation.getServiceId(), expirationStartTimestamp: null, options: sendOptions, diff --git a/ts/jobs/helpers/sendStory.ts b/ts/jobs/helpers/sendStory.ts index 3cdc1055f..98d049c28 100644 --- a/ts/jobs/helpers/sendStory.ts +++ b/ts/jobs/helpers/sendStory.ts @@ -583,7 +583,7 @@ export async function sendStory( await messaging.sendSyncMessage({ // Note: these two fields will be undefined if we're sending to a group - destination: conversation.get('e164'), + destinationE164: conversation.get('e164'), destinationServiceId: conversation.getServiceId(), storyMessage: originalStoryMessage, storyMessageRecipients, diff --git a/ts/messageModifiers/MessageRequests.ts b/ts/messageModifiers/MessageRequests.ts index 55b823337..479550498 100644 --- a/ts/messageModifiers/MessageRequests.ts +++ b/ts/messageModifiers/MessageRequests.ts @@ -13,7 +13,6 @@ export type MessageRequestAttributesType = { groupV2Id?: string; removeFromMessageReceiverCache: () => unknown; threadAci?: AciString; - threadE164?: string; type: number; }; @@ -33,17 +32,6 @@ export function forConversation( const messageRequestValues = Array.from(messageRequests.values()); - if (conversation.get('e164')) { - const syncByE164 = messageRequestValues.find( - item => item.threadE164 === conversation.get('e164') - ); - if (syncByE164) { - log.info(`${logId}: Found early message request response for E164`); - remove(syncByE164); - return syncByE164; - } - } - if (conversation.getServiceId()) { const syncByServiceId = messageRequestValues.find( item => item.threadAci === conversation.getServiceId() @@ -74,9 +62,9 @@ export async function onResponse( sync: MessageRequestAttributesType ): Promise { messageRequests.set(sync.envelopeId, sync); - const { threadE164, threadAci, groupV2Id } = sync; + const { threadAci, groupV2Id } = sync; - const logId = `MessageRequests.onResponse(groupv2(${groupV2Id}) ${threadAci} ${threadE164})`; + const logId = `MessageRequests.onResponse(groupv2(${groupV2Id}) ${threadAci}`; try { let conversation; @@ -85,9 +73,8 @@ export async function onResponse( if (groupV2Id) { conversation = window.ConversationController.get(groupV2Id); } - if (!conversation && (threadE164 || threadAci)) { + if (!conversation && threadAci) { conversation = window.ConversationController.lookupOrCreate({ - e164: threadE164, serviceId: threadAci, reason: logId, }); diff --git a/ts/messageModifiers/ViewOnceOpenSyncs.ts b/ts/messageModifiers/ViewOnceOpenSyncs.ts index 0bbfd174d..6ec6f899f 100644 --- a/ts/messageModifiers/ViewOnceOpenSyncs.ts +++ b/ts/messageModifiers/ViewOnceOpenSyncs.ts @@ -12,7 +12,6 @@ import { MessageModel } from '../models/messages'; export type ViewOnceOpenSyncAttributesType = { removeFromMessageReceiverCache: () => unknown; - source?: string; sourceAci: AciString; timestamp: number; }; @@ -46,15 +45,6 @@ export function forMessage( return syncBySourceServiceId; } - const syncBySource = viewOnceSyncValues.find(item => { - return item.source === message.source && item.timestamp === message.sent_at; - }); - if (syncBySource) { - log.info(`${logId}: Found early view once open sync for message`); - remove(syncBySource); - return syncBySource; - } - return null; } @@ -69,23 +59,16 @@ export async function onSync( const messages = await DataReader.getMessagesBySentAt(sync.timestamp); const found = messages.find(item => { - const itemSourceAci = item.sourceServiceId; - const syncSourceAci = sync.sourceAci; - const itemSource = item.source; - const syncSource = sync.source; + const itemSource = item.sourceServiceId; + const syncSource = sync.sourceAci; - return Boolean( - (itemSourceAci && syncSourceAci && itemSourceAci === syncSourceAci) || - (itemSource && syncSource && itemSource === syncSource) - ); + return Boolean(itemSource && syncSource && itemSource === syncSource); }); - const syncSource = sync.source; const syncSourceAci = sync.sourceAci; const syncTimestamp = sync.timestamp; const wasMessageFound = Boolean(found); log.info(`${logId} receive:`, { - syncSource, syncSourceAci, syncTimestamp, wasMessageFound, diff --git a/ts/messages/handleDataMessage.ts b/ts/messages/handleDataMessage.ts index 13d4c800b..6455ba31c 100644 --- a/ts/messages/handleDataMessage.ts +++ b/ts/messages/handleDataMessage.ts @@ -153,48 +153,44 @@ export async function handleDataMessage( ? data.unidentifiedStatus : []; - unidentifiedStatus.forEach( - ({ destinationServiceId, destination, unidentified }) => { - const identifier = destinationServiceId || destination; - if (!identifier) { - return; - } - - const destinationConversation = - window.ConversationController.lookupOrCreate({ - serviceId: destinationServiceId, - e164: destination || undefined, - reason: `handleDataMessage(${initialMessage.timestamp})`, - }); - if (!destinationConversation) { - return; - } - - const updatedAt: number = - data && isNormalNumber(data.timestamp) - ? data.timestamp - : Date.now(); - - const previousSendState = getOwn( - sendStateByConversationId, - destinationConversation.id - ); - sendStateByConversationId[destinationConversation.id] = - previousSendState - ? sendStateReducer(previousSendState, { - type: SendActionType.Sent, - updatedAt, - }) - : { - status: SendStatus.Sent, - updatedAt, - }; - - if (unidentified) { - unidentifiedDeliveriesSet.add(identifier); - } + unidentifiedStatus.forEach(({ destinationServiceId, unidentified }) => { + if (!destinationServiceId) { + return; } - ); + + const destinationConversation = + window.ConversationController.lookupOrCreate({ + serviceId: destinationServiceId, + reason: `handleDataMessage(${initialMessage.timestamp})`, + }); + if (!destinationConversation) { + return; + } + + const updatedAt: number = + data && isNormalNumber(data.timestamp) + ? data.timestamp + : Date.now(); + + const previousSendState = getOwn( + sendStateByConversationId, + destinationConversation.id + ); + sendStateByConversationId[destinationConversation.id] = + previousSendState + ? sendStateReducer(previousSendState, { + type: SendActionType.Sent, + updatedAt, + }) + : { + status: SendStatus.Sent, + updatedAt, + }; + + if (unidentified) { + unidentifiedDeliveriesSet.add(destinationServiceId); + } + }); toUpdate.set({ sendStateByConversationId, diff --git a/ts/messages/send.ts b/ts/messages/send.ts index 0f80a92f0..7eea4d1bb 100644 --- a/ts/messages/send.ts +++ b/ts/messages/send.ts @@ -408,7 +408,7 @@ export async function sendSyncMessage( messaging.sendSyncMessage({ ...encodedContent, timestamp: targetTimestamp, - destination: conv.get('e164'), + destinationE164: conv.get('e164'), destinationServiceId: conv.getServiceId(), expirationStartTimestamp: message.get('expirationStartTimestamp') || null, diff --git a/ts/services/calling.ts b/ts/services/calling.ts index d3b0e36b7..8dc62c04f 100644 --- a/ts/services/calling.ts +++ b/ts/services/calling.ts @@ -262,21 +262,18 @@ function cleanForLogging(settings?: MediaDeviceSettings): unknown { function protoToCallingMessage({ offer, answer, - iceCandidates, + iceUpdate, busy, hangup, destinationDeviceId, opaque, -}: Proto.ICallingMessage): CallingMessage { +}: Proto.ICallMessage): CallingMessage { const newIceCandidates: Array = []; - if (iceCandidates) { - iceCandidates.forEach(candidate => { - if (candidate.callId && candidate.opaque) { + if (iceUpdate) { + iceUpdate.forEach(candidate => { + if (candidate.id && candidate.opaque) { newIceCandidates.push( - new IceCandidateMessage( - candidate.callId, - Buffer.from(candidate.opaque) - ) + new IceCandidateMessage(candidate.id, Buffer.from(candidate.opaque)) ); } }); @@ -284,23 +281,23 @@ function protoToCallingMessage({ return { offer: - offer && offer.callId && offer.opaque + offer && offer.id && offer.opaque ? new OfferMessage( - offer.callId, + offer.id, dropNull(offer.type) as number, Buffer.from(offer.opaque) ) : undefined, answer: - answer && answer.callId && answer.opaque - ? new AnswerMessage(answer.callId, Buffer.from(answer.opaque)) + answer && answer.id && answer.opaque + ? new AnswerMessage(answer.id, Buffer.from(answer.opaque)) : undefined, iceCandidates: newIceCandidates.length > 0 ? newIceCandidates : undefined, - busy: busy && busy.callId ? new BusyMessage(busy.callId) : undefined, + busy: busy && busy.id ? new BusyMessage(busy.id) : undefined, hangup: - hangup && hangup.callId + hangup && hangup.id ? new HangupMessage( - hangup.callId, + hangup.id, dropNull(hangup.type) as number, hangup.deviceId || 0 ) @@ -2444,7 +2441,7 @@ export class CallingClass { async handleCallingMessage( envelope: ProcessedEnvelope, - callingMessage: Proto.ICallingMessage + callingMessage: Proto.ICallMessage ): Promise { const logId = `CallingClass.handleCallingMessage(${envelope.timestamp})`; @@ -2500,7 +2497,7 @@ export class CallingClass { 'rejecting call message.' ); - const { callId } = callingMessage.offer; + const { id: callId } = callingMessage.offer; assertDev(callId != null, 'Call ID missing from offer'); const hangup = new HangupMessage( @@ -2516,7 +2513,7 @@ export class CallingClass { const wasVideoCall = callingMessage.offer.type === - Proto.CallingMessage.Offer.Type.OFFER_VIDEO_CALL; + Proto.CallMessage.Offer.Type.OFFER_VIDEO_CALL; const peerId = getPeerIdFromConversation(conversation.attributes); const callDetails = getCallDetailsFromEndedDirectCall( @@ -2684,7 +2681,7 @@ export class CallingClass { callingMessage.opaque.data = data; const proto = callingMessageToProto(callingMessage, urgency); - const protoBytes = Proto.CallingMessage.encode(proto).finish(); + const protoBytes = Proto.CallMessage.encode(proto).finish(); const protoBase64 = Bytes.toBase64(protoBytes); await conversationJobQueue.add({ @@ -2845,7 +2842,7 @@ export class CallingClass { try { const proto = callingMessageToProto(message, urgency); - const protoBytes = Proto.CallingMessage.encode(proto).finish(); + const protoBytes = Proto.CallMessage.encode(proto).finish(); const protoBase64 = Bytes.toBase64(protoBytes); await conversationJobQueue.add({ diff --git a/ts/sql/migrations/1280-blob-unprocessed.ts b/ts/sql/migrations/1280-blob-unprocessed.ts index fab7579b6..ada93322b 100644 --- a/ts/sql/migrations/1280-blob-unprocessed.ts +++ b/ts/sql/migrations/1280-blob-unprocessed.ts @@ -150,8 +150,8 @@ export function updateToSchemaVersion1280( : undefined, // Sadly not captured previously messageAgeSec: 0, - reportingToken: decoded.reportingToken?.length - ? decoded.reportingToken + reportingToken: decoded.reportSpamToken?.length + ? decoded.reportSpamToken : null, }); } catch (error) { diff --git a/ts/test-both/processDataMessage_test.ts b/ts/test-both/processDataMessage_test.ts index ac01a0196..fb1b7c729 100644 --- a/ts/test-both/processDataMessage_test.ts +++ b/ts/test-both/processDataMessage_test.ts @@ -222,7 +222,7 @@ describe('processDataMessage', () => { reaction: { emoji: '😎', targetAuthorAci: ACI_1, - targetTimestamp: Long.fromNumber(TIMESTAMP), + targetSentTimestamp: Long.fromNumber(TIMESTAMP), }, }).reaction, { @@ -239,7 +239,7 @@ describe('processDataMessage', () => { emoji: '😎', remove: true, targetAuthorAci: ACI_1, - targetTimestamp: Long.fromNumber(TIMESTAMP), + targetSentTimestamp: Long.fromNumber(TIMESTAMP), }, }).reaction, { diff --git a/ts/test-mock/pnp/pni_signature_test.ts b/ts/test-mock/pnp/pni_signature_test.ts index 97f4b955c..efe913547 100644 --- a/ts/test-mock/pnp/pni_signature_test.ts +++ b/ts/test-mock/pnp/pni_signature_test.ts @@ -280,7 +280,6 @@ describe('pnp/PNI Signature', function (this: Mocha.Suite) { unidentifiedStatus: [ { destinationServiceId, - destination, destinationPniIdentityKey: destinationPniIdentityKey.serialize(), }, ], diff --git a/ts/test-node/sql/migration_1280_test.ts b/ts/test-node/sql/migration_1280_test.ts index d9b2a37f1..4a8910efd 100644 --- a/ts/test-node/sql/migration_1280_test.ts +++ b/ts/test-node/sql/migration_1280_test.ts @@ -59,7 +59,7 @@ describe('SQL/updateToSchemaVersion1280', () => { Proto.Envelope.encode({ destinationServiceId: THEIR_ACI, content: Buffer.from('encrypted1'), - reportingToken: Buffer.from('token'), + reportSpamToken: Buffer.from('token'), }).finish() ).toString('base64'), serverTimestamp: 6, diff --git a/ts/test-node/util/callingMessageToProto_test.ts b/ts/test-node/util/callingMessageToProto_test.ts index 6f3378077..f8e751b80 100644 --- a/ts/test-node/util/callingMessageToProto_test.ts +++ b/ts/test-node/util/callingMessageToProto_test.ts @@ -58,7 +58,7 @@ describe('callingMessageToProto', () => { ); assert.deepEqual( droppableResult.opaque?.urgency, - Proto.CallingMessage.Opaque.Urgency.DROPPABLE + Proto.CallMessage.Opaque.Urgency.DROPPABLE ); const urgentResult = callingMessageToProto( @@ -67,7 +67,7 @@ describe('callingMessageToProto', () => { ); assert.deepEqual( urgentResult.opaque?.urgency, - Proto.CallingMessage.Opaque.Urgency.HANDLE_IMMEDIATELY + Proto.CallMessage.Opaque.Urgency.HANDLE_IMMEDIATELY ); }); @@ -84,7 +84,7 @@ describe('callingMessageToProto', () => { assert.deepEqual(result.opaque?.data, new Uint8Array([1, 2, 3])); assert.deepEqual( result.opaque?.urgency, - Proto.CallingMessage.Opaque.Urgency.HANDLE_IMMEDIATELY + Proto.CallMessage.Opaque.Urgency.HANDLE_IMMEDIATELY ); }); }); diff --git a/ts/textsecure/MessageReceiver.ts b/ts/textsecure/MessageReceiver.ts index c16711e58..9412e7b85 100644 --- a/ts/textsecure/MessageReceiver.ts +++ b/ts/textsecure/MessageReceiver.ts @@ -447,8 +447,8 @@ export default class MessageReceiver serverTimestamp, urgent: isBoolean(decoded.urgent) ? decoded.urgent : true, story: decoded.story ?? false, - reportingToken: Bytes.isNotEmpty(decoded.reportingToken) - ? decoded.reportingToken + reportingToken: Bytes.isNotEmpty(decoded.reportSpamToken) + ? decoded.reportSpamToken : undefined, groupId: undefined, }; @@ -1447,7 +1447,7 @@ export default class MessageReceiver throw new Error('Unsealed envelope dropped due to stopping processing'); } - if (envelope.type === Proto.Envelope.Type.RECEIPT) { + if (envelope.type === Proto.Envelope.Type.SERVER_DELIVERY_RECEIPT) { strictAssert( envelope.sourceServiceId, 'Unsealed delivery receipt must have sourceServiceId' @@ -2145,7 +2145,7 @@ export default class MessageReceiver logUnexpectedUrgentValue(envelope, 'sentSync'); const { - destination, + destinationE164, destinationServiceId, timestamp, message: msg, @@ -2178,7 +2178,7 @@ export default class MessageReceiver const ev = new SentEvent( { envelopeId: envelope.id, - destination: dropNull(destination), + destinationE164: dropNull(destinationE164), destinationServiceId, timestamp: timestamp?.toNumber(), serverTimestamp: envelope.serverTimestamp, @@ -2673,8 +2673,8 @@ export default class MessageReceiver this.#handleNullMessage(envelope); return; } - if (content.callingMessage) { - await this.#handleCallingMessage(envelope, content.callingMessage); + if (content.callMessage) { + await this.#handleCallingMessage(envelope, content.callMessage); return; } if (content.receiptMessage) { @@ -2832,7 +2832,7 @@ export default class MessageReceiver async #handleCallingMessage( envelope: UnsealedEnvelope, - callingMessage: Proto.ICallingMessage + callingMessage: Proto.ICallMessage ): Promise { logUnexpectedUrgentValue(envelope, 'callingMessage'); @@ -3215,7 +3215,7 @@ export default class MessageReceiver } const { - destination, + destinationE164, destinationServiceId, expirationStartTimestamp, unidentifiedStatus, @@ -3227,7 +3227,7 @@ export default class MessageReceiver const ev = new SentEvent( { envelopeId: envelope.id, - destination: dropNull(destination), + destinationE164: dropNull(destinationE164), destinationServiceId, timestamp: envelope.timestamp, serverTimestamp: envelope.serverTimestamp, @@ -3274,7 +3274,6 @@ export default class MessageReceiver const ev = new ViewOnceOpenSyncEvent( { - source: dropNull(sync.sender), sourceAci: sync.senderAci ? normalizeAci(sync.senderAci, 'handleViewOnceOpen.senderUuid') : undefined, @@ -3311,7 +3310,6 @@ export default class MessageReceiver const ev = new MessageRequestResponseEvent( { envelopeId: envelope.id, - threadE164: dropNull(sync.threadE164), threadAci: sync.threadAci ? normalizeAci( sync.threadAci, @@ -3454,11 +3452,10 @@ export default class MessageReceiver logUnexpectedUrgentValue(envelope, 'readSync'); const reads = read.map( - ({ timestamp, sender, senderAci }): ReadSyncEventData => ({ + ({ timestamp, senderAci }): ReadSyncEventData => ({ envelopeId: envelope.id, envelopeTimestamp: envelope.timestamp, timestamp: timestamp?.toNumber(), - sender: dropNull(sender), senderAci: senderAci ? normalizeAci(senderAci, 'handleRead.senderAci') : undefined, @@ -3486,9 +3483,8 @@ export default class MessageReceiver logUnexpectedUrgentValue(envelope, 'viewSync'); const views = viewed.map( - ({ timestamp, senderE164, senderAci }): ViewSyncEventData => ({ + ({ timestamp, senderAci }): ViewSyncEventData => ({ timestamp: timestamp?.toNumber(), - senderE164: dropNull(senderE164), senderAci: senderAci ? normalizeAci(senderAci, 'handleViewed.senderAci') : undefined, @@ -4027,18 +4023,13 @@ function envelopeTypeToCiphertextType(type: number | undefined): number { if (type === Type.CIPHERTEXT) { return CiphertextMessageType.Whisper; } - if (type === Type.KEY_EXCHANGE) { - throw new Error( - 'envelopeTypeToCiphertextType: Cannot process KEY_EXCHANGE messages' - ); - } if (type === Type.PLAINTEXT_CONTENT) { return CiphertextMessageType.Plaintext; } if (type === Type.PREKEY_BUNDLE) { return CiphertextMessageType.PreKey; } - if (type === Type.RECEIPT) { + if (type === Type.SERVER_DELIVERY_RECEIPT) { return CiphertextMessageType.Plaintext; } if (type === Type.UNIDENTIFIED_SENDER) { diff --git a/ts/textsecure/SendMessage.ts b/ts/textsecure/SendMessage.ts index 80fe22de7..2fef0dc7a 100644 --- a/ts/textsecure/SendMessage.ts +++ b/ts/textsecure/SendMessage.ts @@ -414,7 +414,7 @@ class Message { proto.reaction.emoji = this.reaction.emoji || null; proto.reaction.remove = this.reaction.remove || false; proto.reaction.targetAuthorAci = this.reaction.targetAuthorAci || null; - proto.reaction.targetTimestamp = + proto.reaction.targetSentTimestamp = this.reaction.targetTimestamp === undefined ? null : Long.fromNumber(this.reaction.targetTimestamp); @@ -422,7 +422,7 @@ class Message { if (Array.isArray(this.preview)) { proto.preview = this.preview.map(preview => { - const item = new Proto.DataMessage.Preview(); + const item = new Proto.Preview(); item.title = preview.title; item.url = preview.url; item.description = preview.description || null; @@ -504,7 +504,8 @@ class Message { } if (this.quote) { - const { BodyRange: ProtoBodyRange, Quote } = Proto.DataMessage; + const ProtoBodyRange = Proto.BodyRange; + const { Quote } = Proto.DataMessage; proto.quote = new Quote(); const { quote } = proto; @@ -1256,7 +1257,7 @@ export default class MessageSender { encodedDataMessage, encodedEditMessage, timestamp, - destination, + destinationE164, destinationServiceId, expirationStartTimestamp, conversationIdsSentTo = [], @@ -1270,7 +1271,7 @@ export default class MessageSender { encodedDataMessage?: Uint8Array; encodedEditMessage?: Uint8Array; timestamp: number; - destination: string | undefined; + destinationE164: string | undefined; destinationServiceId: ServiceIdString | undefined; expirationStartTimestamp: number | null; conversationIdsSentTo?: Iterable; @@ -1293,8 +1294,8 @@ export default class MessageSender { const dataMessage = Proto.DataMessage.decode(encodedDataMessage); sentMessage.message = dataMessage; } - if (destination) { - sentMessage.destination = destination; + if (destinationE164) { + sentMessage.destinationE164 = destinationE164; } if (destinationServiceId) { sentMessage.destinationServiceId = destinationServiceId; @@ -1325,10 +1326,6 @@ export default class MessageSender { new Proto.SyncMessage.Sent.UnidentifiedDeliveryStatus(); const conv = window.ConversationController.get(conversationId); if (conv) { - const e164 = conv.get('e164'); - if (e164) { - status.destination = e164; - } const serviceId = conv.getServiceId(); if (serviceId) { status.destinationServiceId = serviceId; @@ -1763,7 +1760,7 @@ export default class MessageSender { `syncViewOnceOpen: ${viewOnceOpens.length} opens provided. Can only handle one.` ); } - const { senderE164, senderAci, timestamp } = viewOnceOpens[0]; + const { senderAci, timestamp } = viewOnceOpens[0]; if (!senderAci) { throw new Error('syncViewOnceOpen: Missing senderAci'); @@ -1774,9 +1771,6 @@ export default class MessageSender { const syncMessage = MessageSender.createSyncMessage(); const viewOnceOpen = new Proto.SyncMessage.ViewOnceOpen(); - if (senderE164 !== undefined) { - viewOnceOpen.sender = senderE164; - } viewOnceOpen.senderAci = senderAci; viewOnceOpen.timestamp = Long.fromNumber(timestamp); syncMessage.viewOnceOpen = viewOnceOpen; @@ -1832,7 +1826,6 @@ export default class MessageSender { static getMessageRequestResponseSync( options: Readonly<{ - threadE164?: string; threadAci?: AciString; groupId?: Uint8Array; type: number; @@ -1843,9 +1836,6 @@ export default class MessageSender { const syncMessage = MessageSender.createSyncMessage(); const response = new Proto.SyncMessage.MessageRequestResponse(); - if (options.threadE164 !== undefined) { - response.threadE164 = options.threadE164; - } if (options.threadAci !== undefined) { response.threadAci = options.threadAci; } @@ -1929,9 +1919,6 @@ export default class MessageSender { const verified = new Proto.Verified(); verified.state = state; - if (destinationE164) { - verified.destination = destinationE164; - } if (destinationAci) { verified.destinationAci = destinationAci; } @@ -1962,7 +1949,7 @@ export default class MessageSender { async sendCallingMessage( serviceId: ServiceIdString, - callingMessage: Readonly, + callingMessage: Readonly, timestamp: number, urgent: boolean, options?: Readonly @@ -1970,7 +1957,7 @@ export default class MessageSender { const recipients = [serviceId]; const contentMessage = new Proto.Content(); - contentMessage.callingMessage = callingMessage; + contentMessage.callMessage = callingMessage; const conversation = window.ConversationController.get(serviceId); diff --git a/ts/textsecure/messageReceiverEvents.ts b/ts/textsecure/messageReceiverEvents.ts index 647312692..c8818b312 100644 --- a/ts/textsecure/messageReceiverEvents.ts +++ b/ts/textsecure/messageReceiverEvents.ts @@ -208,7 +208,7 @@ export class RetryRequestEvent extends ConfirmableEvent { export type SentEventData = Readonly<{ envelopeId: string; - destination?: string; + destinationE164?: string; destinationServiceId?: ServiceIdString; timestamp?: number; serverTimestamp: number; @@ -311,25 +311,21 @@ export class ConfigurationEvent extends ConfirmableEvent { } export type ViewOnceOpenSyncOptions = { - source?: string; sourceAci?: AciString; timestamp?: number; }; export class ViewOnceOpenSyncEvent extends ConfirmableEvent { - public readonly source?: string; - public readonly sourceAci?: AciString; public readonly timestamp?: number; constructor( - { source, sourceAci, timestamp }: ViewOnceOpenSyncOptions, + { sourceAci, timestamp }: ViewOnceOpenSyncOptions, confirm: ConfirmCallback ) { super('viewOnceOpenSync', confirm); - this.source = source; this.sourceAci = sourceAci; this.timestamp = timestamp; } @@ -345,8 +341,6 @@ export type MessageRequestResponseOptions = { }; export class MessageRequestResponseEvent extends ConfirmableEvent { - public readonly threadE164?: string; - public readonly threadAci?: AciString; public readonly messageRequestResponseType?: MessageRequestResponseOptions['messageRequestResponseType']; @@ -360,7 +354,6 @@ export class MessageRequestResponseEvent extends ConfirmableEvent { constructor( { envelopeId, - threadE164, threadAci, messageRequestResponseType, groupId, @@ -371,7 +364,6 @@ export class MessageRequestResponseEvent extends ConfirmableEvent { super('messageRequestResponse', confirm); this.envelopeId = envelopeId; - this.threadE164 = threadE164; this.threadAci = threadAci; this.messageRequestResponseType = messageRequestResponseType; this.groupId = groupId; diff --git a/ts/textsecure/processDataMessage.ts b/ts/textsecure/processDataMessage.ts index 6e88a581e..5f44a4462 100644 --- a/ts/textsecure/processDataMessage.ts +++ b/ts/textsecure/processDataMessage.ts @@ -198,7 +198,7 @@ function cleanLinkPreviewDate(value?: Long | null): number | undefined { } export function processPreview( - preview?: ReadonlyArray | null + preview?: ReadonlyArray | null ): ReadonlyArray | undefined { if (!preview) { return undefined; @@ -247,7 +247,7 @@ export function processReaction( emoji: dropNull(reaction.emoji), remove: Boolean(reaction.remove), targetAuthorAci: normalizeAci(targetAuthorAci, 'Reaction.targetAuthorAci'), - targetTimestamp: reaction.targetTimestamp?.toNumber(), + targetTimestamp: reaction.targetSentTimestamp?.toNumber(), }; } diff --git a/ts/types/BodyRange.ts b/ts/types/BodyRange.ts index 9df015585..b8b49e90b 100644 --- a/ts/types/BodyRange.ts +++ b/ts/types/BodyRange.ts @@ -36,8 +36,8 @@ export enum DisplayStyle { // eslint-disable-next-line @typescript-eslint/no-redeclare export namespace BodyRange { // re-export for convenience - export type Style = Proto.DataMessage.BodyRange.Style; - export const { Style } = Proto.DataMessage.BodyRange; + export type Style = Proto.BodyRange.Style; + export const { Style } = Proto.BodyRange; export type Mention = { mentionAci: AciString; @@ -147,10 +147,7 @@ const MENTION_NAME = 'mention'; // We drop unknown bodyRanges and remove extra stuff so they serialize properly export function filterAndClean( - ranges: - | ReadonlyArray - | undefined - | null + ranges: ReadonlyArray | undefined | null ): ReadonlyArray | undefined { if (!ranges) { return undefined; diff --git a/ts/util/callDisposition.ts b/ts/util/callDisposition.ts index 10d62ebb3..b5f65e467 100644 --- a/ts/util/callDisposition.ts +++ b/ts/util/callDisposition.ts @@ -307,7 +307,8 @@ export function getCallLogEventForProto( const directionToProto = { [CallDirection.Incoming]: Proto.SyncMessage.CallEvent.Direction.INCOMING, [CallDirection.Outgoing]: Proto.SyncMessage.CallEvent.Direction.OUTGOING, - [CallDirection.Unknown]: Proto.SyncMessage.CallEvent.Direction.UNKNOWN, + [CallDirection.Unknown]: + Proto.SyncMessage.CallEvent.Direction.UNKNOWN_DIRECTION, }; const typeToProto = { @@ -315,7 +316,7 @@ const typeToProto = { [CallType.Video]: Proto.SyncMessage.CallEvent.Type.VIDEO_CALL, [CallType.Group]: Proto.SyncMessage.CallEvent.Type.GROUP_CALL, [CallType.Adhoc]: Proto.SyncMessage.CallEvent.Type.AD_HOC_CALL, - [CallType.Unknown]: Proto.SyncMessage.CallEvent.Type.UNKNOWN, + [CallType.Unknown]: Proto.SyncMessage.CallEvent.Type.UNKNOWN_TYPE, }; const statusToProto: Record< @@ -335,7 +336,7 @@ const statusToProto: Record< [CallStatusValue.Ringing]: null, [CallStatusValue.Joined]: null, [CallStatusValue.JoinedAdhoc]: Proto.SyncMessage.CallEvent.Event.ACCEPTED, - [CallStatusValue.Unknown]: Proto.SyncMessage.CallEvent.Event.UNKNOWN, + [CallStatusValue.Unknown]: Proto.SyncMessage.CallEvent.Event.UNKNOWN_EVENT, }; function shouldSyncStatus(callStatus: CallStatus) { diff --git a/ts/util/callingMessageToProto.ts b/ts/util/callingMessageToProto.ts index 12736c6bc..6b6b15e1b 100644 --- a/ts/util/callingMessageToProto.ts +++ b/ts/util/callingMessageToProto.ts @@ -19,8 +19,8 @@ export function callingMessageToProto( opaque, }: CallingMessage, urgency?: CallMessageUrgency -): Proto.ICallingMessage { - let opaqueField: undefined | Proto.CallingMessage.IOpaque; +): Proto.ICallMessage { + let opaqueField: undefined | Proto.CallMessage.IOpaque; if (opaque) { opaqueField = { ...opaque, @@ -38,7 +38,7 @@ export function callingMessageToProto( offer: offer ? { ...offer, - callId: Long.fromValue(offer.callId), + id: Long.fromValue(offer.callId), type: offer.type as number, opaque: bufferToProto(offer.opaque), } @@ -46,11 +46,11 @@ export function callingMessageToProto( answer: answer ? { ...answer, - callId: Long.fromValue(answer.callId), + id: Long.fromValue(answer.callId), opaque: bufferToProto(answer.opaque), } : undefined, - iceCandidates: iceCandidates + iceUpdate: iceCandidates ? iceCandidates.map(candidate => { return { ...candidate, @@ -62,13 +62,13 @@ export function callingMessageToProto( busy: busy ? { ...busy, - callId: Long.fromValue(busy.callId), + id: Long.fromValue(busy.callId), } : undefined, hangup: hangup ? { ...hangup, - callId: Long.fromValue(hangup.callId), + id: Long.fromValue(hangup.callId), type: hangup.type as number, } : undefined, @@ -92,14 +92,14 @@ function bufferToProto( function urgencyToProto( urgency: CallMessageUrgency -): Proto.CallingMessage.Opaque.Urgency { +): Proto.CallMessage.Opaque.Urgency { switch (urgency) { case CallMessageUrgency.Droppable: - return Proto.CallingMessage.Opaque.Urgency.DROPPABLE; + return Proto.CallMessage.Opaque.Urgency.DROPPABLE; case CallMessageUrgency.HandleImmediately: - return Proto.CallingMessage.Opaque.Urgency.HANDLE_IMMEDIATELY; + return Proto.CallMessage.Opaque.Urgency.HANDLE_IMMEDIATELY; default: log.error(missingCaseError(urgency)); - return Proto.CallingMessage.Opaque.Urgency.DROPPABLE; + return Proto.CallMessage.Opaque.Urgency.DROPPABLE; } } diff --git a/ts/util/wrapWithSyncMessageSend.ts b/ts/util/wrapWithSyncMessageSend.ts index e9eaedcc9..fa6cfd3c9 100644 --- a/ts/util/wrapWithSyncMessageSend.ts +++ b/ts/util/wrapWithSyncMessageSend.ts @@ -76,7 +76,7 @@ export async function wrapWithSyncMessageSend({ }); await handleMessageSend( sender.sendSyncMessage({ - destination: conversation.get('e164'), + destinationE164: conversation.get('e164'), destinationServiceId: conversation.getServiceId(), encodedDataMessage: dataMessage, expirationStartTimestamp: null,