@social-mail/social-mail-web-server 1.4.705 → 1.4.706
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/dist/server/model/entities/Email.d.ts +1 -0
- package/dist/server/model/entities/Email.d.ts.map +1 -1
- package/dist/server/model/entities/Email.js +10 -0
- package/dist/server/model/entities/Email.js.map +1 -1
- package/dist/server/model/events/EmailEvents.d.ts.map +1 -1
- package/dist/server/model/events/EmailEvents.js +16 -10
- package/dist/server/model/events/EmailEvents.js.map +1 -1
- package/dist/server/smtp/services/EmailSerializerService.d.ts +9 -2
- package/dist/server/smtp/services/EmailSerializerService.d.ts.map +1 -1
- package/dist/server/smtp/services/EmailSerializerService.js +8 -5
- package/dist/server/smtp/services/EmailSerializerService.js.map +1 -1
- package/dist/server/workflows/sync/SyncMailboxWorkflow.d.ts.map +1 -1
- package/dist/server/workflows/sync/SyncMailboxWorkflow.js +8 -2
- package/dist/server/workflows/sync/SyncMailboxWorkflow.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/server/model/entities/Email.ts +9 -0
- package/src/server/model/events/EmailEvents.ts +20 -12
- package/src/server/smtp/services/EmailSerializerService.ts +12 -5
- package/src/server/workflows/sync/SyncMailboxWorkflow.ts +8 -2
package/package.json
CHANGED
|
@@ -34,6 +34,12 @@ export type emailStatusType = typeof emailStatuses[number];
|
|
|
34
34
|
columns: [ { name: (x) => x.externalEmailID, descending: false }],
|
|
35
35
|
filter: (x) => x.externalEmailID !== null
|
|
36
36
|
})
|
|
37
|
+
@Index({
|
|
38
|
+
name: "IX_Emails_SentMessageID",
|
|
39
|
+
columns: [ { name: (x) => x.sentMessageID, descending: false }],
|
|
40
|
+
filter: (x) => x.sentMessageID !== null,
|
|
41
|
+
unique: true
|
|
42
|
+
})
|
|
37
43
|
@Index({
|
|
38
44
|
name: "IX_Emails_HasHtmlBody",
|
|
39
45
|
columns: [ { name: (x) => x.emailID, descending: true }],
|
|
@@ -124,6 +130,9 @@ export class Email {
|
|
|
124
130
|
})
|
|
125
131
|
public mimeFileID: number;
|
|
126
132
|
|
|
133
|
+
@Column({ dataType: "Char", length: 200, nullable: true})
|
|
134
|
+
public sentMessageID: string;
|
|
135
|
+
|
|
127
136
|
@Column({ dataType: "BigInt", nullable: true })
|
|
128
137
|
@RelateTo({
|
|
129
138
|
type: () => EmailLog,
|
|
@@ -223,18 +223,16 @@ export default class EmailEvents extends AuthenticatedEvents<Email> {
|
|
|
223
223
|
|
|
224
224
|
private async updateScheduleAndReferences(entity: Email) {
|
|
225
225
|
|
|
226
|
-
let saveChangesCalled = false;
|
|
227
|
-
|
|
228
226
|
const { emailID, silent, dateReceived, htmlBody, tempID } = entity;
|
|
229
227
|
|
|
230
|
-
|
|
231
|
-
const html = htmlBody.replaceAll(tempID, Base36.encode(emailID));
|
|
228
|
+
let updateEmail = false;
|
|
232
229
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
230
|
+
let html = htmlBody;
|
|
231
|
+
|
|
232
|
+
if (tempID) {
|
|
233
|
+
html = htmlBody.replaceAll(tempID, Base36.encode(emailID));
|
|
234
|
+
updateEmail ||= html !== htmlBody;
|
|
235
|
+
entity.htmlBody = html;
|
|
238
236
|
}
|
|
239
237
|
|
|
240
238
|
|
|
@@ -253,19 +251,29 @@ export default class EmailEvents extends AuthenticatedEvents<Email> {
|
|
|
253
251
|
});
|
|
254
252
|
}
|
|
255
253
|
|
|
254
|
+
let sentMessageID = entity.sentMessageID ?? null;
|
|
255
|
+
|
|
256
256
|
if (entity.status === "scheduled") {
|
|
257
257
|
entity.userID = this.sessionUser?.userID ?? void 0;
|
|
258
258
|
const dateSent = DateTime.from(entity.dateSent);
|
|
259
259
|
// insert a job in queue...
|
|
260
260
|
const id = `send-email-${emailID}-${dateSent.msSinceEpoch.toString(36)}`;
|
|
261
261
|
entity.workflowID = id;
|
|
262
|
+
sentMessageID = entity.headerMessageID;
|
|
263
|
+
updateEmail = true;
|
|
262
264
|
await this.workflowContext.queue(PrepareEmailToSend, emailID, {
|
|
263
265
|
eta: dateSent,
|
|
264
266
|
id
|
|
265
267
|
});
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (updateEmail) {
|
|
271
|
+
await this.db.emails.where(entity, (p) => (x) => x.emailID === p.emailID)
|
|
272
|
+
.update(entity, (p) => (x) => ({
|
|
273
|
+
htmlBody: p.htmlBody,
|
|
274
|
+
workflowID: p.workflowID,
|
|
275
|
+
sentMessageID: p.sentMessageID
|
|
276
|
+
}));
|
|
269
277
|
}
|
|
270
278
|
}
|
|
271
279
|
|
|
@@ -104,6 +104,10 @@ const stripDuplicates = (addresses: IEmailRecipientInfo[]) => {
|
|
|
104
104
|
return r;
|
|
105
105
|
};
|
|
106
106
|
|
|
107
|
+
export interface IEmailInfo {
|
|
108
|
+
externalEmailID: string, labels: string[], mailbox: Mailbox, silent?: boolean,
|
|
109
|
+
messageId: string
|
|
110
|
+
};
|
|
107
111
|
|
|
108
112
|
@RegisterScoped
|
|
109
113
|
export default class EmailSerializerService {
|
|
@@ -135,20 +139,23 @@ export default class EmailSerializerService {
|
|
|
135
139
|
@Inject
|
|
136
140
|
private workflowContext: WorkflowContext;
|
|
137
141
|
|
|
138
|
-
async saveRFC822(text: string,
|
|
142
|
+
async saveRFC822(text: string, emailInfo: IEmailInfo) {
|
|
139
143
|
const { tempFileService } = this;
|
|
140
144
|
const file = await tempFileService.createTempFile(".eml", void 0, "message/rfc822");
|
|
141
145
|
await writeFile(file.path, text, "utf8");
|
|
142
|
-
await this.saveRFC822File(file,
|
|
146
|
+
await this.saveRFC822File(file, emailInfo);
|
|
143
147
|
}
|
|
144
148
|
|
|
145
|
-
async saveRFC822File(file: LocalFile,
|
|
149
|
+
async saveRFC822File(file: LocalFile, emailInfo: IEmailInfo) {
|
|
150
|
+
const { externalEmailID, labels, mailbox, silent, messageId} = emailInfo;
|
|
146
151
|
const { tempFileService, db } = this;
|
|
147
152
|
// check if email already saved in same mailbox...
|
|
148
153
|
const { mailboxID } = mailbox;
|
|
149
154
|
if (externalEmailID) {
|
|
150
|
-
const existing = await db.mailboxEmails.where({ mailboxID, externalEmailID}, (p) => (x) =>
|
|
155
|
+
const existing = await db.mailboxEmails.where({ mailboxID, externalEmailID, messageId }, (p) => (x) =>
|
|
156
|
+
(x.mailboxID === p.mailboxID
|
|
151
157
|
&& x.email.externalEmailID === p.externalEmailID)
|
|
158
|
+
|| x.email.sentMessageID === p.messageId)
|
|
152
159
|
.some();
|
|
153
160
|
|
|
154
161
|
if (existing) {
|
|
@@ -197,7 +204,7 @@ export default class EmailSerializerService {
|
|
|
197
204
|
const mime = mail.compile();
|
|
198
205
|
|
|
199
206
|
const emailFile = await tempFileService.createFrom("harmful-email.zip", mime.createReadStream(), "message/rfc822");
|
|
200
|
-
await this.saveRFC822File(emailFile,
|
|
207
|
+
await this.saveRFC822File(emailFile, emailInfo);
|
|
201
208
|
return;
|
|
202
209
|
}
|
|
203
210
|
throw error;
|
|
@@ -219,7 +219,7 @@ export default class SyncMailboxWorkflow extends Workflow<any, any> {
|
|
|
219
219
|
|
|
220
220
|
i++;
|
|
221
221
|
|
|
222
|
-
const { emailID, uid, labels } = iterator;
|
|
222
|
+
const { emailID, uid, labels, messageId } = iterator;
|
|
223
223
|
const cUID = BigInt(uid);
|
|
224
224
|
if (cUID > currentLastUID && cUID < end) {
|
|
225
225
|
currentLastUID = cUID;
|
|
@@ -255,7 +255,13 @@ export default class SyncMailboxWorkflow extends Workflow<any, any> {
|
|
|
255
255
|
const result = await client.uidFetchRFC822(uid);
|
|
256
256
|
syncState.progress = (BigInt(syncState.progress) + 1n).toString();
|
|
257
257
|
// console.log(`Saving ${uid}`);
|
|
258
|
-
await serializer.saveRFC822(result.rfc822,
|
|
258
|
+
await serializer.saveRFC822(result.rfc822, {
|
|
259
|
+
externalEmailID: emailID,
|
|
260
|
+
messageId,
|
|
261
|
+
labels,
|
|
262
|
+
mailbox: target.mailbox,
|
|
263
|
+
silent: true
|
|
264
|
+
});
|
|
259
265
|
// console.log(`Saved ${uid}`);
|
|
260
266
|
}
|
|
261
267
|
|