2023-01-03 19:55:46 +00:00
|
|
|
// Copyright 2019 Signal Messenger, LLC
|
2021-06-17 17:15:10 +00:00
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
|
|
|
/* eslint-disable max-classes-per-file */
|
|
|
|
|
|
|
|
import { Collection, Model } from 'backbone';
|
2021-10-26 19:15:33 +00:00
|
|
|
import type { MessageModel } from '../models/messages';
|
2021-09-17 18:27:53 +00:00
|
|
|
import * as log from '../logging/log';
|
2022-11-22 18:43:43 +00:00
|
|
|
import * as Errors from '../types/errors';
|
2023-08-10 16:43:33 +00:00
|
|
|
import type { AciString } from '../types/ServiceId';
|
2021-06-17 17:15:10 +00:00
|
|
|
|
2022-01-04 15:27:16 +00:00
|
|
|
export type ViewOnceOpenSyncAttributesType = {
|
2021-06-17 17:15:10 +00:00
|
|
|
source?: string;
|
2023-08-10 16:43:33 +00:00
|
|
|
sourceAci: AciString;
|
2021-06-17 17:15:10 +00:00
|
|
|
timestamp: number;
|
|
|
|
};
|
|
|
|
|
2021-07-22 17:07:53 +00:00
|
|
|
class ViewOnceOpenSyncModel extends Model<ViewOnceOpenSyncAttributesType> {}
|
2021-06-17 17:15:10 +00:00
|
|
|
|
2021-07-22 17:07:53 +00:00
|
|
|
let singleton: ViewOnceOpenSyncs | undefined;
|
2021-06-17 17:15:10 +00:00
|
|
|
|
2021-07-22 17:07:53 +00:00
|
|
|
export class ViewOnceOpenSyncs extends Collection<ViewOnceOpenSyncModel> {
|
|
|
|
static getSingleton(): ViewOnceOpenSyncs {
|
2021-06-17 17:15:10 +00:00
|
|
|
if (!singleton) {
|
2021-07-22 17:07:53 +00:00
|
|
|
singleton = new ViewOnceOpenSyncs();
|
2021-06-17 17:15:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return singleton;
|
|
|
|
}
|
|
|
|
|
2021-07-22 17:07:53 +00:00
|
|
|
forMessage(message: MessageModel): ViewOnceOpenSyncModel | null {
|
2023-08-16 20:54:39 +00:00
|
|
|
const syncBySourceAci = this.find(item => {
|
2021-06-17 17:15:10 +00:00
|
|
|
return (
|
2023-08-16 20:54:39 +00:00
|
|
|
item.get('sourceAci') === message.get('sourceServiceId') &&
|
2021-06-17 17:15:10 +00:00
|
|
|
item.get('timestamp') === message.get('sent_at')
|
|
|
|
);
|
|
|
|
});
|
2023-08-16 20:54:39 +00:00
|
|
|
if (syncBySourceAci) {
|
2021-09-17 18:27:53 +00:00
|
|
|
log.info('Found early view once open sync for message');
|
2023-08-16 20:54:39 +00:00
|
|
|
this.remove(syncBySourceAci);
|
|
|
|
return syncBySourceAci;
|
2021-06-17 17:15:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const syncBySource = this.find(item => {
|
|
|
|
return (
|
|
|
|
item.get('source') === message.get('source') &&
|
|
|
|
item.get('timestamp') === message.get('sent_at')
|
|
|
|
);
|
|
|
|
});
|
|
|
|
if (syncBySource) {
|
2021-09-17 18:27:53 +00:00
|
|
|
log.info('Found early view once open sync for message');
|
2021-06-17 17:15:10 +00:00
|
|
|
this.remove(syncBySource);
|
|
|
|
return syncBySource;
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2021-07-22 17:07:53 +00:00
|
|
|
async onSync(sync: ViewOnceOpenSyncModel): Promise<void> {
|
2021-06-17 17:15:10 +00:00
|
|
|
try {
|
|
|
|
const messages = await window.Signal.Data.getMessagesBySentAt(
|
2021-12-10 22:51:54 +00:00
|
|
|
sync.get('timestamp')
|
2021-06-17 17:15:10 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
const found = messages.find(item => {
|
2023-08-16 20:54:39 +00:00
|
|
|
const itemSourceAci = item.sourceServiceId;
|
2023-08-10 16:43:33 +00:00
|
|
|
const syncSourceAci = sync.get('sourceAci');
|
2021-12-10 22:51:54 +00:00
|
|
|
const itemSource = item.source;
|
2021-06-17 17:15:10 +00:00
|
|
|
const syncSource = sync.get('source');
|
|
|
|
|
|
|
|
return Boolean(
|
2023-08-10 16:43:33 +00:00
|
|
|
(itemSourceAci && syncSourceAci && itemSourceAci === syncSourceAci) ||
|
2021-06-17 17:15:10 +00:00
|
|
|
(itemSource && syncSource && itemSource === syncSource)
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
const syncSource = sync.get('source');
|
2023-08-10 16:43:33 +00:00
|
|
|
const syncSourceAci = sync.get('sourceAci');
|
2021-06-17 17:15:10 +00:00
|
|
|
const syncTimestamp = sync.get('timestamp');
|
|
|
|
const wasMessageFound = Boolean(found);
|
2021-09-17 18:27:53 +00:00
|
|
|
log.info('Receive view once open sync:', {
|
2021-06-17 17:15:10 +00:00
|
|
|
syncSource,
|
2023-08-10 16:43:33 +00:00
|
|
|
syncSourceAci,
|
2021-06-17 17:15:10 +00:00
|
|
|
syncTimestamp,
|
|
|
|
wasMessageFound,
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!found) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const message = window.MessageController.register(found.id, found);
|
2021-07-22 17:07:53 +00:00
|
|
|
await message.markViewOnceMessageViewed({ fromSync: true });
|
2021-06-17 17:15:10 +00:00
|
|
|
|
|
|
|
this.remove(sync);
|
|
|
|
} catch (error) {
|
2022-11-22 18:43:43 +00:00
|
|
|
log.error('ViewOnceOpenSyncs.onSync error:', Errors.toLogFormat(error));
|
2021-06-17 17:15:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|