npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

smtp-protocol-ath

vundefined

Published

implements the smtp protocol for clients and servers

Readme

smtp-protocol

Implements the smtp protocol for clients and servers.

This module does not relay any messages or perform disk I/O by itself.

build status

examples

server

var smtp = require('smtp-protocol');

var server = smtp.createServer(function (req) {
    req.on('to', function (to, ack) {
        var domain = to.split('@')[1] || 'localhost';
        if (domain === 'localhost') ack.accept()
        else ack.reject()
    });
    
    req.on('message', function (stream, ack) {
        console.log('from: ' + req.from);
        console.log('to: ' + req.to);
        
        stream.pipe(process.stdout, { end : false });
        ack.accept();
    });
});

server.listen(9025);

usage:

$ node example/server.js 

elsewhere:

$ nc localhost 9025
250 beep
helo
250 
mail from: <beep@localhost>
250 
rcpt to: <boop@localhost>
250 
data
354 
Beep boop.
I am a computer.
.
250 
quit
221 Bye!

meanwhile:

from: beep@localhost
to: boop@localhost
Beep boop.
I am a computer.

client

var smtp = require('../');
var seq = require('seq');
var fs = require('fs');

smtp.connect('localhost', 25, function (mail) {
    seq()
        .seq_(function (next) {
            mail.on('greeting', function (code, lines) {
                console.dir(lines);
                next();
            });
        })
        .seq(function (next) {
            mail.helo('localhost', this.into('helo'));
        })
        .seq(function () {
            mail.from('substack', this.into('from'));
        })
        .seq(function () {
            mail.to('root', this.into('to'));
        })
        .seq(function () {
            mail.data(this.into('data'))
        })
        .seq(function () {
            mail.message(fs.createReadStream('/etc/issue'), this.into('message'));
        })
        .seq(function () {
            mail.quit(this.into('quit'));
        })
        .seq(function () {
            console.dir(this.vars);
        })
    ;
});

output:

$ node example/client.js
[ 'beep ESMTP Postfix (Ubuntu)' ]
{ helo: 250,
  from: 250,
  to: 250,
  data: 354,
  message: 250,
  quit: 221 }

server methods

var smtp = require('smtp-protocol')

smtp.createServer(domain=os.hostname(), cb)

Return a new net.Server so you can .listen() on a port.

cb(req) fires for new connection. See the "requests" section below.

server requests

events

Every event that can

Every acknowledgeable event except "message" will implicitly call ack.accept() if no listeners are registered.

If there are any listeners for an acknowledgeable event, exactly one listener MUST call either ack.accept() or ack.reject().

'greeting', cmd, ack

Emitted when HELO, EHLO, or LHLO commands are received.

Read the name of the command with cmd.greeting. Read the optional hostname parameter with cmd.hostname.

'from', from, ack

Emitted when the MAIL FROM: command is received.

from is the email address of the sender as a string.

'to', to, ack

Emitted when the RCPT TO: command is received.

to is the email address of the recipient as a string.

'message', stream, ack

Emitted when the DATA command is received.

If the message request is accepted, the message body will be streamed through stream.

This event has no implicit ack.accept() when there are no listeners.

'received', ack

Emitted when the body after the DATA command finishes.

'reset'

Emitted when the connection is reset from a RSET command.

'quit'

Emitted when the connection is closed from a QUIT command.

properties

req.from

The email address of the sender as a string.

req.fromExt

Extended sender data if sent as a string.

req.to

The email address of the recipient as a string.

req.toExt

Extended recipient data if sent as a string.

req.greeting

The greeting command. One of 'helo', 'ehlo', or 'lhlo'.

req.hostname

The hostname specified in the greeting.

server acknowledgements

Many request events have a trailing ack parameter.

If there are any listeners for an acknowledgeable event, exactly one listener MUST call either ack.accept() or ack.reject().

Consult this handy list of SMTP codes for which codes to use in acknowledgement responses.

ack.accept(code=250, message)

Accept the command. Internal staged state modifications from the command are executed.

ack.reject(code, message)

Reject the command. Any staged state modifications from the command are discarded.

client methods

For all client methods, cb(err, code, lines) fires with the server response.

var stream = smtp.connect(host='localhost', port=25, options={}, cb)

Create a new SMTP client connection.

host, port, options and cb are detected by their types in the arguments array so they may be in any order. cb(client) fires when the connection is ready.

You can use unix sockets by supplying a string argument that matches /^[.\/]/.

Alternatively supply your own stream as opts.stream (the stream must already be connected).

To make a connection using TLS, set opts.tls to true (for more control you can also assign options to pass through to tls.connect.) By default, connections to unauthorized servers will be closed and the error will be emitted as an 'error' event on the stream object but you can provide your own authorization logic by doing:

stream.on('secure', function (ack) {
    if (...) ack.accept()
    else ack.reject()
})

client.helo(hostname, cb)

Greet the server with the hostname string.

cb(err, code, lines) fires with the server response.

client.from(addr, ext=undefined, cb)

Set the sender to the email address addr with optional extension data ext.

cb(err, code, lines) fires with the server response.

client.to(addr, ext=undefined, cb)

Set the recipient to the email address addr with optional extension data ext.

cb(err, code, lines) fires with the server response.

client.data(cb)

Tell the server that we are about to transmit data.

cb(err, code, lines) fires with the server response.

client.message(stream, cb)

Write a message body from stream to the server.

cb(err, code, lines) fires with the server response.

client.quit(cb)

Ask the server to sever the connection.

cb(err, code, lines) fires with the server response.

client.reset(cb)

Ask the server to reset the connection.

cb(err, code, lines) fires with the server response.

client events

'greeting', code, lines

Fired when the stream initializes. This should be the first message that the server sends.

install

With npm do:

npm install smtp-protocol