@social-mail/social-mail-web-server 1.7.252 → 1.7.255
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/events/EmailEvents.d.ts.map +1 -1
- package/dist/server/model/events/EmailEvents.js +12 -0
- package/dist/server/model/events/EmailEvents.js.map +1 -1
- package/dist/server/model/events/MailboxEmailEvents.js +1 -1
- package/dist/server/model/events/MailboxEmailEvents.js.map +1 -1
- package/dist/server/services/dom/HtmlSanitizer.d.ts +6 -1
- package/dist/server/services/dom/HtmlSanitizer.d.ts.map +1 -1
- package/dist/server/services/dom/HtmlSanitizer.js +7 -2
- package/dist/server/services/dom/HtmlSanitizer.js.map +1 -1
- package/dist/server/smtp/services/CachedEmailService.d.ts +1 -1
- package/dist/server/smtp/services/CachedEmailService.d.ts.map +1 -1
- package/dist/server/smtp/services/CachedEmailService.js +7 -2
- package/dist/server/smtp/services/CachedEmailService.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/server/model/events/EmailEvents.ts +15 -0
- package/src/server/model/events/MailboxEmailEvents.ts +2 -2
- package/src/server/services/dom/HtmlSanitizer.tsx +7 -4
- package/src/server/smtp/services/CachedEmailService.ts +7 -2
package/package.json
CHANGED
|
@@ -240,6 +240,13 @@ export default class EmailEvents extends AuthenticatedEvents<Email> {
|
|
|
240
240
|
|
|
241
241
|
async afterInsert(entity: Email, entry: ChangeEntry<Email>) {
|
|
242
242
|
|
|
243
|
+
if (entity.status === "scheduled") {
|
|
244
|
+
const r = await this.db.emailRecipients.where(entity, (p) => (x) => x.emailID === p.emailID).some();
|
|
245
|
+
if (!r) {
|
|
246
|
+
throw new EntityAccessError(`Email cannot be sent without any recipients`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
243
250
|
// eslint-disable-next-line
|
|
244
251
|
// console.log(`${(new Date().toJSON())} Inserted Email ${entity.emailID} with ${entity.dateReceived} on ${new Date()}`);
|
|
245
252
|
if (entity.forwardedID) {
|
|
@@ -251,6 +258,14 @@ export default class EmailEvents extends AuthenticatedEvents<Email> {
|
|
|
251
258
|
|
|
252
259
|
async afterUpdate(entity: Email, entry: ChangeEntry<Email>) {
|
|
253
260
|
if (entry.isUpdated("status")) {
|
|
261
|
+
|
|
262
|
+
if (entity.status === "scheduled") {
|
|
263
|
+
const r = await this.db.emailRecipients.where(entity, (p) => (x) => x.emailID === p.emailID).some();
|
|
264
|
+
if (!r) {
|
|
265
|
+
throw new EntityAccessError(`Email cannot be sent without any recipients`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
254
269
|
switch(entity.status) {
|
|
255
270
|
|
|
256
271
|
case "approved":
|
|
@@ -91,10 +91,10 @@ export default class MailboxEmailEvents extends AuthenticatedEvents<ChannelEmail
|
|
|
91
91
|
async getBody(entity: ChannelEmail) {
|
|
92
92
|
const ces = ServiceProvider.resolve(this, CachedEmailService);
|
|
93
93
|
const ea = ServiceProvider.resolve(this, EmailAddressService);
|
|
94
|
-
let file = await ces.getHtmlForRecipient(entity);
|
|
95
94
|
const channel = await ea.getEmailAddress(entity.mailboxID);
|
|
96
|
-
|
|
97
95
|
const blog = `@` + channel.emailAddress.split("@")[0];
|
|
96
|
+
let file = await ces.getHtmlForRecipient(entity, blog);
|
|
97
|
+
|
|
98
98
|
file = RegExpExtra.replaceLinks(file, blog);
|
|
99
99
|
return Content.text(file);
|
|
100
100
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
1
2
|
import { RegisterSingleton } from "@entity-access/entity-access/dist/di/di.js";
|
|
2
3
|
import { JSDOM } from 'jsdom';
|
|
3
4
|
import DOMPurify from 'dompurify';
|
|
@@ -96,7 +97,7 @@ export default class HtmlSanitizer {
|
|
|
96
97
|
return clean.innerHTML;
|
|
97
98
|
}
|
|
98
99
|
|
|
99
|
-
sanitizeExternalResources(html: string, text: string, prefix) {
|
|
100
|
+
sanitizeExternalResources({ html, text, prefix, blog }: { html: string, text: string, prefix, blog?: string }) {
|
|
100
101
|
|
|
101
102
|
const window = new JSDOM('', { url }).window;
|
|
102
103
|
const purify = DOMPurify(window);
|
|
@@ -105,6 +106,11 @@ export default class HtmlSanitizer {
|
|
|
105
106
|
for (const e of clean.querySelectorAll("*")) {
|
|
106
107
|
this.replaceSrc(e, prefix);
|
|
107
108
|
this.replaceBackground(e, prefix);
|
|
109
|
+
if (e.childElementCount === 0) {
|
|
110
|
+
if(e.textContent) {
|
|
111
|
+
e.textContent = RegExpExtra.replaceLinks(e.textContent, blog);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
108
114
|
}
|
|
109
115
|
|
|
110
116
|
html = clean?.outerHTML;
|
|
@@ -113,9 +119,6 @@ export default class HtmlSanitizer {
|
|
|
113
119
|
for (const element of tokenizeCssUrl(html)) {
|
|
114
120
|
html = html.replaceAll(element, element.replace(/https?\:\/\//, prefix));
|
|
115
121
|
}
|
|
116
|
-
|
|
117
|
-
html = RegExpExtra.replaceTimeAndEmail(html);
|
|
118
|
-
|
|
119
122
|
return { html, text };
|
|
120
123
|
}
|
|
121
124
|
|
|
@@ -27,7 +27,7 @@ export default class CachedEmailService {
|
|
|
27
27
|
|
|
28
28
|
async getHtmlForRecipient({ emailID }: {
|
|
29
29
|
emailID: number
|
|
30
|
-
}) {
|
|
30
|
+
}, blog: string = "") {
|
|
31
31
|
|
|
32
32
|
const factory = async () => {
|
|
33
33
|
|
|
@@ -68,7 +68,12 @@ export default class CachedEmailService {
|
|
|
68
68
|
text = mail.text;
|
|
69
69
|
}
|
|
70
70
|
const htmlService = ServiceProvider.resolve(this, HtmlSanitizer);
|
|
71
|
-
const result = htmlService.sanitizeExternalResources(
|
|
71
|
+
const result = htmlService.sanitizeExternalResources({
|
|
72
|
+
html,
|
|
73
|
+
text,
|
|
74
|
+
prefix: `/api/emails/d/${ei}/${emailID}/`,
|
|
75
|
+
blog
|
|
76
|
+
});
|
|
72
77
|
|
|
73
78
|
const htmlFile = await this.tempFileService.createTempFile(".html", "text/html");
|
|
74
79
|
await htmlFile.writeAllText(result.html || "");
|