@stamhoofd/email 2.119.0 → 2.120.1
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/classes/Email.d.ts +4 -4
- package/dist/classes/Email.d.ts.map +1 -1
- package/dist/classes/Email.js +31 -34
- package/dist/classes/Email.js.map +1 -1
- package/dist/classes/EmailMocker.d.ts +1 -1
- package/dist/classes/EmailMocker.d.ts.map +1 -1
- package/dist/classes/EmailMocker.js +12 -49
- package/dist/classes/EmailMocker.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -6
- package/dist/index.js.map +1 -1
- package/dist/models/EmailAddress.d.ts +1 -1
- package/dist/models/EmailAddress.d.ts.map +1 -1
- package/dist/models/EmailAddress.js +34 -38
- package/dist/models/EmailAddress.js.map +1 -1
- package/package.json +9 -6
- package/dist/classes/Email.test.d.ts +0 -2
- package/dist/classes/Email.test.d.ts.map +0 -1
- package/dist/classes/Email.test.js +0 -27
- package/dist/classes/Email.test.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/classes/Email.test.ts +0 -28
- package/src/classes/Email.ts +0 -546
- package/src/classes/EmailMocker.ts +0 -145
- package/src/index.ts +0 -3
- package/src/migrations/1603433451-email-addresses.sql +0 -14
- package/src/migrations/1720080973-convert-charset.sql +0 -5
- package/src/models/EmailAddress.ts +0 -160
- /package/{dist/migrations → migrations}/1603433451-email-addresses.sql +0 -0
- /package/{dist/migrations → migrations}/1720080973-convert-charset.sql +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmailAddress.js","sourceRoot":"","sources":["../../src/models/EmailAddress.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"EmailAddress.js","sourceRoot":"","sources":["../../src/models/EmailAddress.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stamhoofd/email",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"
|
|
3
|
+
"version": "2.120.1",
|
|
4
|
+
"type": "module",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
6
8
|
"license": "UNLICENCED",
|
|
7
9
|
"sideEffects": false,
|
|
8
10
|
"files": [
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
+
"dist",
|
|
12
|
+
"migrations"
|
|
11
13
|
],
|
|
12
14
|
"scripts": {
|
|
13
|
-
"build": "tsc
|
|
15
|
+
"build": "tsc --build tsconfig.build.json",
|
|
16
|
+
"lint": "eslint"
|
|
14
17
|
},
|
|
15
18
|
"peerDependencies": {
|
|
16
19
|
"@simonbackx/simple-errors": "^1.5"
|
|
@@ -25,5 +28,5 @@
|
|
|
25
28
|
"publishConfig": {
|
|
26
29
|
"access": "public"
|
|
27
30
|
},
|
|
28
|
-
"gitHead": "
|
|
31
|
+
"gitHead": "00f65fc28d68feb86c30789784181a8954d638d7"
|
|
29
32
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Email.test.d.ts","sourceRoot":"","sources":["../../src/classes/Email.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const Email_1 = require("./Email");
|
|
4
|
-
describe("Email", () => {
|
|
5
|
-
it("should parse e-mail strings correctly", () => {
|
|
6
|
-
expect(Email_1.Email.parseEmailStr('"My crazy name" <hallo@stamhoofd.be>')).toEqual(["hallo@stamhoofd.be"]);
|
|
7
|
-
expect(Email_1.Email.parseEmailStr('hallo@stamhoofd.be')).toEqual(["hallo@stamhoofd.be"]);
|
|
8
|
-
expect(Email_1.Email.parseEmailStr('hallo@stamhoofd.be ')).toEqual(["hallo@stamhoofd.be"]);
|
|
9
|
-
expect(Email_1.Email.parseEmailStr('"hallo@stamhoofd.be"')).toEqual(["hallo@stamhoofd.be"]);
|
|
10
|
-
expect(Email_1.Email.parseEmailStr('<"hallo@stamhoofd.be">')).toEqual(["hallo@stamhoofd.be"]);
|
|
11
|
-
expect(Email_1.Email.parseEmailStr('Gekke naam <"hallo@stamhoofd.be">')).toEqual(["hallo@stamhoofd.be"]);
|
|
12
|
-
expect(Email_1.Email.parseEmailStr('<"hallo@stam\\"hoofd.be">')).toEqual([]);
|
|
13
|
-
expect(Email_1.Email.parseEmailStr('<"hallo@stam,hoofd.be">')).toEqual([]);
|
|
14
|
-
expect(Email_1.Email.parseEmailStr('<hallo@stam,hoofd.be>')).toEqual([]);
|
|
15
|
-
expect(Email_1.Email.parseEmailStr('"Hallo <dit is een test>" <hallo@stamhoofd.be>')).toEqual(["hallo@stamhoofd.be"]);
|
|
16
|
-
expect(Email_1.Email.parseEmailStr('"Hallo 👋🏽" <hallo@stamhoofd.be>')).toEqual(["hallo@stamhoofd.be"]);
|
|
17
|
-
expect(Email_1.Email.parseEmailStr('Hallo <hallo@stam.hoofd.be>')).toEqual(["hallo@stam.hoofd.be"]);
|
|
18
|
-
expect(Email_1.Email.parseEmailStr('Hallo <hallo@stam.hoofd.be')).toEqual([]);
|
|
19
|
-
expect(Email_1.Email.parseEmailStr('"Hallo <dit is \\" een test>" <hallo@stamhoofd.be>')).toEqual(["hallo@stamhoofd.be"]);
|
|
20
|
-
expect(Email_1.Email.parseEmailStr('"Hallo <dit is \\" een test佐>" <hallo@stamhoofd.be>')).toEqual(["hallo@stamhoofd.be"]);
|
|
21
|
-
expect(Email_1.Email.parseEmailStr('"Voornaam \'l Achternaam, en nog iets" <jwz@netscape.com>')).toEqual(["jwz@netscape.com"]);
|
|
22
|
-
expect(Email_1.Email.parseEmailStr('"Voornaam \'l Achternaam, en nog iets" <jwz@netscape.com>, "My crazy name" <hallo@stamhoofd.be>')).toEqual(["jwz@netscape.com", "hallo@stamhoofd.be"]);
|
|
23
|
-
expect(Email_1.Email.parseEmailStr('hallo@example.com, test@test.com')).toEqual(["hallo@example.com", "test@test.com"]);
|
|
24
|
-
expect(Email_1.Email.parseEmailStr('hallo@example.com, invalid, test@test.com')).toEqual(["hallo@example.com", "test@test.com"]);
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
//# sourceMappingURL=Email.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Email.test.js","sourceRoot":"","sources":["../../src/classes/Email.test.ts"],"names":[],"mappings":";;AAAA,mCAA+B;AAE/B,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACnB,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,sCAAsC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAA;QACnG,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAA;QACjF,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAA;QAClF,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAA;QACnF,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,wBAAwB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAA;QACrF,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,mCAAmC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAA;QAChG,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,2BAA2B,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACpE,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,yBAAyB,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAClE,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,uBAAuB,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAChE,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,gDAAgD,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAA;QAC7G,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,mCAAmC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAA;QAChG,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,6BAA6B,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAA;QAC3F,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,4BAA4B,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAErE,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,oDAAoD,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAA;QACjH,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,qDAAqD,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAA;QAElH,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,2DAA2D,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAA;QACtH,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,iGAAiG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,kBAAkB,EAAE,oBAAoB,CAAC,CAAC,CAAA;QAElL,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,kCAAkC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC,CAAA;QAC/G,MAAM,CAAC,aAAK,CAAC,aAAa,CAAC,2CAA2C,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC,CAAA;IAC5H,CAAC,CAAC,CAAA;AACN,CAAC,CAAC,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"root":["../src/index.ts","../src/classes/email.test.ts","../src/classes/email.ts","../src/classes/emailmocker.ts","../src/models/emailaddress.ts","../../../../environment.d.ts","../../../../jest-extended.d.ts","../../../stamhoofd.d.ts"],"version":"5.8.3"}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { Email } from "./Email"
|
|
2
|
-
|
|
3
|
-
describe("Email", () => {
|
|
4
|
-
it("should parse e-mail strings correctly", () => {
|
|
5
|
-
expect(Email.parseEmailStr('"My crazy name" <hallo@stamhoofd.be>')).toEqual(["hallo@stamhoofd.be"])
|
|
6
|
-
expect(Email.parseEmailStr('hallo@stamhoofd.be')).toEqual(["hallo@stamhoofd.be"])
|
|
7
|
-
expect(Email.parseEmailStr('hallo@stamhoofd.be ')).toEqual(["hallo@stamhoofd.be"])
|
|
8
|
-
expect(Email.parseEmailStr('"hallo@stamhoofd.be"')).toEqual(["hallo@stamhoofd.be"])
|
|
9
|
-
expect(Email.parseEmailStr('<"hallo@stamhoofd.be">')).toEqual(["hallo@stamhoofd.be"])
|
|
10
|
-
expect(Email.parseEmailStr('Gekke naam <"hallo@stamhoofd.be">')).toEqual(["hallo@stamhoofd.be"])
|
|
11
|
-
expect(Email.parseEmailStr('<"hallo@stam\\"hoofd.be">')).toEqual([])
|
|
12
|
-
expect(Email.parseEmailStr('<"hallo@stam,hoofd.be">')).toEqual([])
|
|
13
|
-
expect(Email.parseEmailStr('<hallo@stam,hoofd.be>')).toEqual([])
|
|
14
|
-
expect(Email.parseEmailStr('"Hallo <dit is een test>" <hallo@stamhoofd.be>')).toEqual(["hallo@stamhoofd.be"])
|
|
15
|
-
expect(Email.parseEmailStr('"Hallo 👋🏽" <hallo@stamhoofd.be>')).toEqual(["hallo@stamhoofd.be"])
|
|
16
|
-
expect(Email.parseEmailStr('Hallo <hallo@stam.hoofd.be>')).toEqual(["hallo@stam.hoofd.be"])
|
|
17
|
-
expect(Email.parseEmailStr('Hallo <hallo@stam.hoofd.be')).toEqual([])
|
|
18
|
-
|
|
19
|
-
expect(Email.parseEmailStr('"Hallo <dit is \\" een test>" <hallo@stamhoofd.be>')).toEqual(["hallo@stamhoofd.be"])
|
|
20
|
-
expect(Email.parseEmailStr('"Hallo <dit is \\" een test佐>" <hallo@stamhoofd.be>')).toEqual(["hallo@stamhoofd.be"])
|
|
21
|
-
|
|
22
|
-
expect(Email.parseEmailStr('"Voornaam \'l Achternaam, en nog iets" <jwz@netscape.com>')).toEqual(["jwz@netscape.com"])
|
|
23
|
-
expect(Email.parseEmailStr('"Voornaam \'l Achternaam, en nog iets" <jwz@netscape.com>, "My crazy name" <hallo@stamhoofd.be>')).toEqual(["jwz@netscape.com", "hallo@stamhoofd.be"])
|
|
24
|
-
|
|
25
|
-
expect(Email.parseEmailStr('hallo@example.com, test@test.com')).toEqual(["hallo@example.com", "test@test.com"])
|
|
26
|
-
expect(Email.parseEmailStr('hallo@example.com, invalid, test@test.com')).toEqual(["hallo@example.com", "test@test.com"])
|
|
27
|
-
})
|
|
28
|
-
})
|
package/src/classes/Email.ts
DELETED
|
@@ -1,546 +0,0 @@
|
|
|
1
|
-
import { SimpleError } from '@simonbackx/simple-errors';
|
|
2
|
-
import { I18n } from '@stamhoofd/backend-i18n';
|
|
3
|
-
import { Country, Language } from '@stamhoofd/structures';
|
|
4
|
-
import { DataValidator, Formatter, sleep } from '@stamhoofd/utility';
|
|
5
|
-
import htmlToText from 'html-to-text';
|
|
6
|
-
import nodemailer from 'nodemailer';
|
|
7
|
-
import Mail from 'nodemailer/lib/mailer';
|
|
8
|
-
import { EmailAddress } from '../models/EmailAddress';
|
|
9
|
-
|
|
10
|
-
export type EmailInterfaceRecipient = {
|
|
11
|
-
name?: string | null;
|
|
12
|
-
email: string;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export type EmailInterfaceBase = {
|
|
16
|
-
to: EmailInterfaceRecipient[];
|
|
17
|
-
bcc?: EmailInterfaceRecipient[];
|
|
18
|
-
replyTo?: EmailInterfaceRecipient;
|
|
19
|
-
subject: string;
|
|
20
|
-
text?: string;
|
|
21
|
-
html?: string;
|
|
22
|
-
attachments?: { filename: string; path?: string; href?: string; content?: string | Buffer; contentType?: string; encoding?: string }[];
|
|
23
|
-
retryCount?: number;
|
|
24
|
-
type?: 'transactional' | 'broadcast';
|
|
25
|
-
headers?: Record<string, string> | null;
|
|
26
|
-
callback?: (error: Error | null) => void;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export type EmailInterface = EmailInterfaceBase & {
|
|
30
|
-
from: EmailInterfaceRecipient;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
/// An email builder is called until it returns undefined. This allows to reduce memory usage for an e-mail with multiple recipients
|
|
34
|
-
export type EmailBuilder = () => EmailInterface | undefined;
|
|
35
|
-
|
|
36
|
-
export type InternalEmailData = {
|
|
37
|
-
from: string;
|
|
38
|
-
bcc: string | undefined;
|
|
39
|
-
replyTo: string | undefined;
|
|
40
|
-
to: string;
|
|
41
|
-
subject: string;
|
|
42
|
-
text?: string;
|
|
43
|
-
html?: string;
|
|
44
|
-
attachments?: { filename: string; path?: string; href?: string; content?: string | Buffer; contentType?: string }[];
|
|
45
|
-
headers?: Record<string, string>;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
function emailObjectToString(email: null | undefined): undefined;
|
|
49
|
-
function emailObjectToString(email: EmailInterfaceRecipient): string;
|
|
50
|
-
function emailObjectToString(email: EmailInterfaceRecipient | null | undefined): string | undefined {
|
|
51
|
-
if (!email) {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
if (email.name) {
|
|
55
|
-
const cleaned = Formatter.emailSenderName(email.name);
|
|
56
|
-
if (cleaned.length < 2) {
|
|
57
|
-
return email.email;
|
|
58
|
-
}
|
|
59
|
-
return '"' + email.name.replaceAll('"', '') + '" <' + email.email + '>';
|
|
60
|
-
}
|
|
61
|
-
return email.email;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function emailObjectsToString(emails: EmailInterfaceRecipient[]): string | undefined {
|
|
65
|
-
if (emails.length === 0) {
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
return emails.map(emailObjectToString).join(', ');
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
class EmailStatic {
|
|
72
|
-
transporter: Mail;
|
|
73
|
-
transactionalTransporter: Mail;
|
|
74
|
-
rps = 14;
|
|
75
|
-
|
|
76
|
-
currentQueue: EmailBuilder[] = [];
|
|
77
|
-
sending = false;
|
|
78
|
-
|
|
79
|
-
setupIfNeeded() {
|
|
80
|
-
if (this.transporter) {
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (STAMHOOFD.environment === 'test') {
|
|
85
|
-
throw new Error('When using Email in tests, make sure to use EmailMocker.infect() in jest.setup.ts');
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (!STAMHOOFD.SMTP_HOST || !STAMHOOFD.SMTP_PORT) {
|
|
89
|
-
throw new Error('Missing environment variables to send emails');
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// create reusable transporter object using the default SMTP transport
|
|
93
|
-
this.transporter = nodemailer.createTransport({
|
|
94
|
-
pool: true,
|
|
95
|
-
host: STAMHOOFD.SMTP_HOST,
|
|
96
|
-
port: STAMHOOFD.SMTP_PORT,
|
|
97
|
-
auth: {
|
|
98
|
-
user: STAMHOOFD.SMTP_USERNAME, // generated ethereal user
|
|
99
|
-
pass: STAMHOOFD.SMTP_PASSWORD, // generated ethereal password
|
|
100
|
-
},
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
// create reusable transporter object using the default SMTP transport
|
|
104
|
-
this.transactionalTransporter = nodemailer.createTransport({
|
|
105
|
-
pool: true,
|
|
106
|
-
host: STAMHOOFD.TRANSACTIONAL_SMTP_HOST,
|
|
107
|
-
port: STAMHOOFD.TRANSACTIONAL_SMTP_PORT,
|
|
108
|
-
auth: {
|
|
109
|
-
user: STAMHOOFD.TRANSACTIONAL_SMTP_USERNAME, // generated ethereal user
|
|
110
|
-
pass: STAMHOOFD.TRANSACTIONAL_SMTP_PASSWORD, // generated ethereal password
|
|
111
|
-
},
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
// verify connection configuration
|
|
115
|
-
this.transporter.verify((error) => {
|
|
116
|
-
if (error) {
|
|
117
|
-
console.error('SMTP server not working', error);
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
console.log('SMTP server is ready to take our messages');
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
// verify connection configuration
|
|
125
|
-
this.transactionalTransporter.verify((error) => {
|
|
126
|
-
if (error) {
|
|
127
|
-
console.error('Transactinoal SMTP server not working', error);
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
console.log('Transactinoal SMTP server is ready to take our messages');
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
private sendNextIfNeeded() {
|
|
136
|
-
if (!this.sending) {
|
|
137
|
-
if (this.currentQueue.length == 0) {
|
|
138
|
-
console.log('mail queue is empty');
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
let next = this.currentQueue[0]();
|
|
142
|
-
|
|
143
|
-
while (next === undefined) {
|
|
144
|
-
this.currentQueue.shift();
|
|
145
|
-
if (this.currentQueue.length == 0) {
|
|
146
|
-
console.log('mail queue is empty');
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
next = this.currentQueue[0]();
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
this.sending = true;
|
|
153
|
-
this.doSend(next).catch((e) => {
|
|
154
|
-
console.error(e);
|
|
155
|
-
if (next.callback) {
|
|
156
|
-
next.callback(e);
|
|
157
|
-
}
|
|
158
|
-
}).finally(() => {
|
|
159
|
-
this.sending = false;
|
|
160
|
-
this.sendNextIfNeeded();
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
parseTo(to: string | EmailInterfaceRecipient[]): EmailInterfaceRecipient[] {
|
|
166
|
-
if (typeof to === 'string') {
|
|
167
|
-
return this.parseEmailStr(to).map(email => ({ email }));
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Filter invalid email addresses
|
|
171
|
-
return to.filter(r => DataValidator.isEmailValid(r.email));
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Get the raw email
|
|
176
|
-
*/
|
|
177
|
-
parseEmailStr(emailStr: string): string[] {
|
|
178
|
-
let insideQuote = false;
|
|
179
|
-
let escaped = false;
|
|
180
|
-
let inAddr = false;
|
|
181
|
-
let email = '';
|
|
182
|
-
let didFindAddr = false;
|
|
183
|
-
let cleanedStr = '';
|
|
184
|
-
|
|
185
|
-
const addresses: string[] = [];
|
|
186
|
-
|
|
187
|
-
function endAddress() {
|
|
188
|
-
let m: string;
|
|
189
|
-
if (didFindAddr) {
|
|
190
|
-
m = email.trim();
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
m = cleanedStr.trim();
|
|
194
|
-
}
|
|
195
|
-
if (DataValidator.isEmailValid(m)) {
|
|
196
|
-
addresses.push(m);
|
|
197
|
-
}
|
|
198
|
-
didFindAddr = false;
|
|
199
|
-
email = '';
|
|
200
|
-
inAddr = false;
|
|
201
|
-
insideQuote = false;
|
|
202
|
-
escaped = false;
|
|
203
|
-
cleanedStr = '';
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
207
|
-
for (let index = 0; index < emailStr.length; index++) {
|
|
208
|
-
const shouldEscape = escaped;
|
|
209
|
-
if (escaped) {
|
|
210
|
-
escaped = false;
|
|
211
|
-
}
|
|
212
|
-
const character = emailStr[index];
|
|
213
|
-
if (insideQuote) {
|
|
214
|
-
if (character === '\\') {
|
|
215
|
-
escaped = true;
|
|
216
|
-
continue;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if (!shouldEscape) {
|
|
221
|
-
if (character === '"') {
|
|
222
|
-
if (insideQuote) {
|
|
223
|
-
insideQuote = false;
|
|
224
|
-
continue;
|
|
225
|
-
}
|
|
226
|
-
insideQuote = true;
|
|
227
|
-
continue;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
if (!insideQuote) {
|
|
231
|
-
if (character === '<') {
|
|
232
|
-
inAddr = true;
|
|
233
|
-
continue;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
if (character === '>') {
|
|
237
|
-
inAddr = false;
|
|
238
|
-
didFindAddr = true;
|
|
239
|
-
continue;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
if (character === ',') {
|
|
243
|
-
// End previous address
|
|
244
|
-
endAddress();
|
|
245
|
-
continue;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
if (inAddr) {
|
|
251
|
-
email += character;
|
|
252
|
-
}
|
|
253
|
-
cleanedStr += character;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
endAddress();
|
|
257
|
-
return addresses;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
private matchWhitelist(email: string, whitelist: string[]) {
|
|
261
|
-
if (!whitelist.includes('*') && !whitelist.includes('*@*')) {
|
|
262
|
-
const l = email.toLowerCase();
|
|
263
|
-
if (whitelist.includes(l)) {
|
|
264
|
-
return true;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
const domainIndex = l.indexOf('@');
|
|
268
|
-
const domain = l.substring(domainIndex);
|
|
269
|
-
|
|
270
|
-
if (whitelist.includes('*' + domain)) {
|
|
271
|
-
return true;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
if (STAMHOOFD.environment === 'production') {
|
|
275
|
-
console.warn('Filtered email ' + l + ': not whitelisted');
|
|
276
|
-
}
|
|
277
|
-
return false;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
return true;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
private filterWhitelist(recipients: EmailInterfaceRecipient[], whitelist: string[]) {
|
|
284
|
-
if (!whitelist.includes('*') && !whitelist.includes('*@*')) {
|
|
285
|
-
return recipients.filter((mail) => {
|
|
286
|
-
return this.matchWhitelist(mail.email, whitelist);
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
return recipients;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
private async doSend(data: EmailInterface) {
|
|
294
|
-
let recipients = data.to.filter(({ email }) => DataValidator.isEmailValid(email));
|
|
295
|
-
|
|
296
|
-
// Check if this email is not marked as spam
|
|
297
|
-
// Filter recipients if bounced or spam
|
|
298
|
-
if (recipients.length === 0) {
|
|
299
|
-
// Invalid string
|
|
300
|
-
console.warn('No recipients for email');
|
|
301
|
-
|
|
302
|
-
try {
|
|
303
|
-
data.callback?.(
|
|
304
|
-
new SimpleError({
|
|
305
|
-
code: 'invalid_email_address',
|
|
306
|
-
message: 'Invalid email address',
|
|
307
|
-
human: $t(`%1Mi`),
|
|
308
|
-
}),
|
|
309
|
-
);
|
|
310
|
-
}
|
|
311
|
-
catch (e) {
|
|
312
|
-
console.error('Error in email callback', e);
|
|
313
|
-
}
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// Check spam and bounces
|
|
318
|
-
recipients = await EmailAddress.filterSendTo(recipients);
|
|
319
|
-
|
|
320
|
-
if (recipients.length === 0) {
|
|
321
|
-
// Invalid string
|
|
322
|
-
console.warn("Filtered all emails due hard bounce or spam '" + data.to + "'. E-mail skipped");
|
|
323
|
-
|
|
324
|
-
try {
|
|
325
|
-
data.callback?.(
|
|
326
|
-
new SimpleError({
|
|
327
|
-
code: 'all_filtered',
|
|
328
|
-
message: 'All recipients are filtered due to hard bounce or spam',
|
|
329
|
-
human: data.to.length > 1 ? $t(`%G4`) : $t('%1E7'),
|
|
330
|
-
}),
|
|
331
|
-
);
|
|
332
|
-
}
|
|
333
|
-
catch (e) {
|
|
334
|
-
console.error('Error in email callback', e);
|
|
335
|
-
}
|
|
336
|
-
return;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// Filter by environment
|
|
340
|
-
if (STAMHOOFD.environment !== 'production' || (STAMHOOFD.WHITELISTED_EMAIL_DESTINATIONS && STAMHOOFD.WHITELISTED_EMAIL_DESTINATIONS.length > 0)) {
|
|
341
|
-
const whitelist = STAMHOOFD.WHITELISTED_EMAIL_DESTINATIONS ?? [];
|
|
342
|
-
recipients = this.filterWhitelist(recipients, whitelist);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
const to = emailObjectsToString(recipients);
|
|
346
|
-
|
|
347
|
-
if (!to || recipients.length === 0) {
|
|
348
|
-
// Invalid string
|
|
349
|
-
try {
|
|
350
|
-
data.callback?.(
|
|
351
|
-
new SimpleError({
|
|
352
|
-
code: 'email_skipped_whitelist',
|
|
353
|
-
message: 'All recipients are filtered due to environment',
|
|
354
|
-
human: data.to.length > 1 ? $t(`%G5`) : $t('%1E8'),
|
|
355
|
-
}),
|
|
356
|
-
);
|
|
357
|
-
}
|
|
358
|
-
catch (e) {
|
|
359
|
-
console.error('Error in email callback', e);
|
|
360
|
-
}
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
// Clean bcc
|
|
365
|
-
let bccRecipients: EmailInterfaceRecipient[] = [];
|
|
366
|
-
if (data.bcc) {
|
|
367
|
-
// Filter
|
|
368
|
-
bccRecipients.push(...(await EmailAddress.filterSendTo(data.bcc.filter(({ email }) => DataValidator.isEmailValid(email)))));
|
|
369
|
-
|
|
370
|
-
// Filter by environment
|
|
371
|
-
if (STAMHOOFD.environment !== 'production' || (STAMHOOFD.WHITELISTED_EMAIL_DESTINATIONS && STAMHOOFD.WHITELISTED_EMAIL_DESTINATIONS.length > 0)) {
|
|
372
|
-
const whitelist = STAMHOOFD.WHITELISTED_EMAIL_DESTINATIONS ?? [];
|
|
373
|
-
bccRecipients = this.filterWhitelist(bccRecipients, whitelist);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
this.setupIfNeeded();
|
|
377
|
-
|
|
378
|
-
// send mail with defined transport object
|
|
379
|
-
const mail: InternalEmailData = {
|
|
380
|
-
from: emailObjectToString(data.from), // sender address
|
|
381
|
-
bcc: emailObjectsToString(bccRecipients),
|
|
382
|
-
replyTo: data.replyTo ? emailObjectToString(data.replyTo) : undefined,
|
|
383
|
-
to,
|
|
384
|
-
subject: data.subject.substring(0, 1000), // Subject line
|
|
385
|
-
text: data.text, // plain text body
|
|
386
|
-
};
|
|
387
|
-
|
|
388
|
-
if (data.attachments) {
|
|
389
|
-
mail.attachments = data.attachments;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
if (data.headers) {
|
|
393
|
-
mail.headers = data.headers;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
if (data.html) {
|
|
397
|
-
mail.html = data.html;
|
|
398
|
-
|
|
399
|
-
if (!data.text) {
|
|
400
|
-
mail.text = htmlToText.fromString(data.html, {
|
|
401
|
-
wordwrap: null,
|
|
402
|
-
unorderedListItemPrefix: ' - ',
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
if (!DataValidator.isEmailValid(data.from.email)) {
|
|
408
|
-
throw new Error('Invalid from email ' + data.from.email);
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
try {
|
|
412
|
-
// Can we send from the transactional email server?
|
|
413
|
-
if (STAMHOOFD.TRANSACTIONAL_WHITELIST !== undefined && data.type === 'transactional') {
|
|
414
|
-
if (!this.matchWhitelist(data.from.email, STAMHOOFD.TRANSACTIONAL_WHITELIST)) {
|
|
415
|
-
// Not supported
|
|
416
|
-
data.type = 'broadcast';
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
const transporter = (data.type === 'transactional') ? this.transactionalTransporter : this.transporter;
|
|
421
|
-
|
|
422
|
-
if (data.type === 'transactional') {
|
|
423
|
-
mail.headers = {
|
|
424
|
-
...data.headers,
|
|
425
|
-
...STAMHOOFD.TRANSACTIONAL_SMTP_HEADERS,
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
|
-
else {
|
|
429
|
-
mail.headers = {
|
|
430
|
-
...data.headers,
|
|
431
|
-
...STAMHOOFD.SMTP_HEADERS,
|
|
432
|
-
};
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
console.log('Sending email', to, data.subject, data.type);
|
|
436
|
-
const info = await transporter.sendMail(mail);
|
|
437
|
-
console.log('Message sent:', to, data.subject, info.messageId, data.type);
|
|
438
|
-
|
|
439
|
-
if (STAMHOOFD.environment === 'development') {
|
|
440
|
-
await sleep(100);
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
try {
|
|
444
|
-
data.callback?.(null);
|
|
445
|
-
}
|
|
446
|
-
catch (e) {
|
|
447
|
-
console.error('Error in email callback', e);
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
catch (e) {
|
|
451
|
-
if (STAMHOOFD.environment !== 'test') {
|
|
452
|
-
console.error('Failed to send e-mail:');
|
|
453
|
-
console.error(e);
|
|
454
|
-
console.error(mail);
|
|
455
|
-
|
|
456
|
-
// Sleep 1 second to give servers some time to fix possible rate limits
|
|
457
|
-
await sleep(1000);
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
// Reschedule twice (at maximum) to fix temporary connection issues
|
|
461
|
-
data.retryCount = (data.retryCount ?? 0) + 1;
|
|
462
|
-
|
|
463
|
-
if (data.retryCount <= 2) {
|
|
464
|
-
if (data.type === 'transactional' && data.retryCount === 2) {
|
|
465
|
-
data.type = 'broadcast';
|
|
466
|
-
}
|
|
467
|
-
this.send(data);
|
|
468
|
-
}
|
|
469
|
-
else {
|
|
470
|
-
try {
|
|
471
|
-
if (data.callback) {
|
|
472
|
-
data.callback(e);
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
catch (e2) {
|
|
476
|
-
console.error('Error in email failure callback', e2, 'for original error', e);
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
// Email address is not verified.
|
|
480
|
-
if (STAMHOOFD.environment === 'production') {
|
|
481
|
-
if (data.from.email !== this.getWebmasterFromEmail().email) {
|
|
482
|
-
this.sendWebmaster({
|
|
483
|
-
subject: $t(`%G6`),
|
|
484
|
-
text: $t(`%G7`, { email: data.from.email, to: mail.to }) + ': \n\n' + e + '\n\n' + (mail.text ?? ''),
|
|
485
|
-
type: (data.type === 'transactional') ? 'broadcast' : 'transactional',
|
|
486
|
-
});
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
getWebmasterFromEmail() {
|
|
494
|
-
return {
|
|
495
|
-
name: Formatter.capitalizeFirstLetter(STAMHOOFD.platformName ?? 'Stamhoofd'),
|
|
496
|
-
email: 'webmaster@' + (new I18n(Language.Dutch, Country.Belgium).localizedDomains.defaultTransactionalEmail()),
|
|
497
|
-
};
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
getWebmasterToEmail() {
|
|
501
|
-
return {
|
|
502
|
-
name: 'Stamhoofd',
|
|
503
|
-
email: 'hallo@stamhoofd.be',
|
|
504
|
-
};
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
/**
|
|
508
|
-
* Send an email to the webmaster
|
|
509
|
-
*/
|
|
510
|
-
sendWebmaster(data: Omit<EmailInterfaceBase, 'to'>) {
|
|
511
|
-
const mail = Object.assign(data, {
|
|
512
|
-
from: this.getWebmasterFromEmail(),
|
|
513
|
-
to: [this.getWebmasterToEmail()],
|
|
514
|
-
type: data.type ?? 'transactional',
|
|
515
|
-
});
|
|
516
|
-
this.send(mail);
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
send(data: EmailInterface) {
|
|
520
|
-
let didSend = false;
|
|
521
|
-
|
|
522
|
-
this.schedule(() => {
|
|
523
|
-
if (didSend) {
|
|
524
|
-
return undefined;
|
|
525
|
-
}
|
|
526
|
-
didSend = true;
|
|
527
|
-
return data;
|
|
528
|
-
});
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
schedule(builder: EmailBuilder) {
|
|
532
|
-
this.currentQueue.push(builder);
|
|
533
|
-
this.sendNextIfNeeded();
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
wait() {
|
|
537
|
-
return new Promise<void>((resolve) => {
|
|
538
|
-
this.schedule(() => {
|
|
539
|
-
resolve();
|
|
540
|
-
return undefined;
|
|
541
|
-
});
|
|
542
|
-
});
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
export const Email = new EmailStatic();
|