Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mailcomposer

Package Overview
Dependencies
Maintainers
1
Versions
76
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mailcomposer - npm Package Compare versions

Comparing version 0.1.10 to 0.1.11

lib/dkim.js

114

lib/mailcomposer.js

@@ -5,2 +5,3 @@ var Stream = require("stream").Stream,

toPunycode = require("./punycode"),
DKIMSign = require("./dkim").DKIMSign,
fs = require("fs");

@@ -77,2 +78,20 @@

/**
* <p>If set to true, caches the output for further processing (DKIM signing etc.)</p>
* @private
*/
this._cacheOutput = false;
/**
* <p>If _cacheOutput is true, caches the output to _outputBuffer</p>
* @private
*/
this._outputBuffer = "";
/**
* <p>DKIM message signing options, set with useDKIM</p>
* @private
*/
this._dkim = false;
/**
* <p>Counter for generating unique mime boundaries etc.</p>

@@ -160,2 +179,17 @@ * @private

/**
* <p>Setup DKIM for signing generated message. Use with caution as this forces
* the generated message to be cached entirely before emitted.</p>
*
* @param {Object} dkim DKIM signing settings
* @param {String} [dkim.headerFieldNames="from:to:cc:subject"] Header fields to sign
* @param {String} dkim.privateKey DKMI private key
* @param {String} dkim.domainName Domain name to use for signing (ie: "domain.com")
* @param {String} dkim.keySelector Selector for the DKMI public key (ie. "dkim" if you have set up a TXT record for "dkim._domainkey.domain.com"
*/
MailComposer.prototype.useDKIM = function(dkim){
this._dkim = dkim || {};
this._cacheOutput = true;
};
/**
* <p>Adds an attachment to the list</p>

@@ -466,3 +500,7 @@ *

this.emit("data", new Buffer(headers.join("\r\n")+"\r\n\r\n", "utf-8"));
if(!this._cacheOutput){
this.emit("data", new Buffer(headers.join("\r\n")+"\r\n\r\n", "utf-8"));
}else{
this._outputBuffer += headers.join("\r\n")+"\r\n\r\n";
}
};

@@ -822,3 +860,7 @@

if(slice && slice.length){
this.emit("data", new Buffer(slice.join("\r\n")+"\r\n", "utf-8"));
if(!this._cacheOutput){
this.emit("data", new Buffer(slice.join("\r\n")+"\r\n", "utf-8"));
}else{
this._outputBuffer += slice.join("\r\n")+"\r\n";
}
}

@@ -836,3 +878,7 @@

}else{
this.emit("end");
if(!this._cacheOutput){
this.emit("end");
}else{
this._processBufferedOutput();
}
}

@@ -842,3 +888,7 @@ }).bind(this));

}else if(isEnd){
this.emit("end");
if(!this._cacheOutput){
this.emit("end");
}else{
this._processBufferedOutput();
}
}

@@ -887,3 +937,7 @@ break;

this.emit("data", new Buffer(data + "\r\n", "utf-8"));
if(!this._cacheOutput){
this.emit("data", new Buffer(data + "\r\n", "utf-8"));
}else{
this._outputBuffer += data + "\r\n";
}
process.nextTick(callback);

@@ -913,4 +967,12 @@ return;

if(err || !stat.isFile()){
this.emit("data", new Buffer(new Buffer("<ERROR OPENING FILE>",
if(!this._cacheOutput){
this.emit("data", new Buffer(new Buffer("<ERROR OPENING FILE>",
"utf-8").toString("base64")+"\r\n", "utf-8"));
}else{
this._outputBuffer += new Buffer("<ERROR OPENING FILE>",
"utf-8").toString("base64")+"\r\n";
}
process.nextTick(callback);

@@ -942,4 +1004,9 @@ return;

stream.on("error", (function(error){
this.emit("data", new Buffer(new Buffer("<ERROR READING STREAM>",
if(!this._cacheOutput){
this.emit("data", new Buffer(new Buffer("<ERROR READING STREAM>",
"utf-8").toString("base64")+"\r\n", "utf-8"));
}else{
this._outputBuffer += new Buffer("<ERROR READING STREAM>",
"utf-8").toString("base64")+"\r\n";
}
process.nextTick(callback);

@@ -962,3 +1029,7 @@ }).bind(this));

if(data.length){
this.emit("data", new Buffer(data.trim()+"\r\n", "utf-8"));
if(!this._cacheOutput){
this.emit("data", new Buffer(data.trim()+"\r\n", "utf-8"));
}else{
this._outputBuffer += data.trim()+"\r\n";
}
}

@@ -973,3 +1044,7 @@ }).bind(this));

data = remainder.toString("base64").replace(/.{76}/g,"$&\r\n");
this.emit("data", new Buffer(data.trim()+"\r\n", "utf-8"));
if(!this._cacheOutput){
this.emit("data", new Buffer(data.trim()+"\r\n", "utf-8"));
}else{
this._outputBuffer += data.trim()+"\r\n";
}
}

@@ -983,2 +1058,19 @@ process.nextTick(callback);

/**
* <p>Processes buffered output and emits 'end'</p>
*/
MailComposer.prototype._processBufferedOutput = function(){
var dkimSignature;
if(this._dkim){
if(dkimSignature = DKIMSign(this._outputBuffer, this._dkim)){
this.emit("data", new Buffer(dkimSignature+"\r\n", "utf-8"));
}
}
this.emit("data", new Buffer(this._outputBuffer, "utf-8"))
process.nextTick(this.emit.bind(this,"end"));
};
/* HELPER FUNCTIONS */

