@nocobase/app-plugin-mail 1.0.0-beta.12 → 1.0.0-beta.14
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/CHANGELOG.md +34 -0
- package/README.md +33 -0
- package/dist/client/components/ui/field.d.ts +7 -0
- package/dist/client/components/ui/field.d.ts.map +1 -0
- package/dist/client/components/ui/field.js +20 -0
- package/dist/client/components/ui/field.js.map +1 -0
- package/dist/client/hooks/use-mail-workspace-data.d.ts +3 -1
- package/dist/client/hooks/use-mail-workspace-data.d.ts.map +1 -1
- package/dist/client/hooks/use-mail-workspace-data.js +14 -2
- package/dist/client/hooks/use-mail-workspace-data.js.map +1 -1
- package/dist/client/locales/en-US.d.ts +3 -0
- package/dist/client/locales/en-US.d.ts.map +1 -1
- package/dist/client/locales/en-US.js +3 -0
- package/dist/client/locales/en-US.js.map +1 -1
- package/dist/client/locales/zh-CN.d.ts.map +1 -1
- package/dist/client/locales/zh-CN.js +3 -0
- package/dist/client/locales/zh-CN.js.map +1 -1
- package/dist/client/mail-client.d.ts +5 -1
- package/dist/client/mail-client.d.ts.map +1 -1
- package/dist/client/mail-client.js.map +1 -1
- package/dist/client/pages/mail-workspace-page.d.ts.map +1 -1
- package/dist/client/pages/mail-workspace-page.js +39 -10
- package/dist/client/pages/mail-workspace-page.js.map +1 -1
- package/dist/database/migrations/.manifest.json +10 -2
- package/dist/database/migrations/202609030001_create_mail_tables.d.ts.map +1 -1
- package/dist/database/migrations/202609030001_create_mail_tables.js +8 -4
- package/dist/database/migrations/202609030001_create_mail_tables.js.map +1 -1
- package/dist/database/migrations/202610090001_mail_create_message_participants.d.ts +4 -0
- package/dist/database/migrations/202610090001_mail_create_message_participants.d.ts.map +1 -0
- package/dist/database/migrations/202610090001_mail_create_message_participants.js +167 -0
- package/dist/database/migrations/202610090001_mail_create_message_participants.js.map +1 -0
- package/dist/database/migrations/202610250001_mail_imap_message_locations.d.ts +4 -0
- package/dist/database/migrations/202610250001_mail_imap_message_locations.d.ts.map +1 -0
- package/dist/database/migrations/202610250001_mail_imap_message_locations.js +297 -0
- package/dist/database/migrations/202610250001_mail_imap_message_locations.js.map +1 -0
- package/dist/server/adapters/imap-smtp/adapter.d.ts +60 -3
- package/dist/server/adapters/imap-smtp/adapter.d.ts.map +1 -1
- package/dist/server/adapters/imap-smtp/adapter.js +774 -83
- package/dist/server/adapters/imap-smtp/adapter.js.map +1 -1
- package/dist/server/adapters/imap-smtp/constants.d.ts +6 -0
- package/dist/server/adapters/imap-smtp/constants.d.ts.map +1 -1
- package/dist/server/adapters/imap-smtp/constants.js +6 -0
- package/dist/server/adapters/imap-smtp/constants.js.map +1 -1
- package/dist/server/adapters/imap-smtp/content.d.ts +11 -0
- package/dist/server/adapters/imap-smtp/content.d.ts.map +1 -1
- package/dist/server/adapters/imap-smtp/content.js +82 -3
- package/dist/server/adapters/imap-smtp/content.js.map +1 -1
- package/dist/server/adapters/imap-smtp/definition.d.ts +7 -0
- package/dist/server/adapters/imap-smtp/definition.d.ts.map +1 -1
- package/dist/server/adapters/imap-smtp/definition.js +19 -11
- package/dist/server/adapters/imap-smtp/definition.js.map +1 -1
- package/dist/server/adapters/imap-smtp/locators.d.ts +7 -0
- package/dist/server/adapters/imap-smtp/locators.d.ts.map +1 -1
- package/dist/server/adapters/imap-smtp/locators.js +53 -3
- package/dist/server/adapters/imap-smtp/locators.js.map +1 -1
- package/dist/server/adapters/imap-smtp/types.d.ts +87 -0
- package/dist/server/adapters/imap-smtp/types.d.ts.map +1 -1
- package/dist/server/operations/message-mutations.d.ts.map +1 -1
- package/dist/server/operations/message-mutations.js +57 -5
- package/dist/server/operations/message-mutations.js.map +1 -1
- package/dist/server/operations/sync-mailbox.d.ts.map +1 -1
- package/dist/server/operations/sync-mailbox.js +26 -10
- package/dist/server/operations/sync-mailbox.js.map +1 -1
- package/dist/server/providers/mail-builtins.d.ts.map +1 -1
- package/dist/server/providers/mail-builtins.js +6 -2
- package/dist/server/providers/mail-builtins.js.map +1 -1
- package/dist/server/routes/api.d.ts.map +1 -1
- package/dist/server/routes/api.js +3 -1
- package/dist/server/routes/api.js.map +1 -1
- package/dist/server/routes/schemas.d.ts +2 -0
- package/dist/server/routes/schemas.d.ts.map +1 -1
- package/dist/server/routes/schemas.js +13 -0
- package/dist/server/routes/schemas.js.map +1 -1
- package/dist/server/store/account-removals.d.ts.map +1 -1
- package/dist/server/store/account-removals.js +6 -0
- package/dist/server/store/account-removals.js.map +1 -1
- package/dist/server/store/attachments.d.ts.map +1 -1
- package/dist/server/store/attachments.js +3 -0
- package/dist/server/store/attachments.js.map +1 -1
- package/dist/server/store/draft-states.d.ts.map +1 -1
- package/dist/server/store/draft-states.js +2 -0
- package/dist/server/store/draft-states.js.map +1 -1
- package/dist/server/store/message-participants.d.ts +25 -0
- package/dist/server/store/message-participants.d.ts.map +1 -0
- package/dist/server/store/message-participants.js +109 -0
- package/dist/server/store/message-participants.js.map +1 -0
- package/dist/server/store/message-writes.d.ts +24 -1
- package/dist/server/store/message-writes.d.ts.map +1 -1
- package/dist/server/store/message-writes.js +360 -1
- package/dist/server/store/message-writes.js.map +1 -1
- package/dist/server/store/messages.d.ts.map +1 -1
- package/dist/server/store/messages.js +26 -3
- package/dist/server/store/messages.js.map +1 -1
- package/dist/server/store/rows.d.ts +20 -0
- package/dist/server/store/rows.d.ts.map +1 -1
- package/dist/server/store/sync.d.ts +7 -1
- package/dist/server/store/sync.d.ts.map +1 -1
- package/dist/server/store/sync.js +333 -7
- package/dist/server/store/sync.js.map +1 -1
- package/dist/shared/mail.d.ts +2 -0
- package/dist/shared/mail.d.ts.map +1 -1
- package/dist/shared/mail.js.map +1 -1
- package/dist/shared/participant.d.ts +14 -0
- package/dist/shared/participant.d.ts.map +1 -0
- package/dist/shared/participant.js +45 -0
- package/dist/shared/participant.js.map +1 -0
- package/package.json +12 -11
- package/skills/nocobase-app-plugin-mail/SKILL.md +9 -7
- package/skills/nocobase-app-plugin-mail/references/client-integration.md +19 -1
- package/skills/nocobase-app-plugin-mail/references/http-api.md +32 -24
- package/skills/nocobase-app-plugin-mail/references/public-api.md +2 -0
- package/skills/nocobase-app-plugin-mail/references/synchronization-and-diagnostics.md +14 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { QueryAdapter, Row } from '@nocobase/db';
|
|
2
|
+
export interface MailParticipantSource {
|
|
3
|
+
readonly id: string;
|
|
4
|
+
readonly accountId: string;
|
|
5
|
+
readonly sender?: unknown;
|
|
6
|
+
readonly recipients: unknown;
|
|
7
|
+
}
|
|
8
|
+
export interface MailMessageParticipantRow extends Row {
|
|
9
|
+
messageId: string;
|
|
10
|
+
accountId: string;
|
|
11
|
+
role: 'from' | 'to' | 'cc';
|
|
12
|
+
address: string;
|
|
13
|
+
domain: string;
|
|
14
|
+
}
|
|
15
|
+
export interface MailParticipantCollection {
|
|
16
|
+
readonly rows: readonly MailMessageParticipantRow[];
|
|
17
|
+
readonly malformedValues: number;
|
|
18
|
+
readonly invalidAddresses: number;
|
|
19
|
+
}
|
|
20
|
+
/** Persisted address JSON is the source of truth; search text and Bcc are not. */
|
|
21
|
+
export declare function collectMessageParticipants(message: MailParticipantSource): MailParticipantCollection;
|
|
22
|
+
/** Use the caller's message-write transaction, never an independent connection. */
|
|
23
|
+
export declare function replaceMessageParticipants(query: QueryAdapter, messages: readonly MailParticipantSource[]): Promise<void>;
|
|
24
|
+
export declare function deleteMessageParticipants(query: QueryAdapter, messageIds: readonly string[], accountId?: string): Promise<void>;
|
|
25
|
+
//# sourceMappingURL=message-participants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-participants.d.ts","sourceRoot":"","sources":["../../../server/store/message-participants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAItD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,yBAA0B,SAAQ,GAAG;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,EAAE,SAAS,yBAAyB,EAAE,CAAC;IACpD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAED,kFAAkF;AAClF,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,qBAAqB,GAC7B,yBAAyB,CA6D3B;AAED,mFAAmF;AACnF,wBAAsB,0BAA0B,CAC9C,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,SAAS,qBAAqB,EAAE,GACzC,OAAO,CAAC,IAAI,CAAC,CAmCf;AAED,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,YAAY,EACnB,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CASf"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { normalizeMailParticipantAddress } from '../../shared/participant.js';
|
|
2
|
+
import { chunks } from './serialization.js';
|
|
3
|
+
/** Persisted address JSON is the source of truth; search text and Bcc are not. */
|
|
4
|
+
export function collectMessageParticipants(message) {
|
|
5
|
+
const rows = [];
|
|
6
|
+
let malformedValues = 0;
|
|
7
|
+
let invalidAddresses = 0;
|
|
8
|
+
const parseObject = (value) => {
|
|
9
|
+
if (value === null || value === undefined)
|
|
10
|
+
return undefined;
|
|
11
|
+
let parsed = value;
|
|
12
|
+
if (typeof parsed === 'string') {
|
|
13
|
+
try {
|
|
14
|
+
parsed = JSON.parse(parsed);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
malformedValues++;
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (parsed === null)
|
|
22
|
+
return undefined;
|
|
23
|
+
if (typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
24
|
+
malformedValues++;
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
return parsed;
|
|
28
|
+
};
|
|
29
|
+
const add = (role, candidates) => {
|
|
30
|
+
const seen = new Set();
|
|
31
|
+
for (const candidate of candidates) {
|
|
32
|
+
const address = candidate !== null && typeof candidate === 'object'
|
|
33
|
+
? normalizeMailParticipantAddress(candidate.address)
|
|
34
|
+
: undefined;
|
|
35
|
+
if (!address) {
|
|
36
|
+
invalidAddresses++;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (seen.has(address.address))
|
|
40
|
+
continue;
|
|
41
|
+
seen.add(address.address);
|
|
42
|
+
rows.push({
|
|
43
|
+
messageId: message.id,
|
|
44
|
+
accountId: message.accountId,
|
|
45
|
+
role,
|
|
46
|
+
...address,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const sender = parseObject(message.sender);
|
|
51
|
+
if (sender)
|
|
52
|
+
add('from', [sender]);
|
|
53
|
+
const recipients = parseObject(message.recipients);
|
|
54
|
+
for (const role of ['to', 'cc']) {
|
|
55
|
+
const candidates = recipients?.[role];
|
|
56
|
+
if (candidates === undefined)
|
|
57
|
+
continue;
|
|
58
|
+
if (!Array.isArray(candidates)) {
|
|
59
|
+
malformedValues++;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
add(role, candidates);
|
|
63
|
+
}
|
|
64
|
+
return { rows, malformedValues, invalidAddresses };
|
|
65
|
+
}
|
|
66
|
+
/** Use the caller's message-write transaction, never an independent connection. */
|
|
67
|
+
export async function replaceMessageParticipants(query, messages) {
|
|
68
|
+
await deleteMessageParticipants(query, messages.map((message) => message.id));
|
|
69
|
+
let malformedValues = 0;
|
|
70
|
+
let invalidAddresses = 0;
|
|
71
|
+
let batch = [];
|
|
72
|
+
const flush = async () => {
|
|
73
|
+
if (batch.length === 0)
|
|
74
|
+
return;
|
|
75
|
+
await query
|
|
76
|
+
.insertInto('mailMessageParticipants')
|
|
77
|
+
.values(batch)
|
|
78
|
+
.execute();
|
|
79
|
+
batch = [];
|
|
80
|
+
};
|
|
81
|
+
for (const message of messages) {
|
|
82
|
+
const collected = collectMessageParticipants(message);
|
|
83
|
+
malformedValues += collected.malformedValues;
|
|
84
|
+
invalidAddresses += collected.invalidAddresses;
|
|
85
|
+
// Share batches across messages without flattening the entire mailbox.
|
|
86
|
+
// Five bindings per row: even one mass-recipient message must be bounded.
|
|
87
|
+
for (const row of collected.rows) {
|
|
88
|
+
batch.push(row);
|
|
89
|
+
if (batch.length === 100)
|
|
90
|
+
await flush();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
await flush();
|
|
94
|
+
if (malformedValues || invalidAddresses) {
|
|
95
|
+
// Aggregate counts only: never disclose account/message IDs or addresses.
|
|
96
|
+
process.emitWarning(`Mail participant indexing skipped values: malformedValues=${malformedValues}, invalidAddresses=${invalidAddresses}.`, { code: 'MAIL_PARTICIPANT_INDEX_SKIPPED' });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export async function deleteMessageParticipants(query, messageIds, accountId) {
|
|
100
|
+
for (const ids of chunks(messageIds, 100)) {
|
|
101
|
+
let deletion = query
|
|
102
|
+
.deleteFrom('mailMessageParticipants')
|
|
103
|
+
.where('messageId', 'in', ids);
|
|
104
|
+
if (accountId !== undefined)
|
|
105
|
+
deletion = deletion.where('accountId', '=', accountId);
|
|
106
|
+
await deletion.execute();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=message-participants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-participants.js","sourceRoot":"","sources":["../../../server/store/message-participants.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,+BAA+B,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAuB5C,kFAAkF;AAClF,MAAM,UAAU,0BAA0B,CACxC,OAA8B;IAE9B,MAAM,IAAI,GAAgC,EAAE,CAAC;IAC7C,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,IAAI,gBAAgB,GAAG,CAAC,CAAC;IACzB,MAAM,WAAW,GAAG,CAAC,KAAc,EAAuC,EAAE;QAC1E,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC5D,IAAI,MAAM,GAAY,KAAK,CAAC;QAC5B,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAY,CAAC;YACzC,CAAC;YAAC,MAAM,CAAC;gBACP,eAAe,EAAE,CAAC;gBAClB,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;QACD,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,SAAS,CAAC;QACtC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACxD,eAAe,EAAE,CAAC;YAClB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,MAAiC,CAAC;IAC3C,CAAC,CAAC;IACF,MAAM,GAAG,GAAG,CACV,IAAuC,EACvC,UAA8B,EACxB,EAAE;QACR,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,OAAO,GACX,SAAS,KAAK,IAAI,IAAI,OAAO,SAAS,KAAK,QAAQ;gBACjD,CAAC,CAAC,+BAA+B,CAC5B,SAAqC,CAAC,OAAO,CAC/C;gBACH,CAAC,CAAC,SAAS,CAAC;YAChB,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,gBAAgB,EAAE,CAAC;gBACnB,SAAS;YACX,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC;gBAAE,SAAS;YACxC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC1B,IAAI,CAAC,IAAI,CAAC;gBACR,SAAS,EAAE,OAAO,CAAC,EAAE;gBACrB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,IAAI;gBACJ,GAAG,OAAO;aACX,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;IACF,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,MAAM;QAAE,GAAG,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACnD,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI,CAAU,EAAE,CAAC;QACzC,MAAM,UAAU,GAAG,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,UAAU,KAAK,SAAS;YAAE,SAAS;QACvC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,eAAe,EAAE,CAAC;YAClB,SAAS;QACX,CAAC;QACD,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,gBAAgB,EAAE,CAAC;AACrD,CAAC;AAED,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,KAAmB,EACnB,QAA0C;IAE1C,MAAM,yBAAyB,CAC7B,KAAK,EACL,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CACtC,CAAC;IACF,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,IAAI,gBAAgB,GAAG,CAAC,CAAC;IACzB,IAAI,KAAK,GAAgC,EAAE,CAAC;IAC5C,MAAM,KAAK,GAAG,KAAK,IAAmB,EAAE;QACtC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC/B,MAAM,KAAK;aACR,UAAU,CAA4B,yBAAyB,CAAC;aAChE,MAAM,CAAC,KAAK,CAAC;aACb,OAAO,EAAE,CAAC;QACb,KAAK,GAAG,EAAE,CAAC;IACb,CAAC,CAAC;IACF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,0BAA0B,CAAC,OAAO,CAAC,CAAC;QACtD,eAAe,IAAI,SAAS,CAAC,eAAe,CAAC;QAC7C,gBAAgB,IAAI,SAAS,CAAC,gBAAgB,CAAC;QAC/C,uEAAuE;QACvE,0EAA0E;QAC1E,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChB,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG;gBAAE,MAAM,KAAK,EAAE,CAAC;QAC1C,CAAC;IACH,CAAC;IACD,MAAM,KAAK,EAAE,CAAC;IACd,IAAI,eAAe,IAAI,gBAAgB,EAAE,CAAC;QACxC,0EAA0E;QAC1E,OAAO,CAAC,WAAW,CACjB,6DAA6D,eAAe,sBAAsB,gBAAgB,GAAG,EACrH,EAAE,IAAI,EAAE,gCAAgC,EAAE,CAC3C,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,KAAmB,EACnB,UAA6B,EAC7B,SAAkB;IAElB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE,CAAC;QAC1C,IAAI,QAAQ,GAAG,KAAK;aACjB,UAAU,CAAC,yBAAyB,CAAC;aACrC,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QACjC,IAAI,SAAS,KAAK,SAAS;YACzB,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;QACzD,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;AACH,CAAC"}
|
|
@@ -1,8 +1,31 @@
|
|
|
1
1
|
import { type QueryAdapter } from '@nocobase/db';
|
|
2
2
|
import { type NormalizedMailMessage } from '../contracts/provider.js';
|
|
3
|
-
|
|
3
|
+
import type { ImapCopyEvidence, ImapLocationChange, ImapStoredLocation, ImapLocationTuple, ImapIdSource } from '../adapters/imap-smtp/types.js';
|
|
4
|
+
export declare function upsertMessages(query: QueryAdapter, accountId: string, messages: readonly NormalizedMailMessage[], preserveUpdatedAfter?: string, replaceFolders?: boolean): Promise<void>;
|
|
4
5
|
export declare function removeStaleMessageFolders(query: QueryAdapter, accountId: string, completeProviderFolderIds: readonly string[]): Promise<void>;
|
|
5
6
|
export declare function upsertFolders(query: QueryAdapter, accountId: string, folders: readonly import('../contracts/provider.js').NormalizedMailFolder[]): Promise<void>;
|
|
6
7
|
export declare function deleteMessages(query: QueryAdapter, accountId: string, providerMessageIds: readonly string[]): Promise<void>;
|
|
7
8
|
export declare function removeMessagesFromFolders(query: QueryAdapter, accountId: string, removals: readonly import('../contracts/provider.js').MailProviderFolderRemoval[]): Promise<void>;
|
|
9
|
+
export declare function validateImapLocation(tuple: ImapLocationTuple, source?: ImapIdSource): void;
|
|
10
|
+
export declare function validateImapStoredLocation(location: ImapStoredLocation): void;
|
|
11
|
+
export declare function validateImapCopyEvidence(copy: ImapCopyEvidence): void;
|
|
12
|
+
/**
|
|
13
|
+
* Write one sync step's IMAP copies: one business message per identity, a
|
|
14
|
+
* location per copy, and aggregates derived from every verified copy.
|
|
15
|
+
*/
|
|
16
|
+
export declare function upsertImapMessages(query: QueryAdapter, accountId: string, messages: readonly NormalizedMailMessage[], copies: readonly ImapCopyEvidence[], runId: string, preserveUpdatedAfter?: string): Promise<void>;
|
|
17
|
+
/** Apply verified status changes of stored copies. */
|
|
18
|
+
export declare function applyImapLocationChanges(query: QueryAdapter, accountId: string, changes: readonly ImapLocationChange[], runId: string): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Derive message state from its copies: read when every verified copy is read,
|
|
21
|
+
* starred when any is, received at the earliest verified copy. A message with
|
|
22
|
+
* no verified copy keeps its state and is marked as an orphan of this run.
|
|
23
|
+
*/
|
|
24
|
+
export declare function refreshImapMessages(query: QueryAdapter, accountId: string, messageIds: readonly string[], runId?: string, updatedAt?: string): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Delete IMAP messages with no valid or pending copy after a complete,
|
|
27
|
+
* twice-verified run. Local, submitted and scheduled messages are never IMAP
|
|
28
|
+
* orphans: they carry no IMAP identity source or are locked by a schedule.
|
|
29
|
+
*/
|
|
30
|
+
export declare function deleteImapOrphans(query: QueryAdapter, accountId: string, runId: string): Promise<void>;
|
|
8
31
|
//# sourceMappingURL=message-writes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-writes.d.ts","sourceRoot":"","sources":["../../../server/store/message-writes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"message-writes.d.ts","sourceRoot":"","sources":["../../../server/store/message-writes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAGjD,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAStE,OAAO,KAAK,EACV,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACb,MAAM,gCAAgC,CAAC;AAOxC,wBAAsB,cAAc,CAClC,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,SAAS,qBAAqB,EAAE,EAC1C,oBAAoB,CAAC,EAAE,MAAM,EAC7B,cAAc,UAAO,GACpB,OAAO,CAAC,IAAI,CAAC,CAoIf;AAED,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,yBAAyB,EAAE,SAAS,MAAM,EAAE,GAC3C,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,SAAS,OAAO,0BAA0B,EAAE,oBAAoB,EAAE,GAC1E,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED,wBAAsB,cAAc,CAClC,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,kBAAkB,EAAE,SAAS,MAAM,EAAE,GACpC,OAAO,CAAC,IAAI,CAAC,CA6Bf;AAED,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,SAAS,OAAO,0BAA0B,EAAE,yBAAyB,EAAE,GAChF,OAAO,CAAC,IAAI,CAAC,CAef;AAID,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,iBAAiB,EACxB,MAAM,CAAC,EAAE,YAAY,GACpB,IAAI,CAgBN;AA+BD,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,CAU7E;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAkBrE;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,SAAS,qBAAqB,EAAE,EAC1C,MAAM,EAAE,SAAS,gBAAgB,EAAE,EACnC,KAAK,EAAE,MAAM,EACb,oBAAoB,CAAC,EAAE,MAAM,GAC5B,OAAO,CAAC,IAAI,CAAC,CA0Jf;AAED,sDAAsD;AACtD,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,SAAS,kBAAkB,EAAE,EACtC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CA0Df;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,KAAK,CAAC,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CA2Ff;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CA0Bf"}
|
|
@@ -4,7 +4,8 @@ import { randomUUID } from 'node:crypto';
|
|
|
4
4
|
import { MAIL_LOCAL_DRAFT_FOLDER_ID } from '../../shared/mail.js';
|
|
5
5
|
import { toMessageRow } from './mappers.js';
|
|
6
6
|
import { chunks } from './serialization.js';
|
|
7
|
-
|
|
7
|
+
import { deleteMessageParticipants, replaceMessageParticipants, } from './message-participants.js';
|
|
8
|
+
export async function upsertMessages(query, accountId, messages, preserveUpdatedAfter, replaceFolders = true) {
|
|
8
9
|
const uniqueMessages = [
|
|
9
10
|
...new Map(messages.map((message) => [message.providerMessageId, message])).values(),
|
|
10
11
|
];
|
|
@@ -71,6 +72,10 @@ export async function upsertMessages(query, accountId, messages, preserveUpdated
|
|
|
71
72
|
}
|
|
72
73
|
if (rows.length === 0)
|
|
73
74
|
return;
|
|
75
|
+
await replaceMessageParticipants(query, rows);
|
|
76
|
+
// IMAP derives folders from every stored copy instead of the latest one.
|
|
77
|
+
if (!replaceFolders)
|
|
78
|
+
return;
|
|
74
79
|
const messageIds = rows.map((row) => row.id);
|
|
75
80
|
await query
|
|
76
81
|
.deleteFrom('mailMessageFolders')
|
|
@@ -142,6 +147,7 @@ export async function deleteMessages(query, accountId, providerMessageIds) {
|
|
|
142
147
|
.execute();
|
|
143
148
|
if (messages.length > 0) {
|
|
144
149
|
const messageIds = messages.map((message) => message.id);
|
|
150
|
+
await deleteMessageParticipants(query, messageIds, accountId);
|
|
145
151
|
for (const ids of chunks(messageIds, 100)) {
|
|
146
152
|
await query
|
|
147
153
|
.deleteFrom('mailMessageFolders')
|
|
@@ -177,4 +183,357 @@ export async function removeMessagesFromFolders(query, accountId, removals) {
|
|
|
177
183
|
.execute();
|
|
178
184
|
}
|
|
179
185
|
}
|
|
186
|
+
const IMAP_LOCATIONS = 'mailMessageImapLocations';
|
|
187
|
+
export function validateImapLocation(tuple, source) {
|
|
188
|
+
if (typeof tuple.folder !== 'string' ||
|
|
189
|
+
!tuple.folder.length ||
|
|
190
|
+
tuple.folder.length > 500 ||
|
|
191
|
+
!Number.isSafeInteger(tuple.uid) ||
|
|
192
|
+
tuple.uid < 1 ||
|
|
193
|
+
tuple.uid > 4294967295 ||
|
|
194
|
+
typeof tuple.uidValidity !== 'string' ||
|
|
195
|
+
!/^[1-9]\d{0,9}$/.test(tuple.uidValidity) ||
|
|
196
|
+
BigInt(tuple.uidValidity) > 4294967295n ||
|
|
197
|
+
(source !== undefined &&
|
|
198
|
+
!['objectid', 'x-gm-msgid', 'rfc-message-id', 'locator'].includes(source))) {
|
|
199
|
+
throw new Error('Invalid IMAP location evidence.');
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
function unchanged(row, observed) {
|
|
203
|
+
return row
|
|
204
|
+
? Boolean(observed &&
|
|
205
|
+
row.id === observed.id &&
|
|
206
|
+
row.messageId === observed.messageId &&
|
|
207
|
+
row.providerFolderId === observed.folder &&
|
|
208
|
+
row.uidValidity === observed.uidValidity &&
|
|
209
|
+
Number(row.uid) === observed.uid &&
|
|
210
|
+
new Date(row.updatedAt).toISOString() === observed.updatedAt &&
|
|
211
|
+
row.status === observed.status)
|
|
212
|
+
: !observed;
|
|
213
|
+
}
|
|
214
|
+
function validImapIdentity(value, source) {
|
|
215
|
+
if (typeof value !== 'string' || !value || value.length > 500)
|
|
216
|
+
return false;
|
|
217
|
+
if (source === 'objectid')
|
|
218
|
+
return /^[A-Za-z0-9_-]{1,255}$/.test(value);
|
|
219
|
+
if (source === 'x-gm-msgid')
|
|
220
|
+
return (/^(0|[1-9]\d{0,19})$/.test(value) &&
|
|
221
|
+
BigInt(value) <= 18446744073709551615n);
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
export function validateImapStoredLocation(location) {
|
|
225
|
+
validateImapLocation(location, location.source);
|
|
226
|
+
if (!['valid', 'pending', 'invalid'].includes(location.status) ||
|
|
227
|
+
!location.id ||
|
|
228
|
+
!location.messageId ||
|
|
229
|
+
!validImapIdentity(location.providerMessageId, location.source) ||
|
|
230
|
+
!Number.isFinite(Date.parse(location.updatedAt)))
|
|
231
|
+
throw new Error('Invalid stored IMAP location.');
|
|
232
|
+
}
|
|
233
|
+
export function validateImapCopyEvidence(copy) {
|
|
234
|
+
validateImapLocation(copy, copy.source);
|
|
235
|
+
if (typeof copy.locationId !== 'string' ||
|
|
236
|
+
!/^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/i.test(copy.locationId) ||
|
|
237
|
+
!validImapIdentity(copy.providerMessageId, copy.source) ||
|
|
238
|
+
!['objectid', 'x-gm-msgid', 'rfc-message-id', 'locator'].includes(copy.source) ||
|
|
239
|
+
(copy.flagsOnly !== undefined && typeof copy.flagsOnly !== 'boolean') ||
|
|
240
|
+
(copy.flagsOnly && !copy.observed) ||
|
|
241
|
+
typeof copy.read !== 'boolean' ||
|
|
242
|
+
typeof copy.starred !== 'boolean' ||
|
|
243
|
+
(copy.receivedAt !== undefined &&
|
|
244
|
+
(typeof copy.receivedAt !== 'string' ||
|
|
245
|
+
!Number.isFinite(Date.parse(copy.receivedAt)))))
|
|
246
|
+
throw new Error('Invalid IMAP copy evidence.');
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Write one sync step's IMAP copies: one business message per identity, a
|
|
250
|
+
* location per copy, and aggregates derived from every verified copy.
|
|
251
|
+
*/
|
|
252
|
+
export async function upsertImapMessages(query, accountId, messages, copies, runId, preserveUpdatedAfter) {
|
|
253
|
+
const safe = [];
|
|
254
|
+
const mirrors = new Map();
|
|
255
|
+
for (const copy of copies) {
|
|
256
|
+
validateImapCopyEvidence(copy);
|
|
257
|
+
const row = await query
|
|
258
|
+
.selectFrom(IMAP_LOCATIONS)
|
|
259
|
+
.selectAll()
|
|
260
|
+
.where('accountId', '=', accountId)
|
|
261
|
+
.where('providerFolderId', '=', copy.folder)
|
|
262
|
+
.where('uidValidity', '=', copy.uidValidity)
|
|
263
|
+
.where('uid', '=', copy.uid)
|
|
264
|
+
.executeTakeFirst();
|
|
265
|
+
if (!unchanged(row, copy.observed))
|
|
266
|
+
throw Object.assign(new Error('The IMAP copy changed during synchronization.'), { code: 'IMAP_MESSAGE_COPY_CHANGED' });
|
|
267
|
+
const candidates = await query
|
|
268
|
+
.selectFrom('mailMessages')
|
|
269
|
+
.selectAll()
|
|
270
|
+
.where('accountId', '=', accountId)
|
|
271
|
+
.where((builder) => builder.or([
|
|
272
|
+
builder('providerMessageId', '=', copy.providerMessageId),
|
|
273
|
+
builder('providerDraftMessageId', '=', copy.providerMessageId),
|
|
274
|
+
]))
|
|
275
|
+
.execute();
|
|
276
|
+
if (candidates.length > 1)
|
|
277
|
+
throw new Error('The IMAP identity has conflicting owners.');
|
|
278
|
+
const owner = candidates[0];
|
|
279
|
+
const mirror = owner?.providerMessageId.startsWith('local-draft:') &&
|
|
280
|
+
owner.providerDraftMessageId === copy.providerMessageId;
|
|
281
|
+
const source = mirror
|
|
282
|
+
? owner.providerDraftMessageIdSource
|
|
283
|
+
: owner?.imapIdSource;
|
|
284
|
+
if (owner && source !== copy.source)
|
|
285
|
+
throw new Error('The IMAP identity source conflicts with a stored message.');
|
|
286
|
+
if (row && owner?.id !== row.messageId)
|
|
287
|
+
throw new Error('The IMAP copy belongs to another message.');
|
|
288
|
+
if (mirror)
|
|
289
|
+
mirrors.set(copy.providerMessageId, owner.id);
|
|
290
|
+
if (owner?.scheduledSubmissionId)
|
|
291
|
+
continue;
|
|
292
|
+
safe.push(copy);
|
|
293
|
+
}
|
|
294
|
+
copies = safe;
|
|
295
|
+
const representatives = new Map();
|
|
296
|
+
for (const message of messages) {
|
|
297
|
+
// A remote draft mirror never overwrites locally authored content or UUID.
|
|
298
|
+
if (mirrors.has(message.providerMessageId) ||
|
|
299
|
+
!safe.some((copy) => !copy.flagsOnly &&
|
|
300
|
+
copy.providerMessageId === message.providerMessageId))
|
|
301
|
+
continue;
|
|
302
|
+
const current = representatives.get(message.providerMessageId);
|
|
303
|
+
// An incomplete copy never replaces complete content from another copy.
|
|
304
|
+
if (!current ||
|
|
305
|
+
(current.contentStatus !== undefined &&
|
|
306
|
+
current.contentStatus !== 'complete' &&
|
|
307
|
+
(message.contentStatus ?? 'complete') === 'complete'))
|
|
308
|
+
representatives.set(message.providerMessageId, message);
|
|
309
|
+
}
|
|
310
|
+
await upsertMessages(query, accountId, [...representatives.values()], preserveUpdatedAfter, false);
|
|
311
|
+
const owners = new Map(mirrors);
|
|
312
|
+
for (const ids of chunks([...new Set(copies.map((copy) => copy.providerMessageId))], 100)) {
|
|
313
|
+
const rows = await query
|
|
314
|
+
.selectFrom('mailMessages')
|
|
315
|
+
.select(['id', 'providerMessageId'])
|
|
316
|
+
.where('accountId', '=', accountId)
|
|
317
|
+
.where('providerMessageId', 'in', ids)
|
|
318
|
+
.execute();
|
|
319
|
+
for (const row of rows)
|
|
320
|
+
owners.set(row.providerMessageId, row.id);
|
|
321
|
+
}
|
|
322
|
+
const now = new Date().toISOString();
|
|
323
|
+
const touched = new Set();
|
|
324
|
+
for (const copy of copies) {
|
|
325
|
+
const messageId = owners.get(copy.providerMessageId);
|
|
326
|
+
// Skipped writes, such as a closed or accepted draft, keep no location.
|
|
327
|
+
if (!messageId)
|
|
328
|
+
continue;
|
|
329
|
+
const existing = await query
|
|
330
|
+
.selectFrom(IMAP_LOCATIONS)
|
|
331
|
+
.selectAll()
|
|
332
|
+
.where('accountId', '=', accountId)
|
|
333
|
+
.where('providerFolderId', '=', copy.folder)
|
|
334
|
+
.where('uidValidity', '=', copy.uidValidity)
|
|
335
|
+
.where('uid', '=', copy.uid)
|
|
336
|
+
.executeTakeFirst();
|
|
337
|
+
// A stored copy keeps its owner; a new identity never takes it over.
|
|
338
|
+
if (existing && existing.messageId !== messageId)
|
|
339
|
+
continue;
|
|
340
|
+
const values = {
|
|
341
|
+
status: 'valid',
|
|
342
|
+
invalidationReason: null,
|
|
343
|
+
read: copy.read,
|
|
344
|
+
starred: copy.starred,
|
|
345
|
+
receivedAt: copy.flagsOnly
|
|
346
|
+
? (existing?.receivedAt ?? null)
|
|
347
|
+
: (copy.receivedAt ?? null),
|
|
348
|
+
updatedAt: existing
|
|
349
|
+
? new Date(Math.max(Date.now(), Date.parse(existing.updatedAt) + 1)).toISOString()
|
|
350
|
+
: now,
|
|
351
|
+
};
|
|
352
|
+
if (existing) {
|
|
353
|
+
await query
|
|
354
|
+
.updateTable(IMAP_LOCATIONS)
|
|
355
|
+
.set(values)
|
|
356
|
+
.where('id', '=', existing.id)
|
|
357
|
+
.execute();
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
await query
|
|
361
|
+
.insertInto(IMAP_LOCATIONS)
|
|
362
|
+
.values({
|
|
363
|
+
id: copy.locationId,
|
|
364
|
+
accountId,
|
|
365
|
+
messageId,
|
|
366
|
+
providerFolderId: copy.folder,
|
|
367
|
+
uidValidity: copy.uidValidity,
|
|
368
|
+
uid: copy.uid,
|
|
369
|
+
...values,
|
|
370
|
+
createdAt: now,
|
|
371
|
+
})
|
|
372
|
+
.execute();
|
|
373
|
+
}
|
|
374
|
+
await query
|
|
375
|
+
.updateTable('mailMessages')
|
|
376
|
+
.set(mirrors.has(copy.providerMessageId)
|
|
377
|
+
? { providerDraftMessageIdSource: copy.source }
|
|
378
|
+
: { imapIdSource: copy.source })
|
|
379
|
+
.where('id', '=', messageId)
|
|
380
|
+
.execute();
|
|
381
|
+
touched.add(messageId);
|
|
382
|
+
}
|
|
383
|
+
await refreshImapMessages(query, accountId, [...touched], runId);
|
|
384
|
+
}
|
|
385
|
+
/** Apply verified status changes of stored copies. */
|
|
386
|
+
export async function applyImapLocationChanges(query, accountId, changes, runId) {
|
|
387
|
+
const touched = new Set();
|
|
388
|
+
for (const change of changes) {
|
|
389
|
+
validateImapStoredLocation(change.observed);
|
|
390
|
+
if (change.id !== change.observed.id ||
|
|
391
|
+
!['valid', 'pending', 'invalid'].includes(change.status) ||
|
|
392
|
+
(change.reason !== undefined &&
|
|
393
|
+
![
|
|
394
|
+
'uid-missing',
|
|
395
|
+
'folder-unavailable',
|
|
396
|
+
'generation-changed',
|
|
397
|
+
'generation-replaced',
|
|
398
|
+
].includes(change.reason)))
|
|
399
|
+
throw new Error('Invalid IMAP location change.');
|
|
400
|
+
const row = await query
|
|
401
|
+
.selectFrom(IMAP_LOCATIONS)
|
|
402
|
+
.selectAll()
|
|
403
|
+
.where('accountId', '=', accountId)
|
|
404
|
+
.where('id', '=', change.id)
|
|
405
|
+
.executeTakeFirst();
|
|
406
|
+
if (!unchanged(row, change.observed))
|
|
407
|
+
throw new Error('The IMAP copy changed during verification.');
|
|
408
|
+
if (!row)
|
|
409
|
+
continue;
|
|
410
|
+
const owner = await query
|
|
411
|
+
.selectFrom('mailMessages')
|
|
412
|
+
.selectAll()
|
|
413
|
+
.where('accountId', '=', accountId)
|
|
414
|
+
.where('id', '=', row.messageId)
|
|
415
|
+
.executeTakeFirst();
|
|
416
|
+
const remote = owner?.providerMessageId.startsWith('local-draft:')
|
|
417
|
+
? owner.providerDraftMessageId
|
|
418
|
+
: owner?.providerMessageId;
|
|
419
|
+
const source = remote === owner?.providerDraftMessageId
|
|
420
|
+
? owner?.providerDraftMessageIdSource
|
|
421
|
+
: owner?.imapIdSource;
|
|
422
|
+
if (!owner ||
|
|
423
|
+
remote !== change.observed.providerMessageId ||
|
|
424
|
+
source !== change.observed.source)
|
|
425
|
+
throw new Error('The IMAP identity changed during verification.');
|
|
426
|
+
await query
|
|
427
|
+
.updateTable(IMAP_LOCATIONS)
|
|
428
|
+
.set({
|
|
429
|
+
status: change.status,
|
|
430
|
+
invalidationReason: change.reason ?? null,
|
|
431
|
+
updatedAt: new Date(Math.max(Date.now(), Date.parse(row.updatedAt) + 1)).toISOString(),
|
|
432
|
+
})
|
|
433
|
+
.where('id', '=', change.id)
|
|
434
|
+
.execute();
|
|
435
|
+
touched.add(row.messageId);
|
|
436
|
+
}
|
|
437
|
+
await refreshImapMessages(query, accountId, [...touched], runId);
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Derive message state from its copies: read when every verified copy is read,
|
|
441
|
+
* starred when any is, received at the earliest verified copy. A message with
|
|
442
|
+
* no verified copy keeps its state and is marked as an orphan of this run.
|
|
443
|
+
*/
|
|
444
|
+
export async function refreshImapMessages(query, accountId, messageIds, runId, updatedAt) {
|
|
445
|
+
if (messageIds.length === 0)
|
|
446
|
+
return;
|
|
447
|
+
const folders = new Set((await query
|
|
448
|
+
.selectFrom('mailFolders')
|
|
449
|
+
.select('providerFolderId')
|
|
450
|
+
.where('accountId', '=', accountId)
|
|
451
|
+
.execute()).map((row) => row.providerFolderId));
|
|
452
|
+
for (const ids of chunks(messageIds, 100)) {
|
|
453
|
+
const locations = await query
|
|
454
|
+
.selectFrom(IMAP_LOCATIONS)
|
|
455
|
+
.select(['messageId', 'providerFolderId', 'status', 'read', 'starred'])
|
|
456
|
+
.select('receivedAt')
|
|
457
|
+
.where('accountId', '=', accountId)
|
|
458
|
+
.where('messageId', 'in', ids)
|
|
459
|
+
.execute();
|
|
460
|
+
const messages = await query
|
|
461
|
+
.selectFrom('mailMessages')
|
|
462
|
+
.select(['id', 'receivedAt', 'sentAt', 'createdAt', 'providerMessageId'])
|
|
463
|
+
.where('accountId', '=', accountId)
|
|
464
|
+
.where('id', 'in', ids)
|
|
465
|
+
.execute();
|
|
466
|
+
for (const message of messages) {
|
|
467
|
+
const own = locations.filter((location) => location.messageId === message.id);
|
|
468
|
+
const valid = own.filter((location) => location.status === 'valid');
|
|
469
|
+
const times = valid
|
|
470
|
+
.map((location) => location.receivedAt ? Date.parse(String(location.receivedAt)) : NaN)
|
|
471
|
+
.filter((time) => Number.isFinite(time));
|
|
472
|
+
const receivedAt = !message.providerMessageId.startsWith('local-draft:') && times.length
|
|
473
|
+
? new Date(Math.min(...times)).toISOString()
|
|
474
|
+
: message.receivedAt;
|
|
475
|
+
const values = valid.length
|
|
476
|
+
? {
|
|
477
|
+
read: valid.every((location) => Boolean(location.read)),
|
|
478
|
+
starred: valid.some((location) => Boolean(location.starred)),
|
|
479
|
+
receivedAt,
|
|
480
|
+
sortAt: receivedAt ?? message.sentAt ?? message.createdAt,
|
|
481
|
+
imapOrphanRunId: null,
|
|
482
|
+
}
|
|
483
|
+
: runId
|
|
484
|
+
? { imapOrphanRunId: runId }
|
|
485
|
+
: {};
|
|
486
|
+
if (updatedAt)
|
|
487
|
+
values.updatedAt = updatedAt;
|
|
488
|
+
if (Object.keys(values).length > 0)
|
|
489
|
+
await query
|
|
490
|
+
.updateTable('mailMessages')
|
|
491
|
+
.set(values)
|
|
492
|
+
.where('id', '=', message.id)
|
|
493
|
+
.execute();
|
|
494
|
+
// Unconfirmed copies keep their folder until verification decides.
|
|
495
|
+
const folderIds = new Set(own
|
|
496
|
+
.filter((location) => location.status === 'valid' ||
|
|
497
|
+
(location.status === 'pending' &&
|
|
498
|
+
folders.has(location.providerFolderId)))
|
|
499
|
+
.map((location) => location.providerFolderId));
|
|
500
|
+
await query
|
|
501
|
+
.deleteFrom('mailMessageFolders')
|
|
502
|
+
.where('messageId', '=', message.id)
|
|
503
|
+
.where('providerFolderId', '!=', MAIL_LOCAL_DRAFT_FOLDER_ID)
|
|
504
|
+
.execute();
|
|
505
|
+
if (folderIds.size > 0)
|
|
506
|
+
await query
|
|
507
|
+
.insertInto('mailMessageFolders')
|
|
508
|
+
.values([...folderIds].map((providerFolderId) => ({
|
|
509
|
+
accountId,
|
|
510
|
+
messageId: message.id,
|
|
511
|
+
providerFolderId,
|
|
512
|
+
})))
|
|
513
|
+
.execute();
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Delete IMAP messages with no valid or pending copy after a complete,
|
|
519
|
+
* twice-verified run. Local, submitted and scheduled messages are never IMAP
|
|
520
|
+
* orphans: they carry no IMAP identity source or are locked by a schedule.
|
|
521
|
+
*/
|
|
522
|
+
export async function deleteImapOrphans(query, accountId, runId) {
|
|
523
|
+
const orphans = await query
|
|
524
|
+
.selectFrom('mailMessages')
|
|
525
|
+
.select(['id', 'providerMessageId'])
|
|
526
|
+
.where('accountId', '=', accountId)
|
|
527
|
+
.where('imapIdSource', 'is not', null)
|
|
528
|
+
.where('imapOrphanRunId', '=', runId)
|
|
529
|
+
.where('providerMessageId', 'not like', 'local-draft:%')
|
|
530
|
+
.where('scheduledSubmissionId', 'is', null)
|
|
531
|
+
.where((builder) => builder.not(builder.exists(builder
|
|
532
|
+
.selectFrom(IMAP_LOCATIONS)
|
|
533
|
+
.select('id')
|
|
534
|
+
.whereRef(`${IMAP_LOCATIONS}.messageId`, '=', 'mailMessages.id')
|
|
535
|
+
.where(`${IMAP_LOCATIONS}.status`, 'in', ['valid', 'pending']))))
|
|
536
|
+
.execute();
|
|
537
|
+
await deleteMessages(query, accountId, orphans.map((row) => row.providerMessageId));
|
|
538
|
+
}
|
|
180
539
|
//# sourceMappingURL=message-writes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-writes.js","sourceRoot":"","sources":["../../../server/store/message-writes.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"message-writes.js","sourceRoot":"","sources":["../../../server/store/message-writes.ts"],"names":[],"mappings":"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"}
|