Universal Disappearing Messages

This commit is contained in:
Fedor Indutny 2021-06-01 13:45:43 -07:00 committed by GitHub
parent c63871d71b
commit 19f8042cd3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
50 changed files with 1224 additions and 191 deletions

View file

@ -55,6 +55,7 @@ import { getConversationMembers } from '../util/getConversationMembers';
import { sendReadReceiptsFor } from '../util/sendReadReceiptsFor';
import { updateConversationsWithUuidLookup } from '../updateConversationsWithUuidLookup';
import { filter, map, take } from '../util/iterables';
import * as universalExpireTimer from '../util/universalExpireTimer';
/* eslint-disable more/no-then */
window.Whisper = window.Whisper || {};
@ -1069,10 +1070,15 @@ export class ConversationModel extends window.Backbone
);
}
// On successful fetch - mark contact as registered.
if (this.get('uuid')) {
this.setRegistered();
if (!this.get('uuid')) {
return;
}
// On successful fetch - mark contact as registered.
this.setRegistered();
// If we couldn't apply universal timer before - try it again.
this.queueJob(() => this.maybeSetPendingUniversalTimer());
}
isValid(): boolean {
@ -2749,6 +2755,85 @@ export class ConversationModel extends window.Backbone
}
}
async addUniversalTimerNotification(): Promise<string> {
const now = Date.now();
const message = ({
conversationId: this.id,
type: 'universal-timer-notification',
sent_at: now,
received_at: window.Signal.Util.incrementMessageCounter(),
received_at_ms: now,
unread: 0,
// TODO: DESKTOP-722
} as unknown) as typeof window.Whisper.MessageAttributesType;
const id = await window.Signal.Data.saveMessage(message, {
Message: window.Whisper.Message,
});
const model = window.MessageController.register(
id,
new window.Whisper.Message({
...message,
id,
})
);
this.trigger('newmessage', model);
return id;
}
async maybeSetPendingUniversalTimer(): Promise<void> {
if (!this.isPrivate()) {
return;
}
if (this.isSMSOnly()) {
return;
}
if (this.get('pendingUniversalTimer') || this.get('expireTimer')) {
return;
}
const activeAt = this.get('active_at');
if (activeAt) {
return;
}
const expireTimer = universalExpireTimer.get();
if (!expireTimer) {
return;
}
const notificationId = await this.addUniversalTimerNotification();
this.set('pendingUniversalTimer', notificationId);
}
async maybeApplyUniversalTimer(): Promise<void> {
const notificationId = this.get('pendingUniversalTimer');
if (!notificationId) {
return;
}
const message = window.MessageController.getById(notificationId);
if (message) {
message.cleanup();
}
if (this.get('expireTimer')) {
this.set('pendingUniversalTimer', undefined);
return;
}
const expireTimer = universalExpireTimer.get();
if (expireTimer) {
await this.updateExpirationTimer(expireTimer);
}
this.set('pendingUniversalTimer', undefined);
}
async onReadMessage(
message: MessageModel,
readAt?: number
@ -3243,7 +3328,6 @@ export class ConversationModel extends window.Backbone
): Promise<WhatIsThis> {
const timestamp = Date.now();
const outgoingReaction = { ...reaction, ...target };
const expireTimer = this.get('expireTimer');
const reactionModel = window.Whisper.Reactions.add({
...outgoingReaction,
@ -3269,6 +3353,10 @@ export class ConversationModel extends window.Backbone
timestamp
);
await this.maybeApplyUniversalTimer();
const expireTimer = this.get('expireTimer');
const attributes = ({
id: window.getGuid(),
type: 'outgoing',
@ -3447,12 +3535,15 @@ export class ConversationModel extends window.Backbone
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const destination = this.getSendTarget()!;
const expireTimer = this.get('expireTimer');
const recipients = this.getRecipients();
this.queueJob(async () => {
const now = Date.now();
await this.maybeApplyUniversalTimer();
const expireTimer = this.get('expireTimer');
window.log.info(
'Sending message to conversation',
this.idForLogging(),
@ -3655,6 +3746,8 @@ export class ConversationModel extends window.Backbone
return;
}
this.queueJob(() => this.maybeSetPendingUniversalTimer());
const ourConversationId = window.ConversationController.getOurConversationId();
if (!ourConversationId) {
throw new Error('updateLastMessage: Failed to fetch ourConversationId');
@ -3915,8 +4008,8 @@ export class ConversationModel extends window.Backbone
async updateExpirationTimer(
providedExpireTimer: number | undefined,
providedSource: unknown,
receivedAt: number,
providedSource?: unknown,
receivedAt?: number,
options: { fromSync?: unknown; fromGroupUpdate?: unknown } = {}
): Promise<boolean | null | MessageModel | void> {
if (this.isGroupV2()) {
@ -3964,6 +4057,11 @@ export class ConversationModel extends window.Backbone
const timestamp = (receivedAt || Date.now()) - 1;
this.set({ expireTimer });
// This call actually removes universal timer notification and clears
// the pending flags.
await this.maybeApplyUniversalTimer();
window.Signal.Data.updateConversation(this.attributes);
const model = new window.Whisper.Message(({
@ -4677,6 +4775,7 @@ export class ConversationModel extends window.Backbone
lastMessage: null,
timestamp: null,
active_at: null,
pendingUniversalTimer: undefined,
});
window.Signal.Data.updateConversation(this.attributes);