@@ -1011,3 +1103,5 @@

return c.toUpperCase();
}).replace(/^MIME\-/i, "MIME-");
}).
replace(/^MIME\-/i, "MIME-").
replace(/^DKIM\-/i, "DKIM-");
};

@@ -1014,0 +1108,0 @@

2

lib/punycode.js

@@ -327,4 +327,4 @@ //Javascript Punycode converter derived from example in RFC3492.

var domainParts = domain.split(/\./).map(punycode.ToASCII);
return start + domainParts.join(".");
return (start || "") + domainParts.join(".");
});
};
{
"name": "mailcomposer",
"description": "Compose E-Mail messages",
"version": "0.1.10",
"version": "0.1.11",
"author" : "Andris Reinman",

@@ -6,0 +6,0 @@ "maintainers":[

@@ -13,4 +13,2 @@ # mailcomposer

See autogenerated docs [here](http://www.node.ee/mcdoc/).
**mailcomposer** supports:

@@ -22,2 +20,3 @@

* **Embedded images** in HTML
* **DKIM** signing
* usage of **your own** transport mechanism

@@ -243,2 +242,34 @@

### DKIM Signing
**mailcomposer** supports DKIM signing with very simple setup. Use this with caution
though since the generated message needs to be buffered entirely before it can be
signed - in this case the streaming capability offered by mailcomposer is illusionary,
there will only be one `'data'` event with the entire message. Not a big deal with
small messages but might consume a lot of RAM when using larger attachments.
Set up the DKIM signing with `useDKIM` method:
mailcomposer.useDKIM(dkimOptions)
Where `dkimOptions` includes necessary options for signing
* **domainName** - the domainname that is being used for signing
* **keySelector** - key selector. If you have set up a TXT record with DKIM public key at *zzz._domainkey.example.com* then `zzz` is the selector
* **privateKey** - DKIM private key that is used for signing as a string
* **headerFieldNames** - optional colon separated list of header fields to sign, by default all fields suggested by RFC4871 #5.5 are used
**NB!** Currently if several header fields with the same name exists, only the last one (the one in the bottom) is signed.
Example:
mailcomposer.setMessageOption({from: "andris@tr.ee"});
mailcomposer.setMessageOption({to: "andris@node.ee"});
mailcomposer.setMessageOption({body: "Hello world!"});
mailcomposer.useDKIM({
domainName: "node.ee",
keySelector: "dkim",
privateKey: fs.readFileSync("private_key.pem")
});
### Start streaming

@@ -245,0 +276,0 @@

@@ -925,3 +925,31 @@ var testCase = require('nodeunit').testCase,

exports["Output buffering"] = {
"Use DKIM": function(test){
var mc = new MailComposer();
mc.setMessageOption({
from: "Andris Reinman <andris@node.ee>",
to: "Andris <andris.reinman@gmail.com>",
html: "<b>Hello world!</b>",
subject: "Hello world!"
});
mc.useDKIM({
domainName: "do-not-trust.node.ee",
keySelector: "dkim",
privateKey: fs.readFileSync(__dirname+"/test_private.pem")
});
mc.streamMessage();
var mp = new MailParser();
mc.pipe(mp);
mp.on("end", function(mail){
test.equal(mail.headers['dkim-signature'].replace(/\s/g, ""), 'v=1;a=rsa-sha256;c=relaxed/relaxed;d=do-not-trust.node.ee;q=dns/txt;s=dkim;bh=88i0PUP3tj3X/n0QT6Baw8ZPSeHZPqT7J0EmE26pjng=;h=from:subject:to:mime-version:content-type:content-transfer-encoding;b=dtxxQLotrcarEA5nbgBJLBJQxSAHcfrNxxpItcXSj68ntRvxmjXt9aPZTbVrzfRYe+xRzP2FTGpS7js8iYpAZZ2N3DBRLVp4gyyKHB1oWMkg/EV92uPtnjQ3MlHMbxC0');
test.done();
});
}
}
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