chore: remove lastChangetimestmap and add explciit expiretype and type

on the messages creation
pull/2940/head
Audric Ackermann 5 months ago
parent d1068983bb
commit ad9fa6dbee

@ -75,7 +75,6 @@ message Content {
optional SharedConfigMessage sharedConfigMessage = 11;
optional ExpirationType expirationType = 12;
optional uint32 expirationTimer = 13;
optional uint64 lastDisappearingMessageChangeTimestamp = 14;
}
message KeyPair {

@ -11,7 +11,6 @@ import { Data } from '../data/data';
import { SettingsKey } from '../data/settings-key';
import { uploadFileToFsWithOnionV4 } from '../session/apis/file_server_api/FileServerApi';
import { OpenGroupUtils } from '../session/apis/open_group_api/utils';
import { GetNetworkTime } from '../session/apis/snode_api/getNetworkTime';
import { getConversationController } from '../session/conversations';
import { getSodiumRenderer } from '../session/crypto';
import { getDecryptedMediaUrl } from '../session/crypto/DecryptedAttachmentsManager';
@ -379,19 +378,15 @@ export async function setDisappearingMessagesByConvoId(
return;
}
const providedChangeTimestamp = GetNetworkTime.getNowWithNetworkOffset();
if (!expirationMode || expirationMode === 'off' || !seconds || seconds <= 0) {
await conversation.updateExpireTimer({
providedDisappearingMode: 'off',
providedExpireTimer: 0,
providedChangeTimestamp,
});
} else {
await conversation.updateExpireTimer({
providedDisappearingMode: expirationMode,
providedExpireTimer: seconds,
providedChangeTimestamp,
});
}
}

@ -329,10 +329,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
toRet.expirationMode = this.getExpirationMode();
}
if (this.getLastDisappearingMessageChangeTimestamp()) {
toRet.lastDisappearingMessageChangeTimestamp = this.getLastDisappearingMessageChangeTimestamp();
}
if (this.getHasOutdatedClient()) {
toRet.hasOutdatedClient = this.getHasOutdatedClient();
}
@ -538,14 +534,20 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
if (!sentAt) {
throw new Error('sendReactMessageJob() sent_at must be set.');
}
// an OpenGroupV2 message is just a visible message
const expireTimer = this.getExpireTimer();
const expirationType = DisappearingMessages.changeToDisappearingMessageType(
this,
expireTimer,
this.getExpirationMode()
);
const chatMessageParams: VisibleMessageParams = {
body: '',
// we need to use a new timestamp here, otherwise android&iOS will consider this message as a duplicate and drop the synced reaction
timestamp: GetNetworkTime.getNowWithNetworkOffset(),
reaction,
lokiProfile: UserUtils.getOurProfile(),
expirationType,
expireTimer,
};
const shouldApprove = !this.isApproved() && this.isPrivate();
@ -576,6 +578,10 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
}
if (this.isOpenGroupV2()) {
// communities have no expiration timer support, so enforce it here.
chatMessageParams.expirationType = null;
chatMessageParams.expireTimer = null;
const chatMessageOpenGroupV2 = new OpenGroupVisibleMessage(chatMessageParams);
const roomInfos = this.toOpenGroupV2();
if (!roomInfos) {
@ -812,7 +818,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
public async updateExpireTimer({
providedDisappearingMode,
providedExpireTimer,
providedChangeTimestamp,
providedSource,
receivedAt, // is set if it comes from outside
fromSync = false, // if the update comes from a config or sync message
@ -822,7 +827,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
}: {
providedDisappearingMode?: DisappearingMessageConversationModeType;
providedExpireTimer?: number;
providedChangeTimestamp: number;
providedSource?: string;
receivedAt?: number; // is set if it comes from outside
fromSync?: boolean;
@ -836,7 +840,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
}
let expirationMode = providedDisappearingMode;
let expireTimer = providedExpireTimer;
const lastDisappearingMessageChangeTimestamp = providedChangeTimestamp;
const source = providedSource || UserUtils.getOurPubKeyStrFromCache();
if (expirationMode === undefined || expireTimer === undefined) {
@ -844,18 +847,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
expireTimer = 0;
}
if (
this.getLastDisappearingMessageChangeTimestamp() &&
lastDisappearingMessageChangeTimestamp &&
this.getLastDisappearingMessageChangeTimestamp() > lastDisappearingMessageChangeTimestamp
) {
window.log.debug(
'[updateExpireTimer] This is an outdated disappearing message setting',
`fromSync:${fromSync} ${existingMessage ? ` messageId: ${existingMessage.get('id')}` : ''}`
);
return false;
}
const previousExpirationMode = this.getExpirationMode();
const previousExpirationTimer = this.getExpireTimer();
@ -891,7 +882,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
this.set({
expirationMode,
expireTimer,
lastDisappearingMessageChangeTimestamp,
});
let message: MessageModel | undefined = existingMessage || undefined;
@ -906,7 +896,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
expirationTimerUpdate: {
expirationType,
expireTimer,
lastDisappearingMessageChangeTimestamp,
source,
fromSync,
},
@ -979,7 +968,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
timestamp,
expirationType,
expireTimer,
lastDisappearingMessageChangeTimestamp,
};
if (this.isMe()) {
@ -1832,7 +1820,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
attachments,
expirationType: message.getExpirationType() ?? 'unknown',
expireTimer: message.getExpireTimer(),
lastDisappearingMessageChangeTimestamp: this.getLastDisappearingMessageChangeTimestamp(),
preview: preview ? [preview] : [],
quote,
lokiProfile: UserUtils.getOurProfile(),
@ -1935,8 +1922,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
chatMessage: chatMessageMediumGroup,
groupId: destinationPubkey,
timestamp: sentAt,
expirationType: chatMessageParams.expirationType,
expireTimer: chatMessageParams.expireTimer,
// expirationType & expireTimer are part of the chatMessageMediumGroup object
});
// we need the return await so that errors are caught in the catch {}
@ -2382,10 +2368,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
return this.get('hasOutdatedClient');
}
public getLastDisappearingMessageChangeTimestamp() {
return this.get('lastDisappearingMessageChangeTimestamp');
}
// #endregion
}

