mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-23 11:55:01 +03:00
Updated email sending to remove invalid recipient emails (#16171)
closes https://github.com/TryGhost/Team/issues/2388 We have seen examples of sites with member emails that have invalid characters that can cause an entire email send to fail, or just cause a failure to those addresses. The issue that allowed members with invalid email address to be saved was patched earlier, but its possible there are still sites that contain some of those invalid email addresses. This change updates new sending service to filter out the recipients with invalid email address before passing them to mail provider, so these rogue addresses don't affect the whole batch in anyway. We also trim the recipient emails to clear out any spaces first, which is the most likely culprit. - uses new email validator that detects invalid email addresses with special chars
This commit is contained in:
parent
9df131ee5a
commit
88979c852b
@ -1,3 +1,6 @@
|
||||
const validator = require('@tryghost/validator');
|
||||
const logging = require('@tryghost/logging');
|
||||
|
||||
/**
|
||||
* @typedef {object} EmailData
|
||||
* @prop {string} html
|
||||
@ -111,7 +114,7 @@ class SendingService {
|
||||
buildRecipients(members, replacementDefinitions) {
|
||||
return members.map((member) => {
|
||||
return {
|
||||
email: member.email,
|
||||
email: member.email?.trim(),
|
||||
replacements: replacementDefinitions.map((def) => {
|
||||
return {
|
||||
id: def.id,
|
||||
@ -120,6 +123,13 @@ class SendingService {
|
||||
};
|
||||
})
|
||||
};
|
||||
}).filter((recipient) => {
|
||||
// Remove invalid recipient email addresses
|
||||
const isValidRecipient = validator.isEmail(recipient.email, {legacy: false});
|
||||
if (!isValidRecipient) {
|
||||
logging.warn(`Removed recipient ${recipient.email} from list because it is not a valid email address`);
|
||||
}
|
||||
return isValidRecipient;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
"@tryghost/logging": "2.4.0",
|
||||
"@tryghost/tpl": "0.1.21",
|
||||
"bson-objectid": "2.0.4",
|
||||
"@tryghost/validator": "^0.2.0",
|
||||
"cheerio": "0.22.0",
|
||||
"handlebars": "4.7.7",
|
||||
"juice": "8.1.0",
|
||||
|
@ -102,6 +102,66 @@ describe('Sending service', function () {
|
||||
));
|
||||
});
|
||||
|
||||
it('removes invalid recipients before sending', async function () {
|
||||
const sendingService = new SendingService({
|
||||
emailRenderer,
|
||||
emailProvider
|
||||
});
|
||||
|
||||
const response = await sendingService.send({
|
||||
post: {},
|
||||
newsletter: {},
|
||||
segment: null,
|
||||
emailId: '123',
|
||||
members: [
|
||||
{
|
||||
email: 'member@example.com',
|
||||
name: 'John'
|
||||
},
|
||||
{
|
||||
email: 'member+invalid@example.com<6F>',
|
||||
name: 'John'
|
||||
}
|
||||
]
|
||||
}, {
|
||||
clickTrackingEnabled: true,
|
||||
openTrackingEnabled: true
|
||||
});
|
||||
assert.equal(response.id, 'provider-123');
|
||||
sinon.assert.calledOnce(sendStub);
|
||||
assert(sendStub.calledWith(
|
||||
{
|
||||
subject: 'Hi',
|
||||
from: 'ghost@example.com',
|
||||
replyTo: 'ghost+reply@example.com',
|
||||
html: '<html><body>Hi {{name}}</body></html>',
|
||||
plaintext: 'Hi',
|
||||
emailId: '123',
|
||||
replacementDefinitions: [
|
||||
{
|
||||
id: 'name',
|
||||
token: '{{name}}',
|
||||
getValue: sinon.match.func
|
||||
}
|
||||
],
|
||||
recipients: [
|
||||
{
|
||||
email: 'member@example.com',
|
||||
replacements: [{
|
||||
id: 'name',
|
||||
token: '{{name}}',
|
||||
value: 'John'
|
||||
}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
clickTrackingEnabled: true,
|
||||
openTrackingEnabled: true
|
||||
}
|
||||
));
|
||||
});
|
||||
|
||||
it('maps null replyTo to undefined', async function () {
|
||||
const sendingService = new SendingService({
|
||||
emailRenderer,
|
||||
|
Loading…
Reference in New Issue
Block a user