diff --git a/protos/SignalService.proto b/protos/SignalService.proto index 8559240df..50947dbde 100644 --- a/protos/SignalService.proto +++ b/protos/SignalService.proto @@ -47,6 +47,7 @@ message MessageRequestResponse { message Content { enum ExpirationType { + LEGACY = 0; DELETE_AFTER_READ = 1; DELETE_AFTER_SEND = 2; } diff --git a/ts/receiver/contentMessage.ts b/ts/receiver/contentMessage.ts index 98394d161..93570a1e8 100644 --- a/ts/receiver/contentMessage.ts +++ b/ts/receiver/contentMessage.ts @@ -387,7 +387,7 @@ export async function innerHandleSwarmContentMessage( ConversationTypeEnum.PRIVATE ); - // We need to make sure that we trigger the banner ui on the correct model for the conversation and not the author (for closed groups) + // We need to make sure that we trigger the outdated client banner ui on the correct model for the conversation and not the author (for closed groups) let conversationModelForUIUpdate = senderConversationModel; /** @@ -416,13 +416,16 @@ export async function innerHandleSwarmContentMessage( 'Disappearing Messages V2' ); - const isLegacyConversationSettingMessage = Boolean( - !content.expirationTimer && - dataMessage.flags === SignalService.DataMessage.Flags.EXPIRATION_TIMER_UPDATE + const isLegacy = Boolean( + (!content.expirationType && !content.expirationTimer) || + content.expirationType === SignalService.Content.ExpirationType.LEGACY ); const isLegacyMessage = Boolean( - (!content.expirationTimer && dataMessage.expireTimer && dataMessage.expireTimer > -1) || - isLegacyConversationSettingMessage + isLegacy && dataMessage.expireTimer && dataMessage.expireTimer > -1 + ); + // NOTE When a legacy client sends a Conversation Setting Message dataMessage.expirationType and dataMessage.expireTimer can possibly be undefined. + const isLegacyConversationSettingMessage = Boolean( + isLegacy && dataMessage.flags === SignalService.DataMessage.Flags.EXPIRATION_TIMER_UPDATE ); const expireTimer = isDisappearingMessagesV2Released @@ -430,8 +433,9 @@ export async function innerHandleSwarmContentMessage( : isLegacyMessage ? Number(dataMessage.expireTimer) : 0; + // TODO legacy messages support will be removed in a future release const expirationType = isDisappearingMessagesV2Released - ? DisappearingMessageConversationSetting[content.expirationType] + ? DisappearingMessageConversationSetting[isLegacy ? 3 : content.expirationType] : isLegacyMessage && expireTimer > 0 ? DisappearingMessageConversationSetting[3] : 'off'; @@ -455,7 +459,7 @@ export async function innerHandleSwarmContentMessage( if (conversationModelForUIUpdate.get('hasOutdatedClient')) { // trigger notice banner - if (isLegacyMessage) { + if (isLegacyMessage || isLegacyConversationSettingMessage) { if (conversationModelForUIUpdate.get('hasOutdatedClient') !== outdatedSender) { conversationModelForUIUpdate.set({ hasOutdatedClient: outdatedSender, @@ -468,7 +472,7 @@ export async function innerHandleSwarmContentMessage( } conversationModelForUIUpdate.commit(); } else { - if (isLegacyMessage) { + if (isLegacyMessage || isLegacyConversationSettingMessage) { conversationModelForUIUpdate.set({ hasOutdatedClient: outdatedSender, }); diff --git a/ts/session/messages/outgoing/DataMessage.ts b/ts/session/messages/outgoing/DataMessage.ts index abfe20f07..c19a98d68 100644 --- a/ts/session/messages/outgoing/DataMessage.ts +++ b/ts/session/messages/outgoing/DataMessage.ts @@ -2,12 +2,14 @@ import { SignalService } from '../../../protobuf'; import { ExpirableMessage } from './ExpirableMessage'; export abstract class DataMessage extends ExpirableMessage { - public abstract dataProto(): SignalService.DataMessage; - public contentProto(): SignalService.Content { return new SignalService.Content({ ...super.contentProto(), dataMessage: this.dataProto(), }); } + + public dataProto(): SignalService.DataMessage { + return super.dataProto(); + } } diff --git a/ts/session/messages/outgoing/ExpirableMessage.ts b/ts/session/messages/outgoing/ExpirableMessage.ts index 51b6a1627..5325095f5 100644 --- a/ts/session/messages/outgoing/ExpirableMessage.ts +++ b/ts/session/messages/outgoing/ExpirableMessage.ts @@ -18,18 +18,20 @@ export class ExpirableMessage extends ContentMessage { timestamp: params.timestamp, identifier: params.identifier, }); - // TODO legacy messages support will be removed in a future release - this.expirationType = params.expirationType !== 'legacy' ? params.expirationType : undefined; + this.expirationType = params.expirationType; this.expireTimer = params.expireTimer; } public contentProto(): SignalService.Content { return new SignalService.Content({ + // TODO legacy messages support will be removed in a future release expirationType: this.expirationType === 'deleteAfterSend' ? SignalService.Content.ExpirationType.DELETE_AFTER_SEND : this.expirationType === 'deleteAfterRead' ? SignalService.Content.ExpirationType.DELETE_AFTER_READ + : this.expirationType === 'legacy' + ? SignalService.Content.ExpirationType.LEGACY : undefined, expirationTimer: this.expireTimer && this.expireTimer > -1 ? this.expireTimer : undefined, }); @@ -38,7 +40,10 @@ export class ExpirableMessage extends ContentMessage { public dataProto(): SignalService.DataMessage { return new SignalService.DataMessage({ // TODO legacy messages support will be removed in a future release - expireTimer: !this.expirationType && this.expireTimer ? this.expireTimer : undefined, + expireTimer: + (!this.expirationType || this.expirationType === 'legacy') && this.expireTimer + ? this.expireTimer + : undefined, }); } diff --git a/ts/session/messages/outgoing/controlMessage/ExpirationTimerUpdateMessage.ts b/ts/session/messages/outgoing/controlMessage/ExpirationTimerUpdateMessage.ts index 328743cc6..6c929c58d 100644 --- a/ts/session/messages/outgoing/controlMessage/ExpirationTimerUpdateMessage.ts +++ b/ts/session/messages/outgoing/controlMessage/ExpirationTimerUpdateMessage.ts @@ -42,7 +42,7 @@ export class ExpirationTimerUpdateMessage extends DataMessage { } public dataProto(): SignalService.DataMessage { - const data = new SignalService.DataMessage(); + const data = super.dataProto(); data.flags = SignalService.DataMessage.Flags.EXPIRATION_TIMER_UPDATE; diff --git a/ts/session/messages/outgoing/controlMessage/group/ClosedGroupMessage.ts b/ts/session/messages/outgoing/controlMessage/group/ClosedGroupMessage.ts index 3210b0afb..2c04bff31 100644 --- a/ts/session/messages/outgoing/controlMessage/group/ClosedGroupMessage.ts +++ b/ts/session/messages/outgoing/controlMessage/group/ClosedGroupMessage.ts @@ -31,16 +31,19 @@ export abstract class ClosedGroupMessage extends ExpirableMessage { return new SignalService.Content({ dataMessage: this.dataProto(), ...super.contentProto(), - // Closed Groups only support 'deleteAfterSend' + // TODO legacy messages support will be removed in a future release + // Closed Groups only support 'deleteAfterSend' and 'legacy' expirationType: this.expirationType === 'deleteAfterSend' ? SignalService.Content.ExpirationType.DELETE_AFTER_SEND + : !this.expirationType || this.expirationType === 'legacy' + ? SignalService.Content.ExpirationType.LEGACY : undefined, }); } public dataProto(): SignalService.DataMessage { - const dataMessage = new SignalService.DataMessage(); + const dataMessage = super.dataProto(); dataMessage.closedGroupControlMessage = new SignalService.DataMessage.ClosedGroupControlMessage(); diff --git a/ts/session/messages/outgoing/visibleMessage/VisibleMessage.ts b/ts/session/messages/outgoing/visibleMessage/VisibleMessage.ts index 0fd8d01bc..c513523e8 100644 --- a/ts/session/messages/outgoing/visibleMessage/VisibleMessage.ts +++ b/ts/session/messages/outgoing/visibleMessage/VisibleMessage.ts @@ -114,7 +114,7 @@ export class VisibleMessage extends ExpirableMessage { } public dataProto(): SignalService.DataMessage { - const dataMessage = new SignalService.DataMessage(); + const dataMessage = super.dataProto(); if (this.body) { dataMessage.body = this.body; diff --git a/ts/util/expiringMessages.ts b/ts/util/expiringMessages.ts index cf56b3835..f3d5def11 100644 --- a/ts/util/expiringMessages.ts +++ b/ts/util/expiringMessages.ts @@ -10,9 +10,11 @@ import { getConversationController } from '../session/conversations'; import { getNowWithNetworkOffset } from '../session/apis/snode_api/SNodeAPI'; // 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? export const DisappearingMessageMode = ['deleteAfterRead', 'deleteAfterSend']; export type DisappearingMessageType = typeof DisappearingMessageMode[number] | null; +// TODO legacy messages support will be removed in a future release export const DisappearingMessageConversationSetting = ['off', ...DisappearingMessageMode, 'legacy']; export type DisappearingMessageConversationType = typeof DisappearingMessageConversationSetting[number]; export const DEFAULT_TIMER_OPTION = {