@ -108,8 +108,6 @@ export interface ConversationAttributes {
/** disappearing messages setting for this conversation */
expirationMode: DisappearingMessageConversationModeType;
/** to avoid applying a change of disappear change when our current one was applied more recently */
lastDisappearingMessageChangeTimestamp: number;
// TODO legacy messages support will be removed in a future release
// TODO we need to make a migration to remove this value from the db since the implementation is hacky
/** to warn the user that the person he is talking to is using an old client which might cause issues */
@ -133,7 +131,6 @@ export const fillConvoAttributesWithDefaults = (
lastJoinedTimestamp: 0,
expirationMode: 'off',
expireTimer: 0,
lastDisappearingMessageChangeTimestamp: 0,
active_at: 0,

@ -47,7 +47,10 @@ import { SnodeNamespaces } from '../session/apis/snode_api/namespaces';
import { DURATION } from '../session/constants';
import { DisappearingMessages } from '../session/disappearing_messages';
import { TimerOptions } from '../session/disappearing_messages/timerOptions';
import { OpenGroupVisibleMessage } from '../session/messages/outgoing/visibleMessage/OpenGroupVisibleMessage';
import {
OpenGroupVisibleMessage,
OpenGroupVisibleMessageParams,
} from '../session/messages/outgoing/visibleMessage/OpenGroupVisibleMessage';
import {
VisibleMessage,
VisibleMessageParams,
@ -845,7 +848,7 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
const { body, attachments, preview, quote, fileIdsToLink } = await this.uploadData();
if (conversation.isPublic()) {
const openGroupParams: VisibleMessageParams = {
const openGroupParams: OpenGroupVisibleMessageParams = {
identifier: this.id,
timestamp: GetNetworkTime.getNowWithNetworkOffset(),
lokiProfile: UserUtils.getOurProfile(),
@ -871,17 +874,23 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
}
const timestamp = Date.now(); // force a new timestamp to handle user fixed his clock;
const expireTimer = conversation.getExpireTimer();
const expirationType = DisappearingMessages.changeToDisappearingMessageType(
conversation,
expireTimer,
conversation.getExpirationMode()
);
const chatParams = {
const chatParams: VisibleMessageParams = {
identifier: this.id,
body,
timestamp,
expireTimer: this.getExpireTimer(),
attachments,
preview: preview ? [preview] : [],
reacts: this.get('reacts'),
quote,
lokiProfile: UserUtils.getOurProfile(),
expirationType,
expireTimer,
};
if (!chatParams.lokiProfile) {
delete chatParams.lokiProfile;

@ -1,9 +1,9 @@
import { difference, isNumber, omit, pick } from 'lodash';
import * as BetterSqlite3 from '@signalapp/better-sqlite3';
import { difference, isNumber, omit, pick } from 'lodash';
import {
CONVERSATION_PRIORITIES,
ConversationAttributes,
ConversationAttributesWithNotSavedOnes,
CONVERSATION_PRIORITIES,
} from '../models/conversationAttributes';
export const CONVERSATIONS_TABLE = 'conversations';
@ -75,7 +75,6 @@ const allowedKeysFormatRowOfConversation = [
'blocksSogsMsgReqsTimestamp',
'priority',
'expirationMode',
'lastDisappearingMessageChangeTimestamp',
'hasOutdatedClient',
];
@ -200,7 +199,6 @@ const allowedKeysOfConversationAttributes = [
'blocksSogsMsgReqsTimestamp',
'priority',
'expirationMode',
'lastDisappearingMessageChangeTimestamp',
'hasOutdatedClient',
];

@ -1673,10 +1673,6 @@ function updateToSessionSchemaVersion34(currentVersion: number, db: BetterSqlite
`ALTER TABLE ${CONVERSATIONS_TABLE} ADD COLUMN expirationMode TEXT DEFAULT "off";`
).run();
db.prepare(
`ALTER TABLE ${CONVERSATIONS_TABLE} ADD COLUMN lastDisappearingMessageChangeTimestamp INTEGER DEFAULT 0;`
).run();
db.prepare(`ALTER TABLE ${CONVERSATIONS_TABLE} ADD COLUMN hasOutdatedClient TEXT;`).run();
// Message changes

@ -428,7 +428,6 @@ function saveConversation(data: ConversationAttributes): SaveConversationReturn
left,
expirationMode,
expireTimer,
lastDisappearingMessageChangeTimestamp,
hasOutdatedClient,
lastMessageStatus,
lastMessage,
@ -480,7 +479,6 @@ function saveConversation(data: ConversationAttributes): SaveConversationReturn
left: toSqliteBoolean(left),
expirationMode,
expireTimer,
lastDisappearingMessageChangeTimestamp,
hasOutdatedClient,
lastMessageStatus,
lastMessage: shortenedLastMessage,

@ -325,7 +325,6 @@ export async function handleNewClosedGroup(
? 'deleteAfterSend'
: 'legacy',
providedExpireTimer: expireTimer,
providedChangeTimestamp: GetNetworkTime.getNowWithNetworkOffset(),
providedSource: sender,
receivedAt: GetNetworkTime.getNowWithNetworkOffset(),
fromSync: fromLegacyConfig,
@ -933,6 +932,8 @@ async function sendLatestKeyPairToUsers(
groupId: groupPubKey,
timestamp: Date.now(),
encryptedKeyPairs: wrappers,
expirationType: null,
expireTimer: null,
});
// the encryption keypair is sent using established channels

@ -242,7 +242,6 @@ async function handleUserProfileUpdate(result: IncomingConfResult): Promise<Inco
: 'legacy'
: 'off',
providedExpireTimer: wrapperNoteToSelfExpirySeconds,
providedChangeTimestamp: result.latestEnvelopeTimestamp,
providedSource: ourConvo.id,
receivedAt: result.latestEnvelopeTimestamp,
fromSync: true,
@ -388,7 +387,6 @@ async function handleContactsUpdate(result: IncomingConfResult): Promise<Incomin
const success = await contactConvo.updateExpireTimer({
providedDisappearingMode: wrapperConvo.expirationMode,
providedExpireTimer: wrapperConvo.expirationTimerSeconds,
providedChangeTimestamp: result.latestEnvelopeTimestamp,
providedSource: wrapperConvo.id,
receivedAt: result.latestEnvelopeTimestamp,
fromSync: true,
@ -621,7 +619,6 @@ async function handleLegacyGroupUpdate(latestEnvelopeTimestamp: number) {
: 'legacy'
: 'off',
providedExpireTimer: fromWrapper.disappearingTimerSeconds,
providedChangeTimestamp: latestEnvelopeTimestamp,
providedSource: legacyGroupConvo.id,
receivedAt: latestEnvelopeTimestamp,
fromSync: true,

@ -475,11 +475,6 @@ export async function innerHandleSwarmContentMessage(
conversationModelForUIUpdate
);
if (expireUpdate?.isOutdated) {
await removeFromCache(envelope);
return;
}
// TODO legacy messages support will be removed in a future release
if (expireUpdate?.isDisappearingMessagesV2Released) {
await DisappearingMessages.checkHasOutdatedDisappearingMessageClient(

@ -439,23 +439,10 @@ export async function handleMessageJob(
expirationTimerUpdate?.expirationType,
expireTimerUpdate
);
const lastDisappearingMessageChangeTimestamp =
expirationTimerUpdate?.lastDisappearingMessageChangeTimestamp;
if (!lastDisappearingMessageChangeTimestamp) {
window.log.debug(
`The ExpirationTimerUpdate's lastDisappearingMessageChangeTimestamp is missing. message model: ${messageModel.get(
'id'
)}\nexpirationTimerUpdate: ${JSON.stringify(expirationTimerUpdate)}`
);
confirm?.();
return;
}
await conversation.updateExpireTimer({
providedDisappearingMode: expirationModeUpdate,
providedExpireTimer: expireTimerUpdate,
providedChangeTimestamp: lastDisappearingMessageChangeTimestamp,
providedSource: source,
fromSync: source === UserUtils.getOurPubKeyStrFromCache(),
receivedAt: messageModel.get('received_at'),

@ -15,24 +15,24 @@ import { getOpenGroupManager } from '../apis/open_group_api/opengroupV2/OpenGrou
import { getSwarmFor } from '../apis/snode_api/snodePool';
import { PubKey } from '../types';
import { getMessageQueue } from '..';
import { deleteAllMessagesByConvoIdNoConfirmation } from '../../interactions/conversationInteractions';
import { CONVERSATION_PRIORITIES, ConversationTypeEnum } from '../../models/conversationAttributes';
import { removeAllClosedGroupEncryptionKeyPairs } from '../../receiver/closedGroups';
import { getCurrentlySelectedConversationOutsideRedux } from '../../state/selectors/conversations';
import { assertUnreachable } from '../../types/sqlSharedTypes';
import { UserGroupsWrapperActions } from '../../webworker/workers/browser/libsession_worker_interface';
import { OpenGroupUtils } from '../apis/open_group_api/utils';
import { getSwarmPollingInstance } from '../apis/snode_api';
import { GetNetworkTime } from '../apis/snode_api/getNetworkTime';
import { SnodeNamespaces } from '../apis/snode_api/namespaces';
import { ClosedGroupMemberLeftMessage } from '../messages/outgoing/controlMessage/group/ClosedGroupMemberLeftMessage';
import { UserUtils } from '../utils';
import { ConfigurationSync } from '../utils/job_runners/jobs/ConfigurationSyncJob';
import { LibSessionUtil } from '../utils/libsession/libsession_utils';
import { SessionUtilContact } from '../utils/libsession/libsession_utils_contacts';
import { SessionUtilConvoInfoVolatile } from '../utils/libsession/libsession_utils_convo_info_volatile';
import { SessionUtilUserGroups } from '../utils/libsession/libsession_utils_user_groups';
import { GetNetworkTime } from '../apis/snode_api/getNetworkTime';
import { getMessageQueue } from '..';
import { getSwarmPollingInstance } from '../apis/snode_api';
import { SnodeNamespaces } from '../apis/snode_api/namespaces';
import { ClosedGroupMemberLeftMessage } from '../messages/outgoing/controlMessage/group/ClosedGroupMemberLeftMessage';
import { UserUtils } from '../utils';
import { getCurrentlySelectedConversationOutsideRedux } from '../../state/selectors/conversations';
import { removeAllClosedGroupEncryptionKeyPairs } from '../../receiver/closedGroups';
import { OpenGroupUtils } from '../apis/open_group_api/utils';
let instance: ConversationController | null;
@ -496,6 +496,8 @@ async function leaveClosedGroup(groupId: string, fromSyncMessage: boolean) {
const ourLeavingMessage = new ClosedGroupMemberLeftMessage({
timestamp: networkTimestamp,
groupId,
expirationType: null,
expireTimer: null,
});
window?.log?.info(`We are leaving the group ${groupId}. Sending our leaving message.`);

@ -280,7 +280,7 @@ function changeToDisappearingConversationMode(
async function checkForExpireUpdateInContentMessage(
content: SignalService.Content,
convoToUpdate: ConversationModel,
isOutgoing?: boolean
_isOutgoing?: boolean
): 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
@ -295,9 +295,7 @@ async function checkForExpireUpdateInContentMessage(
dataMessage.flags === SignalService.DataMessage.Flags.EXPIRATION_TIMER_UPDATE;
const isLegacyConversationSettingMessage = isDisappearingMessagesV2Released
? (isLegacyDataMessage ||
(couldBeLegacyContentMessage && !content.lastDisappearingMessageChangeTimestamp)) &&
hasExpirationUpdateFlags
? (isLegacyDataMessage || couldBeLegacyContentMessage) && hasExpirationUpdateFlags
: couldBeLegacyContentMessage && hasExpirationUpdateFlags;
const expirationTimer = isLegacyDataMessage
@ -311,46 +309,6 @@ async function checkForExpireUpdateInContentMessage(
expirationTimer
);
const lastDisappearingMessageChangeTimestamp = content.lastDisappearingMessageChangeTimestamp
? Number(content.lastDisappearingMessageChangeTimestamp)
: undefined;
// NOTE if we are checking an outgoing content message then the conversation's lastDisappearingMessageChangeTimestamp has just been set to match the content message so it can't be outdated if equal
if (
(lastDisappearingMessageChangeTimestamp &&
convoToUpdate.getLastDisappearingMessageChangeTimestamp() &&
convoToUpdate.getLastDisappearingMessageChangeTimestamp() >
lastDisappearingMessageChangeTimestamp) ||
(hasExpirationUpdateFlags &&
convoToUpdate.getLastDisappearingMessageChangeTimestamp() ===
lastDisappearingMessageChangeTimestamp)
) {
// Note: when we receive incoming messages, they will all have the same lastDisappearingMessageChangeTimestamp corresponding to when the latest change was made.
// Those incoming messages are *not* outdated, but a change asking for the same change would be outdated.
window.log.debug(
`[checkForExpireUpdateInContentMessage] This is an outdated ${
isOutgoing ? 'outgoing' : 'incoming'
} disappearing message setting for ${convoToUpdate.get(
'id'
)}. So we will ignore it. Current lastDisappearingMessageChangeTimestamp: ${convoToUpdate.get(
'lastDisappearingMessageChangeTimestamp'
)} New lastDisappearingMessageChangeTimestamp: ${lastDisappearingMessageChangeTimestamp}\n\ncontent: ${JSON.stringify(
content
)}`
);
return {
expirationType: changeToDisappearingMessageType(
convoToUpdate,
expirationTimer,
expirationMode
),
expirationTimer,
isOutdated: true,
};
}
const shouldDisappearButIsntMessage = checkShouldDisappearButIsntMessage(
content,
convoToUpdate,
@ -361,7 +319,6 @@ async function checkForExpireUpdateInContentMessage(
const expireUpdate: DisappearingMessageUpdate = {
expirationType: changeToDisappearingMessageType(convoToUpdate, expirationTimer, expirationMode),
expirationTimer,
lastDisappearingMessageChangeTimestamp,
isLegacyConversationSettingMessage,
isLegacyDataMessage,
isDisappearingMessagesV2Released,
@ -470,9 +427,7 @@ function getMessageReadyToDisappear(
const {
expirationType,
expirationTimer: expireTimer,
lastDisappearingMessageChangeTimestamp,
isLegacyConversationSettingMessage,
isDisappearingMessagesV2Released,
} = expireUpdate;
messageModel.set({
@ -482,7 +437,7 @@ function getMessageReadyToDisappear(
// This message is an ExpirationTimerUpdate
if (
(lastDisappearingMessageChangeTimestamp || isLegacyConversationSettingMessage) &&
isLegacyConversationSettingMessage &&
messageFlags === SignalService.DataMessage.Flags.EXPIRATION_TIMER_UPDATE
) {
const previousExpirationMode = conversationModel.getExpirationMode();
@ -503,11 +458,6 @@ function getMessageReadyToDisappear(
const expirationTimerUpdate = {
expirationType,
expireTimer,
lastDisappearingMessageChangeTimestamp: isLegacyConversationSettingMessage
? isDisappearingMessagesV2Released
? 0
: GetNetworkTime.getNowWithNetworkOffset()
: Number(lastDisappearingMessageChangeTimestamp),
source: messageModel.get('source'),
};

@ -1,6 +1,6 @@
// NOTE this must match Content.ExpirationType in the protobuf
export const DisappearingMessageMode = ['unknown', 'deleteAfterRead', 'deleteAfterSend'] as const;
export type DisappearingMessageType = typeof DisappearingMessageMode[number];
export const DisappearingMessageMode = ['unknown', 'deleteAfterRead', 'deleteAfterSend'] as const;
export type DisappearAfterSendOnly = Exclude<DisappearingMessageType, 'deleteAfterRead'>;
// TODO NOTE legacy is strictly used in the UI and is not a valid disappearing message mode
@ -14,12 +14,11 @@ export const DisappearingMessageConversationModes = [
export type DisappearingMessageConversationModeType = typeof DisappearingMessageConversationModes[number];
// TODO legacy messages support will be removed in a future release
// expirationType and lastDisappearingMessageChangeTimestamp will no longer have an undefined option
// expirationType will no longer have an undefined option
/** Used for setting disappearing messages in conversations */
export type ExpirationTimerUpdate = {
expirationType: DisappearingMessageType | undefined;
expireTimer: number;
lastDisappearingMessageChangeTimestamp: number | undefined;
source: string;
/** updated setting from another device */
fromSync?: boolean;
@ -29,11 +28,9 @@ export type DisappearingMessageUpdate = {
expirationType: DisappearingMessageType;
expirationTimer: number;
// This is used for the expirationTimerUpdate
lastDisappearingMessageChangeTimestamp?: number;
// TODO legacy messages support will be removed in a future release
isLegacyConversationSettingMessage?: boolean;
isLegacyDataMessage?: boolean;
isDisappearingMessagesV2Released?: boolean;
shouldDisappearButIsntMessage?: boolean;
isOutdated?: boolean;
};

@ -285,6 +285,8 @@ async function sendNewName(convo: ConversationModel, name: string, messageId: st
groupId,
identifier: messageId,
name,
expirationType: null,
expireTimer: null,
});
await getMessageQueue().sendToGroup({
message: nameChangeMessage,
@ -321,6 +323,8 @@ async function sendAddedMembers(
groupId,
addedMembers,
identifier: messageId,
expirationType: null,
expireTimer: null,
});
await getMessageQueue().sendToGroup({
message: closedGroupControlMessage,
@ -384,6 +388,8 @@ export async function sendRemovedMembers(
groupId,
removedMembers,
identifier: messageId,
expirationType: null,
expireTimer: null,
});
// Send the group update, and only once sent, generate and distribute a new encryption key pair if needed
await getMessageQueue().sendToGroup({
@ -446,7 +452,6 @@ async function generateAndSendNewEncryptionKeyPair(
encryptedKeyPairs: wrappers,
expirationType: null,
expireTimer: null,
lastDisappearingMessageChangeTimestamp: null,
});
distributingClosedGroupEncryptionKeyPairs.set(toHex(groupId), newKeyPair);

@ -7,14 +7,12 @@ import { MessageParams } from './Message';
export interface ExpirableMessageParams extends MessageParams {
expirationType: DisappearingMessageType | null;
expireTimer: number | null;
lastDisappearingMessageChangeTimestamp: number | null;
}
export class ExpirableMessage extends ContentMessage {
public readonly expirationType: DisappearingMessageType | null;
/** in seconds, 0 means no expiration */
public readonly expireTimer: number | null;
public readonly lastDisappearingMessageChangeTimestamp: number | null;
constructor(params: ExpirableMessageParams) {
super({
@ -23,7 +21,6 @@ export class ExpirableMessage extends ContentMessage {
});
this.expirationType = params.expirationType;
this.expireTimer = params.expireTimer;
this.lastDisappearingMessageChangeTimestamp = params.lastDisappearingMessageChangeTimestamp;
}
public contentProto(): SignalService.Content {
@ -38,7 +35,6 @@ export class ExpirableMessage extends ContentMessage {
? SignalService.Content.ExpirationType.UNKNOWN
: undefined,
expirationTimer: this.expireTimer && this.expireTimer > -1 ? this.expireTimer : undefined,
lastDisappearingMessageChangeTimestamp: this.lastDisappearingMessageChangeTimestamp,
});
}

@ -22,7 +22,6 @@ export class ExpirationTimerUpdateMessage extends DataMessage {
identifier: params.identifier,
expirationType: params.expirationType,
expireTimer: params.expireTimer,
lastDisappearingMessageChangeTimestamp: params.lastDisappearingMessageChangeTimestamp,
});
const { groupId } = params;
@ -34,7 +33,6 @@ export class ExpirationTimerUpdateMessage extends DataMessage {
return new SignalService.Content({
...super.contentProto(),
dataMessage: this.dataProto(),
lastDisappearingMessageChangeTimestamp: this.lastDisappearingMessageChangeTimestamp,
});
}

@ -15,7 +15,6 @@ export abstract class ClosedGroupMessage extends ExpirableMessage {
identifier: params.identifier,
expirationType: params.expirationType,
expireTimer: params.expireTimer,
lastDisappearingMessageChangeTimestamp: params.lastDisappearingMessageChangeTimestamp,
});
this.groupId = PubKey.cast(params.groupId);

@ -22,7 +22,6 @@ export class ClosedGroupNewMessage extends ClosedGroupMessage {
timestamp: params.timestamp,
identifier: params.identifier,
groupId: params.groupId,
lastDisappearingMessageChangeTimestamp: params.lastDisappearingMessageChangeTimestamp,
expirationType: params.expirationType,
expireTimer: params.expireTimer,
});

@ -14,7 +14,6 @@ export class ClosedGroupRemovedMembersMessage extends ClosedGroupMessage {
timestamp: params.timestamp,
identifier: params.identifier,
groupId: params.groupId,
lastDisappearingMessageChangeTimestamp: params.lastDisappearingMessageChangeTimestamp,
expirationType: params.expirationType,
expireTimer: params.expireTimer,
});

@ -8,10 +8,7 @@ import {
import { VisibleMessage } from './VisibleMessage';
interface ClosedGroupVisibleMessageParams
extends Omit<
ClosedGroupMessageParams,
'expireTimer' | 'expirationType' | 'lastDisappearingMessageChangeTimestamp'
> {
extends Omit<ClosedGroupMessageParams, 'expireTimer' | 'expirationType'> {
groupId: PubKey;
chatMessage: VisibleMessage;
}
@ -26,8 +23,6 @@ export class ClosedGroupVisibleMessage extends ClosedGroupMessage {
groupId: params.groupId,
expirationType: params.chatMessage.expirationType,
expireTimer: params.chatMessage.expireTimer,
lastDisappearingMessageChangeTimestamp:
params.chatMessage.lastDisappearingMessageChangeTimestamp ?? null,
});
this.chatMessage = params.chatMessage;

@ -16,7 +16,6 @@ export class GroupInvitationMessage extends VisibleMessage {
identifier: params.identifier,
expirationType: params.expirationType,
expireTimer: params.expireTimer,
lastDisappearingMessageChangeTimestamp: params.lastDisappearingMessageChangeTimestamp,
});
this.url = params.url;
this.name = params.name;

@ -6,7 +6,7 @@ import { VisibleMessage, VisibleMessageParams } from './VisibleMessage';
// eslint-disable-next-line @typescript-eslint/ban-types
export type OpenGroupVisibleMessageParams = Omit<
VisibleMessageParams,
'expirationType' | 'expireTimer' | 'lastDisappearingMessageChangeTimestamp'
'expirationType' | 'expireTimer'
>;
export class OpenGroupVisibleMessage extends VisibleMessage {
@ -15,7 +15,6 @@ export class OpenGroupVisibleMessage extends VisibleMessage {
constructor(params: OpenGroupVisibleMessageParams) {
super({
...params,
lastDisappearingMessageChangeTimestamp: null,
expirationType: null,
expireTimer: null,
});

@ -91,7 +91,6 @@ export class VisibleMessage extends ExpirableMessage {
identifier: params.identifier,
expirationType: params.expirationType,
expireTimer: params.expireTimer,
lastDisappearingMessageChangeTimestamp: params.lastDisappearingMessageChangeTimestamp,
});
this.attachments = params.attachments;
this.body = params.body;

@ -333,7 +333,6 @@ const buildSyncVisibleMessage = (
syncTarget,
expireTimer: expireUpdate?.expirationTimer || dataMessageExpireTimer,
expirationType: expireUpdate?.expirationType || null,
lastDisappearingMessageChangeTimestamp: null,
});
};
@ -343,18 +342,13 @@ const buildSyncExpireTimerMessage = (
timestamp: number,
syncTarget: string
) => {
const {
expirationType,
expirationTimer: expireTimer,
lastDisappearingMessageChangeTimestamp,
} = expireUpdate;
const { expirationType, expirationTimer: expireTimer } = expireUpdate;
return new ExpirationTimerUpdateMessage({
identifier,
timestamp,
expirationType,
expireTimer,
lastDisappearingMessageChangeTimestamp: lastDisappearingMessageChangeTimestamp ?? null,
syncTarget,
});
};
@ -391,13 +385,8 @@ export const buildSyncMessage = (
if (
dataMessage.flags === SignalService.DataMessage.Flags.EXPIRATION_TIMER_UPDATE &&
!isEmpty(expireUpdate) &&
expireUpdate.lastDisappearingMessageChangeTimestamp
!isEmpty(expireUpdate)
) {
if (expireUpdate.isOutdated) {
return null;
}
const expireTimerSyncMessage = buildSyncExpireTimerMessage(
identifier,
expireUpdate,

@ -249,7 +249,6 @@ export interface ReduxConversationType {
mentionedUs?: boolean;
expirationMode?: DisappearingMessageConversationModeType;
expireTimer?: number;
lastDisappearingMessageChangeTimestamp?: number;
hasOutdatedClient?: string;
isTyping?: boolean;
isBlocked?: boolean;

@ -354,16 +354,12 @@ describe('DisappearingMessage', () => {
expect(expireUpdate?.expirationType, 'expirationType should be unknown').to.equal('unknown');
expect(expireUpdate?.expirationTimer, 'expirationTimer should be 0').to.equal(0);
expect(
expireUpdate?.lastDisappearingMessageChangeTimestamp,
'lastDisappearingMessageChangeTimestamp should be 0'
).to.equal(0);
expect(
expireUpdate?.isLegacyConversationSettingMessage,
'isLegacyConversationSettingMessage should be false'
).to.be.false;
expect(expireUpdate?.isLegacyDataMessage, 'isLegacyDataMessage should be false').to.be.false;
expect(expireUpdate?.isOutdated, 'isOutdated should be undefined').to.be.undefined;
});
it('if we receive a deleteAfterRead message after 1 minute then it returns those values', async () => {
const disappearingMessage = generateDisappearingVisibleMessage({
@ -387,26 +383,20 @@ describe('DisappearingMessage', () => {
'deleteAfterRead'
);
expect(expireUpdate?.expirationTimer, 'expirationTimer should be 60').to.equal(60);
expect(
expireUpdate?.lastDisappearingMessageChangeTimestamp,
'lastDisappearingMessageChangeTimestamp should be 0'
).to.equal(0);
expect(
expireUpdate?.isLegacyConversationSettingMessage,
'isLegacyConversationSettingMessage should be false'
).to.be.false;
expect(expireUpdate?.isLegacyDataMessage, 'isLegacyDataMessage should be false').to.be.false;
expect(expireUpdate?.isOutdated, 'isOutdated should be undefined').to.be.undefined;
});
it('if we receive an ExpirationTimerUpdate message for deleteAfterSend after 5 minutes then it returns those values', async () => {
const lastDisappearingMessageChangeTimestamp = GetNetworkTime.getNowWithNetworkOffset();
const expirationTimerUpdateMessage = generateDisappearingVisibleMessage({
expirationType: 'deleteAfterSend',
expireTimer: 300,
expirationTimerUpdate: {
expirationType: 'deleteAfterSend',
expireTimer: 300,
lastDisappearingMessageChangeTimestamp,
source: testPubkey,
},
});
@ -427,33 +417,26 @@ describe('DisappearingMessage', () => {
'deleteAfterSend'
);
expect(expireUpdate?.expirationTimer, 'expirationTimer should be 300').to.equal(300);
expect(
expireUpdate?.lastDisappearingMessageChangeTimestamp,
'lastDisappearingMessageChangeTimestamp should match input value'
).to.equal(lastDisappearingMessageChangeTimestamp);
expect(
expireUpdate?.isLegacyConversationSettingMessage,
'isLegacyConversationSettingMessage should be false'
).to.be.false;
expect(expireUpdate?.isLegacyDataMessage, 'isLegacyDataMessage should be false').to.be.false;
expect(expireUpdate?.isOutdated, 'isOutdated should be undefined').to.be.undefined;
});
it('if we receive an outdated ExpirationTimerUpdate message then it should be ignored and is outdated', async () => {
const lastDisappearingMessageChangeTimestamp = GetNetworkTime.getNowWithNetworkOffset();
const expirationTimerUpdateMessage = generateDisappearingVisibleMessage({
expirationType: 'deleteAfterSend',
expireTimer: 300,
expirationTimerUpdate: {
expirationType: 'deleteAfterSend',
expireTimer: 300,
lastDisappearingMessageChangeTimestamp: lastDisappearingMessageChangeTimestamp - 20000,
source: testPubkey,
},
});
const convoToUpdate = new ConversationModel({
...conversationArgs,
lastDisappearingMessageChangeTimestamp,
});
// TODO legacy messages support will be removed in a future release
Sinon.stub(ReleasedFeatures, 'checkIsDisappearMessageV2FeatureReleased').resolves(true);
@ -468,17 +451,13 @@ describe('DisappearingMessage', () => {
'deleteAfterSend'
);
expect(expireUpdate?.expirationTimer, 'expirationTimer should be 300').to.equal(300);
expect(
expireUpdate?.lastDisappearingMessageChangeTimestamp,
'lastDisappearingMessageChangeTimestamp should be undefined'
).to.equal(undefined);
expect(
expireUpdate?.isLegacyConversationSettingMessage,
'isLegacyConversationSettingMessage should be undefined'
).to.be.undefined;
expect(expireUpdate?.isLegacyDataMessage, 'isLegacyDataMessage should be undefined').to.be
.undefined;
expect(expireUpdate?.isOutdated, 'isOutdated should be true').to.be.true;
});
});
@ -578,34 +557,13 @@ describe('DisappearingMessage', () => {
const updateSuccess = await conversation.updateExpireTimer({
providedDisappearingMode: 'deleteAfterSend',
providedExpireTimer: 600,
providedChangeTimestamp: GetNetworkTime.getNowWithNetworkOffset(),
fromSync: false, // if the update comes from a config or sync message
shouldCommitConvo: false,
existingMessage: undefined,
});
expect(updateSuccess, 'should be false').to.be.false;
});
it('if the lastDisappearingMessageChangeTimestamp is outdated we ignore it', async () => {
const lastDisappearingMessageChangeTimestamp = GetNetworkTime.getNowWithNetworkOffset();
const conversation = new ConversationModel({
...conversationArgs,
});
conversation.set({
expirationMode: 'deleteAfterRead',
expireTimer: 60,
lastDisappearingMessageChangeTimestamp: lastDisappearingMessageChangeTimestamp + 20000,
});
const updateSuccess = await conversation.updateExpireTimer({
providedDisappearingMode: 'deleteAfterSend',
providedExpireTimer: 600,
providedChangeTimestamp: lastDisappearingMessageChangeTimestamp,
fromSync: false,
shouldCommitConvo: false,
existingMessage: undefined,
});
expect(updateSuccess, 'should be false').to.be.false;
});
it('if we receive the same settings we ignore it', async () => {
const conversation = new ConversationModel({
...conversationArgs,
@ -618,7 +576,6 @@ describe('DisappearingMessage', () => {
const updateSuccess = await conversation.updateExpireTimer({
providedDisappearingMode: 'deleteAfterRead',
providedExpireTimer: 60,
providedChangeTimestamp: GetNetworkTime.getNowWithNetworkOffset(),
fromSync: false,
shouldCommitConvo: false,
existingMessage: undefined,
@ -626,7 +583,6 @@ describe('DisappearingMessage', () => {
expect(updateSuccess, 'should be false').to.be.false;
});
it("if an update is successful then the conversation should have it's settings updated", async () => {
const lastDisappearingMessageChangeTimestamp = GetNetworkTime.getNowWithNetworkOffset();
const conversation = new ConversationModel({
...conversationArgs,
});
@ -638,7 +594,6 @@ describe('DisappearingMessage', () => {
const updateSuccess = await conversation.updateExpireTimer({
providedDisappearingMode: 'deleteAfterSend',
providedExpireTimer: 600,
providedChangeTimestamp: lastDisappearingMessageChangeTimestamp,
providedSource: testPubkey,
receivedAt: GetNetworkTime.getNowWithNetworkOffset(),
fromSync: true,
@ -652,10 +607,6 @@ describe('DisappearingMessage', () => {
'expirationMode should be deleteAfterSend'
).to.equal('deleteAfterSend');
expect(conversation.getExpireTimer(), 'expireTimer should be 5 minutes').to.equal(600);
expect(
conversation.getLastDisappearingMessageChangeTimestamp(),
'lastDisappearingMessageChangeTimestamp should match the input value'
).to.equal(lastDisappearingMessageChangeTimestamp);
});
});
});
@ -666,7 +617,6 @@ describe('DisappearingMessage', () => {
const expirationTimerUpdateMessage = generateFakeExpirationTimerUpdate({
expirationType: 'deleteAfterSend',
expireTimer: 300,
lastDisappearingMessageChangeTimestamp: GetNetworkTime.getNowWithNetworkOffset(),
source: testPubkey,
});

@ -14,7 +14,6 @@ import {
const sharedNoExpire = {
expirationType: null,
expireTimer: null,
lastDisappearingMessageChangeTimestamp: null,
};
describe('VisibleMessage', () => {

@ -18,7 +18,6 @@ describe('GroupInvitationMessage', () => {
name,
expirationType: null,
expireTimer: null,
lastDisappearingMessageChangeTimestamp: null,
});
});

@ -20,15 +20,11 @@ describe('ClosedGroupVisibleMessage', () => {
body: 'body',
expirationType: null,
expireTimer: null,
lastDisappearingMessageChangeTimestamp: null,
});
const message = new ClosedGroupVisibleMessage({
groupId,
timestamp,
chatMessage,
expirationType: null,
expireTimer: null,
lastDisappearingMessageChangeTimestamp: null,
});
const plainText = message.plainTextBuffer();
const decoded = SignalService.Content.decode(plainText);
@ -56,15 +52,11 @@ describe('ClosedGroupVisibleMessage', () => {
timestamp,
expirationType: null,
expireTimer: null,
lastDisappearingMessageChangeTimestamp: null,
});
const message = new ClosedGroupVisibleMessage({
groupId,
timestamp,
chatMessage,
expirationType: null,
expireTimer: null,
lastDisappearingMessageChangeTimestamp: null,
});
expect(message.ttl()).to.equal(Constants.TTL_DEFAULT.CONTENT_MESSAGE);
});
@ -75,15 +67,11 @@ describe('ClosedGroupVisibleMessage', () => {
timestamp,
expirationType: null,
expireTimer: null,
lastDisappearingMessageChangeTimestamp: null,
});
const message = new ClosedGroupVisibleMessage({
groupId,
timestamp,
chatMessage,
expirationType: null,
expireTimer: null,
lastDisappearingMessageChangeTimestamp: null,
});
expect(message.identifier).to.not.equal(null, 'identifier cannot be null');
expect(message.identifier).to.not.equal(undefined, 'identifier cannot be undefined');
@ -97,16 +85,12 @@ describe('ClosedGroupVisibleMessage', () => {
identifier: 'chatMessage',
expirationType: null,
expireTimer: null,
lastDisappearingMessageChangeTimestamp: null,
});
const message = new ClosedGroupVisibleMessage({
groupId,
timestamp,
chatMessage,
identifier: 'closedGroupMessage',
expirationType: null,
expireTimer: null,
lastDisappearingMessageChangeTimestamp: null,
});
expect(message.identifier).to.be.equal('closedGroupMessage');
});
@ -119,15 +103,11 @@ describe('ClosedGroupVisibleMessage', () => {
identifier: 'chatMessage',
expirationType: null,
expireTimer: null,
lastDisappearingMessageChangeTimestamp: null,
});
const message = new ClosedGroupVisibleMessage({
groupId,
timestamp,
chatMessage,
expirationType: null,
expireTimer: null,
lastDisappearingMessageChangeTimestamp: null,
});
expect(message.identifier).to.be.equal('chatMessage');
});

@ -32,7 +32,6 @@ const { expect } = chai;
const sharedNoExpire = {
expireTimer: null,
expirationType: null,
lastDisappearingMessageChangeTimestamp: null,
};
describe('Message Utils', () => {

@ -35,7 +35,6 @@ export function generateVisibleMessage({
quote: undefined,
expirationType: null,
expireTimer: null,
lastDisappearingMessageChangeTimestamp: null,
lokiProfile: undefined,
preview: undefined,
});
@ -96,9 +95,6 @@ export function generateClosedGroupMessage(
groupId: groupId ? PubKey.cast(groupId) : generateFakePubKey(),
timestamp: timestamp || Date.now(),
chatMessage: generateVisibleMessage(),
expirationType: null,
expireTimer: null,
lastDisappearingMessageChangeTimestamp: null,
});
}
@ -159,8 +155,6 @@ export function generateDisappearingVisibleMessage({
timestamp: timestamp || Date.now(),
expirationType: expirationTimerUpdate.expirationType || null,
expireTimer: expirationTimerUpdate.expireTimer,
lastDisappearingMessageChangeTimestamp:
expirationTimerUpdate.lastDisappearingMessageChangeTimestamp || null,
});
}
@ -174,19 +168,16 @@ export function generateDisappearingVisibleMessage({
expireTimer: expireTimer ?? null,
lokiProfile: undefined,
preview: undefined,
lastDisappearingMessageChangeTimestamp: null,
});
}
export function generateFakeExpirationTimerUpdate({
expirationType,
expireTimer,
lastDisappearingMessageChangeTimestamp,
source = '',
}: {
expirationType: DisappearingMessageType;
expireTimer: number;
lastDisappearingMessageChangeTimestamp: number;
source?: string;
}): MessageModel {
const convoId = TestUtils.generateFakePubKeyStr();
@ -199,7 +190,6 @@ export function generateFakeExpirationTimerUpdate({
expirationTimerUpdate: {
expirationType,
expireTimer,
lastDisappearingMessageChangeTimestamp,
source,
},
flags: 2,

Loading…
Cancel
Save