Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
buildmail is a low level rfc2822 message composer. Define your own mime tree, no magic included.
The buildmail npm package is used for generating email messages in MIME format. It allows you to create complex email structures with attachments, HTML content, and alternative text versions.
Create a simple email
This feature allows you to create a simple email with basic fields like from, to, subject, and text content.
const BuildMail = require('buildmail');
const mail = new BuildMail({
from: 'sender@example.com',
to: 'recipient@example.com',
subject: 'Hello World',
text: 'Hello, this is a simple email.'
});
mail.build((err, message) => {
if (err) throw err;
console.log(message.toString());
});
Add HTML content
This feature allows you to add HTML content to your email, making it possible to send rich-text emails.
const BuildMail = require('buildmail');
const mail = new BuildMail({
from: 'sender@example.com',
to: 'recipient@example.com',
subject: 'Hello World',
html: '<h1>Hello, this is an HTML email.</h1>'
});
mail.build((err, message) => {
if (err) throw err;
console.log(message.toString());
});
Add attachments
This feature allows you to add attachments to your email, which can be any type of file.
const BuildMail = require('buildmail');
const fs = require('fs');
const mail = new BuildMail({
from: 'sender@example.com',
to: 'recipient@example.com',
subject: 'Hello World',
text: 'Hello, this email has an attachment.'
});
mail.attach({
filename: 'file.txt',
content: fs.createReadStream('path/to/file.txt')
});
mail.build((err, message) => {
if (err) throw err;
console.log(message.toString());
});
Nodemailer is a module for Node.js applications to allow easy email sending. It supports various transport methods, including SMTP, and can handle attachments, HTML content, and more. Compared to buildmail, Nodemailer is more focused on the actual sending of emails rather than just building them.
EmailJS is a library for sending emails from JavaScript applications. It supports SMTP and can handle attachments and HTML content. Like Nodemailer, it is more focused on sending emails rather than just constructing them.
Mailcomposer is a Node.js module for generating email messages, similar to buildmail. It allows you to create MIME-compliant email messages with attachments and HTML content. Mailcomposer is very similar to buildmail in terms of functionality but is less actively maintained.
Low level rfc2822 message composer that streams output. Define your own mime tree, no magic included.
Ported from MailBuild of the emailjs.org project. This port uses similar API but is for Node only and streams the output.
Install with npm
npm install buildmail
Require in your scripts
var BuildMail = require('buildmail');
Create a new BuildMail
object with
var builder = new BuildMail(contentType [, options]);
Where
filename
option if available)from
address is used but this might not be availableThe same methods apply to the root node created with new BuildMail()
and to any child nodes.
Creates and appends a child node to the node object
node.createChild(contentType, options)
The same arguments apply as with new BuildMail()
. Created node object is returned.
Example
new BuildMail('multipart/mixed').
createChild('multipart/related').
createChild('text/plain');
Generates the following mime tree:
multipart/mixed
↳ multipart/related
↳ text/plain
Appends an existing child node to the node object. Removes the node from an existing tree if needed.
node.appendChild(childNode)
Where
Method returns appended child node.
Example
var childNode = new BuildMail('text/plain'),
rootNode = new BuildMail('multipart/mixed');
rootnode.appendChild(childNode);
Generates the following mime tree:
multipart/mixed
↳ text/plain
Replaces current node with another node
node.replace(replacementNode)
Where
Method returns replacement node.
Example
var rootNode = new BuildMail('multipart/mixed'),
childNode = rootNode.createChild('text/plain');
childNode.replace(new BuildMail('text/html'));
Generates the following mime tree:
multipart/mixed
↳ text/html
Removes current node from the mime tree. Does not make a lot of sense for a root node.
node.remove();
Method returns removed node.
Example
var rootNode = new BuildMail('multipart/mixed'),
childNode = rootNode.createChild('text/plain');
childNode.remove();
Generates the following mime tree:
multipart/mixed
Sets a header value. If the value for selected key exists, it is overwritten.
You can set multiple values as well by using [{key:'', value:''}]
or
{key: 'value'}
structures as the first argument.
node.setHeader(key, value);
Where
Method returns current node.
Example
new BuildMail('text/plain').
setHeader('content-disposition', 'inline').
setHeader({
'content-transfer-encoding': '7bit'
}).
setHeader([
{key: 'message-id', value: 'abcde'}
Generates the following header:
Content-type: text/plain
Content-Disposition: inline
Content-Transfer-Encoding: 7bit
Message-Id: <abcde>
Adds a header value. If the value for selected key exists, the value is appended as a new field and old one is not touched.
You can set multiple values as well by using [{key:'', value:''}]
or
{key: 'value'}
structures as the first argument.
node.addHeader(key, value);
Where
Method returns current node.
Example
new BuildMail('text/plain').
addHeader('X-Spam', '1').
setHeader({
'x-spam': '2'
}).
setHeader([
{key: 'x-spam', value: '3'}
]);
Generates the following header:
Content-type: text/plain
X-Spam: 1
X-Spam: 2
X-Spam: 3
Normally all headers are encoded and folded to meet the requirement of having plain-ASCII messages with lines no longer than 78 bytes. Sometimes it is preferable to not modify header values and pass these as provided. This can be achieved with the prepared
option:
new BuildMail('text/plain').
addHeader('X-Long-Header', {
prepared: true,
value: 'a really long header or value with non-ascii characters 👮'
});
// normal output:
// X-Long-Header: a really long header or value with non-ascii characters
// =?UTF-8?Q?=F0=9F=91=AE?=
// output with the prepared option:
// X-Long-Header: a really long header or value with non-ascii characters 👮
Retrieves the first mathcing value of a selected key
node.getHeader(key)
Where
Example
new BuildMail('text/plain').getHeader('content-type'); // text/plain
Builds the current header info into a header block that can be used in an e-mail
var headers = node.buildHeaders()
Example
new BuildMail('text/plain').
addHeader('X-Spam', '1').
setHeader({
'x-spam': '2'
}).
setHeader([
{key: 'x-spam', value: '3'}
]).buildHeaders();
returns the following String
Content-Type: text/plain
X-Spam: 3
Date: Sat, 21 Jun 2014 10:52:44 +0000
Message-Id: <1403347964894-790a5296-0eb7c7c7-6440334f@localhost>
MIME-Version: 1.0
If the node is the root node, then Date
and Message-Id
values are generated automatically if missing
Sets body content for current node. If the value is a string and Content-Type is text/* then charset is set automatically. If the value is a Buffer or a Stream you need to specify the charset yourself.
node.setContent(body)
Where
If the value is an object, it should include one of the following properties
Example
new BuildMail('text/plain').setContent('Hello world!');
new BuildMail('text/plain; charset=utf-8').setContent(fs.createReadStream('message.txt'));
Sets pre-generated output value for current node. When building the final message then this value is returned instead of building a fresh rfc822 mime message from normal input.
This also means that other methods (getAddresses
, getEnvelope
etc.) that use normal
input do not return valid values as the raw message is not parsed. You must set
envelope contents manually with setEnvelope
and you probably should set the
Message-Id header (even though it wouldn't break anything if you would not set it).
node.setRaw(message)
Where
If the value is an object, it should include one of the following properties
Example
new BuildMail().setRaw(fs.createReadStream('message.eml'));
Builds the rfc2822 message from the current node. If this is a root node, mandatory header fields are set if missing (Date, Message-Id, MIME-Version)
node.build(callback)
Callback returns the rfc2822 message as a Buffer
Example
new BuildMail('text/plain').setContent('Hello world!').build(function(err, mail){
console.log(mail.toString('ascii'));
});
Returns the following string:
Content-type: text/plain
Date: <current datetime>
Message-Id: <generated value>
MIME-Version: 1.0
Hello world!
If you manage large attachments you probably do not want to generate but stream the message.
var stream = node.createReadStream(options)
Where
highWaterMark
)Example
var message = new BuildMail();
message.addHeader({
from: 'From <from@example.com>',
to: 'receiver1@example.com',
cc: 'receiver2@example.com'
});
message.setContent(fs.createReadStream('message.txt'));
message.createReadStream().pipe(fs.createWriteStream('message.eml'));
If you want to modify the created stream, you can add transform streams that the output will be piped through.
node.transform(transformStream)
Where
createReadStream
. If the value is a function the function should return a transform stream object when called.Example
var PassThrough = require('stream').PassThrough;
var message = new BuildMail();
message.addHeader({
from: 'From <from@example.com>',
to: 'receiver1@example.com',
cc: 'receiver2@example.com'
});
message.setContent(fs.createReadStream('message.txt'));
message.transform(new PassThrough()); // add a stream that the output will be piped through
message.createReadStream().pipe(fs.createWriteStream('message.eml'));
Set envelope object to use. If one is not set, it is generated based ong the headers.
node.setEnvelope(envelope)
Where
{from:'address', to: ['addresses']}
Generates a SMTP envelope object. Makes sense only for root node.
var envelope = node.generateEnvelope()
Method returns the envelope in the form of {from:'address', to: ['addresses']}
Example
new BuildMail().
addHeader({
from: 'From <from@example.com>',
to: 'receiver1@example.com',
cc: 'receiver2@example.com'
}).
getEnvelope();
Returns the following object:
{
from: 'from@example.com',
to: ['receiver1@example.com', 'receiver2@example.com']
}
Returns Message-Id value. If it does not exist then generates one.
var messageId = node.messageId();
Method returns the Message-Id value <unique-message-id@example.com
Example
new BuildMail().
addHeader({
from: 'From <from@example.com>'
}).
messageId();
Returns the following value:
"<1453237212620-0657660b-8df9255d-18bcdcb5@example.com>"
Returns an address container object. Includes all parsed addresses from From, Sender, To, Cc, Bcc and Reply-To fields.
While getEnvelope()
returns 'from' value as a single address (the first one encountered) then getAddresses
return all values as arrays, including from
. Additionally while getEnvelope
returns only from
and a combined to
value then getAddresses
returns all fields separately.
Possbile return values (all arrays in the form of [{name:'', address:''}]
):
If no addresses were found for a particular field, the field is not set in the response object.
Example
new BuildMail().
addHeader({
from: 'From <from@example.com>',
to: '"Receiver" receiver1@example.com',
cc: 'receiver2@example.com'
}).
getAddresses();
Returns the following object:
{
from: [{
name: 'From',
address: 'from@example.com'
}],
to: [{
name: 'Receiver',
address: 'receiver1@example.com'
}],
cc: [{
name: '',
address: 'receiver2@example.com'
}]
}
When setting address headers (From
, To
, Cc
, Bcc
) use of unicode is allowed. If needed
the addresses are converted to punycode automatically.
For attachments you should minimally set filename
option and Content-Disposition
header. If filename is specified, you can leave content type blank - if content type is not set, it is detected from the filename.
new BuildMail('multipart/mixed').
createChild(false, {filename: 'image.png'}).
setHeader('Content-Disposition', 'attachment');
Obviously you might want to add Content-Id
header as well if you want to reference this attachment from the HTML content.
Most probably you only need to deal with the following multipart types when generating messages:
type
parameter that indicates the Content-Type of the root element in the nodeExamples
One content node and an attachment
multipart/mixed
↳ text/plain
↳ image/png
Content node with referenced attachment (eg. image with Content-Type
referenced by cid:
url in the HTML)
multipart/related
↳ text/html
↳ image/png
Plaintext and HTML alternatives
multipart/alternative
↳ text/html
↳ text/plain
One content node with referenced attachment and a regular attachment
multipart/mixed
↳ multipart/related
↳ text/plain
↳ image/png
↳ application/x-zip
Alternative content with referenced attachment for HTML and a regular attachment
multipart/mixed
↳ multipart/alternative
↳ text/plain
↳ multipart/related
↳ text/html
↳ image/png
↳ application/x-zip
MIT
FAQs
buildmail is a low level rfc2822 message composer. Define your own mime tree, no magic included.
The npm package buildmail receives a total of 203,961 weekly downloads. As such, buildmail popularity was classified as popular.
We found that buildmail demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.