smtp-server-as-promised
Advanced tools
Comparing version 4.1.0 to 5.0.0
# Changelog | ||
## v5.0.0 2018-09-17 | ||
* Callback handler are replaced with protected methods that should be overriden | ||
in own subclass. | ||
* `onData` handler consumes the stream after error. | ||
## v4.1.0 2018-09-10 | ||
@@ -4,0 +10,0 @@ |
@@ -14,9 +14,9 @@ /// <reference types="node" /> | ||
export interface SMTPServerAsPromisedOptions extends SMTPServerOptions { | ||
onAuth?: (auth: SMTPServerAuthentication, session: SMTPServerSession) => Promise<SMTPServerAuthenticationResponse>; | ||
onClose?: (session: SMTPServerSession) => Promise<void>; | ||
onConnect?: (session: SMTPServerSession) => Promise<void>; | ||
onData?: (stream: Readable, session: SMTPServerSession) => Promise<void>; | ||
onMailFrom?: (address: SMTPServerAddress, session: SMTPServerSession) => Promise<void>; | ||
onRcptTo?: (address: SMTPServerAddress, session: SMTPServerSession) => Promise<void>; | ||
onError?: (error: Error) => Promise<void>; | ||
onConnect?: never; | ||
onAuth?: never; | ||
onMailFrom?: never; | ||
onRcptTo?: never; | ||
onData?: never; | ||
onClose?: never; | ||
onError?: never; | ||
} | ||
@@ -32,3 +32,10 @@ export declare class SMTPServerAsPromised { | ||
destroy(): Promise<void>; | ||
protected onAuth(auth: SMTPServerAuthentication, session: SMTPServerSession): Promise<SMTPServerAuthenticationResponse>; | ||
protected onClose(session: SMTPServerSession): Promise<void>; | ||
protected onConnect(session: SMTPServerSession): Promise<void>; | ||
protected onData(stream: Readable, session: SMTPServerSession): Promise<void>; | ||
protected onMailFrom(address: SMTPServerAddress, session: SMTPServerSession): Promise<void>; | ||
protected onRcptTo(address: SMTPServerAddress, session: SMTPServerSession): Promise<void>; | ||
protected onError(error: Error): Promise<void>; | ||
} | ||
export default SMTPServerAsPromised; |
@@ -6,2 +6,3 @@ "use strict"; | ||
const tslib_1 = require("tslib"); | ||
const null_writable_1 = tslib_1.__importDefault(require("null-writable")); | ||
const smtp_server_1 = require("smtp-server"); | ||
@@ -12,48 +13,24 @@ tslib_1.__exportStar(require("smtp-server"), exports); | ||
this.closed = false; | ||
const smtpSeverOptions = Object.assign({}, options); | ||
if (options.onConnect) { | ||
const handlerWithPromise = options.onConnect; | ||
const handlerWithCallback = (session, callback) => handlerWithPromise(session) | ||
.then(() => callback()) | ||
.catch((err) => callback(err)); | ||
smtpSeverOptions.onConnect = handlerWithCallback; | ||
} | ||
if (options.onAuth) { | ||
const handlerWithPromise = options.onAuth; | ||
const handlerWithCallback = (auth, session, callback) => handlerWithPromise(auth, session) | ||
.then((response) => callback(null, response)) | ||
.catch((err) => callback(err)); | ||
smtpSeverOptions.onAuth = handlerWithCallback; | ||
} | ||
if (options.onMailFrom) { | ||
const handlerWithPromise = options.onMailFrom; | ||
const handlerWithCallback = (address, session, callback) => handlerWithPromise(address, session) | ||
.then(() => callback()) | ||
.catch((err) => callback(err)); | ||
smtpSeverOptions.onMailFrom = handlerWithCallback; | ||
} | ||
if (options.onRcptTo) { | ||
const handlerWithPromise = options.onRcptTo; | ||
const handlerWithCallback = (address, session, callback) => handlerWithPromise(address, session) | ||
.then(() => callback()) | ||
.catch((err) => callback(err)); | ||
smtpSeverOptions.onRcptTo = handlerWithCallback; | ||
} | ||
if (options.onData) { | ||
const handlerWithPromise = options.onData; | ||
const handlerWithCallback = (stream, session, callback) => handlerWithPromise(stream, session) | ||
.then(() => callback()) | ||
.catch((err) => callback(err)); | ||
smtpSeverOptions.onData = handlerWithCallback; | ||
} | ||
if (options.onClose) { | ||
const handlerWithPromise = options.onClose; | ||
const handlerWithCallback = (session) => handlerWithPromise(session); | ||
smtpSeverOptions.onClose = handlerWithCallback; | ||
} | ||
this.server = new smtp_server_1.SMTPServer(smtpSeverOptions); | ||
if (options.onError) { | ||
this.errorHandler = options.onError; | ||
this.server.on('error', this.errorHandler); | ||
} | ||
const newOptions = {}; | ||
newOptions.onConnect = (session, callback) => this.onConnect(session) | ||
.then(() => callback()) | ||
.catch((err) => callback(err)); | ||
newOptions.onAuth = (auth, session, callback) => this.onAuth(auth, session) | ||
.then((response) => callback(null, response)) | ||
.catch((err) => callback(err)); | ||
newOptions.onMailFrom = (address, session, callback) => this.onMailFrom(address, session) | ||
.then(() => callback()) | ||
.catch((err) => callback(err)); | ||
newOptions.onRcptTo = (address, session, callback) => this.onRcptTo(address, session) | ||
.then(() => callback()) | ||
.catch((err) => callback(err)); | ||
newOptions.onData = (stream, session, callback) => this.onData(stream, session) | ||
.then(() => callback()) | ||
.catch((err) => { | ||
stream.pipe(new null_writable_1.default()); | ||
callback(err); | ||
}); | ||
newOptions.onClose = (session) => this.onClose(session); | ||
this.server = new smtp_server_1.SMTPServer(Object.assign({}, options, newOptions)); | ||
this.server.on('error', (err) => this.onError(err)); | ||
} | ||
@@ -105,4 +82,26 @@ listen(options = {}) { | ||
} | ||
onAuth(auth, session) { | ||
return Promise.reject(new Error('onAuth method not overriden in subclass')); | ||
} | ||
onClose(session) { | ||
return Promise.resolve(); | ||
} | ||
onConnect(session) { | ||
return Promise.resolve(); | ||
} | ||
onData(stream, session) { | ||
stream.pipe(new null_writable_1.default()); | ||
return Promise.resolve(); | ||
} | ||
onMailFrom(address, session) { | ||
return Promise.resolve(); | ||
} | ||
onRcptTo(address, session) { | ||
return Promise.resolve(); | ||
} | ||
onError(error) { | ||
return Promise.resolve(); | ||
} | ||
} | ||
exports.SMTPServerAsPromised = SMTPServerAsPromised; | ||
exports.default = SMTPServerAsPromised; |
{ | ||
"name": "smtp-server-as-promised", | ||
"version": "4.1.0", | ||
"version": "5.0.0", | ||
"description": "Promisify smtp-server module", | ||
@@ -33,10 +33,10 @@ "main": "lib/smtp-server-as-promised.js", | ||
"@types/mocha": "^5.2.5", | ||
"@types/node": "^10.9.4", | ||
"@types/nodemailer": "^4.6.2", | ||
"@types/node": "^10.10.0", | ||
"@types/nodemailer": "^4.6.5", | ||
"@types/semver": "^5.5.0", | ||
"@types/smtp-server": "^3.4.0", | ||
"@types/smtp-server": "^3.4.1", | ||
"chai": "^4.1.2", | ||
"chai-as-promised": "^7.1.1", | ||
"coveralls": "^3.0.2", | ||
"eslint": "^5.5.0", | ||
"eslint": "^5.6.0", | ||
"eslint-config-standard": "^12.0.0", | ||
@@ -61,4 +61,5 @@ "eslint-plugin-import": "^2.14.0", | ||
"scripts": { | ||
"build": "tsc --pretty", | ||
"build": "npm run compile", | ||
"clean": "rimraf lib", | ||
"compile": "tsc --pretty", | ||
"postpublish": "git tag v$npm_package_version -a -m \"Release v$npm_package_version\" && git push --tags", | ||
@@ -65,0 +66,0 @@ "prepublishOnly": "npm run build", |
122
README.md
@@ -11,3 +11,4 @@ # smtp-server-as-promised | ||
[`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) | ||
object and callback options which are `Promise` objects. | ||
object and callback options which should be replaced with overriden method in | ||
own subclass. | ||
@@ -48,2 +49,4 @@ ## Requirements | ||
const { SMTPServerAsPromised } = require('smtp-server-as-promised') | ||
class MySMTPServer extends SMTPServerAsPromised {} | ||
``` | ||
@@ -55,2 +58,4 @@ | ||
import SMTPServerAsPromised from 'smtp-server-as-promised' | ||
class MySMTPServer extends SMTPServerAsPromised {} | ||
``` | ||
@@ -61,6 +66,6 @@ | ||
```js | ||
const server = new SMTPServerAsPromised(options) | ||
const server = new MySMTPServer(options) | ||
``` | ||
Create new SMTPServer instance. | ||
Create new `SMTPServerAsPromised` instance. | ||
@@ -70,15 +75,21 @@ _Example:_ | ||
```js | ||
const server = new SMTPServerAsPromised({ | ||
onConnect, onMailFrom, onData, onError | ||
const server = new MySMTPServer({ | ||
disabledCommands: ['AUTH'] | ||
}) | ||
``` | ||
Options are the same as for original `smtp-server` constructor. Callback | ||
handlers are `Promise` objects or `async` functions: | ||
Options are the same as for original `smtp-server` constructor except callback | ||
handlers that methods of this class should be used instead. | ||
### onConnect | ||
This method can be overriden in subclass. | ||
_Example:_ | ||
```js | ||
async function onConnect (session) { | ||
console.log(`[${session.id}] onConnect`) | ||
class MySMTPServer extends SMTPServerAsPromised { | ||
async onConnect (session) { | ||
console.log(`[${session.id}] onConnect`) | ||
} | ||
} | ||
@@ -89,10 +100,16 @@ ``` | ||
This method can be overriden in subclass. | ||
_Example:_ | ||
<!-- markdownlint-disable MD013 --> | ||
```js | ||
async function onAuth (auth, session) { | ||
if (auth.method === 'PLAIN' && auth.username === 'username' && auth.password === 'password') { | ||
return {user: auth.username} | ||
} else { | ||
throw new Error('Invalid username or password') | ||
class MySMTPServer extends SMTPServerAsPromised { | ||
async onAuth (auth, session) { | ||
if (auth.method === 'PLAIN' && auth.username === 'username' && auth.password === 'password') { | ||
return { user: auth.username } | ||
} else { | ||
throw new Error('Invalid username or password') | ||
} | ||
} | ||
@@ -108,7 +125,13 @@ } | ||
This method can be overriden in subclass. | ||
_Example:_ | ||
```js | ||
async function onMailFrom (from, session) { | ||
console.log(`[${session.id}] onMailFrom ${from.address}`) | ||
if (from.address.split('@')[1] === 'spammer.com') { | ||
throw new Error('we do not like spam!') | ||
class MySMTPServer extends SMTPServerAsPromised { | ||
async onMailFrom (from, session) { | ||
console.log(`[${session.id}] onMailFrom ${from.address}`) | ||
if (from.address.split('@')[1] === 'spammer.com') { | ||
throw new Error('we do not like spam!') | ||
} | ||
} | ||
@@ -122,7 +145,13 @@ } | ||
This method can be overriden in subclass. | ||
_Example:_ | ||
```js | ||
async function onRcptTo (to, session) { | ||
console.log(`[${session.id}] onRcptTo ${to.address}`) | ||
if (from.address.split('@')[1] === 'spammer.com') { | ||
throw new Error('we do not like spam!') | ||
class MySMTPServer extends SMTPServerAsPromised { | ||
async onRcptTo (to, session) { | ||
console.log(`[${session.id}] onRcptTo ${to.address}`) | ||
if (from.address.split('@')[1] === 'spammer.com') { | ||
throw new Error('we do not like spam!') | ||
} | ||
} | ||
@@ -134,15 +163,21 @@ } | ||
This method can be overriden in subclass. | ||
_Example:_ | ||
<!-- markdownlint-disable MD013 --> | ||
```js | ||
async function onData (stream, session) { | ||
console.log(`[${session.id}] onData started`) | ||
session.messageLength = 0 | ||
class MySMTPServer extends SMTPServerAsPromised { | ||
async onData (stream, session) { | ||
console.log(`[${session.id}] onData started`) | ||
session.messageLength = 0 | ||
for (let chunk; (chunk = await stream.read());) { | ||
console.log(`[${session.id}] onData got data chunk ${chunk.length} bytes`) | ||
session.messageLength += chunk.length | ||
for (let chunk; (chunk = await stream.read());) { | ||
console.log(`[${session.id}] onData got data chunk ${chunk.length} bytes`) | ||
session.messageLength += chunk.length | ||
} | ||
console.log(`[${session.id}] onData finished after reading ${session.messageLength} bytes`) | ||
} | ||
console.log(`[${session.id}] onData finished after reading ${session.messageLength} bytes`) | ||
} | ||
@@ -157,25 +192,16 @@ ``` | ||
Warning: if an error occures in `onData` handler, stream have to be consumed | ||
before return from function. | ||
If the method throws an error then the stream is silently consumed to prevent | ||
SMTP stream to be blocked. | ||
_Example_: | ||
### onError | ||
```js | ||
const { NullWritable } = require('null-writable') | ||
This method can be overriden in subclass. | ||
async function onData (stream, session) { | ||
try { | ||
throw new Error('Something bad happened') | ||
} catch (e) { | ||
stream.pipe(new NullWritable()) // read it to the end | ||
throw e // rethrow original error | ||
} | ||
} | ||
``` | ||
_Example:_ | ||
### onError | ||
```js | ||
async function onError (e) { | ||
console.log('Server error:', e) | ||
class MySMTPServer extends SMTPServerAsPromised { | ||
async onError (error) { | ||
console.log('Server error:', error) | ||
} | ||
} | ||
@@ -182,0 +208,0 @@ ``` |
@@ -6,2 +6,3 @@ /// <reference types="node" /> | ||
export { Logger, LoggerLevel } from 'nodemailer/lib/shared' | ||
import NullWritable from 'null-writable' | ||
import { Readable } from 'stream' | ||
@@ -21,9 +22,9 @@ import tls from 'tls' | ||
export interface SMTPServerAsPromisedOptions extends SMTPServerOptions { | ||
onAuth?: (auth: SMTPServerAuthentication, session: SMTPServerSession) => Promise<SMTPServerAuthenticationResponse> | ||
onClose?: (session: SMTPServerSession) => Promise<void> | ||
onConnect?: (session: SMTPServerSession) => Promise<void> | ||
onData?: (stream: Readable, session: SMTPServerSession) => Promise<void> | ||
onMailFrom?: (address: SMTPServerAddress, session: SMTPServerSession) => Promise<void> | ||
onRcptTo?: (address: SMTPServerAddress, session: SMTPServerSession) => Promise<void> | ||
onError?: (error: Error) => Promise<void> | ||
onConnect?: never | ||
onAuth?: never | ||
onMailFrom?: never | ||
onRcptTo?: never | ||
onData?: never | ||
onClose?: never | ||
onError?: never | ||
} | ||
@@ -38,51 +39,32 @@ | ||
constructor (options: SMTPServerAsPromisedOptions = {}) { | ||
const smtpSeverOptions: SMTPServerOptions = Object.assign({}, options) | ||
const newOptions: SMTPServerOptions = {} | ||
if (options.onConnect) { | ||
const handlerWithPromise = options.onConnect | ||
const handlerWithCallback = (session: SMTPServerSession, callback: (err?: Error) => void) => handlerWithPromise(session) | ||
newOptions.onConnect = (session: SMTPServerSession, callback: (err?: Error) => void) => this.onConnect(session) | ||
.then(() => callback()) | ||
.catch((err: Error) => callback(err)) | ||
newOptions.onAuth = (auth: SMTPServerAuthentication, session: SMTPServerSession, callback: (err: Error | null, response?: SMTPServerAuthenticationResponse) => void) => this.onAuth(auth, session) | ||
.then((response: SMTPServerAuthenticationResponse) => callback(null, response)) | ||
.catch((err: Error) => callback(err)) | ||
newOptions.onMailFrom = (address: SMTPServerAddress, session: SMTPServerSession, callback: (err?: Error | null) => void) => this.onMailFrom(address, session) | ||
.then(() => callback()) | ||
.catch((err) => callback(err)) | ||
smtpSeverOptions.onConnect = handlerWithCallback | ||
} | ||
if (options.onAuth) { | ||
const handlerWithPromise = options.onAuth | ||
const handlerWithCallback = (auth: SMTPServerAuthentication, session: SMTPServerSession, callback: (err: Error | null, response?: SMTPServerAuthenticationResponse) => void) => handlerWithPromise(auth, session) | ||
.then((response) => callback(null, response)) | ||
.catch((err) => callback(err)) | ||
smtpSeverOptions.onAuth = handlerWithCallback as any | ||
} | ||
if (options.onMailFrom) { | ||
const handlerWithPromise = options.onMailFrom | ||
const handlerWithCallback = (address: SMTPServerAddress, session: SMTPServerSession, callback: (err?: Error | null) => void) => handlerWithPromise(address, session) | ||
.catch((err: Error) => callback(err)) | ||
newOptions.onRcptTo = (address: SMTPServerAddress, session: SMTPServerSession, callback: (err?: Error | null) => void) => this.onRcptTo(address, session) | ||
.then(() => callback()) | ||
.catch((err) => callback(err)) | ||
smtpSeverOptions.onMailFrom = handlerWithCallback | ||
} | ||
if (options.onRcptTo) { | ||
const handlerWithPromise = options.onRcptTo | ||
const handlerWithCallback = (address: SMTPServerAddress, session: SMTPServerSession, callback: (err?: Error | null) => void) => handlerWithPromise(address, session) | ||
.catch((err: Error) => callback(err)) | ||
newOptions.onData = (stream: Readable, session: SMTPServerSession, callback: (err?: Error | null) => void) => this.onData(stream, session) | ||
.then(() => callback()) | ||
.catch((err) => callback(err)) | ||
smtpSeverOptions.onRcptTo = handlerWithCallback | ||
} | ||
if (options.onData) { | ||
const handlerWithPromise = options.onData | ||
const handlerWithCallback = (stream: Readable, session: SMTPServerSession, callback: (err?: Error | null) => void) => handlerWithPromise(stream, session) | ||
.then(() => callback()) | ||
.catch((err) => callback(err)) | ||
smtpSeverOptions.onData = handlerWithCallback | ||
} | ||
if (options.onClose) { | ||
const handlerWithPromise = options.onClose | ||
const handlerWithCallback = (session: SMTPServerSession) => handlerWithPromise(session) | ||
smtpSeverOptions.onClose = handlerWithCallback | ||
} | ||
.catch((err: Error) => { | ||
stream.pipe(new NullWritable()) | ||
callback(err) | ||
}) | ||
this.server = new SMTPServer(smtpSeverOptions) | ||
newOptions.onClose = (session: SMTPServerSession) => this.onClose(session) | ||
if (options.onError) { | ||
this.errorHandler = options.onError | ||
this.server.on('error', this.errorHandler) | ||
} | ||
this.server = new SMTPServer({ ...options as SMTPServerOptions, ...newOptions }) | ||
this.server.on('error', (err: Error) => this.onError(err)) | ||
} | ||
@@ -140,4 +122,33 @@ | ||
} | ||
protected onAuth (auth: SMTPServerAuthentication, session: SMTPServerSession): Promise<SMTPServerAuthenticationResponse> { | ||
return Promise.reject(new Error('onAuth method not overriden in subclass')) | ||
} | ||
protected onClose (session: SMTPServerSession): Promise<void> { | ||
return Promise.resolve() | ||
} | ||
protected onConnect (session: SMTPServerSession): Promise<void> { | ||
return Promise.resolve() | ||
} | ||
protected onData (stream: Readable, session: SMTPServerSession): Promise<void> { | ||
stream.pipe(new NullWritable()) | ||
return Promise.resolve() | ||
} | ||
protected onMailFrom (address: SMTPServerAddress, session: SMTPServerSession): Promise<void> { | ||
return Promise.resolve() | ||
} | ||
protected onRcptTo (address: SMTPServerAddress, session: SMTPServerSession): Promise<void> { | ||
return Promise.resolve() | ||
} | ||
protected onError (error: Error): Promise<void> { | ||
return Promise.resolve() | ||
} | ||
} | ||
export default SMTPServerAsPromised |
@@ -10,6 +10,4 @@ { | ||
"module": "commonjs", | ||
"noImplicitAny": true, | ||
"noImplicitReturns": true, | ||
"noUnusedLocals": true, | ||
"noUnusedParameters": true, | ||
"outDir": "./lib", | ||
@@ -16,0 +14,0 @@ "target": "es6", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
22039
286
264