Stories: Fix sender key persistence, pipe story: true into sends

This commit is contained in:
Scott Nonnenberg 2022-09-30 09:59:36 -07:00 committed by GitHub
parent 67c706a7ef
commit 2b2594c20a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 76 additions and 30 deletions

View File

@ -71,10 +71,11 @@ export async function sendStory(
return; return;
} }
const messageTimestamp = message.get('timestamp');
const messageConversation = message.getConversation(); const messageConversation = message.getConversation();
if (messageConversation !== conversation) { if (messageConversation !== conversation) {
log.error( log.error(
`stories.sendStory(${messageId}): Message conversation '${messageConversation?.idForLogging()}' does not match job conversation ${conversation.idForLogging()}` `stories.sendStory(${messageTimestamp}): Message conversation '${messageConversation?.idForLogging()}' does not match job conversation ${conversation.idForLogging()}`
); );
return; return;
} }
@ -84,7 +85,7 @@ export async function sendStory(
if (!attachment) { if (!attachment) {
log.info( log.info(
`stories.sendStory(${messageId}): message does not have any attachments to send. Giving up on sending it` `stories.sendStory(${messageTimestamp}): message does not have any attachments to send. Giving up on sending it`
); );
return; return;
} }
@ -163,17 +164,18 @@ export async function sendStory(
return; return;
} }
const messageTimestamp = message.get('timestamp');
const messageConversation = message.getConversation(); const messageConversation = message.getConversation();
if (messageConversation !== conversation) { if (messageConversation !== conversation) {
log.error( log.error(
`stories.sendStory(${messageId}): Message conversation '${messageConversation?.idForLogging()}' does not match job conversation ${conversation.idForLogging()}` `stories.sendStory(${messageTimestamp}): Message conversation '${messageConversation?.idForLogging()}' does not match job conversation ${conversation.idForLogging()}`
); );
return; return;
} }
if (message.isErased() || message.get('deletedForEveryone')) { if (message.isErased() || message.get('deletedForEveryone')) {
log.info( log.info(
`stories.sendStory(${messageId}): message was erased. Giving up on sending it` `stories.sendStory(${messageTimestamp}): message was erased. Giving up on sending it`
); );
return; return;
} }
@ -185,7 +187,7 @@ export async function sendStory(
if (!receiverId) { if (!receiverId) {
log.info( log.info(
`stories.sendStory(${messageId}): did not get a valid recipient ID for message. Giving up on sending it` `stories.sendStory(${messageTimestamp}): did not get a valid recipient ID for message. Giving up on sending it`
); );
return; return;
} }
@ -212,7 +214,7 @@ export async function sendStory(
if (!shouldContinue) { if (!shouldContinue) {
log.info( log.info(
`stories.sendStory(${messageId}): ran out of time. Giving up on sending it` `stories.sendStory(${messageTimestamp}): ran out of time. Giving up on sending it`
); );
await markMessageFailed(message, [ await markMessageFailed(message, [
new Error('Message send ran out of time'), new Error('Message send ran out of time'),
@ -242,7 +244,7 @@ export async function sendStory(
} }
); );
throw new Error( throw new Error(
`stories.sendStory(${messageId}): sending blocked because ${untrustedUuids.length} conversation(s) were untrusted. Failing this attempt.` `stories.sendStory(${messageTimestamp}): sending blocked because ${untrustedUuids.length} conversation(s) were untrusted. Failing this attempt.`
); );
} }
@ -266,7 +268,7 @@ export async function sendStory(
); );
log.info( log.info(
`stories.sendStory(${messageId}): sending story to ${receiverId}` `stories.sendStory(${messageTimestamp}): sending story to ${receiverId}`
); );
const storyMessage = new Proto.StoryMessage(); const storyMessage = new Proto.StoryMessage();
@ -314,6 +316,7 @@ export async function sendStory(
sendOptions, sendOptions,
sendTarget, sendTarget,
sendType: 'story', sendType: 'story',
story: true,
timestamp: message.get('timestamp'), timestamp: message.get('timestamp'),
urgent: false, urgent: false,
}); });

View File

@ -4556,7 +4556,7 @@ async function getStoryDistributionWithMembers(
id: string id: string
): Promise<StoryDistributionWithMembersType | undefined> { ): Promise<StoryDistributionWithMembersType | undefined> {
const db = getInstance(); const db = getInstance();
const storyDistribution = prepare( const storyDistribution: StoryDistributionForDatabase | undefined = prepare(
db, db,
'SELECT * FROM storyDistributions WHERE id = $id;' 'SELECT * FROM storyDistributions WHERE id = $id;'
).get({ ).get({
@ -4575,7 +4575,7 @@ async function getStoryDistributionWithMembers(
}); });
return { return {
...storyDistribution, ...hydrateStoryDistribution(storyDistribution),
members: members.map(({ uuid }) => uuid), members: members.map(({ uuid }) => uuid),
}; };
} }

View File

@ -134,6 +134,8 @@ export default class OutgoingMessage {
urgent: boolean; urgent: boolean;
story?: boolean;
recipients: Record<string, Array<number>>; recipients: Record<string, Array<number>>;
sendLogCallback?: SendLogCallbackType; sendLogCallback?: SendLogCallbackType;
@ -147,6 +149,7 @@ export default class OutgoingMessage {
options, options,
sendLogCallback, sendLogCallback,
server, server,
story,
timestamp, timestamp,
urgent, urgent,
}: { }: {
@ -158,6 +161,7 @@ export default class OutgoingMessage {
options?: OutgoingMessageOptionsType; options?: OutgoingMessageOptionsType;
sendLogCallback?: SendLogCallbackType; sendLogCallback?: SendLogCallbackType;
server: WebAPIType; server: WebAPIType;
story?: boolean;
timestamp: number; timestamp: number;
urgent: boolean; urgent: boolean;
}) { }) {
@ -175,6 +179,7 @@ export default class OutgoingMessage {
this.contentHint = contentHint; this.contentHint = contentHint;
this.groupId = groupId; this.groupId = groupId;
this.callback = callback; this.callback = callback;
this.story = story;
this.urgent = urgent; this.urgent = urgent;
this.identifiersCompleted = 0; this.identifiersCompleted = 0;
@ -310,11 +315,17 @@ export default class OutgoingMessage {
identifier, identifier,
jsonData, jsonData,
timestamp, timestamp,
{ accessKey, online: this.online, urgent: this.urgent } {
accessKey,
online: this.online,
story: this.story,
urgent: this.urgent,
}
); );
} else { } else {
promise = this.server.sendMessages(identifier, jsonData, timestamp, { promise = this.server.sendMessages(identifier, jsonData, timestamp, {
online: this.online, online: this.online,
story: this.story,
urgent: this.urgent, urgent: this.urgent,
}); });
} }

View File

@ -1203,6 +1203,7 @@ export default class MessageSender {
proto, proto,
recipients, recipients,
sendLogCallback, sendLogCallback,
story,
timestamp, timestamp,
urgent, urgent,
}: Readonly<{ }: Readonly<{
@ -1213,6 +1214,7 @@ export default class MessageSender {
proto: Proto.Content | Proto.DataMessage | PlaintextContent; proto: Proto.Content | Proto.DataMessage | PlaintextContent;
recipients: ReadonlyArray<string>; recipients: ReadonlyArray<string>;
sendLogCallback?: SendLogCallbackType; sendLogCallback?: SendLogCallbackType;
story?: boolean;
timestamp: number; timestamp: number;
urgent: boolean; urgent: boolean;
}>): void { }>): void {
@ -1233,6 +1235,7 @@ export default class MessageSender {
options, options,
sendLogCallback, sendLogCallback,
server: this.server, server: this.server,
story,
timestamp, timestamp,
urgent, urgent,
}); });
@ -2220,6 +2223,7 @@ export default class MessageSender {
proto, proto,
recipients, recipients,
sendLogCallback, sendLogCallback,
story,
timestamp = Date.now(), timestamp = Date.now(),
urgent, urgent,
}: Readonly<{ }: Readonly<{
@ -2229,6 +2233,7 @@ export default class MessageSender {
proto: Proto.Content; proto: Proto.Content;
recipients: ReadonlyArray<string>; recipients: ReadonlyArray<string>;
sendLogCallback?: SendLogCallbackType; sendLogCallback?: SendLogCallbackType;
story?: boolean;
timestamp: number; timestamp: number;
urgent: boolean; urgent: boolean;
}>): Promise<CallbackResultType> { }>): Promise<CallbackResultType> {
@ -2269,6 +2274,7 @@ export default class MessageSender {
proto, proto,
recipients: identifiers, recipients: identifiers,
sendLogCallback, sendLogCallback,
story,
timestamp, timestamp,
urgent, urgent,
}); });
@ -2341,6 +2347,7 @@ export default class MessageSender {
groupId, groupId,
identifiers, identifiers,
throwIfNotInDatabase, throwIfNotInDatabase,
story,
urgent, urgent,
}: Readonly<{ }: Readonly<{
contentHint: number; contentHint: number;
@ -2348,6 +2355,7 @@ export default class MessageSender {
groupId: string | undefined; groupId: string | undefined;
identifiers: ReadonlyArray<string>; identifiers: ReadonlyArray<string>;
throwIfNotInDatabase?: boolean; throwIfNotInDatabase?: boolean;
story?: boolean;
urgent: boolean; urgent: boolean;
}>, }>,
options?: Readonly<SendOptionsType> options?: Readonly<SendOptionsType>
@ -2380,6 +2388,7 @@ export default class MessageSender {
proto: contentMessage, proto: contentMessage,
recipients: identifiers, recipients: identifiers,
sendLogCallback, sendLogCallback,
story,
timestamp, timestamp,
urgent, urgent,
}); });

