Introduce Service Id Types
Co-authored-by: Scott Nonnenberg <scott@signal.org>
This commit is contained in:
parent
414c0a58d3
commit
366b875fd2
269 changed files with 5832 additions and 5550 deletions
|
@ -17,7 +17,6 @@ import type { ConversationModel } from '../models/conversations';
|
|||
import { GLOBAL_ZONE } from '../SignalProtocolStore';
|
||||
import { assertDev, strictAssert } from '../util/assert';
|
||||
import { parseIntOrThrow } from '../util/parseIntOrThrow';
|
||||
import { getTaggedConversationUuid } from '../util/getConversationUuid';
|
||||
import { Address } from '../types/Address';
|
||||
import { QualifiedAddress } from '../types/QualifiedAddress';
|
||||
import { SenderKeys } from '../LibSignalStores';
|
||||
|
@ -25,7 +24,8 @@ import type {
|
|||
TextAttachmentType,
|
||||
UploadedAttachmentType,
|
||||
} from '../types/Attachment';
|
||||
import { type UUID, type TaggedUUIDStringType, UUIDKind } from '../types/UUID';
|
||||
import type { AciString, ServiceIdString } from '../types/ServiceId';
|
||||
import { ServiceIdKind } from '../types/ServiceId';
|
||||
import type {
|
||||
ChallengeType,
|
||||
GetGroupLogOptionsType,
|
||||
|
@ -81,7 +81,7 @@ import { missingCaseError } from '../util/missingCaseError';
|
|||
import { drop } from '../util/drop';
|
||||
|
||||
export type SendMetadataType = {
|
||||
[identifier: string]: {
|
||||
[serviceId: ServiceIdString]: {
|
||||
accessKey: string;
|
||||
senderCertificate?: SerializedCertificateType;
|
||||
};
|
||||
|
@ -101,7 +101,7 @@ export type OutgoingQuoteAttachmentType = Readonly<{
|
|||
export type OutgoingQuoteType = Readonly<{
|
||||
isGiftBadge?: boolean;
|
||||
id?: number;
|
||||
authorUuid?: string;
|
||||
authorAci?: AciString;
|
||||
text?: string;
|
||||
attachments: ReadonlyArray<OutgoingQuoteAttachmentType>;
|
||||
bodyRanges?: ReadonlyArray<RawBodyRange>;
|
||||
|
@ -125,7 +125,7 @@ export type GroupV2InfoType = {
|
|||
groupChange?: Uint8Array;
|
||||
masterKey: Uint8Array;
|
||||
revision: number;
|
||||
members: ReadonlyArray<string>;
|
||||
members: ReadonlyArray<ServiceIdString>;
|
||||
};
|
||||
|
||||
type GroupCallUpdateType = {
|
||||
|
@ -143,7 +143,7 @@ export type OutgoingStickerType = Readonly<{
|
|||
export type ReactionType = {
|
||||
emoji?: string;
|
||||
remove?: boolean;
|
||||
targetAuthorUuid?: string;
|
||||
targetAuthorAci?: AciString;
|
||||
targetTimestamp?: number;
|
||||
};
|
||||
|
||||
|
@ -176,7 +176,7 @@ export type MessageOptionsType = {
|
|||
preview?: ReadonlyArray<OutgoingLinkPreviewType>;
|
||||
profileKey?: Uint8Array;
|
||||
quote?: OutgoingQuoteType;
|
||||
recipients: ReadonlyArray<string>;
|
||||
recipients: ReadonlyArray<ServiceIdString>;
|
||||
sticker?: OutgoingStickerType;
|
||||
reaction?: ReactionType;
|
||||
deletedForEveryoneTimestamp?: number;
|
||||
|
@ -232,7 +232,7 @@ class Message {
|
|||
|
||||
quote?: OutgoingQuoteType;
|
||||
|
||||
recipients: ReadonlyArray<string>;
|
||||
recipients: ReadonlyArray<ServiceIdString>;
|
||||
|
||||
sticker?: OutgoingStickerType;
|
||||
|
||||
|
@ -377,7 +377,7 @@ class Message {
|
|||
proto.reaction = new Proto.DataMessage.Reaction();
|
||||
proto.reaction.emoji = this.reaction.emoji || null;
|
||||
proto.reaction.remove = this.reaction.remove || false;
|
||||
proto.reaction.targetAuthorUuid = this.reaction.targetAuthorUuid || null;
|
||||
proto.reaction.targetAuthorAci = this.reaction.targetAuthorAci || null;
|
||||
proto.reaction.targetTimestamp =
|
||||
this.reaction.targetTimestamp === undefined
|
||||
? null
|
||||
|
@ -481,7 +481,7 @@ class Message {
|
|||
|
||||
quote.id =
|
||||
this.quote.id === undefined ? null : Long.fromNumber(this.quote.id);
|
||||
quote.authorUuid = this.quote.authorUuid || null;
|
||||
quote.authorAci = this.quote.authorAci || null;
|
||||
quote.text = this.quote.text || null;
|
||||
quote.attachments = this.quote.attachments.slice() || [];
|
||||
const bodyRanges = this.quote.bodyRanges || [];
|
||||
|
@ -490,7 +490,7 @@ class Message {
|
|||
bodyRange.start = range.start;
|
||||
bodyRange.length = range.length;
|
||||
if (BodyRange.isMention(range)) {
|
||||
bodyRange.mentionUuid = range.mentionUuid;
|
||||
bodyRange.mentionAci = range.mentionUuid;
|
||||
} else if (BodyRange.isFormatting(range)) {
|
||||
bodyRange.style = range.style;
|
||||
} else {
|
||||
|
@ -529,7 +529,7 @@ class Message {
|
|||
return {
|
||||
start,
|
||||
length,
|
||||
mentionUuid: bodyRange.mentionUuid,
|
||||
mentionAci: bodyRange.mentionUuid,
|
||||
};
|
||||
}
|
||||
if (BodyRange.isFormatting(bodyRange)) {
|
||||
|
@ -556,8 +556,8 @@ class Message {
|
|||
const { StoryContext } = Proto.DataMessage;
|
||||
|
||||
const storyContext = new StoryContext();
|
||||
if (this.storyContext.authorUuid) {
|
||||
storyContext.authorUuid = this.storyContext.authorUuid;
|
||||
if (this.storyContext.authorAci) {
|
||||
storyContext.authorAci = this.storyContext.authorAci;
|
||||
}
|
||||
storyContext.sentTimestamp = Long.fromNumber(this.storyContext.timestamp);
|
||||
|
||||
|
@ -610,12 +610,12 @@ export default class MessageSender {
|
|||
this.pendingMessages = {};
|
||||
}
|
||||
|
||||
async queueJobForIdentifier<T>(
|
||||
identifier: string,
|
||||
async queueJobForServiceId<T>(
|
||||
serviceId: ServiceIdString,
|
||||
runJob: () => Promise<T>
|
||||
): Promise<T> {
|
||||
const { id } = await window.ConversationController.getOrCreateAndWait(
|
||||
identifier,
|
||||
serviceId,
|
||||
'private'
|
||||
);
|
||||
this.pendingMessages[id] =
|
||||
|
@ -625,7 +625,7 @@ export default class MessageSender {
|
|||
|
||||
const taskWithTimeout = createTaskWithTimeout(
|
||||
runJob,
|
||||
`queueJobForIdentifier ${identifier} ${id}`
|
||||
`queueJobForServiceId ${serviceId} ${id}`
|
||||
);
|
||||
|
||||
return queue.add(taskWithTimeout);
|
||||
|
@ -808,9 +808,9 @@ export default class MessageSender {
|
|||
|
||||
getTypingContentMessage(
|
||||
options: Readonly<{
|
||||
recipientId?: string;
|
||||
recipientId?: ServiceIdString;
|
||||
groupId?: Uint8Array;
|
||||
groupMembers: ReadonlyArray<string>;
|
||||
groupMembers: ReadonlyArray<ServiceIdString>;
|
||||
isTyping: boolean;
|
||||
timestamp?: number;
|
||||
}>
|
||||
|
@ -877,19 +877,10 @@ export default class MessageSender {
|
|||
);
|
||||
}
|
||||
|
||||
const myE164 = window.textsecure.storage.user.getNumber();
|
||||
const myUuid = window.textsecure.storage.user.getUuid()?.toString();
|
||||
const myAci = window.textsecure.storage.user.getCheckedAci();
|
||||
|
||||
const groupMembers = groupV2?.members || [];
|
||||
|
||||
// We should always have a UUID but have this check just in case we don't.
|
||||
let isNotMe: (recipient: string) => boolean;
|
||||
if (myUuid) {
|
||||
isNotMe = r => r !== myE164 && r !== myUuid.toString();
|
||||
} else {
|
||||
isNotMe = r => r !== myE164;
|
||||
}
|
||||
|
||||
const blockedIdentifiers = new Set(
|
||||
concat(
|
||||
window.storage.blocked.getBlockedUuids(),
|
||||
|
@ -898,7 +889,7 @@ export default class MessageSender {
|
|||
);
|
||||
|
||||
const recipients = groupMembers.filter(
|
||||
recipient => isNotMe(recipient) && !blockedIdentifiers.has(recipient)
|
||||
recipient => recipient !== myAci && !blockedIdentifiers.has(recipient)
|
||||
);
|
||||
|
||||
return {
|
||||
|
@ -997,7 +988,7 @@ export default class MessageSender {
|
|||
groupId: string | undefined;
|
||||
options?: SendOptionsType;
|
||||
proto: Proto.Content | Proto.DataMessage | PlaintextContent;
|
||||
recipients: ReadonlyArray<string>;
|
||||
recipients: ReadonlyArray<ServiceIdString>;
|
||||
sendLogCallback?: SendLogCallbackType;
|
||||
story?: boolean;
|
||||
timestamp: number;
|
||||
|
@ -1005,12 +996,12 @@ export default class MessageSender {
|
|||
}>): Promise<void> {
|
||||
const accountManager = window.getAccountManager();
|
||||
try {
|
||||
if (accountManager.areKeysOutOfDate(UUIDKind.ACI)) {
|
||||
if (accountManager.areKeysOutOfDate(ServiceIdKind.ACI)) {
|
||||
log.warn(
|
||||
`sendMessageProto/${timestamp}: Keys are out of date; updating before send`
|
||||
);
|
||||
await accountManager.maybeUpdateKeys(UUIDKind.ACI);
|
||||
if (accountManager.areKeysOutOfDate(UUIDKind.ACI)) {
|
||||
await accountManager.maybeUpdateKeys(ServiceIdKind.ACI);
|
||||
if (accountManager.areKeysOutOfDate(ServiceIdKind.ACI)) {
|
||||
throw new Error('Keys still out of date after update');
|
||||
}
|
||||
}
|
||||
|
@ -1028,7 +1019,7 @@ export default class MessageSender {
|
|||
callback,
|
||||
contentHint,
|
||||
groupId,
|
||||
identifiers: recipients,
|
||||
serviceIds: recipients,
|
||||
message: proto,
|
||||
options,
|
||||
sendLogCallback,
|
||||
|
@ -1038,10 +1029,10 @@ export default class MessageSender {
|
|||
urgent,
|
||||
});
|
||||
|
||||
recipients.forEach(identifier => {
|
||||
recipients.forEach(serviceId => {
|
||||
drop(
|
||||
this.queueJobForIdentifier(identifier, async () =>
|
||||
outgoing.sendToIdentifier(identifier)
|
||||
this.queueJobForServiceId(serviceId, async () =>
|
||||
outgoing.sendToServiceId(serviceId)
|
||||
)
|
||||
);
|
||||
});
|
||||
|
@ -1058,7 +1049,7 @@ export default class MessageSender {
|
|||
story,
|
||||
}: Readonly<{
|
||||
timestamp: number;
|
||||
recipients: Array<string>;
|
||||
recipients: Array<ServiceIdString>;
|
||||
proto: Proto.Content | Proto.DataMessage | PlaintextContent;
|
||||
contentHint: number;
|
||||
groupId: string | undefined;
|
||||
|
@ -1094,7 +1085,7 @@ export default class MessageSender {
|
|||
async sendIndividualProto({
|
||||
contentHint,
|
||||
groupId,
|
||||
identifier,
|
||||
serviceId,
|
||||
options,
|
||||
proto,
|
||||
timestamp,
|
||||
|
@ -1102,13 +1093,13 @@ export default class MessageSender {
|
|||
}: Readonly<{
|
||||
contentHint: number;
|
||||
groupId?: string;
|
||||
identifier: string | undefined;
|
||||
serviceId: ServiceIdString | undefined;
|
||||
options?: SendOptionsType;
|
||||
proto: Proto.DataMessage | Proto.Content | PlaintextContent;
|
||||
timestamp: number;
|
||||
urgent: boolean;
|
||||
}>): Promise<CallbackResultType> {
|
||||
assertDev(identifier, "Identifier can't be undefined");
|
||||
assertDev(serviceId, "ServiceId can't be undefined");
|
||||
return new Promise((resolve, reject) => {
|
||||
const callback = (res: CallbackResultType) => {
|
||||
if (res && res.errors && res.errors.length > 0) {
|
||||
|
@ -1124,7 +1115,7 @@ export default class MessageSender {
|
|||
groupId,
|
||||
options,
|
||||
proto,
|
||||
recipients: [identifier],
|
||||
recipients: [serviceId],
|
||||
timestamp,
|
||||
urgent,
|
||||
})
|
||||
|
@ -1134,7 +1125,7 @@ export default class MessageSender {
|
|||
|
||||
// You might wonder why this takes a groupId. models/messages.resend() can send a group
|
||||
// message to just one person.
|
||||
async sendMessageToIdentifier({
|
||||
async sendMessageToServiceId({
|
||||
attachments,
|
||||
bodyRanges,
|
||||
contact,
|
||||
|
@ -1143,7 +1134,7 @@ export default class MessageSender {
|
|||
editedMessageTimestamp,
|
||||
expireTimer,
|
||||
groupId,
|
||||
identifier,
|
||||
serviceId,
|
||||
messageText,
|
||||
options,
|
||||
preview,
|
||||
|
@ -1165,7 +1156,7 @@ export default class MessageSender {
|
|||
editedMessageTimestamp?: number;
|
||||
expireTimer: DurationInSeconds | undefined;
|
||||
groupId: string | undefined;
|
||||
identifier: string;
|
||||
serviceId: ServiceIdString;
|
||||
messageText: string | undefined;
|
||||
options?: SendOptionsType;
|
||||
preview?: ReadonlyArray<OutgoingLinkPreviewType> | undefined;
|
||||
|
@ -1192,7 +1183,7 @@ export default class MessageSender {
|
|||
profileKey,
|
||||
quote,
|
||||
reaction,
|
||||
recipients: [identifier],
|
||||
recipients: [serviceId],
|
||||
sticker,
|
||||
storyContext,
|
||||
timestamp,
|
||||
|
@ -1215,7 +1206,7 @@ export default class MessageSender {
|
|||
encodedEditMessage,
|
||||
timestamp,
|
||||
destination,
|
||||
destinationUuid,
|
||||
destinationServiceId,
|
||||
expirationStartTimestamp,
|
||||
conversationIdsSentTo = [],
|
||||
conversationIdsWithSealedSender = new Set(),
|
||||
|
@ -1229,7 +1220,7 @@ export default class MessageSender {
|
|||
encodedEditMessage?: Uint8Array;
|
||||
timestamp: number;
|
||||
destination: string | undefined;
|
||||
destinationUuid: TaggedUUIDStringType | undefined;
|
||||
destinationServiceId: ServiceIdString | undefined;
|
||||
expirationStartTimestamp: number | null;
|
||||
conversationIdsSentTo?: Iterable<string>;
|
||||
conversationIdsWithSealedSender?: Set<string>;
|
||||
|
@ -1239,7 +1230,7 @@ export default class MessageSender {
|
|||
storyMessage?: Proto.StoryMessage;
|
||||
storyMessageRecipients?: ReadonlyArray<Proto.SyncMessage.Sent.IStoryMessageRecipient>;
|
||||
}>): Promise<CallbackResultType> {
|
||||
const myUuid = window.textsecure.storage.user.getCheckedUuid();
|
||||
const myAci = window.textsecure.storage.user.getCheckedAci();
|
||||
|
||||
const sentMessage = new Proto.SyncMessage.Sent();
|
||||
sentMessage.timestamp = Long.fromNumber(timestamp);
|
||||
|
@ -1254,10 +1245,8 @@ export default class MessageSender {
|
|||
if (destination) {
|
||||
sentMessage.destination = destination;
|
||||
}
|
||||
if (destinationUuid?.aci) {
|
||||
sentMessage.destinationAci = destinationUuid.aci;
|
||||
} else if (destinationUuid?.pni) {
|
||||
sentMessage.destinationPni = destinationUuid.pni;
|
||||
if (destinationServiceId) {
|
||||
sentMessage.destinationServiceId = destinationServiceId;
|
||||
}
|
||||
if (expirationStartTimestamp) {
|
||||
sentMessage.expirationStartTimestamp = Long.fromNumber(
|
||||
|
@ -1288,11 +1277,9 @@ export default class MessageSender {
|
|||
if (e164) {
|
||||
status.destination = e164;
|
||||
}
|
||||
const taggedUuid = getTaggedConversationUuid(conv.attributes);
|
||||
if (taggedUuid?.aci) {
|
||||
status.destinationAci = taggedUuid.aci;
|
||||
} else if (taggedUuid?.pni) {
|
||||
status.destinationPni = taggedUuid.pni;
|
||||
const serviceId = conv.getServiceId();
|
||||
if (serviceId) {
|
||||
status.destinationServiceId = serviceId;
|
||||
}
|
||||
}
|
||||
status.unidentified =
|
||||
|
@ -1310,7 +1297,7 @@ export default class MessageSender {
|
|||
const { ContentHint } = Proto.UnidentifiedSenderMessage.Message;
|
||||
|
||||
return this.sendIndividualProto({
|
||||
identifier: myUuid.toString(),
|
||||
serviceId: myAci,
|
||||
proto: contentMessage,
|
||||
timestamp,
|
||||
contentHint: ContentHint.RESENDABLE,
|
||||
|
@ -1320,7 +1307,7 @@ export default class MessageSender {
|
|||
}
|
||||
|
||||
static getRequestBlockSyncMessage(): SingleProtoJobData {
|
||||
const myUuid = window.textsecure.storage.user.getCheckedUuid();
|
||||
const myAci = window.textsecure.storage.user.getCheckedAci();
|
||||
|
||||
const request = new Proto.SyncMessage.Request();
|
||||
request.type = Proto.SyncMessage.Request.Type.BLOCKED;
|
||||
|
@ -1333,7 +1320,7 @@ export default class MessageSender {
|
|||
|
||||
return {
|
||||
contentHint: ContentHint.RESENDABLE,
|
||||
identifier: myUuid.toString(),
|
||||
identifier: myAci,
|
||||
isSyncMessage: true,
|
||||
protoBase64: Bytes.toBase64(
|
||||
Proto.Content.encode(contentMessage).finish()
|
||||
|
@ -1344,7 +1331,7 @@ export default class MessageSender {
|
|||
}
|
||||
|
||||
static getRequestConfigurationSyncMessage(): SingleProtoJobData {
|
||||
const myUuid = window.textsecure.storage.user.getCheckedUuid();
|
||||
const myAci = window.textsecure.storage.user.getCheckedAci();
|
||||
|
||||
const request = new Proto.SyncMessage.Request();
|
||||
request.type = Proto.SyncMessage.Request.Type.CONFIGURATION;
|
||||
|
@ -1357,7 +1344,7 @@ export default class MessageSender {
|
|||
|
||||
return {
|
||||
contentHint: ContentHint.RESENDABLE,
|
||||
identifier: myUuid.toString(),
|
||||
identifier: myAci,
|
||||
isSyncMessage: true,
|
||||
protoBase64: Bytes.toBase64(
|
||||
Proto.Content.encode(contentMessage).finish()
|
||||
|
@ -1368,7 +1355,7 @@ export default class MessageSender {
|
|||
}
|
||||
|
||||
static getRequestContactSyncMessage(): SingleProtoJobData {
|
||||
const myUuid = window.textsecure.storage.user.getCheckedUuid();
|
||||
const myAci = window.textsecure.storage.user.getCheckedAci();
|
||||
|
||||
const request = new Proto.SyncMessage.Request();
|
||||
request.type = Proto.SyncMessage.Request.Type.CONTACTS;
|
||||
|
@ -1381,7 +1368,7 @@ export default class MessageSender {
|
|||
|
||||
return {
|
||||
contentHint: ContentHint.RESENDABLE,
|
||||
identifier: myUuid.toString(),
|
||||
identifier: myAci,
|
||||
isSyncMessage: true,
|
||||
protoBase64: Bytes.toBase64(
|
||||
Proto.Content.encode(contentMessage).finish()
|
||||
|
@ -1392,7 +1379,7 @@ export default class MessageSender {
|
|||
}
|
||||
|
||||
static getFetchManifestSyncMessage(): SingleProtoJobData {
|
||||
const myUuid = window.textsecure.storage.user.getCheckedUuid();
|
||||
const myAci = window.textsecure.storage.user.getCheckedAci();
|
||||
|
||||
const fetchLatest = new Proto.SyncMessage.FetchLatest();
|
||||
fetchLatest.type = Proto.SyncMessage.FetchLatest.Type.STORAGE_MANIFEST;
|
||||
|
@ -1406,7 +1393,7 @@ export default class MessageSender {
|
|||
|
||||
return {
|
||||
contentHint: ContentHint.RESENDABLE,
|
||||
identifier: myUuid.toString(),
|
||||
identifier: myAci,
|
||||
isSyncMessage: true,
|
||||
protoBase64: Bytes.toBase64(
|
||||
Proto.Content.encode(contentMessage).finish()
|
||||
|
@ -1417,7 +1404,7 @@ export default class MessageSender {
|
|||
}
|
||||
|
||||
static getFetchLocalProfileSyncMessage(): SingleProtoJobData {
|
||||
const myUuid = window.textsecure.storage.user.getCheckedUuid();
|
||||
const myAci = window.textsecure.storage.user.getCheckedAci();
|
||||
|
||||
const fetchLatest = new Proto.SyncMessage.FetchLatest();
|
||||
fetchLatest.type = Proto.SyncMessage.FetchLatest.Type.LOCAL_PROFILE;
|
||||
|
@ -1431,7 +1418,7 @@ export default class MessageSender {
|
|||
|
||||
return {
|
||||
contentHint: ContentHint.RESENDABLE,
|
||||
identifier: myUuid.toString(),
|
||||
identifier: myAci,
|
||||
isSyncMessage: true,
|
||||
protoBase64: Bytes.toBase64(
|
||||
Proto.Content.encode(contentMessage).finish()
|
||||
|
@ -1442,7 +1429,7 @@ export default class MessageSender {
|
|||
}
|
||||
|
||||
static getRequestKeySyncMessage(): SingleProtoJobData {
|
||||
const myUuid = window.textsecure.storage.user.getCheckedUuid();
|
||||
const myAci = window.textsecure.storage.user.getCheckedAci();
|
||||
|
||||
const request = new Proto.SyncMessage.Request();
|
||||
request.type = Proto.SyncMessage.Request.Type.KEYS;
|
||||
|
@ -1456,7 +1443,7 @@ export default class MessageSender {
|
|||
|
||||
return {
|
||||
contentHint: ContentHint.RESENDABLE,
|
||||
identifier: myUuid.toString(),
|
||||
identifier: myAci,
|
||||
isSyncMessage: true,
|
||||
protoBase64: Bytes.toBase64(
|
||||
Proto.Content.encode(contentMessage).finish()
|
||||
|
@ -1474,7 +1461,7 @@ export default class MessageSender {
|
|||
}>,
|
||||
options?: Readonly<SendOptionsType>
|
||||
): Promise<CallbackResultType> {
|
||||
const myUuid = window.textsecure.storage.user.getCheckedUuid();
|
||||
const myAci = window.textsecure.storage.user.getCheckedAci();
|
||||
|
||||
const syncMessage = MessageSender.createSyncMessage();
|
||||
syncMessage.read = [];
|
||||
|
@ -1492,7 +1479,7 @@ export default class MessageSender {
|
|||
const { ContentHint } = Proto.UnidentifiedSenderMessage.Message;
|
||||
|
||||
return this.sendIndividualProto({
|
||||
identifier: myUuid.toString(),
|
||||
serviceId: myAci,
|
||||
proto: contentMessage,
|
||||
timestamp: Date.now(),
|
||||
contentHint: ContentHint.RESENDABLE,
|
||||
|
@ -1503,13 +1490,13 @@ export default class MessageSender {
|
|||
|
||||
async syncView(
|
||||
views: ReadonlyArray<{
|
||||
senderUuid?: string;
|
||||
senderAci?: AciString;
|
||||
senderE164?: string;
|
||||
timestamp: number;
|
||||
}>,
|
||||
options?: SendOptionsType
|
||||
): Promise<CallbackResultType> {
|
||||
const myUuid = window.textsecure.storage.user.getCheckedUuid();
|
||||
const myAci = window.textsecure.storage.user.getCheckedAci();
|
||||
|
||||
const syncMessage = MessageSender.createSyncMessage();
|
||||
syncMessage.viewed = views.map(
|
||||
|
@ -1525,7 +1512,7 @@ export default class MessageSender {
|
|||
const { ContentHint } = Proto.UnidentifiedSenderMessage.Message;
|
||||
|
||||
return this.sendIndividualProto({
|
||||
identifier: myUuid.toString(),
|
||||
serviceId: myAci,
|
||||
proto: contentMessage,
|
||||
timestamp: Date.now(),
|
||||
contentHint: ContentHint.RESENDABLE,
|
||||
|
@ -1536,7 +1523,7 @@ export default class MessageSender {
|
|||
|
||||
async syncViewOnceOpen(
|
||||
viewOnceOpens: ReadonlyArray<{
|
||||
senderUuid?: string;
|
||||
senderAci?: AciString;
|
||||
senderE164?: string;
|
||||
timestamp: number;
|
||||
}>,
|
||||
|
@ -1547,13 +1534,13 @@ export default class MessageSender {
|
|||
`syncViewOnceOpen: ${viewOnceOpens.length} opens provided. Can only handle one.`
|
||||
);
|
||||
}
|
||||
const { senderE164, senderUuid, timestamp } = viewOnceOpens[0];
|
||||
const { senderE164, senderAci, timestamp } = viewOnceOpens[0];
|
||||
|
||||
if (!senderUuid) {
|
||||
throw new Error('syncViewOnceOpen: Missing senderUuid');
|
||||
if (!senderAci) {
|
||||
throw new Error('syncViewOnceOpen: Missing senderAci');
|
||||
}
|
||||
|
||||
const myUuid = window.textsecure.storage.user.getCheckedUuid();
|
||||
const myAci = window.textsecure.storage.user.getCheckedAci();
|
||||
|
||||
const syncMessage = MessageSender.createSyncMessage();
|
||||
|
||||
|
@ -1561,7 +1548,7 @@ export default class MessageSender {
|
|||
if (senderE164 !== undefined) {
|
||||
viewOnceOpen.sender = senderE164;
|
||||
}
|
||||
viewOnceOpen.senderUuid = senderUuid;
|
||||
viewOnceOpen.senderAci = senderAci;
|
||||
viewOnceOpen.timestamp = Long.fromNumber(timestamp);
|
||||
syncMessage.viewOnceOpen = viewOnceOpen;
|
||||
|
||||
|
@ -1571,7 +1558,7 @@ export default class MessageSender {
|
|||
const { ContentHint } = Proto.UnidentifiedSenderMessage.Message;
|
||||
|
||||
return this.sendIndividualProto({
|
||||
identifier: myUuid.toString(),
|
||||
serviceId: myAci,
|
||||
proto: contentMessage,
|
||||
timestamp: Date.now(),
|
||||
contentHint: ContentHint.RESENDABLE,
|
||||
|
@ -1583,12 +1570,12 @@ export default class MessageSender {
|
|||
static getMessageRequestResponseSync(
|
||||
options: Readonly<{
|
||||
threadE164?: string;
|
||||
threadUuid?: string;
|
||||
threadAci?: AciString;
|
||||
groupId?: Uint8Array;
|
||||
type: number;
|
||||
}>
|
||||
): SingleProtoJobData {
|
||||
const myUuid = window.textsecure.storage.user.getCheckedUuid();
|
||||
const myAci = window.textsecure.storage.user.getCheckedAci();
|
||||
|
||||
const syncMessage = MessageSender.createSyncMessage();
|
||||
|
||||
|
@ -1596,8 +1583,8 @@ export default class MessageSender {
|
|||
if (options.threadE164 !== undefined) {
|
||||
response.threadE164 = options.threadE164;
|
||||
}
|
||||
if (options.threadUuid !== undefined) {
|
||||
response.threadUuid = options.threadUuid;
|
||||
if (options.threadAci !== undefined) {
|
||||
response.threadAci = options.threadAci;
|
||||
}
|
||||
if (options.groupId) {
|
||||
response.groupId = options.groupId;
|
||||
|
@ -1612,7 +1599,7 @@ export default class MessageSender {
|
|||
|
||||
return {
|
||||
contentHint: ContentHint.RESENDABLE,
|
||||
identifier: myUuid.toString(),
|
||||
identifier: myAci,
|
||||
isSyncMessage: true,
|
||||
protoBase64: Bytes.toBase64(
|
||||
Proto.Content.encode(contentMessage).finish()
|
||||
|
@ -1629,7 +1616,7 @@ export default class MessageSender {
|
|||
installed: boolean;
|
||||
}>
|
||||
): SingleProtoJobData {
|
||||
const myUuid = window.textsecure.storage.user.getCheckedUuid();
|
||||
const myAci = window.textsecure.storage.user.getCheckedAci();
|
||||
const ENUM = Proto.SyncMessage.StickerPackOperation.Type;
|
||||
|
||||
const packOperations = operations.map(item => {
|
||||
|
@ -1653,7 +1640,7 @@ export default class MessageSender {
|
|||
|
||||
return {
|
||||
contentHint: ContentHint.RESENDABLE,
|
||||
identifier: myUuid.toString(),
|
||||
identifier: myAci,
|
||||
isSyncMessage: true,
|
||||
protoBase64: Bytes.toBase64(
|
||||
Proto.Content.encode(contentMessage).finish()
|
||||
|
@ -1665,13 +1652,13 @@ export default class MessageSender {
|
|||
|
||||
static getVerificationSync(
|
||||
destinationE164: string | undefined,
|
||||
destinationUuid: string | undefined,
|
||||
destinationAci: AciString | undefined,
|
||||
state: number,
|
||||
identityKey: Readonly<Uint8Array>
|
||||
): SingleProtoJobData {
|
||||
const myUuid = window.textsecure.storage.user.getCheckedUuid();
|
||||
const myAci = window.textsecure.storage.user.getCheckedAci();
|
||||
|
||||
if (!destinationE164 && !destinationUuid) {
|
||||
if (!destinationE164 && !destinationAci) {
|
||||
throw new Error('syncVerification: Neither e164 nor UUID were provided');
|
||||
}
|
||||
|
||||
|
@ -1682,8 +1669,8 @@ export default class MessageSender {
|
|||
if (destinationE164) {
|
||||
verified.destination = destinationE164;
|
||||
}
|
||||
if (destinationUuid) {
|
||||
verified.destinationUuid = destinationUuid;
|
||||
if (destinationAci) {
|
||||
verified.destinationAci = destinationAci;
|
||||
}
|
||||
verified.identityKey = identityKey;
|
||||
verified.nullMessage = padding;
|
||||
|
@ -1698,7 +1685,7 @@ export default class MessageSender {
|
|||
|
||||
return {
|
||||
contentHint: ContentHint.RESENDABLE,
|
||||
identifier: myUuid.toString(),
|
||||
identifier: myAci,
|
||||
isSyncMessage: true,
|
||||
protoBase64: Bytes.toBase64(
|
||||
Proto.Content.encode(contentMessage).finish()
|
||||
|
@ -1711,17 +1698,17 @@ export default class MessageSender {
|
|||
// Sending messages to contacts
|
||||
|
||||
async sendCallingMessage(
|
||||
recipientId: string,
|
||||
serviceId: ServiceIdString,
|
||||
callingMessage: Readonly<Proto.ICallingMessage>,
|
||||
options?: Readonly<SendOptionsType>
|
||||
): Promise<CallbackResultType> {
|
||||
const recipients = [recipientId];
|
||||
const recipients = [serviceId];
|
||||
const finalTimestamp = Date.now();
|
||||
|
||||
const contentMessage = new Proto.Content();
|
||||
contentMessage.callingMessage = callingMessage;
|
||||
|
||||
const conversation = window.ConversationController.get(recipientId);
|
||||
const conversation = window.ConversationController.get(serviceId);
|
||||
|
||||
addPniSignatureMessageToProto({
|
||||
conversation,
|
||||
|
@ -1744,8 +1731,7 @@ export default class MessageSender {
|
|||
|
||||
async sendDeliveryReceipt(
|
||||
options: Readonly<{
|
||||
senderE164?: string;
|
||||
senderUuid?: string;
|
||||
senderServiceId: ServiceIdString;
|
||||
timestamps: Array<number>;
|
||||
isDirectConversation: boolean;
|
||||
options?: Readonly<SendOptionsType>;
|
||||
|
@ -1759,8 +1745,7 @@ export default class MessageSender {
|
|||
|
||||
async sendReadReceipt(
|
||||
options: Readonly<{
|
||||
senderE164?: string;
|
||||
senderUuid?: string;
|
||||
senderServiceId: AciString;
|
||||
timestamps: Array<number>;
|
||||
isDirectConversation: boolean;
|
||||
options?: Readonly<SendOptionsType>;
|
||||
|
@ -1774,8 +1759,7 @@ export default class MessageSender {
|
|||
|
||||
async sendViewedReceipt(
|
||||
options: Readonly<{
|
||||
senderE164?: string;
|
||||
senderUuid?: string;
|
||||
senderServiceId: ServiceIdString;
|
||||
timestamps: Array<number>;
|
||||
isDirectConversation: boolean;
|
||||
options?: Readonly<SendOptionsType>;
|
||||
|
@ -1788,26 +1772,18 @@ export default class MessageSender {
|
|||
}
|
||||
|
||||
private async sendReceiptMessage({
|
||||
senderE164,
|
||||
senderUuid,
|
||||
senderServiceId,
|
||||
timestamps,
|
||||
type,
|
||||
isDirectConversation,
|
||||
options,
|
||||
}: Readonly<{
|
||||
senderE164?: string;
|
||||
senderUuid?: string;
|
||||
senderServiceId: ServiceIdString;
|
||||
timestamps: Array<number>;
|
||||
type: Proto.ReceiptMessage.Type;
|
||||
isDirectConversation: boolean;
|
||||
options?: Readonly<SendOptionsType>;
|
||||
}>): Promise<CallbackResultType> {
|
||||
if (!senderUuid && !senderE164) {
|
||||
throw new Error(
|
||||
'sendReceiptMessage: Neither uuid nor e164 was provided!'
|
||||
);
|
||||
}
|
||||
|
||||
const timestamp = Date.now();
|
||||
|
||||
const receiptMessage = new Proto.ReceiptMessage();
|
||||
|
@ -1820,9 +1796,7 @@ export default class MessageSender {
|
|||
contentMessage.receiptMessage = receiptMessage;
|
||||
|
||||
if (isDirectConversation) {
|
||||
const conversation = window.ConversationController.get(
|
||||
senderUuid || senderE164
|
||||
);
|
||||
const conversation = window.ConversationController.get(senderServiceId);
|
||||
|
||||
addPniSignatureMessageToProto({
|
||||
conversation,
|
||||
|
@ -1834,7 +1808,7 @@ export default class MessageSender {
|
|||
const { ContentHint } = Proto.UnidentifiedSenderMessage.Message;
|
||||
|
||||
return this.sendIndividualProto({
|
||||
identifier: senderUuid || senderE164,
|
||||
serviceId: senderServiceId,
|
||||
proto: contentMessage,
|
||||
timestamp,
|
||||
contentHint: ContentHint.RESENDABLE,
|
||||
|
@ -1882,25 +1856,25 @@ export default class MessageSender {
|
|||
let initialSavePromise: Promise<number>;
|
||||
|
||||
return async ({
|
||||
identifier,
|
||||
serviceId,
|
||||
deviceIds,
|
||||
}: {
|
||||
identifier: string;
|
||||
serviceId: ServiceIdString;
|
||||
deviceIds: Array<number>;
|
||||
}) => {
|
||||
if (!shouldSaveProto(sendType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const conversation = window.ConversationController.get(identifier);
|
||||
const conversation = window.ConversationController.get(serviceId);
|
||||
if (!conversation) {
|
||||
log.warn(
|
||||
`makeSendLogCallback: Unable to find conversation for identifier ${identifier}`
|
||||
`makeSendLogCallback: Unable to find conversation for serviceId ${serviceId}`
|
||||
);
|
||||
return;
|
||||
}
|
||||
const recipientUuid = conversation.get('uuid');
|
||||
if (!recipientUuid) {
|
||||
const recipientServiceId = conversation.get('uuid');
|
||||
if (!recipientServiceId) {
|
||||
log.warn(
|
||||
`makeSendLogCallback: Conversation ${conversation.idForLogging()} had no UUID`
|
||||
);
|
||||
|
@ -1917,7 +1891,7 @@ export default class MessageSender {
|
|||
hasPniSignatureMessage,
|
||||
},
|
||||
{
|
||||
recipients: { [recipientUuid]: deviceIds },
|
||||
recipients: { [recipientServiceId]: deviceIds },
|
||||
messageIds: messageId ? [messageId] : [],
|
||||
}
|
||||
);
|
||||
|
@ -1926,7 +1900,7 @@ export default class MessageSender {
|
|||
const id = await initialSavePromise;
|
||||
await window.Signal.Data.insertProtoRecipients({
|
||||
id,
|
||||
recipientUuid,
|
||||
recipientServiceId,
|
||||
deviceIds,
|
||||
});
|
||||
}
|
||||
|
@ -1949,17 +1923,17 @@ export default class MessageSender {
|
|||
groupId: string | undefined;
|
||||
options?: SendOptionsType;
|
||||
proto: Proto.Content;
|
||||
recipients: ReadonlyArray<string>;
|
||||
recipients: ReadonlyArray<ServiceIdString>;
|
||||
sendLogCallback?: SendLogCallbackType;
|
||||
story?: boolean;
|
||||
timestamp: number;
|
||||
urgent: boolean;
|
||||
}>): Promise<CallbackResultType> {
|
||||
const myE164 = window.textsecure.storage.user.getNumber();
|
||||
const myUuid = window.textsecure.storage.user.getUuid()?.toString();
|
||||
const identifiers = recipients.filter(id => id !== myE164 && id !== myUuid);
|
||||
const myAci = window.textsecure.storage.user.getAci();
|
||||
const serviceIds = recipients.filter(id => id !== myE164 && id !== myAci);
|
||||
|
||||
if (identifiers.length === 0) {
|
||||
if (serviceIds.length === 0) {
|
||||
const dataMessage = proto.dataMessage
|
||||
? Proto.DataMessage.encode(proto.dataMessage).finish()
|
||||
: undefined;
|
||||
|
@ -1972,8 +1946,8 @@ export default class MessageSender {
|
|||
dataMessage,
|
||||
editMessage,
|
||||
errors: [],
|
||||
failoverIdentifiers: [],
|
||||
successfulIdentifiers: [],
|
||||
failoverServiceIds: [],
|
||||
successfulServiceIds: [],
|
||||
unidentifiedDeliveries: [],
|
||||
contentHint,
|
||||
urgent,
|
||||
|
@ -1996,7 +1970,7 @@ export default class MessageSender {
|
|||
groupId,
|
||||
options,
|
||||
proto,
|
||||
recipients: identifiers,
|
||||
recipients: serviceIds,
|
||||
sendLogCallback,
|
||||
story,
|
||||
timestamp,
|
||||
|
@ -2013,26 +1987,26 @@ export default class MessageSender {
|
|||
timestamp,
|
||||
}: { throwIfNotInDatabase?: boolean; timestamp: number }
|
||||
): Promise<Proto.Content> {
|
||||
const ourUuid = window.textsecure.storage.user.getCheckedUuid();
|
||||
const ourAci = window.textsecure.storage.user.getCheckedAci();
|
||||
const ourDeviceId = parseIntOrThrow(
|
||||
window.textsecure.storage.user.getDeviceId(),
|
||||
'getSenderKeyDistributionMessage'
|
||||
);
|
||||
|
||||
const protocolAddress = ProtocolAddress.new(
|
||||
ourUuid.toString(),
|
||||
ourDeviceId
|
||||
);
|
||||
const protocolAddress = ProtocolAddress.new(ourAci, ourDeviceId);
|
||||
const address = new QualifiedAddress(
|
||||
ourUuid,
|
||||
new Address(ourUuid, ourDeviceId)
|
||||
ourAci,
|
||||
new Address(ourAci, ourDeviceId)
|
||||
);
|
||||
|
||||
const senderKeyDistributionMessage =
|
||||
await window.textsecure.storage.protocol.enqueueSenderKeyJob(
|
||||
address,
|
||||
async () => {
|
||||
const senderKeyStore = new SenderKeys({ ourUuid, zone: GLOBAL_ZONE });
|
||||
const senderKeyStore = new SenderKeys({
|
||||
ourServiceId: ourAci,
|
||||
zone: GLOBAL_ZONE,
|
||||
});
|
||||
|
||||
if (throwIfNotInDatabase) {
|
||||
const key = await senderKeyStore.getSenderKey(
|
||||
|
@ -2070,7 +2044,7 @@ export default class MessageSender {
|
|||
contentHint,
|
||||
distributionId,
|
||||
groupId,
|
||||
identifiers,
|
||||
serviceIds,
|
||||
throwIfNotInDatabase,
|
||||
story,
|
||||
urgent,
|
||||
|
@ -2078,7 +2052,7 @@ export default class MessageSender {
|
|||
contentHint?: number;
|
||||
distributionId: string;
|
||||
groupId: string | undefined;
|
||||
identifiers: ReadonlyArray<string>;
|
||||
serviceIds: ReadonlyArray<ServiceIdString>;
|
||||
throwIfNotInDatabase?: boolean;
|
||||
story?: boolean;
|
||||
urgent: boolean;
|
||||
|
@ -2096,7 +2070,7 @@ export default class MessageSender {
|
|||
);
|
||||
|
||||
const sendLogCallback =
|
||||
identifiers.length > 1
|
||||
serviceIds.length > 1
|
||||
? this.makeSendLogCallback({
|
||||
contentHint: contentHint ?? ContentHint.IMPLICIT,
|
||||
proto: Buffer.from(Proto.Content.encode(contentMessage).finish()),
|
||||
|
@ -2112,7 +2086,7 @@ export default class MessageSender {
|
|||
groupId,
|
||||
options,
|
||||
proto: contentMessage,
|
||||
recipients: identifiers,
|
||||
recipients: serviceIds,
|
||||
sendLogCallback,
|
||||
story,
|
||||
timestamp,
|
||||
|
@ -2126,14 +2100,14 @@ export default class MessageSender {
|
|||
// directly to window.textsecure.messaging.server.<function>
|
||||
|
||||
async getProfile(
|
||||
uuid: UUID,
|
||||
serviceId: ServiceIdString,
|
||||
options: GetProfileOptionsType | GetProfileUnauthOptionsType
|
||||
): ReturnType<WebAPIType['getProfile']> {
|
||||
if (options.accessKey !== undefined) {
|
||||
return this.server.getProfileUnauth(uuid.toString(), options);
|
||||
return this.server.getProfileUnauth(serviceId, options);
|
||||
}
|
||||
|
||||
return this.server.getProfile(uuid.toString(), options);
|
||||
return this.server.getProfile(serviceId, options);
|
||||
}
|
||||
|
||||
async getAvatar(path: string): Promise<ReturnType<WebAPIType['getAvatar']>> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue