feat: updated clients can send ExpirationTimerUpdateMessages to older clients

fixed syncing of ExpirationTimerUpdateMessages
pull/2660/head
William Grant 2 years ago
parent 75f1b5ed65
commit d698f66d50

@ -1,7 +1,6 @@
import Backbone from 'backbone';
import {
debounce,
defaults,
filter,
includes,
isArray,
@ -1058,7 +1057,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
providedChangeTimestamp,
providedSource,
receivedAt, // is set if it comes from outside
fromSync,
fromSync = false,
shouldCommit = true,
existingMessage,
}: {
@ -1076,8 +1075,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
const lastDisappearingMessageChangeTimestamp = providedChangeTimestamp;
let source = providedSource;
defaults({ fromSync }, { fromSync: false });
if (!expirationType || !expireTimer) {
expirationType = 'off';
expireTimer = 0;
@ -1191,7 +1188,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
}
if (this.isPrivate()) {
// TODO Check that the args are correct
const expirationTimerMessage = new ExpirationTimerUpdateMessage(expireUpdate);
const pubkey = new PubKey(this.get('id'));
await getMessageQueue().sendToPubKey(pubkey, expirationTimerMessage);

@ -4,7 +4,7 @@ import filesize from 'filesize';
import { SignalService } from '../../ts/protobuf';
import { getMessageQueue } from '../../ts/session';
import { getConversationController } from '../../ts/session/conversations';
import { DataMessage } from '../../ts/session/messages/outgoing';
import { ContentMessage } from '../../ts/session/messages/outgoing';
import { ClosedGroupVisibleMessage } from '../session/messages/outgoing/visibleMessage/ClosedGroupVisibleMessage';
import { PubKey } from '../../ts/session/types';
import {
@ -82,6 +82,7 @@ import {
loadQuoteData,
} from '../types/MessageAttachment';
import {
DisappearingMessageConversationSetting,
DisappearingMessageUpdate,
ExpirationTimerOptions,
setExpirationStartTimestamp,
@ -1063,8 +1064,7 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
await this.commit();
}
public async sendSyncMessageOnly(dataMessage: DataMessage) {
const contentMessage = dataMessage.contentProto();
public async sendSyncMessageOnly(contentMessage: ContentMessage) {
const now = Date.now();
this.set({
@ -1072,51 +1072,56 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
sent: true,
});
let expireUpdate: DisappearingMessageUpdate | null = null;
const expirationType = dataMessage.getDisappearingMessageType();
if (expirationType && contentMessage.expirationTimer) {
expireUpdate = {
expirationType,
expireTimer: contentMessage.expirationTimer,
lastDisappearingMessageChangeTimestamp: Number(
contentMessage.lastDisappearingMessageChangeTimestamp
),
};
}
await this.commit();
await this.sendSyncMessage(dataMessage, now, expireUpdate || undefined);
const content =
contentMessage instanceof ContentMessage ? contentMessage.contentProto() : contentMessage;
await this.sendSyncMessage(content, now);
}
public async sendSyncMessage(
data: DataMessage | SignalService.DataMessage,
sentTimestamp: number,
expireUpdate?: DisappearingMessageUpdate
) {
public async sendSyncMessage(content: SignalService.Content, sentTimestamp: number) {
if (this.get('synced') || this.get('sentSync')) {
return;
}
const { dataMessage } = content;
const dataMessage = data instanceof DataMessage ? data.dataProto() : data;
// TODO maybe we need to account for lastDisappearingMessageChangeTimestamp?
// if this message needs to be synced
if (
dataMessage.body?.length ||
dataMessage.attachments.length ||
dataMessage.flags === SignalService.DataMessage.Flags.EXPIRATION_TIMER_UPDATE
dataMessage &&
(dataMessage.body?.length ||
dataMessage.attachments?.length ||
dataMessage.flags === SignalService.DataMessage.Flags.EXPIRATION_TIMER_UPDATE)
) {
const conversation = this.getConversation();
if (!conversation) {
throw new Error('Cannot trigger syncMessage with unknown convo.');
}
// TODO legacy messages support will be removed in a future release
const expirationType = content.expirationType
? DisappearingMessageConversationSetting[content.expirationType]
: DisappearingMessageConversationSetting[3];
const expireTimer = content.expirationTimer || content?.dataMessage?.expireTimer || undefined;
const lastDisappearingMessageChangeTimestamp = content.lastDisappearingMessageChangeTimestamp
? Number(content.lastDisappearingMessageChangeTimestamp)
: undefined;
let expireUpdate: DisappearingMessageUpdate | null = null;
if (expirationType && expireTimer !== undefined) {
expireUpdate = {
expirationType,
expireTimer,
lastDisappearingMessageChangeTimestamp,
};
}
const syncMessage = buildSyncMessage(
this.id,
data,
dataMessage as SignalService.DataMessage,
conversation.id,
sentTimestamp,
expireUpdate
expireUpdate || undefined
);
await getMessageQueue().sendSyncMessage(syncMessage);
}

@ -180,10 +180,12 @@ export interface MessageAttributesOptionals {
expireTimer?: number;
expirationStartTimestamp?: number;
expires_at?: number;
// TODO legacy messages support will be removed in a future release
// types will no longer have an undefined option
expirationTimerUpdate?: {
expirationType: DisappearingMessageType;
expirationType: DisappearingMessageType | undefined;
expireTimer: number;
lastDisappearingMessageChangeTimestamp: number;
lastDisappearingMessageChangeTimestamp: number | undefined;
source: string;
fromSync?: boolean;
};

@ -7,17 +7,16 @@ import { ExpirableMessageParams } from '../ExpirableMessage';
interface ExpirationTimerUpdateMessageParams extends ExpirableMessageParams {
groupId?: string | PubKey;
syncTarget?: string | PubKey;
lastDisappearingMessageChangeTimestamp: number | null;
lastDisappearingMessageChangeTimestamp?: number;
}
// Note the old disappearing messages used a data message for the expiration time.
// NOTE legacy messages used a data message for the expireTimer.
// The new ones use properties on the Content Message
// We will remove support for the old one 2 weeks after the release
export class ExpirationTimerUpdateMessage extends DataMessage {
public readonly groupId?: PubKey;
public readonly syncTarget?: string;
// TODO should this typing be updated
public readonly lastDisappearingMessageChangeTimestamp: number | null;
public readonly lastDisappearingMessageChangeTimestamp?: number;
constructor(params: ExpirationTimerUpdateMessageParams) {
super({
@ -64,10 +63,10 @@ export class ExpirationTimerUpdateMessage extends DataMessage {
data.syncTarget = this.syncTarget;
}
// TODO should only happen in legacy mode and should be cancelled out once we have trigger the unix timestamp
// if (this.expireTimer) {
// data.expireTimer = this.expireTimer;
// }
// TODO legacy messages support will be removed in a future release
if (this.expirationType === 'legacy' && this.expireTimer) {
data.expireTimer = this.expireTimer;
}
return data;
}

@ -70,9 +70,7 @@ async function handleMessageSentSuccess(
!isOurDevice &&
!isClosedGroupMessage &&
!fetchedMessage.get('synced') &&
!fetchedMessage.get('sentSync') &&
// TODO not 100% on this. Handling syncing later
!fetchedMessage.get('expirationType');
!fetchedMessage.get('sentSync');
// A message is synced if we triggered a sync message (sentSync)
// and the current message was sent to our device (so a sync message)
@ -105,10 +103,7 @@ async function handleMessageSentSuccess(
if (shouldTriggerSyncMessage) {
if (dataMessage) {
try {
await fetchedMessage.sendSyncMessage(
dataMessage as SignalService.DataMessage,
effectiveTimestamp
);
await fetchedMessage.sendSyncMessage(contentDecoded, effectiveTimestamp);
const tempFetchMessage = await fetchHandleMessageSentData(sentMessage.identifier);
if (!tempFetchMessage) {
window?.log?.warn(
@ -123,7 +118,6 @@ async function handleMessageSentSuccess(
}
} else if (shouldMarkMessageAsSynced) {
fetchedMessage.set({ synced: true });
// TODO handle sync messages separately
}
sentTo = _.union(sentTo, [sentMessage.device]);

@ -307,7 +307,7 @@ const buildSyncExpireTimerMessage = (
timestamp,
expirationType,
expireTimer,
lastDisappearingMessageChangeTimestamp: lastDisappearingMessageChangeTimestamp || null,
lastDisappearingMessageChangeTimestamp,
syncTarget,
});
};
@ -347,7 +347,11 @@ export const buildSyncMessage = (
) {
return buildSyncExpireTimerMessage(identifier, expireUpdate, timestamp, syncTarget);
} else {
window.log.info(`WIP: Something went wrong when syncing a disappearing message`);
window.log.info(
`WIP: Something went wrong when syncing a disappearing message`,
dataMessage,
expireUpdate
);
}
return buildSyncVisibleMessage(identifier, dataMessage, timestamp, syncTarget);
};

Loading…
Cancel
Save