View File

@ -917,13 +917,18 @@ export type WebAPIType = {
destination: string, destination: string,
messageArray: ReadonlyArray<MessageType>, messageArray: ReadonlyArray<MessageType>,
timestamp: number, timestamp: number,
options: { online?: boolean; urgent?: boolean } options: { online?: boolean; story?: boolean; urgent?: boolean }
) => Promise<void>; ) => Promise<void>;
sendMessagesUnauth: ( sendMessagesUnauth: (
destination: string, destination: string,
messageArray: ReadonlyArray<MessageType>, messageArray: ReadonlyArray<MessageType>,
timestamp: number, timestamp: number,
options: { accessKey?: string; online?: boolean; urgent?: boolean } options: {
accessKey?: string;
online?: boolean;
story?: boolean;
urgent?: boolean;
}
) => Promise<void>; ) => Promise<void>;
sendWithSenderKey: ( sendWithSenderKey: (
payload: Uint8Array, payload: Uint8Array,
@ -2084,12 +2089,19 @@ export function initialize({
accessKey, accessKey,
online, online,
urgent = true, urgent = true,
}: { accessKey?: string; online?: boolean; urgent?: boolean } story = false,
}: {
accessKey?: string;
online?: boolean;
story?: boolean;
urgent?: boolean;
}
) { ) {
const jsonData = { const jsonData = {
messages, messages,
timestamp, timestamp,
online: Boolean(online), online: Boolean(online),
story,
urgent, urgent,
}; };
@ -2108,12 +2120,17 @@ export function initialize({
destination: string, destination: string,
messages: ReadonlyArray<MessageType>, messages: ReadonlyArray<MessageType>,
timestamp: number, timestamp: number,
{ online, urgent = true }: { online?: boolean; urgent?: boolean } {
online,
urgent = true,
story = false,
}: { online?: boolean; story?: boolean; urgent?: boolean }
) { ) {
const jsonData = { const jsonData = {
messages, messages,
timestamp, timestamp,
online: Boolean(online), online: Boolean(online),
story,
urgent, urgent,
}; };

View File

@ -17,7 +17,6 @@ import {
conversationJobQueue, conversationJobQueue,
conversationQueueJobEnum, conversationQueueJobEnum,
} from '../jobs/conversationJobQueue'; } from '../jobs/conversationJobQueue';
import { formatJobForInsert } from '../jobs/formatJobForInsert';
import { getRecipients } from './getRecipients'; import { getRecipients } from './getRecipients';
import { getSignalConnections } from './getSignalConnections'; import { getSignalConnections } from './getSignalConnections';
import { incrementMessageCounter } from './incrementMessageCounter'; import { incrementMessageCounter } from './incrementMessageCounter';
@ -144,6 +143,8 @@ export async function sendStoryMessage(
); );
} }
// Note: we use the same sent_at for these messages because we want de-duplication
// on the receiver side.
return window.Signal.Migrations.upgradeMessageSchema({ return window.Signal.Migrations.upgradeMessageSchema({
attachments, attachments,
conversationId: ourConversation.id, conversationId: ourConversation.id,
@ -247,7 +248,9 @@ export async function sendStoryMessage(
ourConversation.addSingleMessage(model, { isJustSent: true }); ourConversation.addSingleMessage(model, { isJustSent: true });
log.info(`stories.sendStoryMessage: saving message ${message.id}`); log.info(
`stories.sendStoryMessage: saving message ${messageAttributes.timestamp}`
);
return dataInterface.saveMessage(message.attributes, { return dataInterface.saveMessage(message.attributes, {
forceSave: true, forceSave: true,
ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(), ourUuid: window.textsecure.storage.user.getCheckedUuid().toString(),
@ -258,18 +261,12 @@ export async function sendStoryMessage(
// * Send to the distribution lists // * Send to the distribution lists
// * Place into job queue // * Place into job queue
// * Save the job // * Save the job
await conversationJobQueue.add( await conversationJobQueue.add({
{ type: conversationQueueJobEnum.enum.Story,
type: conversationQueueJobEnum.enum.Story, conversationId: ourConversation.id,
conversationId: ourConversation.id, messageIds: distributionListMessages.map(m => m.id),
messageIds: distributionListMessages.map(m => m.id), timestamp,
timestamp, });
},
async jobToInsert => {
log.info(`stories.sendStoryMessage: saving job ${jobToInsert.id}`);
await dataInterface.insertJob(formatJobForInsert(jobToInsert));
}
);
// * Send to groups // * Send to groups
// * Save the message models // * Save the message models
@ -301,7 +298,9 @@ export async function sendStoryMessage(
const conversation = message.getConversation(); const conversation = message.getConversation();
conversation?.addSingleMessage(model, { isJustSent: true }); conversation?.addSingleMessage(model, { isJustSent: true });
log.info(`stories.sendStoryMessage: saving message ${message.id}`); log.info(
`stories.sendStoryMessage: saving message ${messageAttributes.timestamp}`
);
await dataInterface.saveMessage(message.attributes, { await dataInterface.saveMessage(message.attributes, {
forceSave: true, forceSave: true,
jobToInsert, jobToInsert,

View File

@ -156,6 +156,7 @@ export async function sendContentMessageToGroup({
sendOptions, sendOptions,
sendTarget, sendTarget,
sendType, sendType,
story,
timestamp, timestamp,
urgent, urgent,
}: { }: {
@ -168,6 +169,7 @@ export async function sendContentMessageToGroup({
sendOptions?: SendOptionsType; sendOptions?: SendOptionsType;
sendTarget: SenderKeyTargetType; sendTarget: SenderKeyTargetType;
sendType: SendTypesType; sendType: SendTypesType;
story?: boolean;
timestamp: number; timestamp: number;
urgent: boolean; urgent: boolean;
}): Promise<CallbackResultType> { }): Promise<CallbackResultType> {
@ -199,6 +201,7 @@ export async function sendContentMessageToGroup({
sendOptions, sendOptions,
sendTarget, sendTarget,
sendType, sendType,
story,
timestamp, timestamp,
urgent, urgent,
}); });
@ -235,6 +238,7 @@ export async function sendContentMessageToGroup({
proto: contentMessage, proto: contentMessage,
recipients, recipients,
sendLogCallback, sendLogCallback,
story,
timestamp, timestamp,
urgent, urgent,
}); });
@ -253,6 +257,7 @@ export async function sendToGroupViaSenderKey(options: {
sendOptions?: SendOptionsType; sendOptions?: SendOptionsType;
sendTarget: SenderKeyTargetType; sendTarget: SenderKeyTargetType;
sendType: SendTypesType; sendType: SendTypesType;
story?: boolean;
timestamp: number; timestamp: number;
urgent: boolean; urgent: boolean;
}): Promise<CallbackResultType> { }): Promise<CallbackResultType> {
@ -267,6 +272,7 @@ export async function sendToGroupViaSenderKey(options: {
sendOptions, sendOptions,
sendTarget, sendTarget,
sendType, sendType,
story,
timestamp, timestamp,
urgent, urgent,
} = options; } = options;
@ -433,6 +439,7 @@ export async function sendToGroupViaSenderKey(options: {
distributionId, distributionId,
groupId, groupId,
identifiers: newToMemberUuids, identifiers: newToMemberUuids,
story,
urgent, urgent,
}, },
sendOptions ? { ...sendOptions, online: false } : undefined sendOptions ? { ...sendOptions, online: false } : undefined