fix: refactor and works for all legacy test cases, modern to modern is broken

pull/2660/head
William Grant 2 years ago
parent 6dd340ca6c
commit 89c70760a5

@ -1198,7 +1198,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
}
if (this.isPrivate()) {
// debugger;
const expirationTimerMessage = new ExpirationTimerUpdateMessage(expireUpdate);
const pubkey = new PubKey(this.get('id'));
await getMessageQueue().sendToPubKey(pubkey, expirationTimerMessage);

@ -29,12 +29,10 @@ import { ConversationTypeEnum } from '../models/conversationAttributes';
import { findCachedBlindedMatchOrLookupOnAllServers } from '../session/apis/open_group_api/sogsv3/knownBlindedkeys';
import { appendFetchAvatarAndProfileJob } from './userProfileImageUpdates';
import {
DisappearingMessageConversationSetting,
DisappearingMessageUpdate,
DisappearingMessageUtils,
checkForExpireUpdate,
checkHasOutdatedClient,
setExpirationStartTimestamp,
} from '../util/expiringMessages';
import { checkIsFeatureReleased } from '../util/releaseFeature';
export async function handleSwarmContentMessage(envelope: EnvelopePlus, messageHash: string) {
try {
@ -404,100 +402,34 @@ export async function innerHandleSwarmContentMessage(
}
if (content.dataMessage) {
const dataMessage = content.dataMessage;
// because typescript is funky with incoming protobufs
if (dataMessage.profileKey && dataMessage.profileKey.length === 0) {
dataMessage.profileKey = null;
if (content.dataMessage.profileKey && content.dataMessage.profileKey.length === 0) {
content.dataMessage.profileKey = null;
}
// TODO legacy messages support will be removed in a future release
// We will only support legacy disappearing messages for a short period before disappearing messages v2 is unlocked
const isDisappearingMessagesV2Released = await checkIsFeatureReleased(
'Disappearing Messages V2'
);
const isLegacyContentMessage = DisappearingMessageUtils.isLegacyContentMessage(content);
const isLegacyMessage = Boolean(
isLegacyContentMessage &&
DisappearingMessageUtils.isLegacyDataMessage(dataMessage as SignalService.DataMessage)
);
// NOTE When a legacy client sends a Conversation Setting Message dataMessage.expirationType and dataMessage.expireTimer can possibly be undefined.
const isLegacyConversationSettingMessage = Boolean(
isLegacyContentMessage &&
dataMessage.flags === SignalService.DataMessage.Flags.EXPIRATION_TIMER_UPDATE
);
debugger;
const expireUpdate = await checkForExpireUpdate(conversationModelForUIUpdate, content);
let expirationTimer = isDisappearingMessagesV2Released
? content.expirationTimer
: isLegacyMessage
? Number(dataMessage.expireTimer)
: content.expirationTimer;
if (expireUpdate && !isEmpty(expireUpdate)) {
// TODO legacy messages support will be removed in a future release
// TODO so close! just have to fix the case of turning off disappearing messages in modern clients. Probably if the timer is zero then override any settings.
let expirationType =
expirationTimer === 0
? 'off'
: isDisappearingMessagesV2Released
? DisappearingMessageConversationSetting[
isLegacyContentMessage ? 3 : content.expirationType
]
: DisappearingMessageConversationSetting[3];
const lastDisappearingMessageChangeTimestamp = content.lastDisappearingMessageChangeTimestamp
? Number(content.lastDisappearingMessageChangeTimestamp)
: undefined;
checkHasOutdatedClient(conversationModelForUIUpdate, senderConversationModel, expireUpdate);
}
// TODO legacy messages support will be removed in a future release
// if it is a legacy message and disappearing messages v2 is released then we ignore it and use the local client's conversation settings
if (isDisappearingMessagesV2Released && isLegacyContentMessage) {
window.log.info(`WIP: received a legacy disappearing message after v2 was released.`);
expirationType = conversationModelForUIUpdate.get('expirationType');
expirationTimer = conversationModelForUIUpdate.get('expireTimer');
}
const expireUpdate: DisappearingMessageUpdate = {
expirationType,
expirationTimer,
lastDisappearingMessageChangeTimestamp,
isLegacyConversationSettingMessage,
isLegacyMessage,
isDisappearingMessagesV2Released,
};
const outdatedSender =
senderConversationModel.get('nickname') ||
senderConversationModel.get('displayNameInProfile') ||
senderConversationModel.get('id');
if (conversationModelForUIUpdate.get('hasOutdatedClient')) {
// trigger notice banner
if (isLegacyMessage || isLegacyConversationSettingMessage) {
if (conversationModelForUIUpdate.get('hasOutdatedClient') !== outdatedSender) {
conversationModelForUIUpdate.set({
hasOutdatedClient: outdatedSender,
});
}
} else {
conversationModelForUIUpdate.set({
hasOutdatedClient: undefined,
});
}
conversationModelForUIUpdate.commit();
} else {
if (isLegacyMessage || isLegacyConversationSettingMessage) {
conversationModelForUIUpdate.set({
hasOutdatedClient: outdatedSender,
});
conversationModelForUIUpdate.commit();
}
if (
expireUpdate?.isDisappearingMessagesV2Released &&
(expireUpdate?.isLegacyConversationSettingMessage ||
(expireUpdate?.isMismatchedMessage &&
content.dataMessage.flags === SignalService.DataMessage.Flags.EXPIRATION_TIMER_UPDATE))
) {
window.log.info(`WIP: The legacy message is an expiration timer update. Ignoring it.`);
return;
}
perfStart(`handleSwarmDataMessage-${envelope.id}`);
await handleSwarmDataMessage(
envelope,
sentAtTimestamp,
dataMessage as SignalService.DataMessage,
content.dataMessage as SignalService.DataMessage,
messageHash,
senderConversationModel,
expireUpdate

@ -23,7 +23,7 @@ import { toLogFormat } from '../types/attachments/Errors';
import { ConversationTypeEnum } from '../models/conversationAttributes';
import { Reactions } from '../util/reactions';
import { Action, Reaction } from '../types/Reaction';
import { DisappearingMessageUpdate } from '../util/expiringMessages';
import { DisappearingMessageUpdate, handleExpireUpdate } from '../util/expiringMessages';
function cleanAttachment(attachment: any) {
return {
@ -155,7 +155,7 @@ export async function handleSwarmDataMessage(
rawDataMessage: SignalService.DataMessage,
messageHash: string,
senderConversationModel: ConversationModel,
expireUpdate: DisappearingMessageUpdate
expireUpdate?: DisappearingMessageUpdate
): Promise<void> {
window.log.info('handleSwarmDataMessage');
@ -229,7 +229,7 @@ export async function handleSwarmDataMessage(
return;
}
const msgModel =
let msgModel =
isSyncedMessage || (envelope.senderIdentity && isUsFromCache(envelope.senderIdentity))
? createSwarmMessageSentFromUs({
conversationId: convoIdToAddTheMessageTo,
@ -243,46 +243,12 @@ export async function handleSwarmDataMessage(
sentAt: sentAtTimestamp,
});
if (expireUpdate && !isEmpty(expireUpdate)) {
if (isSyncedMessage) {
// TODO handle sync messages separately
// TODO handle sync messages expiring separately
window.log.info('WIP: Sync Message dropping');
} else {
let {
expirationType,
// TODO renamed expireTimer to expirationTimer
expirationTimer: expireTimer,
lastDisappearingMessageChangeTimestamp,
isLegacyConversationSettingMessage,
isDisappearingMessagesV2Released,
} = expireUpdate;
msgModel.set({
expirationType,
expireTimer,
});
// TODO legacy messages support will be removed in a future release
// This message is conversation setting change message
if (lastDisappearingMessageChangeTimestamp || isLegacyConversationSettingMessage) {
if (isDisappearingMessagesV2Released && isLegacyConversationSettingMessage) {
window.log.info(`WIP: The legacy message is an expiration timer update. Ignoring it.`);
return;
}
const expirationTimerUpdate = {
expirationType,
expireTimer,
lastDisappearingMessageChangeTimestamp: isLegacyConversationSettingMessage
? isDisappearingMessagesV2Released
? convoToAddMessageTo.get('lastDisappearingMessageChangeTimestamp')
: Date.now()
: Number(lastDisappearingMessageChangeTimestamp),
source: msgModel.get('source'),
};
msgModel.set({
expirationTimerUpdate,
});
msgModel = handleExpireUpdate(convoToAddMessageTo, msgModel, expireUpdate);
}
}

@ -9,6 +9,9 @@ import { Data } from '../data/data';
import { getConversationController } from '../session/conversations';
import { getNowWithNetworkOffset } from '../session/apis/snode_api/SNodeAPI';
import { ProtobufUtils, SignalService } from '../protobuf';
import { ConversationModel } from '../models/conversation';
import { checkIsFeatureReleased } from './releaseFeature';
import { MessageModel } from '../models/message';
// TODO Might need to be improved by using an enum
// TODO do we need to add legacy here now that it's explicitly in the protbuf?
@ -28,30 +31,11 @@ export type DisappearingMessageUpdate = {
expirationTimer: number;
// This is used for the expirationTimerUpdate
lastDisappearingMessageChangeTimestamp?: number;
// TODO legacy messages support will be removed in a future release
isLegacyConversationSettingMessage?: boolean;
isLegacyMessage?: boolean;
isDisappearingMessagesV2Released?: boolean;
};
// TODO legacy messages support will be removed in a future release
// NOTE We need this to check for legacy disappearing messages where the expirationType and expireTimer should be undefined on the ContentMessage
function isLegacyContentMessage(contentMessage: SignalService.Content): boolean {
return (
(contentMessage.expirationType === SignalService.Content.ExpirationType.UNKNOWN ||
!ProtobufUtils.hasDefinedProperty(contentMessage, 'expirationType')) &&
!ProtobufUtils.hasDefinedProperty(contentMessage, 'expirationTimer')
);
}
function isLegacyDataMessage(dataMessage: SignalService.DataMessage): boolean {
return (
ProtobufUtils.hasDefinedProperty(dataMessage, 'expireTimer') && dataMessage.expireTimer > -1
);
}
export const DisappearingMessageUtils = {
isLegacyContentMessage,
isLegacyDataMessage,
isMismatchedMessage?: boolean;
};
export async function destroyMessagesAndUpdateRedux(
@ -277,3 +261,159 @@ export function setExpirationStartTimestamp(
return expirationStartTimestamp;
}
// TODO legacy messages support will be removed in a future release
// NOTE We need this to check for legacy disappearing messages where the expirationType and expireTimer should be undefined on the ContentMessage
function checkIsLegacyContentMessage(contentMessage: SignalService.Content): boolean {
return (
(contentMessage.expirationType === SignalService.Content.ExpirationType.UNKNOWN ||
!ProtobufUtils.hasDefinedProperty(contentMessage, 'expirationType')) &&
!ProtobufUtils.hasDefinedProperty(contentMessage, 'expirationTimer')
);
}
function checkIsLegacyDataMessage(dataMessage: SignalService.DataMessage): boolean {
return (
ProtobufUtils.hasDefinedProperty(dataMessage, 'expireTimer') && dataMessage.expireTimer > -1
);
}
// TODO legacy messages support will be removed in a future release
export async function checkForExpireUpdate(
convoToUpdate: ConversationModel,
content: SignalService.Content
): Promise<DisappearingMessageUpdate | undefined> {
const dataMessage = content.dataMessage as SignalService.DataMessage;
// We will only support legacy disappearing messages for a short period before disappearing messages v2 is unlocked
const isDisappearingMessagesV2Released = await checkIsFeatureReleased('Disappearing Messages V2');
const isLegacyContentMessage = checkIsLegacyContentMessage(content);
const isLegacyMessage = Boolean(
isLegacyContentMessage && checkIsLegacyDataMessage(dataMessage as SignalService.DataMessage)
);
let expirationTimer = isLegacyMessage ? Number(dataMessage.expireTimer) : content.expirationTimer;
let expirationType =
expirationTimer > 0
? DisappearingMessageConversationSetting[isLegacyContentMessage ? 3 : content.expirationType]
: DisappearingMessageConversationSetting[0];
const lastDisappearingMessageChangeTimestamp = content.lastDisappearingMessageChangeTimestamp
? Number(content.lastDisappearingMessageChangeTimestamp)
: undefined;
const isLegacyConversationSettingMessage =
isLegacyContentMessage &&
isLegacyMessage &&
dataMessage.flags === SignalService.DataMessage.Flags.EXPIRATION_TIMER_UPDATE;
const isMismatchedMessage =
(!isLegacyConversationSettingMessage &&
convoToUpdate.get('expirationType') !== 'off' &&
convoToUpdate.get('expirationType') !== expirationType) ||
(convoToUpdate.get('expireTimer') !== 0 &&
convoToUpdate.get('expireTimer') !== expirationTimer);
// If it is a legacy message and disappearing messages v2 is released then we ignore it and use the local client's conversation settings
if (
isDisappearingMessagesV2Released &&
(isLegacyMessage ||
isLegacyConversationSettingMessage ||
(!isLegacyConversationSettingMessage && isMismatchedMessage))
) {
window.log.info(`WIP: received a legacy disappearing message after v2 was released.`);
expirationType = convoToUpdate.get('expirationType');
expirationTimer = convoToUpdate.get('expireTimer');
}
const expireUpdate: DisappearingMessageUpdate = {
expirationType,
expirationTimer,
lastDisappearingMessageChangeTimestamp,
isLegacyConversationSettingMessage,
isLegacyMessage,
isDisappearingMessagesV2Released,
isMismatchedMessage,
};
return expireUpdate;
}
// TODO legacy messages support will be removed in a future release
export function handleExpireUpdate(
converationModel: ConversationModel,
messageModel: MessageModel,
expireUpdate: DisappearingMessageUpdate
) {
let {
expirationType,
// TODO renamed expireTimer to expirationTimer
expirationTimer: expireTimer,
lastDisappearingMessageChangeTimestamp,
isLegacyConversationSettingMessage,
isDisappearingMessagesV2Released,
} = expireUpdate;
messageModel.set({
expirationType,
expireTimer,
});
// This message is conversation setting change message
if (lastDisappearingMessageChangeTimestamp || isLegacyConversationSettingMessage) {
const expirationTimerUpdate = {
expirationType,
expireTimer,
lastDisappearingMessageChangeTimestamp: isLegacyConversationSettingMessage
? isDisappearingMessagesV2Released
? converationModel.get('lastDisappearingMessageChangeTimestamp')
: Date.now()
: Number(lastDisappearingMessageChangeTimestamp),
source: messageModel.get('source'),
};
messageModel.set({
expirationTimerUpdate,
});
}
return messageModel;
}
export function checkHasOutdatedClient(
convoToUpdate: ConversationModel,
sender: ConversationModel,
expireUpdate: DisappearingMessageUpdate
) {
const outdatedSender =
sender.get('nickname') || sender.get('displayNameInProfile') || sender.get('id');
if (convoToUpdate.get('hasOutdatedClient')) {
// trigger notice banner
if (
expireUpdate.isLegacyMessage ||
expireUpdate.isLegacyConversationSettingMessage ||
(expireUpdate.isDisappearingMessagesV2Released && expireUpdate.isMismatchedMessage)
) {
if (convoToUpdate.get('hasOutdatedClient') !== outdatedSender) {
convoToUpdate.set({
hasOutdatedClient: outdatedSender,
});
}
} else {
convoToUpdate.set({
hasOutdatedClient: undefined,
});
}
convoToUpdate.commit();
} else {
if (
expireUpdate.isLegacyMessage ||
expireUpdate.isLegacyConversationSettingMessage ||
(expireUpdate.isDisappearingMessagesV2Released && expireUpdate.isMismatchedMessage)
) {
convoToUpdate.set({
hasOutdatedClient: outdatedSender,
});
convoToUpdate.commit();
}
}
}

Loading…
Cancel
Save