2021-07-15 23:48:09 +00:00
|
|
|
// Copyright 2021 Signal Messenger, LLC
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
|
|
|
import { assert } from 'chai';
|
2023-08-10 16:43:33 +00:00
|
|
|
import { v4 as generateUuid } from 'uuid';
|
2021-07-15 23:48:09 +00:00
|
|
|
|
2024-07-22 18:16:33 +00:00
|
|
|
import { DataReader, DataWriter } from '../../sql/Client';
|
2023-08-10 16:43:33 +00:00
|
|
|
import { generateAci } from '../../types/ServiceId';
|
2021-09-24 00:49:05 +00:00
|
|
|
import { constantTimeEqual, getRandomBytes } from '../../Crypto';
|
2024-06-17 19:24:39 +00:00
|
|
|
import { singleProtoJobQueue } from '../../jobs/singleProtoJobQueue';
|
2021-07-15 23:48:09 +00:00
|
|
|
|
|
|
|
const {
|
|
|
|
_getAllSentProtoMessageIds,
|
|
|
|
_getAllSentProtoRecipients,
|
2024-07-22 18:16:33 +00:00
|
|
|
getAllSentProtos,
|
|
|
|
} = DataReader;
|
|
|
|
const {
|
2021-07-15 23:48:09 +00:00
|
|
|
deleteSentProtoByMessageId,
|
|
|
|
deleteSentProtoRecipient,
|
|
|
|
deleteSentProtosOlderThan,
|
|
|
|
getSentProtoByRecipient,
|
|
|
|
insertProtoRecipients,
|
|
|
|
insertSentProto,
|
|
|
|
removeAllSentProtos,
|
|
|
|
removeMessage,
|
|
|
|
saveMessage,
|
2024-07-22 18:16:33 +00:00
|
|
|
} = DataWriter;
|
2021-07-15 23:48:09 +00:00
|
|
|
|
2021-12-08 19:52:46 +00:00
|
|
|
describe('sql/sendLog', () => {
|
2021-07-15 23:48:09 +00:00
|
|
|
beforeEach(async () => {
|
|
|
|
await removeAllSentProtos();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('roundtrips with insertSentProto/getAllSentProtos', async () => {
|
2021-09-24 00:49:05 +00:00
|
|
|
const bytes = getRandomBytes(128);
|
2021-07-15 23:48:09 +00:00
|
|
|
const timestamp = Date.now();
|
|
|
|
const proto = {
|
|
|
|
contentHint: 1,
|
|
|
|
proto: bytes,
|
|
|
|
timestamp,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: false,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
await insertSentProto(proto, {
|
2023-08-10 16:43:33 +00:00
|
|
|
messageIds: [generateUuid()],
|
2021-07-15 23:48:09 +00:00
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[generateAci()]: [1, 2],
|
2021-07-15 23:48:09 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
const allProtos = await getAllSentProtos();
|
|
|
|
|
|
|
|
assert.lengthOf(allProtos, 1);
|
|
|
|
const actual = allProtos[0];
|
|
|
|
|
|
|
|
assert.strictEqual(actual.contentHint, proto.contentHint);
|
2021-09-24 00:49:05 +00:00
|
|
|
assert.isTrue(constantTimeEqual(actual.proto, proto.proto));
|
2021-07-15 23:48:09 +00:00
|
|
|
assert.strictEqual(actual.timestamp, proto.timestamp);
|
2022-07-01 16:55:13 +00:00
|
|
|
assert.strictEqual(actual.urgent, proto.urgent);
|
2022-08-15 21:53:33 +00:00
|
|
|
assert.strictEqual(
|
|
|
|
actual.hasPniSignatureMessage,
|
|
|
|
proto.hasPniSignatureMessage
|
|
|
|
);
|
2021-07-15 23:48:09 +00:00
|
|
|
|
|
|
|
await removeAllSentProtos();
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 0);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('cascades deletes into both tables with foreign keys', async () => {
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 0);
|
|
|
|
assert.lengthOf(await _getAllSentProtoMessageIds(), 0);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 0);
|
|
|
|
|
2021-09-24 00:49:05 +00:00
|
|
|
const bytes = getRandomBytes(128);
|
2021-07-15 23:48:09 +00:00
|
|
|
const timestamp = Date.now();
|
|
|
|
const proto = {
|
|
|
|
contentHint: 1,
|
|
|
|
proto: bytes,
|
|
|
|
timestamp,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: true,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: true,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
await insertSentProto(proto, {
|
2023-08-10 16:43:33 +00:00
|
|
|
messageIds: [generateUuid(), generateUuid()],
|
2021-07-15 23:48:09 +00:00
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[generateAci()]: [1, 2],
|
|
|
|
[generateAci()]: [1],
|
2021-07-15 23:48:09 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
2022-07-01 16:55:13 +00:00
|
|
|
const allProtos = await getAllSentProtos();
|
|
|
|
assert.lengthOf(allProtos, 1);
|
|
|
|
const actual = allProtos[0];
|
|
|
|
|
|
|
|
assert.strictEqual(actual.contentHint, proto.contentHint);
|
|
|
|
assert.isTrue(constantTimeEqual(actual.proto, proto.proto));
|
|
|
|
assert.strictEqual(actual.timestamp, proto.timestamp);
|
|
|
|
assert.strictEqual(actual.urgent, proto.urgent);
|
2022-08-15 21:53:33 +00:00
|
|
|
assert.strictEqual(
|
|
|
|
actual.hasPniSignatureMessage,
|
|
|
|
proto.hasPniSignatureMessage
|
|
|
|
);
|
2022-07-01 16:55:13 +00:00
|
|
|
|
2021-07-15 23:48:09 +00:00
|
|
|
assert.lengthOf(await _getAllSentProtoMessageIds(), 2);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 3);
|
|
|
|
|
|
|
|
await removeAllSentProtos();
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 0);
|
|
|
|
assert.lengthOf(await _getAllSentProtoMessageIds(), 0);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 0);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('trigger deletes payload when referenced message is deleted', async () => {
|
2023-08-10 16:43:33 +00:00
|
|
|
const id = generateUuid();
|
2021-07-15 23:48:09 +00:00
|
|
|
const timestamp = Date.now();
|
2023-08-10 16:43:33 +00:00
|
|
|
const ourAci = generateAci();
|
2021-07-15 23:48:09 +00:00
|
|
|
|
|
|
|
await saveMessage(
|
|
|
|
{
|
|
|
|
id,
|
|
|
|
|
|
|
|
body: 'some text',
|
2023-08-10 16:43:33 +00:00
|
|
|
conversationId: generateUuid(),
|
2021-07-15 23:48:09 +00:00
|
|
|
received_at: timestamp,
|
|
|
|
sent_at: timestamp,
|
|
|
|
timestamp,
|
|
|
|
type: 'outgoing',
|
|
|
|
},
|
2023-08-10 16:43:33 +00:00
|
|
|
{ forceSave: true, ourAci }
|
2021-07-15 23:48:09 +00:00
|
|
|
);
|
|
|
|
|
2021-09-24 00:49:05 +00:00
|
|
|
const bytes = getRandomBytes(128);
|
2021-07-15 23:48:09 +00:00
|
|
|
const proto = {
|
|
|
|
contentHint: 1,
|
|
|
|
proto: bytes,
|
|
|
|
timestamp,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: false,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
await insertSentProto(proto, {
|
|
|
|
messageIds: [id],
|
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[generateAci()]: [1, 2],
|
2021-07-15 23:48:09 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
const allProtos = await getAllSentProtos();
|
|
|
|
|
|
|
|
assert.lengthOf(allProtos, 1);
|
|
|
|
const actual = allProtos[0];
|
|
|
|
|
|
|
|
assert.strictEqual(actual.timestamp, proto.timestamp);
|
|
|
|
|
2024-06-17 19:24:39 +00:00
|
|
|
await removeMessage(id, { singleProtoJobQueue });
|
2021-07-15 23:48:09 +00:00
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 0);
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('#insertSentProto', () => {
|
|
|
|
it('supports adding duplicates', async () => {
|
|
|
|
const timestamp = Date.now();
|
|
|
|
|
2023-08-10 16:43:33 +00:00
|
|
|
const messageIds = [generateUuid()];
|
2021-07-15 23:48:09 +00:00
|
|
|
const recipients = {
|
2023-08-10 16:43:33 +00:00
|
|
|
[generateAci()]: [1],
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
const proto1 = {
|
|
|
|
contentHint: 7,
|
2021-09-24 00:49:05 +00:00
|
|
|
proto: getRandomBytes(128),
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: true,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
const proto2 = {
|
|
|
|
contentHint: 9,
|
2021-09-24 00:49:05 +00:00
|
|
|
proto: getRandomBytes(128),
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: false,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: true,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 0);
|
|
|
|
assert.lengthOf(await _getAllSentProtoMessageIds(), 0);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 0);
|
|
|
|
|
|
|
|
await insertSentProto(proto1, { messageIds, recipients });
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoMessageIds(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 1);
|
|
|
|
|
|
|
|
await insertSentProto(proto2, { messageIds, recipients });
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 2);
|
|
|
|
assert.lengthOf(await _getAllSentProtoMessageIds(), 2);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 2);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('#insertProtoRecipients', () => {
|
|
|
|
it('handles duplicates, adding new recipients if needed', async () => {
|
|
|
|
const timestamp = Date.now();
|
|
|
|
|
2023-08-10 16:43:33 +00:00
|
|
|
const messageIds = [generateUuid()];
|
2021-07-15 23:48:09 +00:00
|
|
|
const proto = {
|
|
|
|
contentHint: 1,
|
2021-09-24 00:49:05 +00:00
|
|
|
proto: getRandomBytes(128),
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: true,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 0);
|
|
|
|
assert.lengthOf(await _getAllSentProtoMessageIds(), 0);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 0);
|
|
|
|
|
|
|
|
const id = await insertSentProto(proto, {
|
|
|
|
messageIds,
|
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[generateAci()]: [1],
|
2021-07-15 23:48:09 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoMessageIds(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 1);
|
|
|
|
|
2023-08-10 16:43:33 +00:00
|
|
|
const recipientServiceId = generateAci();
|
2021-07-15 23:48:09 +00:00
|
|
|
await insertProtoRecipients({
|
|
|
|
id,
|
2023-08-10 16:43:33 +00:00
|
|
|
recipientServiceId,
|
2021-07-15 23:48:09 +00:00
|
|
|
deviceIds: [1, 2],
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoMessageIds(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 3);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('#deleteSentProtosOlderThan', () => {
|
|
|
|
it('deletes all older timestamps', async () => {
|
|
|
|
const timestamp = Date.now();
|
|
|
|
|
|
|
|
const proto1 = {
|
|
|
|
contentHint: 1,
|
2021-09-24 00:49:05 +00:00
|
|
|
proto: getRandomBytes(128),
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp: timestamp + 10,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: true,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
const proto2 = {
|
|
|
|
contentHint: 2,
|
2021-09-24 00:49:05 +00:00
|
|
|
proto: getRandomBytes(128),
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: true,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
const proto3 = {
|
|
|
|
contentHint: 0,
|
2021-09-24 00:49:05 +00:00
|
|
|
proto: getRandomBytes(128),
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp: timestamp - 15,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: true,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
await insertSentProto(proto1, {
|
2023-08-10 16:43:33 +00:00
|
|
|
messageIds: [generateUuid()],
|
2021-07-15 23:48:09 +00:00
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[generateAci()]: [1],
|
2021-07-15 23:48:09 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
await insertSentProto(proto2, {
|
2023-08-10 16:43:33 +00:00
|
|
|
messageIds: [generateUuid()],
|
2021-07-15 23:48:09 +00:00
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[generateAci()]: [1, 2],
|
2021-07-15 23:48:09 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
await insertSentProto(proto3, {
|
2023-08-10 16:43:33 +00:00
|
|
|
messageIds: [generateUuid()],
|
2021-07-15 23:48:09 +00:00
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[generateAci()]: [1, 2, 3],
|
2021-07-15 23:48:09 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 3);
|
|
|
|
|
|
|
|
await deleteSentProtosOlderThan(timestamp);
|
|
|
|
|
|
|
|
const allProtos = await getAllSentProtos();
|
|
|
|
assert.lengthOf(allProtos, 2);
|
|
|
|
|
|
|
|
const actual1 = allProtos[0];
|
|
|
|
assert.strictEqual(actual1.contentHint, proto1.contentHint);
|
2021-09-24 00:49:05 +00:00
|
|
|
assert.isTrue(constantTimeEqual(actual1.proto, proto1.proto));
|
2021-07-15 23:48:09 +00:00
|
|
|
assert.strictEqual(actual1.timestamp, proto1.timestamp);
|
|
|
|
|
|
|
|
const actual2 = allProtos[1];
|
|
|
|
assert.strictEqual(actual2.contentHint, proto2.contentHint);
|
2021-09-24 00:49:05 +00:00
|
|
|
assert.isTrue(constantTimeEqual(actual2.proto, proto2.proto));
|
2021-07-15 23:48:09 +00:00
|
|
|
assert.strictEqual(actual2.timestamp, proto2.timestamp);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('#deleteSentProtoByMessageId', () => {
|
2022-02-09 20:33:19 +00:00
|
|
|
it('deletes all records related to that messageId', async () => {
|
2021-07-15 23:48:09 +00:00
|
|
|
assert.lengthOf(await getAllSentProtos(), 0);
|
|
|
|
assert.lengthOf(await _getAllSentProtoMessageIds(), 0);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 0);
|
|
|
|
|
2023-08-10 16:43:33 +00:00
|
|
|
const messageId = generateUuid();
|
2021-07-15 23:48:09 +00:00
|
|
|
const timestamp = Date.now();
|
|
|
|
const proto1 = {
|
|
|
|
contentHint: 1,
|
2021-09-24 00:49:05 +00:00
|
|
|
proto: getRandomBytes(128),
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: true,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
const proto2 = {
|
|
|
|
contentHint: 1,
|
2021-09-24 00:49:05 +00:00
|
|
|
proto: getRandomBytes(128),
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp: timestamp - 10,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: true,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
const proto3 = {
|
|
|
|
contentHint: 1,
|
2021-09-24 00:49:05 +00:00
|
|
|
proto: getRandomBytes(128),
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp: timestamp - 20,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: true,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
await insertSentProto(proto1, {
|
2023-08-10 16:43:33 +00:00
|
|
|
messageIds: [messageId, generateUuid()],
|
2021-07-15 23:48:09 +00:00
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[generateAci()]: [1, 2],
|
|
|
|
[generateAci()]: [1],
|
2021-07-15 23:48:09 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
await insertSentProto(proto2, {
|
|
|
|
messageIds: [messageId],
|
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[generateAci()]: [1],
|
2021-07-15 23:48:09 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
await insertSentProto(proto3, {
|
2023-08-10 16:43:33 +00:00
|
|
|
messageIds: [generateUuid()],
|
2021-07-15 23:48:09 +00:00
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[generateAci()]: [1],
|
2021-07-15 23:48:09 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 3);
|
|
|
|
assert.lengthOf(await _getAllSentProtoMessageIds(), 4);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 5);
|
|
|
|
|
|
|
|
await deleteSentProtoByMessageId(messageId);
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoMessageIds(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 1);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('#deleteSentProtoRecipient', () => {
|
|
|
|
it('does not delete payload if recipient remains', async () => {
|
|
|
|
const timestamp = Date.now();
|
|
|
|
|
2023-08-10 16:43:33 +00:00
|
|
|
const recipientServiceId1 = generateAci();
|
|
|
|
const recipientServiceId2 = generateAci();
|
2021-07-15 23:48:09 +00:00
|
|
|
const proto = {
|
|
|
|
contentHint: 1,
|
2021-09-24 00:49:05 +00:00
|
|
|
proto: getRandomBytes(128),
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: true,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
await insertSentProto(proto, {
|
2023-08-10 16:43:33 +00:00
|
|
|
messageIds: [generateUuid()],
|
2021-07-15 23:48:09 +00:00
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[recipientServiceId1]: [1, 2],
|
|
|
|
[recipientServiceId2]: [1],
|
2021-07-15 23:48:09 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 3);
|
|
|
|
|
2022-08-15 21:53:33 +00:00
|
|
|
const { successfulPhoneNumberShares } = await deleteSentProtoRecipient({
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp,
|
2023-08-10 16:43:33 +00:00
|
|
|
recipientServiceId: recipientServiceId1,
|
2021-07-15 23:48:09 +00:00
|
|
|
deviceId: 1,
|
|
|
|
});
|
2022-08-15 21:53:33 +00:00
|
|
|
assert.lengthOf(successfulPhoneNumberShares, 0);
|
2021-07-15 23:48:09 +00:00
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 2);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('deletes payload if no recipients remain', async () => {
|
|
|
|
const timestamp = Date.now();
|
|
|
|
|
2023-08-10 16:43:33 +00:00
|
|
|
const recipientServiceId1 = generateAci();
|
|
|
|
const recipientServiceId2 = generateAci();
|
2021-07-15 23:48:09 +00:00
|
|
|
const proto = {
|
|
|
|
contentHint: 1,
|
2021-09-24 00:49:05 +00:00
|
|
|
proto: getRandomBytes(128),
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: true,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
await insertSentProto(proto, {
|
2023-08-10 16:43:33 +00:00
|
|
|
messageIds: [generateUuid()],
|
2021-07-15 23:48:09 +00:00
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[recipientServiceId1]: [1, 2],
|
|
|
|
[recipientServiceId2]: [1],
|
2021-07-15 23:48:09 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 3);
|
|
|
|
|
2022-08-15 21:53:33 +00:00
|
|
|
{
|
|
|
|
const { successfulPhoneNumberShares } = await deleteSentProtoRecipient({
|
|
|
|
timestamp,
|
2023-08-10 16:43:33 +00:00
|
|
|
recipientServiceId: recipientServiceId1,
|
2022-08-15 21:53:33 +00:00
|
|
|
deviceId: 1,
|
|
|
|
});
|
|
|
|
assert.lengthOf(successfulPhoneNumberShares, 0);
|
|
|
|
}
|
2021-07-15 23:48:09 +00:00
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 2);
|
|
|
|
|
2022-08-15 21:53:33 +00:00
|
|
|
{
|
|
|
|
const { successfulPhoneNumberShares } = await deleteSentProtoRecipient({
|
|
|
|
timestamp,
|
2023-08-10 16:43:33 +00:00
|
|
|
recipientServiceId: recipientServiceId1,
|
2022-08-15 21:53:33 +00:00
|
|
|
deviceId: 2,
|
|
|
|
});
|
|
|
|
assert.lengthOf(successfulPhoneNumberShares, 0);
|
|
|
|
}
|
2021-07-15 23:48:09 +00:00
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 1);
|
|
|
|
|
2022-08-15 21:53:33 +00:00
|
|
|
{
|
|
|
|
const { successfulPhoneNumberShares } = await deleteSentProtoRecipient({
|
|
|
|
timestamp,
|
2023-08-10 16:43:33 +00:00
|
|
|
recipientServiceId: recipientServiceId2,
|
2022-08-15 21:53:33 +00:00
|
|
|
deviceId: 1,
|
|
|
|
});
|
|
|
|
assert.lengthOf(successfulPhoneNumberShares, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 0);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 0);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('returns deleted recipients when pni signature was sent', async () => {
|
|
|
|
const timestamp = Date.now();
|
|
|
|
|
2023-08-10 16:43:33 +00:00
|
|
|
const recipientServiceId1 = generateAci();
|
|
|
|
const recipientServiceId2 = generateAci();
|
2022-08-15 21:53:33 +00:00
|
|
|
const proto = {
|
|
|
|
contentHint: 1,
|
|
|
|
proto: getRandomBytes(128),
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp,
|
2022-08-15 21:53:33 +00:00
|
|
|
urgent: true,
|
|
|
|
hasPniSignatureMessage: true,
|
|
|
|
};
|
|
|
|
await insertSentProto(proto, {
|
2023-08-10 16:43:33 +00:00
|
|
|
messageIds: [generateUuid()],
|
2022-08-15 21:53:33 +00:00
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[recipientServiceId1]: [1, 2],
|
|
|
|
[recipientServiceId2]: [1],
|
2022-08-15 21:53:33 +00:00
|
|
|
},
|
2021-07-15 23:48:09 +00:00
|
|
|
});
|
|
|
|
|
2022-08-15 21:53:33 +00:00
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 3);
|
|
|
|
|
|
|
|
{
|
|
|
|
const { successfulPhoneNumberShares } = await deleteSentProtoRecipient({
|
|
|
|
timestamp,
|
2023-08-10 16:43:33 +00:00
|
|
|
recipientServiceId: recipientServiceId1,
|
2022-08-15 21:53:33 +00:00
|
|
|
deviceId: 1,
|
|
|
|
});
|
|
|
|
assert.lengthOf(successfulPhoneNumberShares, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 2);
|
|
|
|
|
|
|
|
{
|
|
|
|
const { successfulPhoneNumberShares } = await deleteSentProtoRecipient({
|
|
|
|
timestamp,
|
2023-08-10 16:43:33 +00:00
|
|
|
recipientServiceId: recipientServiceId1,
|
2022-08-15 21:53:33 +00:00
|
|
|
deviceId: 2,
|
|
|
|
});
|
2023-08-10 16:43:33 +00:00
|
|
|
assert.deepStrictEqual(successfulPhoneNumberShares, [
|
|
|
|
recipientServiceId1,
|
|
|
|
]);
|
2022-08-15 21:53:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 1);
|
|
|
|
|
|
|
|
{
|
|
|
|
const { successfulPhoneNumberShares } = await deleteSentProtoRecipient({
|
|
|
|
timestamp,
|
2023-08-10 16:43:33 +00:00
|
|
|
recipientServiceId: recipientServiceId2,
|
2022-08-15 21:53:33 +00:00
|
|
|
deviceId: 1,
|
|
|
|
});
|
2023-08-10 16:43:33 +00:00
|
|
|
assert.deepStrictEqual(successfulPhoneNumberShares, [
|
|
|
|
recipientServiceId2,
|
|
|
|
]);
|
2022-08-15 21:53:33 +00:00
|
|
|
}
|
|
|
|
|
2021-07-15 23:48:09 +00:00
|
|
|
assert.lengthOf(await getAllSentProtos(), 0);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 0);
|
|
|
|
});
|
2021-08-31 21:35:01 +00:00
|
|
|
|
|
|
|
it('deletes multiple recipients in a single transaction', async () => {
|
|
|
|
const timestamp = Date.now();
|
|
|
|
|
2023-08-10 16:43:33 +00:00
|
|
|
const recipientServiceId1 = generateAci();
|
|
|
|
const recipientServiceId2 = generateAci();
|
2021-08-31 21:35:01 +00:00
|
|
|
const proto = {
|
|
|
|
contentHint: 1,
|
2021-09-24 00:49:05 +00:00
|
|
|
proto: getRandomBytes(128),
|
2021-08-31 21:35:01 +00:00
|
|
|
timestamp,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: true,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-08-31 21:35:01 +00:00
|
|
|
};
|
|
|
|
await insertSentProto(proto, {
|
2023-08-10 16:43:33 +00:00
|
|
|
messageIds: [generateUuid()],
|
2021-08-31 21:35:01 +00:00
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[recipientServiceId1]: [1, 2],
|
|
|
|
[recipientServiceId2]: [1],
|
2021-08-31 21:35:01 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 3);
|
|
|
|
|
2022-08-15 21:53:33 +00:00
|
|
|
const { successfulPhoneNumberShares } = await deleteSentProtoRecipient([
|
2021-08-31 21:35:01 +00:00
|
|
|
{
|
|
|
|
timestamp,
|
2023-08-10 16:43:33 +00:00
|
|
|
recipientServiceId: recipientServiceId1,
|
2021-08-31 21:35:01 +00:00
|
|
|
deviceId: 1,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
timestamp,
|
2023-08-10 16:43:33 +00:00
|
|
|
recipientServiceId: recipientServiceId1,
|
2021-08-31 21:35:01 +00:00
|
|
|
deviceId: 2,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
timestamp,
|
2023-08-10 16:43:33 +00:00
|
|
|
recipientServiceId: recipientServiceId2,
|
2021-08-31 21:35:01 +00:00
|
|
|
deviceId: 1,
|
|
|
|
},
|
|
|
|
]);
|
2022-08-15 21:53:33 +00:00
|
|
|
assert.lengthOf(successfulPhoneNumberShares, 0);
|
2021-08-31 21:35:01 +00:00
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 0);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 0);
|
|
|
|
});
|
2021-07-15 23:48:09 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
describe('#getSentProtoByRecipient', () => {
|
|
|
|
it('returns matching payload', async () => {
|
|
|
|
const timestamp = Date.now();
|
|
|
|
|
2023-08-10 16:43:33 +00:00
|
|
|
const recipientServiceId = generateAci();
|
|
|
|
const messageIds = [generateUuid(), generateUuid()];
|
2021-07-15 23:48:09 +00:00
|
|
|
const proto = {
|
|
|
|
contentHint: 1,
|
2021-09-24 00:49:05 +00:00
|
|
|
proto: getRandomBytes(128),
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: true,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
await insertSentProto(proto, {
|
|
|
|
messageIds,
|
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[recipientServiceId]: [1, 2],
|
2021-07-15 23:48:09 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 2);
|
|
|
|
assert.lengthOf(await _getAllSentProtoMessageIds(), 2);
|
|
|
|
|
|
|
|
const actual = await getSentProtoByRecipient({
|
|
|
|
now: timestamp,
|
|
|
|
timestamp,
|
2023-08-10 16:43:33 +00:00
|
|
|
recipientServiceId,
|
2021-07-15 23:48:09 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
if (!actual) {
|
|
|
|
throw new Error('Failed to fetch proto!');
|
|
|
|
}
|
|
|
|
assert.strictEqual(actual.contentHint, proto.contentHint);
|
2021-09-24 00:49:05 +00:00
|
|
|
assert.isTrue(constantTimeEqual(actual.proto, proto.proto));
|
2021-07-15 23:48:09 +00:00
|
|
|
assert.strictEqual(actual.timestamp, proto.timestamp);
|
|
|
|
assert.sameMembers(actual.messageIds, messageIds);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('returns matching payload with no messageIds', async () => {
|
|
|
|
const timestamp = Date.now();
|
|
|
|
|
2023-08-10 16:43:33 +00:00
|
|
|
const recipientServiceId = generateAci();
|
2021-07-15 23:48:09 +00:00
|
|
|
const proto = {
|
|
|
|
contentHint: 1,
|
2021-09-24 00:49:05 +00:00
|
|
|
proto: getRandomBytes(128),
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: true,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
await insertSentProto(proto, {
|
|
|
|
messageIds: [],
|
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[recipientServiceId]: [1, 2],
|
2021-07-15 23:48:09 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 2);
|
|
|
|
assert.lengthOf(await _getAllSentProtoMessageIds(), 0);
|
|
|
|
|
|
|
|
const actual = await getSentProtoByRecipient({
|
|
|
|
now: timestamp,
|
|
|
|
timestamp,
|
2023-08-10 16:43:33 +00:00
|
|
|
recipientServiceId,
|
2021-07-15 23:48:09 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
if (!actual) {
|
|
|
|
throw new Error('Failed to fetch proto!');
|
|
|
|
}
|
|
|
|
assert.strictEqual(actual.contentHint, proto.contentHint);
|
2021-09-24 00:49:05 +00:00
|
|
|
assert.isTrue(constantTimeEqual(actual.proto, proto.proto));
|
2021-07-15 23:48:09 +00:00
|
|
|
assert.strictEqual(actual.timestamp, proto.timestamp);
|
|
|
|
assert.deepEqual(actual.messageIds, []);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('returns nothing if payload does not have recipient', async () => {
|
|
|
|
const timestamp = Date.now();
|
|
|
|
|
2023-08-10 16:43:33 +00:00
|
|
|
const recipientServiceId = generateAci();
|
2021-07-15 23:48:09 +00:00
|
|
|
const proto = {
|
|
|
|
contentHint: 1,
|
2021-09-24 00:49:05 +00:00
|
|
|
proto: getRandomBytes(128),
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: true,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
await insertSentProto(proto, {
|
2023-08-10 16:43:33 +00:00
|
|
|
messageIds: [generateUuid()],
|
2021-07-15 23:48:09 +00:00
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[recipientServiceId]: [1, 2],
|
2021-07-15 23:48:09 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 2);
|
|
|
|
|
|
|
|
const actual = await getSentProtoByRecipient({
|
|
|
|
now: timestamp,
|
|
|
|
timestamp,
|
2023-08-10 16:43:33 +00:00
|
|
|
recipientServiceId: generateAci(),
|
2021-07-15 23:48:09 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
assert.isUndefined(actual);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('returns nothing if timestamp does not match', async () => {
|
|
|
|
const timestamp = Date.now();
|
|
|
|
|
2023-08-10 16:43:33 +00:00
|
|
|
const recipientServiceId = generateAci();
|
2021-07-15 23:48:09 +00:00
|
|
|
const proto = {
|
|
|
|
contentHint: 1,
|
2021-09-24 00:49:05 +00:00
|
|
|
proto: getRandomBytes(128),
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: true,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
await insertSentProto(proto, {
|
2023-08-10 16:43:33 +00:00
|
|
|
messageIds: [generateUuid()],
|
2021-07-15 23:48:09 +00:00
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[recipientServiceId]: [1, 2],
|
2021-07-15 23:48:09 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 2);
|
|
|
|
|
|
|
|
const actual = await getSentProtoByRecipient({
|
|
|
|
now: timestamp,
|
|
|
|
timestamp: timestamp + 1,
|
2023-08-10 16:43:33 +00:00
|
|
|
recipientServiceId,
|
2021-07-15 23:48:09 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
assert.isUndefined(actual);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('returns nothing if timestamp proto is too old', async () => {
|
|
|
|
const TWO_DAYS = 2 * 24 * 60 * 60 * 1000;
|
|
|
|
const timestamp = Date.now();
|
|
|
|
|
2023-08-10 16:43:33 +00:00
|
|
|
const recipientServiceId = generateAci();
|
2021-07-15 23:48:09 +00:00
|
|
|
const proto = {
|
|
|
|
contentHint: 1,
|
2021-09-24 00:49:05 +00:00
|
|
|
proto: getRandomBytes(128),
|
2021-07-15 23:48:09 +00:00
|
|
|
timestamp,
|
2022-07-01 16:55:13 +00:00
|
|
|
urgent: true,
|
2022-08-15 21:53:33 +00:00
|
|
|
hasPniSignatureMessage: false,
|
2021-07-15 23:48:09 +00:00
|
|
|
};
|
|
|
|
await insertSentProto(proto, {
|
2023-08-10 16:43:33 +00:00
|
|
|
messageIds: [generateUuid()],
|
2021-07-15 23:48:09 +00:00
|
|
|
recipients: {
|
2023-08-10 16:43:33 +00:00
|
|
|
[recipientServiceId]: [1, 2],
|
2021-07-15 23:48:09 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 1);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 2);
|
|
|
|
|
|
|
|
const actual = await getSentProtoByRecipient({
|
|
|
|
now: timestamp + TWO_DAYS,
|
|
|
|
timestamp,
|
2023-08-10 16:43:33 +00:00
|
|
|
recipientServiceId,
|
2021-07-15 23:48:09 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
assert.isUndefined(actual);
|
|
|
|
|
|
|
|
assert.lengthOf(await getAllSentProtos(), 0);
|
|
|
|
assert.lengthOf(await _getAllSentProtoRecipients(), 0);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|