New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

zone-mta

Package Overview
Dependencies
Maintainers
1
Versions
334
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

zone-mta - npm Package Compare versions

Comparing version 1.4.0 to 1.5.0

20

config/default.js

@@ -113,3 +113,19 @@ 'use strict';

},
sendingZone: 'bounces'
sendingZone: 'bounces',
zoneConfig: {
// specify zone specific bounce options
myzonename: {
// if true then ignore this block, revert to default
disabled: true,
// if not set then default mailerDaemon config is used
mailerDaemon: {
name: 'Mail Delivery Subsystem',
// [HOSTNAME] will be replaced with the hostname that was used to send this message
address: 'mailer-daemon@[HOSTNAME]'
},
// use same queue for handling bounces as for the original message
// if not set then default queue is used
sendingZone: 'myzonename'
}
}
},

@@ -213,3 +229,3 @@

api: {
port: 8080,
port: 12080,
// bind to localhost only

@@ -216,0 +232,0 @@ host: '127.0.0.1',

30

lib/db.js

@@ -8,2 +8,4 @@ 'use strict';

module.exports.mongoclient = false;
module.exports.database = false;

@@ -19,3 +21,3 @@ module.exports.senderDb = false;

if (!config) {
return callback(null, main);
return callback(null, false);
}

@@ -30,2 +32,5 @@ if (config && !/[:/]/.test(config)) {

}
if (main && db.s && db.s.options && db.s.options.dbName) {
db = db.db(db.s.options.dbName);
}
return callback(null, db);

@@ -40,18 +45,27 @@ });

}
module.exports.database = db;
getDBConnection(db, config.dbs.gridfs, (err, db) => {
module.exports.mongoclient = db;
if (db.s && db.s.options && db.s.options.dbName) {
module.exports.database = db.db(db.s.options.dbName);
} else {
module.exports.database = db;
}
getDBConnection(db, config.dbs.gridfs, (err, gdb) => {
if (err) {
return callback(err);
}
module.exports.gridfs = db;
getDBConnection(db, config.dbs.users, (err, db) => {
module.exports.gridfs = gdb || module.exports.database;
getDBConnection(db, config.dbs.users, (err, udb) => {
if (err) {
return callback(err);
}
module.exports.users = db;
getDBConnection(db, config.dbs.sender, (err, db) => {
module.exports.users = udb || module.exports.database;
getDBConnection(db, config.dbs.sender, (err, sdb) => {
if (err) {
return callback(err);
}
module.exports.senderDb = db;
module.exports.senderDb = sdb || module.exports.database;

@@ -58,0 +72,0 @@ module.exports.redisConfig = redisConfig(config.dbs.redis);

@@ -113,14 +113,20 @@ 'use strict';

setMeta(id, data, callback) {
this.mongodb.collection(this.options.gfs + '.files').findAndModify({
filename: 'message ' + id
}, false, {
$set: {
'metadata.data': data
this.mongodb.collection(this.options.gfs + '.files').findAndModify(
{
filename: 'message ' + id
},
false,
{
$set: {
'metadata.data': data
}
},
{},
err => {
if (err) {
return callback(err);
}
return callback();
}
}, {}, err => {
if (err) {
return callback(err);
}
return callback();
});
);
}

@@ -135,15 +141,18 @@

getMeta(id, callback) {
this.mongodb.collection(this.options.gfs + '.files').findOne({
filename: 'message ' + id
}, (err, item) => {
if (err) {
return callback(err);
}
this.mongodb.collection(this.options.gfs + '.files').findOne(
{
filename: 'message ' + id
},
(err, item) => {
if (err) {
return callback(err);
}
if (!item) {
return callback(null, false);
if (!item) {
return callback(null, false);
}
return callback(null, (item && item.metadata && item.metadata.data) || {});
}
return callback(null, (item && item.metadata && item.metadata.data) || {});
});
);
}

@@ -483,53 +492,56 @@

this.mongodb.collection('suppressionlist').findOne({
$or: [
{
address: (delivery.recipient || '').toLowerCase().trim()
},
{
domain: delivery.domain
this.mongodb.collection('suppressionlist').findOne(
{
$or: [
{
address: (delivery.recipient || '').toLowerCase().trim()
},
{
domain: delivery.domain
}
]
},
(err, suppressed) => {
if (err) {
// just ignore, not important, even though should not happen
}
]
}, (err, suppressed) => {
if (err) {
// just ignore, not important, even though should not happen
}
if (suppressed) {
return this.releaseDelivery(delivery, err => {
if (err) {
this.locks.release(delivery._lock);
return callback(err);
}
log.info(
'Queue',
'%s.%s DROP[suppressed] Recipient %s was found from suppression list',
delivery.id,
delivery.seq,
delivery.recipient
);
if (suppressed) {
return this.releaseDelivery(delivery, err => {
if (err) {
this.locks.release(delivery._lock);
return callback(err);
}
log.info(
'Queue',
'%s.%s DROP[suppressed] Recipient %s was found from suppression list',
delivery.id,
delivery.seq,
delivery.recipient
);
let suppresskey = '';
let suppressvalue = '';
let suppresskey = '';
let suppressvalue = '';
if (suppressed.address && (delivery.recipient || '').toLowerCase().trim() === suppressed.address) {
suppresskey = 'suppressed address';
suppressvalue = suppressed.address;
} else if (suppressed.domain && delivery.domain === suppressed.domain) {
suppresskey = 'suppressed domain';
suppressvalue = suppressed.domain;
}
if (suppressed.address && (delivery.recipient || '').toLowerCase().trim() === suppressed.address) {
suppresskey = 'suppressed address';
suppressvalue = suppressed.address;
} else if (suppressed.domain && delivery.domain === suppressed.domain) {
suppresskey = 'suppressed domain';
suppressvalue = suppressed.domain;
}
remotelog(delivery.id, delivery.seq, 'DROP', {
reason: 'Recipient was found from suppression list',
recipient: delivery.recipient,
[suppresskey]: suppressvalue
remotelog(delivery.id, delivery.seq, 'DROP', {
reason: 'Recipient was found from suppression list',
recipient: delivery.recipient,
[suppresskey]: suppressvalue
});
// try to find another delivery
return setImmediate(tryNext);
});
}
// try to find another delivery
return setImmediate(tryNext);
});
return callback(null, delivery);
}
return callback(null, delivery);
});
);
});

@@ -827,13 +839,16 @@ }

log.verbose('Queue', '%s REMOVE', id);
this.mongodb.collection(this.options.gfs + '.files').findOne({
filename: 'message ' + id
}, (err, entry) => {
if (err) {
return callback(err);
this.mongodb.collection(this.options.gfs + '.files').findOne(
{
filename: 'message ' + id
},
(err, entry) => {
if (err) {
return callback(err);
}
if (!entry) {
return callback(null, false);
}
this.gridstore.delete(entry._id, callback);
}
if (!entry) {
return callback(null, false);
}
this.gridstore.delete(entry._id, callback);
});
);
}

@@ -1140,12 +1155,15 @@

this.mongodb.collection(this.options.collection).find(query).count((err, count) => {
if (err) {
return reject(err);
}
this.mongodb
.collection(this.options.collection)
.find(query)
.count((err, count) => {
if (err) {
return reject(err);
}
resolve({
key: zone,
value: count
resolve({
key: zone,
value: count
});
});
});
});

@@ -1170,4 +1188,4 @@

this.closing = true;
if (this.mongodb) {
this.mongodb.close(() => false);
if (db.mongoclient) {
db.mongoclient.close(() => false);
}

@@ -1200,121 +1218,140 @@ this.stopPeriodicCheck();

// ensure indexes for the gridstore queries
this.mongodb.collection(this.options.gfs + '.files').createIndexes([
{
key: {
uploadDate: 1
},
name: 'mailupload'
},
{
key: {
filename: 1
},
name: 'mailfile'
}
], () => {
// ensure indexes for the suppression list table
this.mongodb.collection('suppressionlist').createIndexes([
this.mongodb.collection(this.options.gfs + '.files').createIndexes(
[
{
key: {
address: 1
uploadDate: 1
},
name: 'suppressed_address'
name: 'mailupload'
},
{
key: {
domain: 1
filename: 1
},
name: 'suppressed_domain'
},
{
key: {
created: -1
},
name: 'list_by_newer'
name: 'mailfile'
}
], () => {
// ensure indexes for the queue queries
this.mongodb.collection(this.options.collection).createIndexes([
{
key: {
created: 1
],
() => {
// ensure indexes for the suppression list table
this.mongodb.collection('suppressionlist').createIndexes(
[
{
key: {
address: 1
},
name: 'suppressed_address'
},
name: 'findall'
},
{
key: {
sendingZone: 1,
queued: 1,
locked: 1,
assigned: 1,
domain: 1
{
key: {
domain: 1
},
name: 'suppressed_domain'
},
name: 'search_next'
},
{
key: {
id: 1,
seq: 1
},
name: 'delivery'
},
{
key: {
locked: 1,
assigned: 1,
lockTime: 1
},
name: 'message_locking'
}
], () => {
// release old locks
this.mongodb.collection(this.options.collection).updateMany({
locked: true,
// only touch messages assigned to this instance
assigned: this.instanceId
}, {
$set: {
locked: false,
lockTime: 0
{
key: {
created: -1
},
name: 'list_by_newer'
}
}, {
w: 1,
multi: true
}, (err, r) => {
if (err) {
return callback(err);
}
],
() => {
// ensure indexes for the queue queries
this.mongodb.collection(this.options.collection).createIndexes(
[
{
key: {
created: 1
},
name: 'findall'
},
{
key: {
sendingZone: 1,
queued: 1,
locked: 1,
assigned: 1,
domain: 1
},
name: 'search_next'
},
{
key: {
id: 1,
seq: 1
},
name: 'delivery'
},
{
key: {
locked: 1,
assigned: 1,
lockTime: 1
},
name: 'message_locking'
}
],
() => {
// release old locks
this.mongodb.collection(this.options.collection).updateMany(
{
locked: true,
// only touch messages assigned to this instance
assigned: this.instanceId
},
{
$set: {
locked: false,
lockTime: 0
}
},
{
w: 1,
multi: true
},
(err, r) => {
if (err) {
return callback(err);
}
if (r.result.n) {
log.verbose('GC', 'Released %s expired locks for queued messages', r.result.n);
}
if (r.result.n) {
log.verbose('GC', 'Released %s expired locks for queued messages', r.result.n);
}
// assign unassigned messages
this.mongodb.collection(this.options.collection).updateMany({
assigned: {
$exists: false
}
}, {
$set: {
assigned: 'no'
}
}, {
w: 1,
multi: true
}, (err, r) => {
if (err) {
return callback(err);
}
// assign unassigned messages
this.mongodb.collection(this.options.collection).updateMany(
{
assigned: {
$exists: false
}
},
{
$set: {
assigned: 'no'
}
},
{
w: 1,
multi: true
},
(err, r) => {
if (err) {
return callback(err);
}
if (r.result.n) {
log.verbose('GC', 'Updated %s unassigned messages', r.result.n);
if (r.result.n) {
log.verbose('GC', 'Updated %s unassigned messages', r.result.n);
}
this.startPeriodicCheck();
return setImmediate(() => callback(null, true));
}
);
}
);
}
this.startPeriodicCheck();
return setImmediate(() => callback(null, true));
});
});
});
});
});
);
}
);
}
);
});

@@ -1321,0 +1358,0 @@ }

@@ -1115,2 +1115,3 @@ 'use strict';

zone: this.zone.name,
from: delivery.from,

@@ -1117,0 +1118,0 @@ to: delivery.recipient,

{
"name": "zone-mta",
"private": false,
"version": "1.4.0",
"version": "1.5.0",
"description": "Tiny outbound MTA",

@@ -45,3 +45,3 @@ "main": "app.js",

"grunt-eslint": "^20.1.0",
"moment": "^2.20.0",
"moment": "^2.20.1",
"random-message": "^1.1.0",

@@ -48,0 +48,0 @@ "zip-stream": "^1.2.0"

@@ -9,6 +9,15 @@ 'use strict';

// generate a multipart/report DSN failure response
function generateBounceMessage(from, to, bounce) {
function generateBounceMessage(bounce) {
let headers = bounce.headers;
let messageId = headers.getFirst('Message-ID');
let cfg = app.config.zoneConfig[bounce.zone];
if (!cfg || cfg.disabled) {
cfg = {};
}
let from = cfg.mailerDaemon || app.config.mailerDaemon;
let to = bounce.from;
let sendingZone = cfg.sendingZone || app.config.sendingZone;
let rootNode = new MimeNode('multipart/report; report-type=delivery-status');

@@ -21,3 +30,3 @@

rootNode.setHeader('To', to);
rootNode.setHeader('X-Sending-Zone', app.config.sendingZone);
rootNode.setHeader('X-Sending-Zone', sendingZone);
rootNode.setHeader('X-Failed-Recipients', bounce.to);

@@ -32,4 +41,7 @@ rootNode.setHeader('Auto-Submitted', 'auto-replied');

rootNode.createChild('text/plain').setHeader('Content-Description', 'Notification').setContent(
`Delivery to the following recipient failed permanently:
rootNode
.createChild('text/plain')
.setHeader('Content-Description', 'Notification')
.setContent(
`Delivery to the following recipient failed permanently:
${bounce.to}

@@ -42,6 +54,9 @@

`
);
);
rootNode.createChild('message/delivery-status').setHeader('Content-Description', 'Delivery report').setContent(
`Reporting-MTA: dns; ${bounce.name || os.hostname()}
rootNode
.createChild('message/delivery-status')
.setHeader('Content-Description', 'Delivery report')
.setContent(
`Reporting-MTA: dns; ${bounce.name || os.hostname()}
X-ZoneMTA-Queue-ID: ${bounce.id}

@@ -55,12 +70,15 @@ X-ZoneMTA-Sender: rfc822; ${bounce.from}

` +
(bounce.mxHostname
? `Remote-MTA: dns; ${bounce.mxHostname}
(bounce.mxHostname
? `Remote-MTA: dns; ${bounce.mxHostname}
`
: '') +
`Diagnostic-Code: smtp; ${bounce.response}
: '') +
`Diagnostic-Code: smtp; ${bounce.response}
`
);
);
rootNode.createChild('text/rfc822-headers').setHeader('Content-Description', 'Undelivered Message Headers').setContent(headers.build());
rootNode
.createChild('text/rfc822-headers')
.setHeader('Content-Description', 'Undelivered Message Headers')
.setContent(headers.build());

@@ -99,3 +117,3 @@ return rootNode;

let mail = generateBounceMessage(app.config.mailerDaemon, bounce.from, bounce);
let mail = generateBounceMessage(bounce);

@@ -102,0 +120,0 @@ app.getQueue().generateId((err, id) => {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc