commit 86b42a3716cf4f2a2980e5e263630c0f670bef6c Author: Julien Fontanet Date: Thu Nov 19 18:22:57 2015 +0100 Initial commit. diff --git a/packages/xo-server-transport-email/.babelrc b/packages/xo-server-transport-email/.babelrc new file mode 100644 index 000000000..b8d41d8a4 --- /dev/null +++ b/packages/xo-server-transport-email/.babelrc @@ -0,0 +1,11 @@ +{ + "comments": false, + "compact": true, + "plugins": [ + "transform-runtime" + ], + "presets": [ + "stage-0", + "es2015" + ] +} diff --git a/packages/xo-server-transport-email/.editorconfig b/packages/xo-server-transport-email/.editorconfig new file mode 100644 index 000000000..da21ef4c5 --- /dev/null +++ b/packages/xo-server-transport-email/.editorconfig @@ -0,0 +1,65 @@ +# http://EditorConfig.org +# +# Julien Fontanet's configuration +# https://gist.github.com/julien-f/8096213 + +# Top-most EditorConfig file. +root = true + +# Common config. +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespaces = true + +# CoffeeScript +# +# https://github.com/polarmobile/coffeescript-style-guide/blob/master/README.md +[*.{,lit}coffee] +indent_size = 2 +indent_style = space + +# Markdown +[*.{md,mdwn,mdown,markdown}] +indent_size = 4 +indent_style = space + +# Package.json +# +# This indentation style is the one used by npm. +[/package.json] +indent_size = 2 +indent_style = space + +# Jade +[*.jade] +indent_size = 2 +indent_style = space + +# JavaScript +# +# Two spaces seems to be the standard most common style, at least in +# Node.js (http://nodeguide.com/style.html#tabs-vs-spaces). +[*.js] +indent_size = 2 +indent_style = space + +# Less +[*.less] +indent_size = 2 +indent_style = space + +# Sass +# +# Style used for http://libsass.com +[*.s[ac]ss] +indent_size = 2 +indent_style = space + +# YAML +# +# Only spaces are allowed. +[*.yaml] +indent_size = 2 +indent_style = space diff --git a/packages/xo-server-transport-email/.gitignore b/packages/xo-server-transport-email/.gitignore new file mode 100644 index 000000000..6959be1cf --- /dev/null +++ b/packages/xo-server-transport-email/.gitignore @@ -0,0 +1,9 @@ +/.nyc_output/ +/bower_components/ +/dist/ + +npm-debug.log +npm-debug.log.* + +!node_modules/* +node_modules/*/ diff --git a/packages/xo-server-transport-email/.mocha.js b/packages/xo-server-transport-email/.mocha.js new file mode 100644 index 000000000..e6d84e403 --- /dev/null +++ b/packages/xo-server-transport-email/.mocha.js @@ -0,0 +1,5 @@ +Error.stackTraceLimit = 100 + +try { require('trace') } catch (_) {} +try { require('clarify') } catch (_) {} +try { require('source-map-support/register') } catch (_) {} diff --git a/packages/xo-server-transport-email/.mocha.opts b/packages/xo-server-transport-email/.mocha.opts new file mode 100644 index 000000000..6cfd94898 --- /dev/null +++ b/packages/xo-server-transport-email/.mocha.opts @@ -0,0 +1 @@ +--require ./.mocha.js diff --git a/packages/xo-server-transport-email/.npmignore b/packages/xo-server-transport-email/.npmignore new file mode 100644 index 000000000..c31ee82cb --- /dev/null +++ b/packages/xo-server-transport-email/.npmignore @@ -0,0 +1,10 @@ +/examples/ +example.js +example.js.map +*.example.js +*.example.js.map + +/test/ +/tests/ +*.spec.js +*.spec.js.map diff --git a/packages/xo-server-transport-email/.travis.yml b/packages/xo-server-transport-email/.travis.yml new file mode 100644 index 000000000..502095fce --- /dev/null +++ b/packages/xo-server-transport-email/.travis.yml @@ -0,0 +1,10 @@ +language: node_js +node_js: + - 'stable' + - '4' + - '0.12' + - '0.10' + +# Use containers. +# http://docs.travis-ci.com/user/workers/container-based-infrastructure/ +sudo: false diff --git a/packages/xo-server-transport-email/README.md b/packages/xo-server-transport-email/README.md new file mode 100644 index 000000000..4adddc9c3 --- /dev/null +++ b/packages/xo-server-transport-email/README.md @@ -0,0 +1,52 @@ +# xo-server-transport-email [![Build Status](https://travis-ci.org/vatesfr/xo-server-transport-email.png?branch=master)](https://travis-ci.org/vatesfr/xo-server-transport-email) + +> ${pkg.description} + +## Install + +Installation of the [npm package](https://npmjs.org/package/xo-server-transport-email): + +``` +> npm install --global xo-server-transport-email +``` + +## Usage + +**TODO** + +## Development + +### Installing dependencies + +``` +> npm install +``` + +### Compilation + +The sources files are watched and automatically recompiled on changes. + +``` +> npm run dev +``` + +### Tests + +``` +> npm run test-dev +``` + +## Contributions + +Contributions are *very* welcomed, either on the documentation or on +the code. + +You may: + +- report any [issue](https://google.com/vatesfr/xo-server-transport-email/issues) + you've encountered; +- fork and create a pull request. + +## License + +AGPL3 © [Vates SAS](http://vates.fr) diff --git a/packages/xo-server-transport-email/package.json b/packages/xo-server-transport-email/package.json new file mode 100644 index 000000000..a0252b13e --- /dev/null +++ b/packages/xo-server-transport-email/package.json @@ -0,0 +1,66 @@ +{ + "private": true, + "name": "xo-server-transport-email", + "version": "0.0.0", + "license": "AGPL-3.0", + "description": "", + "keywords": [ + "xo-server", + "email", + "mail" + ], + "homepage": "https://google.com/vatesfr/xo-server-transport-email", + "bugs": "https://google.com/vatesfr/xo-server-transport-email/issues", + "repository": { + "type": "git", + "url": "https://google.com/vatesfr/xo-server-transport-email" + }, + "author": { + "name": "Julien Fontanet", + "email": "julien.fontanet@isonoe.net" + }, + "preferGlobal": false, + "main": "dist/", + "bin": {}, + "files": [ + "dist/" + ], + "dependencies": { + "babel-runtime": "^6.1.18", + "nodemailer": "^1.10.0", + "nodemailer-markdown": "^1.0.0", + "pify": "^2.3.0" + }, + "devDependencies": { + "babel-cli": "^6.1.18", + "babel-core": "^6.1.21", + "babel-eslint": "^4.1.5", + "babel-plugin-transform-runtime": "^6.1.18", + "babel-preset-es2015": "^6.1.18", + "babel-preset-stage-0": "^6.1.18", + "clarify": "^1.0.5", + "dependency-check": "^2.5.1", + "mocha": "^2.3.4", + "must": "^0.13.1", + "nyc": "^3.2.2", + "source-map-support": "^0.3.3", + "standard": "^5.4.1", + "trace": "^2.0.1" + }, + "scripts": { + "build": "babel --source-maps --out-dir=dist/ src/", + "dev": "babel --watch --source-maps --out-dir=dist/ src/", + "dev-test": "mocha --opts .mocha.opts --watch --reporter=min \"dist/**/*.spec.js\"", + "lint": "standard", + "depcheck": "dependency-check ./package.json", + "posttest": "npm run lint && npm run depcheck", + "prepublish": "npm run build", + "test": "nyc mocha --opts .mocha.opts \"dist/**/*.spec.js\"" + }, + "standard": { + "ignore": [ + "dist/**" + ], + "parser": "babel-eslint" + } +} diff --git a/packages/xo-server-transport-email/src/index.js b/packages/xo-server-transport-email/src/index.js new file mode 100644 index 000000000..21f85e33a --- /dev/null +++ b/packages/xo-server-transport-email/src/index.js @@ -0,0 +1,151 @@ +import pify from 'pify' +import { createTransport } from 'nodemailer' +import { markdown as nodemailerMarkdown } from 'nodemailer-markdown' + +// =================================================================== + +const bind = (fn, thisArg) => function () { + return fn.apply(thisArg, arguments) +} + +const { + defineProperty, + protoype: { + hasOwnProperty + } +} = Object + +const setProp = (obj, prop, value, attributes) => { + if (hasOwnProperty.call(obj, prop)) { + throw new Error(`Xo#${prop} is already defined`) + } + + defineProperty(obj, prop, { ...attributes, value }) +} + +const unsetProp = (obj, prop, expectedValue) => { + if ( + hasOwnProperty.call(obj, prop) && + expectedValue !== undefined && + obj.prop !== expectedValue + ) { + throw new Error(`Xo#${prop} has not the expected value, not removed`) + } + + delete obj[prop] +} + +const markdownCompiler = nodemailerMarkdown() + +// =================================================================== + +export const configurationSchema = { + type: 'object', + + properties: { + from: { + type: 'object', + + properties: { + name: { + type: 'string' + }, + address: { + type: 'string' + } + }, + + additionalProperties: true, + required: ['address'] + }, + + transport: { + type: 'object', + properties: { + host: { + type: 'string', + description: 'hostname or IP address of the SMTP server' + }, + port: { + type: 'integer', + description: 'port of the SMTP server (defaults to 25 or 465)' + }, + secure: { + type: 'boolean', + description: 'whether the connection should use SSL' + }, + auth: { + type: 'object', + properties: { + user: { + type: 'string', + description: 'name to use to authenticate' + }, + pass: { + type: 'string', + description: 'password to use to authenticate' + } + }, + + additionalProperties: true, + required: ['user', 'pass'] + }, + + additionalProperties: true + } + } + }, + + additionalProperties: true, + required: ['host', 'auth'] +} + +// =================================================================== + +class TransportEmailPlugin { + constructor (xo) { + this._xo = xo + this._sendEmail = bind(this._sendEmail, this) + + // Defined in configure(). + this._conf = null + this._send = null + } + + configure ({ + transport: transportConf, + ...conf + }) { + const transport = createTransport(transportConf) + transport.use('compile', markdownCompiler) + + this._conf = conf + this._send = pify(::transport.sendMail, Promise) + } + + load () { + setProp(this._xo, 'sendEmail', this._sendEmail) + } + + unload () { + unsetProp(this._xo, 'sendEmail', this._sendEmail) + } + + async _sendEmail ({ + from, + to, cc, bcc, + subject, + markdown + }) { + await this._send({ + from: from || this._conf.from, + to, cc, bcc, + subject, + markdown + }) + } +} + +// =================================================================== + +export default ({ xo }) => new TransportEmailPlugin(xo)