Refactor SendMessage.ts to named parameters

This commit is contained in:
Scott Nonnenberg 2021-07-02 11:34:17 -07:00 committed by GitHub
parent 56933192ba
commit 615ae1ccf7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 540 additions and 470 deletions

View file

@ -181,12 +181,12 @@ export async function startApp(): Promise<void> {
} = await window.ConversationController.prepareForSend(c.get('id')); } = await window.ConversationController.prepareForSend(c.get('id'));
// eslint-disable-next-line no-await-in-loop // eslint-disable-next-line no-await-in-loop
await wrap( await wrap(
window.textsecure.messaging.sendDeliveryReceipt( window.textsecure.messaging.sendDeliveryReceipt({
e164, e164,
uuid, uuid,
timestamps, timestamps,
sendOptions options: sendOptions,
) })
); );
} catch (error) { } catch (error) {
window.log.error( window.log.error(

View file

@ -1298,8 +1298,8 @@ export async function modifyGroupV2({
const { ContentHint } = Proto.UnidentifiedSenderMessage.Message; const { ContentHint } = Proto.UnidentifiedSenderMessage.Message;
const promise = handleMessageSend( const promise = handleMessageSend(
window.Signal.Util.sendToGroup( window.Signal.Util.sendToGroup({
{ groupSendOptions: {
groupV2: conversation.getGroupV2Info({ groupV2: conversation.getGroupV2Info({
groupChange: typedArrayToArrayBuffer(groupChangeBuffer), groupChange: typedArrayToArrayBuffer(groupChangeBuffer),
includePendingMembers: true, includePendingMembers: true,
@ -1309,9 +1309,9 @@ export async function modifyGroupV2({
profileKey, profileKey,
}, },
conversation, conversation,
ContentHint.DEFAULT, contentHint: ContentHint.DEFAULT,
sendOptions sendOptions,
) })
); );
// We don't save this message; we just use it to ensure that a sync message is // We don't save this message; we just use it to ensure that a sync message is
@ -1676,16 +1676,16 @@ export async function createGroupV2({
conversation, conversation,
logId: `sendToGroup/${logId}`, logId: `sendToGroup/${logId}`,
send: async () => send: async () =>
window.Signal.Util.sendToGroup( window.Signal.Util.sendToGroup({
{ groupSendOptions: {
groupV2: groupV2Info, groupV2: groupV2Info,
timestamp, timestamp,
profileKey, profileKey,
}, },
conversation, conversation,
ContentHint.DEFAULT, contentHint: ContentHint.DEFAULT,
sendOptions sendOptions,
), }),
timestamp, timestamp,
}); });
@ -2207,8 +2207,8 @@ export async function initiateMigrationToGroupV2(
logId: `sendToGroup/${logId}`, logId: `sendToGroup/${logId}`,
send: async () => send: async () =>
// Minimal message to notify group members about migration // Minimal message to notify group members about migration
window.Signal.Util.sendToGroup( window.Signal.Util.sendToGroup({
{ groupSendOptions: {
groupV2: conversation.getGroupV2Info({ groupV2: conversation.getGroupV2Info({
includePendingMembers: true, includePendingMembers: true,
}), }),
@ -2216,9 +2216,9 @@ export async function initiateMigrationToGroupV2(
profileKey: ourProfileKey, profileKey: ourProfileKey,
}, },
conversation, conversation,
ContentHint.DEFAULT, contentHint: ContentHint.DEFAULT,
sendOptions sendOptions,
), }),
timestamp, timestamp,
}); });
} }
@ -2278,17 +2278,15 @@ export async function wrapWithSyncMessageSend({
); );
} }
await sender.sendSyncMessage( await sender.sendSyncMessage({
dataMessage, encodedDataMessage: dataMessage,
timestamp, timestamp,
ourConversation.get('e164'), destination: ourConversation.get('e164'),
ourConversation.get('uuid'), destinationUuid: ourConversation.get('uuid'),
null, // expirationStartTimestamp expirationStartTimestamp: null,
[], // sentTo sentTo: [],
[], // unidentifiedDeliveries unidentifiedDeliveries: [],
undefined, // isUpdate });
undefined // options
);
} }
export async function waitThenRespondToGroupV2Migration( export async function waitThenRespondToGroupV2Migration(

View file

@ -1186,20 +1186,21 @@ export class ConversationModel extends window.Backbone
const { const {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
const sendOptions = await getSendOptions(this.attributes); const sendOptions = await getSendOptions(this.attributes);
if (isDirectConversation(this.attributes)) { if (isDirectConversation(this.attributes)) {
handleMessageSend( handleMessageSend(
window.textsecure.messaging.sendMessageProtoAndWait( window.textsecure.messaging.sendMessageProtoAndWait({
timestamp, timestamp,
groupMembers, recipients: groupMembers,
contentMessage, proto: contentMessage,
ContentHint.IMPLICIT, contentHint: ContentHint.IMPLICIT,
undefined, groupId: undefined,
{ options: {
...sendOptions, ...sendOptions,
online: true, online: true,
} },
) })
); );
} else { } else {
handleMessageSend( handleMessageSend(
@ -3204,7 +3205,7 @@ export class ConversationModel extends window.Backbone
throw new Error('Cannot send DOE while offline!'); throw new Error('Cannot send DOE while offline!');
} }
const options = await getSendOptions(this.attributes); const sendOptions = await getSendOptions(this.attributes);
const promise = (async () => { const promise = (async () => {
let profileKey: ArrayBuffer | undefined; let profileKey: ArrayBuffer | undefined;
@ -3217,36 +3218,36 @@ export class ConversationModel extends window.Backbone
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
if (isDirectConversation(this.attributes)) { if (isDirectConversation(this.attributes)) {
return window.textsecure.messaging.sendMessageToIdentifier( return window.textsecure.messaging.sendMessageToIdentifier({
destination, identifier: destination,
undefined, // body messageText: undefined,
[], // attachments attachments: [],
undefined, // quote quote: undefined,
[], // preview preview: [],
undefined, // sticker sticker: undefined,
undefined, // reaction reaction: undefined,
targetTimestamp, deletedForEveryoneTimestamp: targetTimestamp,
timestamp, timestamp,
undefined, // expireTimer expireTimer: undefined,
ContentHint.DEFAULT, contentHint: ContentHint.DEFAULT,
undefined, // groupId groupId: undefined,
profileKey, profileKey,
options options: sendOptions,
); });
} }
return window.Signal.Util.sendToGroup( return window.Signal.Util.sendToGroup({
{ groupSendOptions: {
groupV1: this.getGroupV1Info(), groupV1: this.getGroupV1Info(),
groupV2: this.getGroupV2Info(), groupV2: this.getGroupV2Info(),
deletedForEveryoneTimestamp: targetTimestamp, deletedForEveryoneTimestamp: targetTimestamp,
timestamp, timestamp,
profileKey, profileKey,
}, },
this, conversation: this,
ContentHint.DEFAULT, contentHint: ContentHint.DEFAULT,
options sendOptions,
); });
})(); })();
// This is to ensure that the functions in send() and sendSyncMessage() don't save // This is to ensure that the functions in send() and sendSyncMessage() don't save
@ -3341,7 +3342,6 @@ export class ConversationModel extends window.Backbone
if (this.get('profileSharing')) { if (this.get('profileSharing')) {
profileKey = await ourProfileKeyService.get(); profileKey = await ourProfileKeyService.get();
} }
// Special-case the self-send case - we send only a sync message // Special-case the self-send case - we send only a sync message
if (isMe(this.attributes)) { if (isMe(this.attributes)) {
const dataMessage = await window.textsecure.messaging.getDataMessage({ const dataMessage = await window.textsecure.messaging.getDataMessage({
@ -3369,26 +3369,26 @@ export class ConversationModel extends window.Backbone
const promise = (() => { const promise = (() => {
if (isDirectConversation(this.attributes)) { if (isDirectConversation(this.attributes)) {
return window.textsecure.messaging.sendMessageToIdentifier( return window.textsecure.messaging.sendMessageToIdentifier({
destination, identifier: destination,
undefined, // body messageText: undefined,
[], // attachments attachments: [],
undefined, // quote quote: undefined,
[], // preview preview: [],
undefined, // sticker sticker: undefined,
outgoingReaction, reaction: outgoingReaction,
undefined, // deletedForEveryoneTimestamp deletedForEveryoneTimestamp: undefined,
timestamp, timestamp,
expireTimer, expireTimer,
ContentHint.DEFAULT, contentHint: ContentHint.DEFAULT,
undefined, // groupId groupId: undefined,
profileKey, profileKey,
options options,
); });
} }
return window.Signal.Util.sendToGroup( return window.Signal.Util.sendToGroup({
{ groupSendOptions: {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
groupV1: this.getGroupV1Info()!, groupV1: this.getGroupV1Info()!,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
@ -3398,10 +3398,10 @@ export class ConversationModel extends window.Backbone
expireTimer, expireTimer,
profileKey, profileKey,
}, },
this, conversation: this,
ContentHint.DEFAULT, contentHint: ContentHint.DEFAULT,
options sendOptions: options,
); });
})(); })();
const result = await message.send(handleMessageSend(promise)); const result = await message.send(handleMessageSend(promise));
@ -3627,8 +3627,8 @@ export class ConversationModel extends window.Backbone
let promise; let promise;
if (conversationType === Message.GROUP) { if (conversationType === Message.GROUP) {
promise = window.Signal.Util.sendToGroup( promise = window.Signal.Util.sendToGroup({
{ groupSendOptions: {
attachments: finalAttachments, attachments: finalAttachments,
expireTimer, expireTimer,
groupV1: this.getGroupV1Info(), groupV1: this.getGroupV1Info(),
@ -3641,27 +3641,27 @@ export class ConversationModel extends window.Backbone
timestamp: now, timestamp: now,
mentions, mentions,
}, },
this, conversation: this,
ContentHint.RESENDABLE, contentHint: ContentHint.RESENDABLE,
options sendOptions: options,
); });
} else { } else {
promise = window.textsecure.messaging.sendMessageToIdentifier( promise = window.textsecure.messaging.sendMessageToIdentifier({
destination, identifier: destination,
messageBody, messageText: messageBody,
finalAttachments, attachments: finalAttachments,
quote, quote,
preview, preview,
sticker, sticker,
null, // reaction reaction: null,
undefined, // deletedForEveryoneTimestamp deletedForEveryoneTimestamp: undefined,
now, timestamp: now,
expireTimer, expireTimer,
ContentHint.RESENDABLE, contentHint: ContentHint.RESENDABLE,
undefined, // groupId groupId: undefined,
profileKey, profileKey,
options options,
); });
} }
return message.send(handleMessageSend(promise)); return message.send(handleMessageSend(promise));

View file

@ -1278,6 +1278,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
sticker: stickerWithData, sticker: stickerWithData,
timestamp: this.get('sent_at'), timestamp: this.get('sent_at'),
}); });
return this.sendSyncMessageOnly(dataMessage); return this.sendSyncMessageOnly(dataMessage);
} }
@ -1290,22 +1291,23 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
if (isDirectConversation(conversation.attributes)) { if (isDirectConversation(conversation.attributes)) {
const [identifier] = recipients; const [identifier] = recipients;
promise = window.textsecure.messaging.sendMessageToIdentifier(
promise = window.textsecure.messaging.sendMessageToIdentifier({
identifier, identifier,
body, messageText: body,
attachments, attachments,
quoteWithData, quote: quoteWithData,
previewWithData, preview: previewWithData,
stickerWithData, sticker: stickerWithData,
null, reaction: null,
this.get('deletedForEveryoneTimestamp'), deletedForEveryoneTimestamp: this.get('deletedForEveryoneTimestamp'),
this.get('sent_at'), timestamp: this.get('sent_at'),
this.get('expireTimer'), expireTimer: this.get('expireTimer'),
ContentHint.RESENDABLE, contentHint: ContentHint.RESENDABLE,
undefined, // groupId groupId: undefined,
profileKey, profileKey,
options options,
); });
} else { } else {
const initialGroupV2 = conversation.getGroupV2Info(); const initialGroupV2 = conversation.getGroupV2Info();
const groupId = conversation.get('groupId'); const groupId = conversation.get('groupId');
@ -1326,12 +1328,8 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
members: recipients, members: recipients,
}; };
// Important to ensure that we don't consider this receipient list to be the entire promise = window.Signal.Util.sendToGroup({
// member list. groupSendOptions: {
const partialSend = true;
promise = window.Signal.Util.sendToGroup(
{
messageText: body, messageText: body,
timestamp: this.get('sent_at'), timestamp: this.get('sent_at'),
attachments, attachments,
@ -1345,10 +1343,12 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
groupV1, groupV1,
}, },
conversation, conversation,
ContentHint.RESENDABLE, contentHint: ContentHint.RESENDABLE,
options, // Important to ensure that we don't consider this recipient list to be the
partialSend // entire member list.
); isPartialSend: true,
sendOptions: options,
});
} }
return this.send(handleMessageSend(promise)); return this.send(handleMessageSend(promise));
@ -1423,6 +1423,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
sticker: stickerWithData, sticker: stickerWithData,
timestamp: this.get('sent_at'), timestamp: this.get('sent_at'),
}); });
return this.sendSyncMessageOnly(dataMessage); return this.sendSyncMessageOnly(dataMessage);
} }
@ -1465,7 +1466,7 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
senderKeyInfo.distributionId senderKeyInfo.distributionId
); );
window.dcodeIO.ByteBuffer.wrap( contentMessage.senderKeyDistributionMessage = window.dcodeIO.ByteBuffer.wrap(
window.Signal.Crypto.typedArrayToArrayBuffer( window.Signal.Crypto.typedArrayToArrayBuffer(
senderKeyDistributionMessage.serialize() senderKeyDistributionMessage.serialize()
) )
@ -1473,16 +1474,17 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
} }
} }
const promise = window.textsecure.messaging.sendMessageProtoAndWait( const promise = window.textsecure.messaging.sendMessageProtoAndWait({
timestamp, timestamp,
[identifier], recipients: [identifier],
contentMessage, proto: contentMessage,
ContentHint.RESENDABLE, contentHint: ContentHint.RESENDABLE,
groupId:
groupId && isGroupV2(parentConversation?.attributes) groupId && isGroupV2(parentConversation?.attributes)
? groupId ? groupId
: undefined, : undefined,
sendOptions options: sendOptions,
); });
return this.send(wrap(promise)); return this.send(wrap(promise));
} }
@ -1780,18 +1782,18 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
const conv = this.getConversation()!; const conv = this.getConversation()!;
return wrap( return wrap(
window.textsecure.messaging.sendSyncMessage( window.textsecure.messaging.sendSyncMessage({
dataMessage, encodedDataMessage: dataMessage,
this.get('sent_at'), timestamp: this.get('sent_at'),
conv.get('e164'), destination: conv.get('e164'),
conv.get('uuid'), destinationUuid: conv.get('uuid'),
expirationStartTimestamp:
this.get('expirationStartTimestamp') || null, this.get('expirationStartTimestamp') || null,
this.get('sent_to'), sentTo: this.get('sent_to') || [],
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion unidentifiedDeliveries: this.get('unidentifiedDeliveries') || [],
this.get('unidentifiedDeliveries')!,
isUpdate, isUpdate,
sendOptions options: sendOptions,
) })
).then(async (result: unknown) => { ).then(async (result: unknown) => {
this.set({ this.set({
synced: true, synced: true,

View file

@ -807,12 +807,12 @@ export class CallingClass {
conversation, conversation,
logId: `sendToGroup/groupCallUpdate/${conversationId}-${eraId}`, logId: `sendToGroup/groupCallUpdate/${conversationId}-${eraId}`,
send: () => send: () =>
window.Signal.Util.sendToGroup( window.Signal.Util.sendToGroup({
{ groupCallUpdate: { eraId }, groupV2, timestamp }, groupSendOptions: { groupCallUpdate: { eraId }, groupV2, timestamp },
conversation, conversation,
ContentHint.DEFAULT, contentHint: ContentHint.DEFAULT,
sendOptions sendOptions,
), }),
timestamp, timestamp,
}).catch(err => { }).catch(err => {
window.log.error( window.log.error(

View file

@ -438,11 +438,13 @@ export default class OutgoingMessage {
ciphertextMessage.type() ciphertextMessage.type()
); );
const content = ciphertextMessage.serialize().toString('base64');
return { return {
type, type,
destinationDeviceId, destinationDeviceId,
destinationRegistrationId, destinationRegistrationId,
content: ciphertextMessage.serialize().toString('base64'), content,
}; };
} }
); );

View file

@ -791,13 +791,18 @@ export default class MessageSender {
// Low-level sends // Low-level sends
async sendMessage( async sendMessage({
attrs: MessageOptionsType, messageOptions,
contentHint: number, contentHint,
groupId: string | undefined, groupId,
options?: SendOptionsType options,
): Promise<CallbackResultType> { }: {
const message = new Message(attrs); messageOptions: MessageOptionsType;
contentHint: number;
groupId: string | undefined;
options?: SendOptionsType;
}): Promise<CallbackResultType> {
const message = new Message(messageOptions);
return Promise.all([ return Promise.all([
this.uploadAttachments(message), this.uploadAttachments(message),
@ -807,13 +812,8 @@ export default class MessageSender {
]).then( ]).then(
async (): Promise<CallbackResultType> => async (): Promise<CallbackResultType> =>
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
this.sendMessageProto( this.sendMessageProto({
message.timestamp, callback: (res: CallbackResultType) => {
message.recipients || [],
message.toProto(),
contentHint,
groupId,
(res: CallbackResultType) => {
res.dataMessage = message.toArrayBuffer(); res.dataMessage = message.toArrayBuffer();
if (res.errors && res.errors.length > 0) { if (res.errors && res.errors.length > 0) {
reject(res); reject(res);
@ -821,21 +821,34 @@ export default class MessageSender {
resolve(res); resolve(res);
} }
}, },
options contentHint,
); groupId,
options,
proto: message.toProto(),
recipients: message.recipients || [],
timestamp: message.timestamp,
});
}) })
); );
} }
sendMessageProto( sendMessageProto({
timestamp: number, timestamp,
recipients: Array<string>, recipients,
messageProto: ContentClass | DataMessageClass | PlaintextContent, proto,
contentHint: number, contentHint,
groupId: string | undefined, groupId,
callback: (result: CallbackResultType) => void, callback,
options?: SendOptionsType options,
): void { }: {
timestamp: number;
recipients: Array<string>;
proto: ContentClass | DataMessageClass | PlaintextContent;
contentHint: number;
groupId: string | undefined;
callback: (result: CallbackResultType) => void;
options?: SendOptionsType;
}): void {
const rejections = window.textsecure.storage.get( const rejections = window.textsecure.storage.get(
'signedKeyRotationRejected', 'signedKeyRotationRejected',
0 0
@ -848,7 +861,7 @@ export default class MessageSender {
this.server, this.server,
timestamp, timestamp,
recipients, recipients,
messageProto, proto,
contentHint, contentHint,
groupId, groupId,
callback, callback,
@ -862,14 +875,21 @@ export default class MessageSender {
}); });
} }
async sendMessageProtoAndWait( async sendMessageProtoAndWait({
timestamp: number, timestamp,
identifiers: Array<string>, recipients,
messageProto: ContentClass | DataMessageClass | PlaintextContent, proto,
contentHint: number, contentHint,
groupId: string | undefined, groupId,
options?: SendOptionsType options,
): Promise<CallbackResultType> { }: {
timestamp: number;
recipients: Array<string>;
proto: ContentClass | DataMessageClass | PlaintextContent;
contentHint: number;
groupId: string | undefined;
options?: SendOptionsType;
}): Promise<CallbackResultType> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const callback = (result: CallbackResultType) => { const callback = (result: CallbackResultType) => {
if (result && result.errors && result.errors.length > 0) { if (result && result.errors && result.errors.length > 0) {
@ -880,25 +900,31 @@ export default class MessageSender {
resolve(result); resolve(result);
}; };
this.sendMessageProto( this.sendMessageProto({
timestamp, callback,
identifiers,
messageProto,
contentHint, contentHint,
groupId, groupId,
callback, options,
options proto,
); recipients,
timestamp,
});
}); });
} }
async sendIndividualProto( async sendIndividualProto({
identifier: string | undefined, identifier,
proto: DataMessageClass | ContentClass | PlaintextContent, proto,
timestamp: number, timestamp,
contentHint: number, contentHint,
options?: SendOptionsType options,
): Promise<CallbackResultType> { }: {
identifier: string | undefined;
proto: DataMessageClass | ContentClass | PlaintextContent;
timestamp: number;
contentHint: number;
options?: SendOptionsType;
}): Promise<CallbackResultType> {
assert(identifier, "Identifier can't be undefined"); assert(identifier, "Identifier can't be undefined");
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const callback = (res: CallbackResultType) => { const callback = (res: CallbackResultType) => {
@ -908,38 +934,53 @@ export default class MessageSender {
resolve(res); resolve(res);
} }
}; };
this.sendMessageProto( this.sendMessageProto({
timestamp,
[identifier],
proto,
contentHint,
undefined, // groupId
callback, callback,
options contentHint,
); groupId: undefined,
options,
proto,
recipients: [identifier],
timestamp,
});
}); });
} }
// You might wonder why this takes a groupId. models/messages.resend() can send a group // You might wonder why this takes a groupId. models/messages.resend() can send a group
// message to just one person. // message to just one person.
async sendMessageToIdentifier( async sendMessageToIdentifier({
identifier: string, identifier,
messageText: string | undefined, messageText,
attachments: Array<AttachmentType> | undefined, attachments,
quote: unknown, quote,
preview: Array<PreviewType> | undefined, preview,
sticker: unknown, sticker,
reaction: unknown, reaction,
deletedForEveryoneTimestamp: number | undefined, deletedForEveryoneTimestamp,
timestamp: number, timestamp,
expireTimer: number | undefined, expireTimer,
contentHint: number, contentHint,
groupId: string | undefined, groupId,
profileKey?: ArrayBuffer, profileKey,
options?: SendOptionsType options,
): Promise<CallbackResultType> { }: {
return this.sendMessage( identifier: string;
{ messageText: string | undefined;
attachments: Array<AttachmentType> | undefined;
quote: unknown;
preview: Array<PreviewType> | undefined;
sticker: unknown;
reaction: unknown;
deletedForEveryoneTimestamp: number | undefined;
timestamp: number;
expireTimer: number | undefined;
contentHint: number;
groupId: string | undefined;
profileKey?: ArrayBuffer;
options?: SendOptionsType;
}): Promise<CallbackResultType> {
return this.sendMessage({
messageOptions: {
recipients: [identifier], recipients: [identifier],
body: messageText, body: messageText,
timestamp, timestamp,
@ -954,23 +995,33 @@ export default class MessageSender {
}, },
contentHint, contentHint,
groupId, groupId,
options options,
); });
} }
// Support for sync messages // Support for sync messages
async sendSyncMessage( async sendSyncMessage({
encodedDataMessage: ArrayBuffer, encodedDataMessage,
timestamp: number, timestamp,
destination: string | undefined, destination,
destinationUuid: string | null | undefined, destinationUuid,
expirationStartTimestamp: number | null, expirationStartTimestamp,
sentTo: Array<string> = [], sentTo,
unidentifiedDeliveries: Array<string> = [], unidentifiedDeliveries,
isUpdate = false, isUpdate,
options?: SendOptionsType options,
): Promise<CallbackResultType | void> { }: {
encodedDataMessage: ArrayBuffer;
timestamp: number;
destination: string | undefined;
destinationUuid: string | null | undefined;
expirationStartTimestamp: number | null;
sentTo?: Array<string>;
unidentifiedDeliveries?: Array<string>;
isUpdate?: boolean;
options?: SendOptionsType;
}): Promise<CallbackResultType | void> {
const myNumber = window.textsecure.storage.user.getNumber(); const myNumber = window.textsecure.storage.user.getNumber();
const myUuid = window.textsecure.storage.user.getUuid(); const myUuid = window.textsecure.storage.user.getUuid();
const myDevice = window.textsecure.storage.user.getDeviceId(); const myDevice = window.textsecure.storage.user.getDeviceId();
@ -995,7 +1046,7 @@ export default class MessageSender {
sentMessage.expirationStartTimestamp = expirationStartTimestamp; sentMessage.expirationStartTimestamp = expirationStartTimestamp;
} }
const unidentifiedLookup = unidentifiedDeliveries.reduce( const unidentifiedLookup = (unidentifiedDeliveries || []).reduce(
(accumulator, item) => { (accumulator, item) => {
// eslint-disable-next-line no-param-reassign // eslint-disable-next-line no-param-reassign
accumulator[item] = true; accumulator[item] = true;
@ -1034,13 +1085,13 @@ export default class MessageSender {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
return this.sendIndividualProto( return this.sendIndividualProto({
myUuid || myNumber, identifier: myUuid || myNumber,
contentMessage, proto: contentMessage,
timestamp, timestamp,
ContentHint.IMPLICIT, contentHint: ContentHint.IMPLICIT,
options options,
); });
} }
async sendRequestBlockSyncMessage( async sendRequestBlockSyncMessage(
@ -1062,13 +1113,13 @@ export default class MessageSender {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
return this.sendIndividualProto( return this.sendIndividualProto({
myUuid || myNumber, identifier: myUuid || myNumber,
contentMessage, proto: contentMessage,
Date.now(), timestamp: Date.now(),
ContentHint.IMPLICIT, contentHint: ContentHint.IMPLICIT,
options options,
); });
} }
return Promise.resolve(); return Promise.resolve();
@ -1093,13 +1144,13 @@ export default class MessageSender {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
return this.sendIndividualProto( return this.sendIndividualProto({
myUuid || myNumber, identifier: myUuid || myNumber,
contentMessage, proto: contentMessage,
Date.now(), timestamp: Date.now(),
ContentHint.IMPLICIT, contentHint: ContentHint.IMPLICIT,
options options,
); });
} }
return Promise.resolve(); return Promise.resolve();
@ -1123,13 +1174,13 @@ export default class MessageSender {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
return this.sendIndividualProto( return this.sendIndividualProto({
myUuid || myNumber, identifier: myUuid || myNumber,
contentMessage, proto: contentMessage,
Date.now(), timestamp: Date.now(),
ContentHint.IMPLICIT, contentHint: ContentHint.IMPLICIT,
options options,
); });
} }
return Promise.resolve(); return Promise.resolve();
@ -1155,13 +1206,13 @@ export default class MessageSender {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
return this.sendIndividualProto( return this.sendIndividualProto({
myUuid || myNumber, identifier: myUuid || myNumber,
contentMessage, proto: contentMessage,
Date.now(), timestamp: Date.now(),
ContentHint.IMPLICIT, contentHint: ContentHint.IMPLICIT,
options options,
); });
} }
return Promise.resolve(); return Promise.resolve();
@ -1191,13 +1242,13 @@ export default class MessageSender {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
await this.sendIndividualProto( await this.sendIndividualProto({
myUuid || myNumber, identifier: myUuid || myNumber,
contentMessage, proto: contentMessage,
Date.now(), timestamp: Date.now(),
ContentHint.IMPLICIT, contentHint: ContentHint.IMPLICIT,
options options,
); });
} }
async sendRequestKeySyncMessage( async sendRequestKeySyncMessage(
@ -1223,13 +1274,13 @@ export default class MessageSender {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
await this.sendIndividualProto( await this.sendIndividualProto({
myUuid || myNumber, identifier: myUuid || myNumber,
contentMessage, proto: contentMessage,
Date.now(), timestamp: Date.now(),
ContentHint.IMPLICIT, contentHint: ContentHint.IMPLICIT,
options options,
); });
} }
async syncReadMessages( async syncReadMessages(
@ -1243,7 +1294,10 @@ export default class MessageSender {
const myNumber = window.textsecure.storage.user.getNumber(); const myNumber = window.textsecure.storage.user.getNumber();
const myUuid = window.textsecure.storage.user.getUuid(); const myUuid = window.textsecure.storage.user.getUuid();
const myDevice = window.textsecure.storage.user.getDeviceId(); const myDevice = window.textsecure.storage.user.getDeviceId();
if (myDevice !== 1) { if (myDevice === 1) {
return Promise.resolve();
}
const syncMessage = this.createSyncMessage(); const syncMessage = this.createSyncMessage();
syncMessage.read = []; syncMessage.read = [];
for (let i = 0; i < reads.length; i += 1) { for (let i = 0; i < reads.length; i += 1) {
@ -1261,16 +1315,13 @@ export default class MessageSender {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
return this.sendIndividualProto( return this.sendIndividualProto({
myUuid || myNumber, identifier: myUuid || myNumber,
contentMessage, proto: contentMessage,
Date.now(), timestamp: Date.now(),
ContentHint.DEFAULT, contentHint: ContentHint.IMPLICIT,
options options,
); });
}
return Promise.resolve();
} }
async syncViewOnceOpen( async syncViewOnceOpen(
@ -1301,13 +1352,13 @@ export default class MessageSender {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
return this.sendIndividualProto( return this.sendIndividualProto({
myUuid || myNumber, identifier: myUuid || myNumber,
contentMessage, proto: contentMessage,
Date.now(), timestamp: Date.now(),
ContentHint.IMPLICIT, contentHint: ContentHint.IMPLICIT,
options options,
); });
} }
async syncMessageRequestResponse( async syncMessageRequestResponse(
@ -1317,7 +1368,7 @@ export default class MessageSender {
groupId?: ArrayBuffer; groupId?: ArrayBuffer;
type: number; type: number;
}, },
sendOptions?: SendOptionsType options?: SendOptionsType
): Promise<CallbackResultType | null> { ): Promise<CallbackResultType | null> {
const myNumber = window.textsecure.storage.user.getNumber(); const myNumber = window.textsecure.storage.user.getNumber();
const myUuid = window.textsecure.storage.user.getUuid(); const myUuid = window.textsecure.storage.user.getUuid();
@ -1342,13 +1393,13 @@ export default class MessageSender {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
return this.sendIndividualProto( return this.sendIndividualProto({
myUuid || myNumber, identifier: myUuid || myNumber,
contentMessage, proto: contentMessage,
Date.now(), timestamp: Date.now(),
ContentHint.IMPLICIT, contentHint: ContentHint.IMPLICIT,
sendOptions options,
); });
} }
async sendStickerPackSync( async sendStickerPackSync(
@ -1390,13 +1441,13 @@ export default class MessageSender {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
return this.sendIndividualProto( return this.sendIndividualProto({
myUuid || myNumber, identifier: myUuid || myNumber,
contentMessage, proto: contentMessage,
Date.now(), timestamp: Date.now(),
ContentHint.IMPLICIT, contentHint: ContentHint.IMPLICIT,
options options,
); });
} }
async syncVerification( async syncVerification(
@ -1446,13 +1497,13 @@ export default class MessageSender {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
return this.sendIndividualProto( await this.sendIndividualProto({
myUuid || myNumber, identifier: myUuid || myNumber,
secondMessage, proto: secondMessage,
now, timestamp: now,
ContentHint.IMPLICIT, contentHint: ContentHint.IMPLICIT,
options options,
); });
}); });
} }
@ -1461,15 +1512,15 @@ export default class MessageSender {
async sendProfileKeyUpdate( async sendProfileKeyUpdate(
profileKey: ArrayBuffer, profileKey: ArrayBuffer,
recipients: Array<string>, recipients: Array<string>,
sendOptions: SendOptionsType, options: SendOptionsType,
groupId?: string groupId?: string
): Promise<CallbackResultType> { ): Promise<CallbackResultType> {
const { const {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
return this.sendMessage( return this.sendMessage({
{ messageOptions: {
recipients, recipients,
timestamp: Date.now(), timestamp: Date.now(),
profileKey, profileKey,
@ -1483,16 +1534,16 @@ export default class MessageSender {
} }
: {}), : {}),
}, },
ContentHint.IMPLICIT, contentHint: ContentHint.IMPLICIT,
undefined, // groupId groupId: undefined,
sendOptions options,
); });
} }
async sendCallingMessage( async sendCallingMessage(
recipientId: string, recipientId: string,
callingMessage: CallingMessageClass, callingMessage: CallingMessageClass,
sendOptions?: SendOptionsType options?: SendOptionsType
): Promise<void> { ): Promise<void> {
const recipients = [recipientId]; const recipients = [recipientId];
const finalTimestamp = Date.now(); const finalTimestamp = Date.now();
@ -1504,29 +1555,31 @@ export default class MessageSender {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
await this.sendMessageProtoAndWait( await this.sendMessageProtoAndWait({
finalTimestamp, timestamp: finalTimestamp,
recipients, recipients,
contentMessage, proto: contentMessage,
ContentHint.DEFAULT, contentHint: ContentHint.DEFAULT,
undefined, // groupId groupId: undefined,
sendOptions options,
); });
} }
async sendDeliveryReceipt( async sendDeliveryReceipt({
recipientE164: string, e164,
recipientUuid: string, uuid,
timestamps: Array<number>, timestamps,
options?: SendOptionsType options,
): Promise<CallbackResultType | void> { }: {
e164: string;
uuid: string;
timestamps: Array<number>;
options?: SendOptionsType;
}): Promise<CallbackResultType | void> {
const myNumber = window.textsecure.storage.user.getNumber(); const myNumber = window.textsecure.storage.user.getNumber();
const myUuid = window.textsecure.storage.user.getUuid(); const myUuid = window.textsecure.storage.user.getUuid();
const myDevice = window.textsecure.storage.user.getDeviceId(); const myDevice = window.textsecure.storage.user.getDeviceId();
if ( if ((myNumber === e164 || myUuid === uuid) && myDevice === 1) {
(myNumber === recipientE164 || myUuid === recipientUuid) &&
myDevice === 1
) {
return Promise.resolve(); return Promise.resolve();
} }
@ -1542,21 +1595,26 @@ export default class MessageSender {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
return this.sendIndividualProto( return this.sendIndividualProto({
recipientUuid || recipientE164, identifier: uuid || e164,
contentMessage, proto: contentMessage,
Date.now(), timestamp: Date.now(),
ContentHint.IMPLICIT, contentHint: ContentHint.IMPLICIT,
options options,
); });
} }
async sendReadReceipts( async sendReadReceipts({
senderE164: string, senderE164,
senderUuid: string, senderUuid,
timestamps: Array<number>, timestamps,
options?: SendOptionsType options,
): Promise<CallbackResultType> { }: {
senderE164: string;
senderUuid: string;
timestamps: Array<number>;
options?: SendOptionsType;
}): Promise<CallbackResultType> {
const receiptMessage = new window.textsecure.protobuf.ReceiptMessage(); const receiptMessage = new window.textsecure.protobuf.ReceiptMessage();
receiptMessage.type = window.textsecure.protobuf.ReceiptMessage.Type.READ; receiptMessage.type = window.textsecure.protobuf.ReceiptMessage.Type.READ;
receiptMessage.timestamp = timestamps; receiptMessage.timestamp = timestamps;
@ -1568,13 +1626,13 @@ export default class MessageSender {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
return this.sendIndividualProto( return this.sendIndividualProto({
senderUuid || senderE164, identifier: senderUuid || senderE164,
contentMessage, proto: contentMessage,
Date.now(), timestamp: Date.now(),
ContentHint.IMPLICIT, contentHint: ContentHint.IMPLICIT,
options options,
); });
} }
async sendNullMessage( async sendNullMessage(
@ -1603,13 +1661,13 @@ export default class MessageSender {
// We want the NullMessage to look like a normal outgoing message // We want the NullMessage to look like a normal outgoing message
const timestamp = Date.now(); const timestamp = Date.now();
return this.sendIndividualProto( return this.sendIndividualProto({
identifier, identifier,
contentMessage, proto: contentMessage,
timestamp, timestamp,
ContentHint.IMPLICIT, contentHint: ContentHint.IMPLICIT,
options options,
); });
} }
async resetSession( async resetSession(
@ -1644,13 +1702,13 @@ export default class MessageSender {
window.log.info( window.log.info(
'resetSession: finished closing local sessions, now sending to contact' 'resetSession: finished closing local sessions, now sending to contact'
); );
return this.sendIndividualProto( return this.sendIndividualProto({
identifier, identifier,
proto, proto,
timestamp, timestamp,
ContentHint.DEFAULT, contentHint: ContentHint.DEFAULT,
options options,
).catch(logError('resetSession/sendToContact error:')); }).catch(logError('resetSession/sendToContact error:'));
}) })
.then(async () => .then(async () =>
window.textsecure.storage.protocol window.textsecure.storage.protocol
@ -1666,17 +1724,16 @@ export default class MessageSender {
} }
const buffer = proto.toArrayBuffer(); const buffer = proto.toArrayBuffer();
const sendSyncPromise = this.sendSyncMessage( const sendSyncPromise = this.sendSyncMessage({
buffer, encodedDataMessage: buffer,
timestamp, timestamp,
e164, destination: e164,
uuid, destinationUuid: uuid,
null, expirationStartTimestamp: null,
[], sentTo: [],
[], unidentifiedDeliveries: [],
false, options,
options }).catch(logError('resetSession/sendSync error:'));
).catch(logError('resetSession/sendSync error:'));
return Promise.all([sendToContactPromise, sendSyncPromise]); return Promise.all([sendToContactPromise, sendSyncPromise]);
} }
@ -1692,8 +1749,8 @@ export default class MessageSender {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
return this.sendMessage( return this.sendMessage({
{ messageOptions: {
recipients: [identifier], recipients: [identifier],
timestamp, timestamp,
expireTimer, expireTimer,
@ -1701,10 +1758,10 @@ export default class MessageSender {
flags: flags:
window.textsecure.protobuf.DataMessage.Flags.EXPIRATION_TIMER_UPDATE, window.textsecure.protobuf.DataMessage.Flags.EXPIRATION_TIMER_UPDATE,
}, },
ContentHint.DEFAULT, contentHint: ContentHint.DEFAULT,
undefined, // groupId groupId: undefined,
options options,
); });
} }
async sendRetryRequest({ async sendRetryRequest({
@ -1720,34 +1777,39 @@ export default class MessageSender {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
return this.sendMessageProtoAndWait( return this.sendMessageProtoAndWait({
Date.now(), timestamp: Date.now(),
[uuid], recipients: [uuid],
plaintext, proto: plaintext,
ContentHint.IMPLICIT, contentHint: ContentHint.IMPLICIT,
undefined, // groupId groupId: undefined,
options options,
); });
} }
// Group sends // Group sends
// No functions should really call this; since most group sends are now via Sender Key // No functions should really call this; since most group sends are now via Sender Key
async sendGroupProto( async sendGroupProto({
providedIdentifiers: Array<string>, recipients,
proto: ContentClass, proto,
timestamp = Date.now(), timestamp = Date.now(),
contentHint: number, contentHint,
groupId: string | undefined, groupId,
options?: SendOptionsType options,
): Promise<CallbackResultType> { }: {
recipients: Array<string>;
proto: ContentClass;
timestamp: number;
contentHint: number;
groupId: string | undefined;
options?: SendOptionsType;
}): Promise<CallbackResultType> {
const dataMessage = proto.dataMessage?.toArrayBuffer(); const dataMessage = proto.dataMessage?.toArrayBuffer();
const myE164 = window.textsecure.storage.user.getNumber(); const myE164 = window.textsecure.storage.user.getNumber();
const myUuid = window.textsecure.storage.user.getUuid(); const myUuid = window.textsecure.storage.user.getUuid();
const identifiers = providedIdentifiers.filter( const identifiers = recipients.filter(id => id !== myE164 && id !== myUuid);
id => id !== myE164 && id !== myUuid
);
if (identifiers.length === 0) { if (identifiers.length === 0) {
return Promise.resolve({ return Promise.resolve({
@ -1769,15 +1831,15 @@ export default class MessageSender {
} }
}; };
this.sendMessageProto( this.sendMessageProto({
timestamp, timestamp,
providedIdentifiers, recipients: identifiers,
proto, proto,
contentHint, contentHint,
groupId, groupId,
callback, callback,
options options,
); });
}); });
} }
@ -1834,14 +1896,14 @@ export default class MessageSender {
typedArrayToArrayBuffer(senderKeyDistributionMessage.serialize()) typedArrayToArrayBuffer(senderKeyDistributionMessage.serialize())
); );
return this.sendGroupProto( return this.sendGroupProto({
identifiers, recipients: identifiers,
contentMessage, proto: contentMessage,
Date.now(), timestamp: Date.now(),
contentHint, contentHint,
groupId, groupId,
options options,
); });
} }
// GroupV1-only functions; not to be used in the future // GroupV1-only functions; not to be used in the future
@ -1859,14 +1921,14 @@ export default class MessageSender {
const { const {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
return this.sendGroupProto( return this.sendGroupProto({
groupIdentifiers, recipients: groupIdentifiers,
proto, proto,
Date.now(), timestamp: Date.now(),
ContentHint.DEFAULT, contentHint: ContentHint.DEFAULT,
undefined, // only for GV2 ids groupId: undefined, // only for GV2 ids
options options,
); });
} }
async sendExpirationTimerUpdateToGroup( async sendExpirationTimerUpdateToGroup(
@ -1882,7 +1944,7 @@ export default class MessageSender {
const recipients = groupIdentifiers.filter( const recipients = groupIdentifiers.filter(
identifier => identifier !== myNumber && identifier !== myUuid identifier => identifier !== myNumber && identifier !== myUuid
); );
const attrs = { const messageOptions = {
recipients, recipients,
timestamp, timestamp,
expireTimer, expireTimer,
@ -1901,19 +1963,19 @@ export default class MessageSender {
failoverIdentifiers: [], failoverIdentifiers: [],
errors: [], errors: [],
unidentifiedDeliveries: [], unidentifiedDeliveries: [],
dataMessage: await this.getDataMessage(attrs), dataMessage: await this.getDataMessage(messageOptions),
}); });
} }
const { const {
ContentHint, ContentHint,
} = window.textsecure.protobuf.UnidentifiedSenderMessage.Message; } = window.textsecure.protobuf.UnidentifiedSenderMessage.Message;
return this.sendMessage( return this.sendMessage({
attrs, messageOptions,
ContentHint.DEFAULT, contentHint: ContentHint.DEFAULT,
undefined, // only for GV2 ids groupId: undefined, // only for GV2 ids
options options,
); });
} }
// Simple pass-throughs // Simple pass-throughs

View file

@ -17,7 +17,7 @@ export async function sendReadReceiptsFor(
isConversationAccepted(conversationAttrs) isConversationAccepted(conversationAttrs)
) { ) {
window.log.info(`Sending ${items.length} read receipts`); window.log.info(`Sending ${items.length} read receipts`);
const convoSendOptions = await getSendOptions(conversationAttrs); const sendOptions = await getSendOptions(conversationAttrs);
const receiptsBySender = groupBy(items, 'senderId'); const receiptsBySender = groupBy(items, 'senderId');
await Promise.all( await Promise.all(
@ -27,14 +27,14 @@ export async function sendReadReceiptsFor(
if (conversation) { if (conversation) {
await handleMessageSend( await handleMessageSend(
window.textsecure.messaging.sendReadReceipts( window.textsecure.messaging.sendReadReceipts({
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
conversation.get('e164')!, senderE164: conversation.get('e164')!,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
conversation.get('uuid')!, senderUuid: conversation.get('uuid')!,
timestamps, timestamps,
convoSendOptions options: sendOptions,
) })
); );
} }
}) })

View file

@ -55,13 +55,19 @@ const MAX_RECURSION = 5;
// Public API: // Public API:
export async function sendToGroup( export async function sendToGroup({
groupSendOptions: GroupSendOptionsType, groupSendOptions,
conversation: ConversationModel, conversation,
contentHint: number, contentHint,
sendOptions?: SendOptionsType, sendOptions,
isPartialSend?: boolean isPartialSend,
): Promise<CallbackResultType> { }: {
groupSendOptions: GroupSendOptionsType;
conversation: ConversationModel;
contentHint: number;
sendOptions?: SendOptionsType;
isPartialSend?: boolean;
}): Promise<CallbackResultType> {
assert( assert(
window.textsecure.messaging, window.textsecure.messaging,
'sendToGroup: textsecure.messaging not available!' 'sendToGroup: textsecure.messaging not available!'
@ -145,14 +151,14 @@ export async function sendContentMessageToGroup({
const groupId = isGroupV2(conversation.attributes) const groupId = isGroupV2(conversation.attributes)
? conversation.get('groupId') ? conversation.get('groupId')
: undefined; : undefined;
return window.textsecure.messaging.sendGroupProto( return window.textsecure.messaging.sendGroupProto({
recipients, recipients,
contentMessage, proto: contentMessage,
timestamp, timestamp,
contentHint, contentHint,
groupId, groupId,
{ ...sendOptions, online } options: { ...sendOptions, online },
); });
} }
// The Primary Sender Key workflow // The Primary Sender Key workflow
@ -433,14 +439,14 @@ export async function sendToGroupViaSenderKey(options: {
// 12. Send normal message to the leftover normal recipients. Then combine normal send // 12. Send normal message to the leftover normal recipients. Then combine normal send
// result with result from sender key send for final return value. // result with result from sender key send for final return value.
const normalSendResult = await window.textsecure.messaging.sendGroupProto( const normalSendResult = await window.textsecure.messaging.sendGroupProto({
normalRecipients, recipients: normalRecipients,
contentMessage, proto: contentMessage,
timestamp, timestamp,
contentHint, contentHint,
groupId, groupId,
{ ...sendOptions, online } options: { ...sendOptions, online },
); });
return { return {
dataMessage: contentMessage.dataMessage?.toArrayBuffer(), dataMessage: contentMessage.dataMessage?.toArrayBuffer(),