@remit/mailbox-service 0.0.67 → 0.0.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -49,7 +49,9 @@ interface TrashMessage {
|
|
|
49
49
|
|
|
50
50
|
interface EnqueuedEvent {
|
|
51
51
|
type: string;
|
|
52
|
+
schemaVersion?: number;
|
|
52
53
|
trashMailboxId?: string;
|
|
54
|
+
trashUidValidity?: number;
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
const buildWorld = (
|
|
@@ -87,7 +89,12 @@ const buildWorld = (
|
|
|
87
89
|
|
|
88
90
|
const config: MessageMoveConfig = {
|
|
89
91
|
messageService,
|
|
90
|
-
mailboxService: {
|
|
92
|
+
mailboxService: {
|
|
93
|
+
get: async (_accountId: string, mailboxId: string) => ({
|
|
94
|
+
mailboxId,
|
|
95
|
+
uidValidity: 42,
|
|
96
|
+
}),
|
|
97
|
+
} as unknown as IMailboxRepository,
|
|
91
98
|
addressService: {
|
|
92
99
|
reconcileJunkOnlyForMessage: async () => {},
|
|
93
100
|
} as unknown as IAddressRepository,
|
|
@@ -220,4 +227,16 @@ describe("MessageMoveService.emptyTrash", () => {
|
|
|
220
227
|
["EMPTY_TRASH", "EMPTY_TRASH"],
|
|
221
228
|
);
|
|
222
229
|
});
|
|
230
|
+
|
|
231
|
+
it("carries the folder's identity as it stood at consent time", async () => {
|
|
232
|
+
// The worker compares this against what its own SELECT serves. Without
|
|
233
|
+
// it the expunge would be authorised by a path, and a path is reusable.
|
|
234
|
+
const { service, events } = buildWorld(appointedTrash);
|
|
235
|
+
|
|
236
|
+
await service.emptyTrash(ACCOUNT_CONFIG, ACCOUNT);
|
|
237
|
+
|
|
238
|
+
assert.equal(events[0]?.schemaVersion, 2);
|
|
239
|
+
assert.equal(events[0]?.trashMailboxId, REAL_TRASH);
|
|
240
|
+
assert.equal(events[0]?.trashUidValidity, 42);
|
|
241
|
+
});
|
|
223
242
|
});
|
package/src/message-move.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
UNCONFIRMED_TRASH_FOLDER_REASON,
|
|
23
23
|
} from "@remit/data-ports/folder-role";
|
|
24
24
|
import { deriveCopyMessageId } from "@remit/data-ports/id";
|
|
25
|
+
import { MUTATION_EVENT_SCHEMA_VERSION } from "@remit/data-ports/mutation-events";
|
|
25
26
|
import {
|
|
26
27
|
CanonicalMailboxRole,
|
|
27
28
|
MessageStatus,
|
|
@@ -35,6 +36,7 @@ import { createQueueProducer } from "@remit/sqs-client/producer";
|
|
|
35
36
|
*/
|
|
36
37
|
interface MessageDeleteEvent {
|
|
37
38
|
type: "MESSAGE_DELETE";
|
|
39
|
+
schemaVersion: typeof MUTATION_EVENT_SCHEMA_VERSION;
|
|
38
40
|
eventId: string;
|
|
39
41
|
timestamp: number;
|
|
40
42
|
accountId: string;
|
|
@@ -62,11 +64,14 @@ interface MessageMoveEvent {
|
|
|
62
64
|
|
|
63
65
|
interface EmptyTrashEvent {
|
|
64
66
|
type: "EMPTY_TRASH";
|
|
67
|
+
schemaVersion: typeof MUTATION_EVENT_SCHEMA_VERSION;
|
|
65
68
|
eventId: string;
|
|
66
69
|
timestamp: number;
|
|
67
70
|
accountId: string;
|
|
68
71
|
trashMailboxId: string;
|
|
69
72
|
trashMailboxPath: string;
|
|
73
|
+
/** The folder's UIDVALIDITY at consent time; the worker re-checks it. */
|
|
74
|
+
trashUidValidity: number;
|
|
70
75
|
}
|
|
71
76
|
|
|
72
77
|
interface MessageCopyEvent {
|
|
@@ -382,6 +387,7 @@ export class MessageMoveService {
|
|
|
382
387
|
|
|
383
388
|
events.push({
|
|
384
389
|
type: "MESSAGE_DELETE",
|
|
390
|
+
schemaVersion: MUTATION_EVENT_SCHEMA_VERSION,
|
|
385
391
|
eventId: randomUUID(),
|
|
386
392
|
timestamp: Date.now(),
|
|
387
393
|
accountId,
|
|
@@ -425,6 +431,7 @@ export class MessageMoveService {
|
|
|
425
431
|
|
|
426
432
|
events.push({
|
|
427
433
|
type: "MESSAGE_DELETE",
|
|
434
|
+
schemaVersion: MUTATION_EVENT_SCHEMA_VERSION,
|
|
428
435
|
eventId: randomUUID(),
|
|
429
436
|
timestamp: Date.now(),
|
|
430
437
|
accountId,
|
|
@@ -764,6 +771,15 @@ export class MessageMoveService {
|
|
|
764
771
|
accountId,
|
|
765
772
|
);
|
|
766
773
|
|
|
774
|
+
// The identity the user consented to, carried on the event so the worker
|
|
775
|
+
// can tell this folder from a different one that has since taken over its
|
|
776
|
+
// path. Read here rather than re-read there: the value at consent time is
|
|
777
|
+
// the whole point, and the stored row is rewritten by every sync.
|
|
778
|
+
const { uidValidity: trashUidValidity } = await this.mailboxService.get(
|
|
779
|
+
accountId,
|
|
780
|
+
trashMailbox.mailboxId,
|
|
781
|
+
);
|
|
782
|
+
|
|
767
783
|
const messages = await this.messageService.listAllByMailbox(
|
|
768
784
|
trashMailbox.mailboxId,
|
|
769
785
|
);
|
|
@@ -793,11 +809,13 @@ export class MessageMoveService {
|
|
|
793
809
|
// Enqueue single event for worker to handle batch
|
|
794
810
|
const event: EmptyTrashEvent = {
|
|
795
811
|
type: "EMPTY_TRASH",
|
|
812
|
+
schemaVersion: MUTATION_EVENT_SCHEMA_VERSION,
|
|
796
813
|
eventId: randomUUID(),
|
|
797
814
|
timestamp: Date.now(),
|
|
798
815
|
accountId,
|
|
799
816
|
trashMailboxId: trashMailbox.mailboxId,
|
|
800
817
|
trashMailboxPath: trashMailbox.fullPath,
|
|
818
|
+
trashUidValidity,
|
|
801
819
|
};
|
|
802
820
|
|
|
803
821
|
await this.enqueueEvent(event);
|
|
@@ -201,6 +201,15 @@ describe("what a mailbox says about the addresses on its messages", () => {
|
|
|
201
201
|
assert.deepEqual(emails(saved.envelopeAddresses), BOTH);
|
|
202
202
|
});
|
|
203
203
|
|
|
204
|
+
it("leaves the identity of an envelope address to the store", async () => {
|
|
205
|
+
const saved = await save(mailboxAt("INBOX"));
|
|
206
|
+
|
|
207
|
+
assert.ok(saved.envelopeAddresses.length > 0);
|
|
208
|
+
for (const envelopeAddress of saved.envelopeAddresses) {
|
|
209
|
+
assert.ok(!("envelopeAddressId" in envelopeAddress));
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
|
|
204
213
|
it("keeps a message in Trash from deciding either way", async () => {
|
|
205
214
|
const saved = await save(mailboxAt("Trash"), "Trash");
|
|
206
215
|
|
package/src/message-sync.ts
CHANGED
|
@@ -16,7 +16,6 @@ import { storedDisplayName } from "@remit/data-ports/display-name";
|
|
|
16
16
|
import {
|
|
17
17
|
deriveAddressId,
|
|
18
18
|
deriveBodyPartId,
|
|
19
|
-
deriveEnvelopeAddressId,
|
|
20
19
|
deriveEnvelopeId,
|
|
21
20
|
deriveMessageIdFromSource,
|
|
22
21
|
deriveThreadId,
|
|
@@ -1506,8 +1505,6 @@ export class MessageSyncService {
|
|
|
1506
1505
|
|
|
1507
1506
|
const addressId = deriveAddressId(accountConfigId, normalizedEmail);
|
|
1508
1507
|
|
|
1509
|
-
const envelopeAddressId = deriveEnvelopeAddressId(messageId, role, order);
|
|
1510
|
-
|
|
1511
1508
|
const addressInput = {
|
|
1512
1509
|
addressId,
|
|
1513
1510
|
accountConfigId,
|
|
@@ -1526,7 +1523,6 @@ export class MessageSyncService {
|
|
|
1526
1523
|
}
|
|
1527
1524
|
|
|
1528
1525
|
await addressService.upsertEnvelopeAddress({
|
|
1529
|
-
envelopeAddressId,
|
|
1530
1526
|
messageId,
|
|
1531
1527
|
addressId,
|
|
1532
1528
|
displayName,
|