Refactor email model into mail connector
This commit is contained in:
parent
26d0f74d66
commit
a3f1d8d944
53
docs/api.md
53
docs/api.md
|
@ -1164,6 +1164,22 @@ POST /users/logout
|
|||
Require a user to verify their email address before being able to login. This will send an email to the user containing a link to verify their address. Once the user follows the link they will be redirected to `/` and be able to login normally.
|
||||
|
||||
```js
|
||||
// first setup the mail datasource (see #mail-model for more info)
|
||||
var mail = loopback.createDataSource({
|
||||
connector: loopback.Mail,
|
||||
transports: [{
|
||||
type: 'smtp',
|
||||
host: 'smtp.gmail.com',
|
||||
secureConnection: true,
|
||||
port: 465,
|
||||
auth: {
|
||||
user: 'you@gmail.com',
|
||||
pass: 'your-password'
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
User.email.attachTo(mail);
|
||||
User.requireEmailVerfication = true;
|
||||
User.afterRemote('create', function(ctx, user, next) {
|
||||
var options = {
|
||||
|
@ -1231,6 +1247,43 @@ MySession.attachTo(loopback.memory());
|
|||
|
||||
Send emails from your loopback app.
|
||||
|
||||
```js
|
||||
// extend a one-off model for sending email
|
||||
var MyEmail = loopback.Email.extend('my-email');
|
||||
|
||||
// create a mail data source
|
||||
var mail = loopback.createDataSource({
|
||||
connector: loopback.Mail,
|
||||
transports: [{
|
||||
type: 'smtp',
|
||||
host: 'smtp.gmail.com',
|
||||
secureConnection: true,
|
||||
port: 465,
|
||||
auth: {
|
||||
user: 'you@gmail.com',
|
||||
pass: 'your-password'
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
// attach the model
|
||||
MyEmail.attachTo(mail);
|
||||
|
||||
// send an email
|
||||
MyEmail.send({
|
||||
to: 'foo@bar.com',
|
||||
from: 'you@gmail.com',
|
||||
subject: 'my subject',
|
||||
text: 'my text',
|
||||
html: 'my <em>html</em>'
|
||||
}, function(err, mail) {
|
||||
console.log('email sent!');
|
||||
});
|
||||
```
|
||||
|
||||
> NOTE: the mail connector uses [nodemailer](http://www.nodemailer.com/). See
|
||||
> the [nodemailer docs](http://www.nodemailer.com/) for more info.
|
||||
|
||||
### REST Router
|
||||
|
||||
Expose models over rest using the `loopback.rest` router.
|
||||
|
|
1
index.js
1
index.js
|
@ -10,6 +10,7 @@ var loopback = module.exports = require('./lib/loopback');
|
|||
|
||||
loopback.Connector = require('./lib/connectors/base-connector');
|
||||
loopback.Memory = require('./lib/connectors/memory');
|
||||
loopback.Mail = require('./lib/connectors/mail');
|
||||
|
||||
/**
|
||||
* Types
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/**
|
||||
* Dependencies.
|
||||
*/
|
||||
|
||||
var mailer = require('nodemailer')
|
||||
, assert = require('assert');
|
||||
|
||||
/**
|
||||
* Export the MailConnector class.
|
||||
*/
|
||||
|
||||
module.exports = MailConnector;
|
||||
|
||||
/**
|
||||
* Create an instance of the connector with the given `settings`.
|
||||
*/
|
||||
|
||||
function MailConnector(settings) {
|
||||
assert(typeof settings === 'object', 'cannot initiaze MailConnector without a settings object');
|
||||
var transports = settings.transports || [];
|
||||
|
||||
transports.forEach(this.setupTransport.bind(this));
|
||||
}
|
||||
|
||||
MailConnector.initialize = function(dataSource, callback) {
|
||||
dataSource.connector = new MailConnector(dataSource.settings);
|
||||
callback();
|
||||
}
|
||||
|
||||
MailConnector.prototype.DataAccessObject = Mailer;
|
||||
|
||||
|
||||
/**
|
||||
* Add a transport to the available transports. See https://github.com/andris9/Nodemailer#setting-up-a-transport-method.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* Email.setupTransport({
|
||||
* type: 'SMTP',
|
||||
* host: "smtp.gmail.com", // hostname
|
||||
* secureConnection: true, // use SSL
|
||||
* port: 465, // port for secure SMTP
|
||||
* auth: {
|
||||
* user: "gmail.user@gmail.com",
|
||||
* pass: "userpass"
|
||||
* }
|
||||
* });
|
||||
*
|
||||
*/
|
||||
|
||||
MailConnector.prototype.setupTransport = function(setting) {
|
||||
var connector = this;
|
||||
connector.transports = connector.transports || [];
|
||||
connector.transportsIndex = connector.transportsIndex || {};
|
||||
var transport = mailer.createTransport(setting.type, setting);
|
||||
connector.transportsIndex[setting.type] = transport;
|
||||
connector.transports.push(transport);
|
||||
}
|
||||
|
||||
function Mailer() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email with the given `options`.
|
||||
*
|
||||
* Example Options:
|
||||
*
|
||||
* {
|
||||
* from: "Fred Foo ✔ <foo@blurdybloop.com>", // sender address
|
||||
* to: "bar@blurdybloop.com, baz@blurdybloop.com", // list of receivers
|
||||
* subject: "Hello ✔", // Subject line
|
||||
* text: "Hello world ✔", // plaintext body
|
||||
* html: "<b>Hello world ✔</b>" // html body
|
||||
* }
|
||||
*
|
||||
* See https://github.com/andris9/Nodemailer for other supported options.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @param {Function} callback Called after the e-mail is sent or the sending failed
|
||||
*/
|
||||
|
||||
Mailer.send = function (options, fn) {
|
||||
var dataSource = this.dataSource;
|
||||
var settings = dataSource && dataSource.settings;
|
||||
var connector = dataSource.connector;
|
||||
var transportsIndex = connector.transportsIndex;
|
||||
var transport = transportsIndex[options.transport || 'SMTP'] || connector.transports[0];
|
||||
assert(transport, 'You must supply an Email.settings.transports array containing at least one transport');
|
||||
|
||||
if(settings && settings.debug) {
|
||||
console.log('Sending Mail:');
|
||||
if(options.transport) {
|
||||
console.log('\t TRANSPORT:', options.transport);
|
||||
}
|
||||
console.log('\t TO:', options.to);
|
||||
console.log('\t FROM:', options.from);
|
||||
console.log('\t SUBJECT:', options.subject);
|
||||
console.log('\t TEXT:', options.text);
|
||||
console.log('\t HTML:', options.html);
|
||||
}
|
||||
|
||||
transport.sendMail(options, fn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email instance using `modelInstance.send()`.
|
||||
*/
|
||||
|
||||
Mailer.prototype.send = function (fn) {
|
||||
this.constructor.send(this, fn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Access the node mailer object.
|
||||
*/
|
||||
|
||||
MailConnector.mailer =
|
||||
MailConnector.prototype.mailer =
|
||||
Mailer.mailer =
|
||||
Mailer.prototype.mailer = mailer;
|
|
@ -3,9 +3,7 @@
|
|||
*/
|
||||
|
||||
var Model = require('../loopback').Model
|
||||
, loopback = require('../loopback')
|
||||
, mailer = require('nodemailer')
|
||||
, assert = require('assert');
|
||||
, loopback = require('../loopback');
|
||||
|
||||
/**
|
||||
* Default Email properties.
|
||||
|
@ -24,87 +22,3 @@ var properties = {
|
|||
*/
|
||||
|
||||
var Email = module.exports = Model.extend('email', properties);
|
||||
|
||||
/*!
|
||||
* Setup the Email class after extension.
|
||||
*/
|
||||
|
||||
Email.setup = function (settings) {
|
||||
settings = settings || this.settings;
|
||||
var transports = settings.transports || [];
|
||||
|
||||
transports.forEach(this.setupTransport.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a transport to the available transports. See https://github.com/andris9/Nodemailer#setting-up-a-transport-method.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* Email.setupTransport({
|
||||
* type: 'SMTP',
|
||||
* host: "smtp.gmail.com", // hostname
|
||||
* secureConnection: true, // use SSL
|
||||
* port: 465, // port for secure SMTP
|
||||
* auth: {
|
||||
* user: "gmail.user@gmail.com",
|
||||
* pass: "userpass"
|
||||
* }
|
||||
* });
|
||||
*
|
||||
*/
|
||||
|
||||
Email.setupTransport = function (setting) {
|
||||
var Email = this;
|
||||
Email.transports = Email.transports || [];
|
||||
Email.transportsIndex = Email.transportsIndex || {};
|
||||
var transport = mailer.createTransport(setting.type, setting);
|
||||
Email.transportsIndex[setting.type] = transport;
|
||||
Email.transports.push(transport);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email with the given `options`.
|
||||
*
|
||||
* Example Options:
|
||||
*
|
||||
* {
|
||||
* from: "Fred Foo ✔ <foo@blurdybloop.com>", // sender address
|
||||
* to: "bar@blurdybloop.com, baz@blurdybloop.com", // list of receivers
|
||||
* subject: "Hello ✔", // Subject line
|
||||
* text: "Hello world ✔", // plaintext body
|
||||
* html: "<b>Hello world ✔</b>" // html body
|
||||
* }
|
||||
*
|
||||
* See https://github.com/andris9/Nodemailer for other supported options.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @param {Function} callback Called after the e-mail is sent or the sending failed
|
||||
*/
|
||||
|
||||
Email.send = function (options, fn) {
|
||||
var transport = this.transportsIndex[options.transport || 'SMTP'] || this.transports[0];
|
||||
assert(transport, 'You must supply an Email.settings.transports array containing at least one transport');
|
||||
|
||||
transport.sendMail(options, fn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Access the node mailer object.
|
||||
*
|
||||
* Email.mailer
|
||||
* // or
|
||||
* var email = new Email({to: 'foo@bar.com', from: 'bar@bat.com'});
|
||||
* email.mailer
|
||||
*/
|
||||
|
||||
Email.mailer =
|
||||
Email.prototype.mailer = mailer;
|
||||
|
||||
/**
|
||||
* Send an email instance using `Email.send()`.
|
||||
*/
|
||||
|
||||
Email.prototype.send = function (fn) {
|
||||
this.constructor.send(this, fn);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
var loopback = require('../');
|
||||
var MailConnector = loopback.Mail;
|
||||
var MyEmail = loopback.Email.extend('my-email');
|
||||
var assert = require('assert');
|
||||
|
||||
describe('Email and SMTP', function () {
|
||||
var mail = loopback.createDataSource({
|
||||
connector: MailConnector,
|
||||
transports: [
|
||||
{type: 'STUB'}
|
||||
]
|
||||
});
|
||||
|
||||
MyEmail.attachTo(mail);
|
||||
|
||||
it('should have a send method', function () {
|
||||
assert(typeof MyEmail.send === 'function');
|
||||
assert(typeof MyEmail.prototype.send === 'function');
|
||||
});
|
||||
|
||||
describe('MyEmail', function () {
|
||||
it('MyEmail.send(options, callback)', function (done) {
|
||||
var options = {
|
||||
to: 'to@to.com',
|
||||
from: 'from@from.com',
|
||||
subject: 'subject',
|
||||
text: 'text',
|
||||
html: '<h1>html</h1>'
|
||||
};
|
||||
|
||||
MyEmail.send(options, function(err, mail) {
|
||||
assert(mail.message);
|
||||
assert(mail.envelope);
|
||||
assert(mail.messageId);
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
it('myEmail.send(callback)', function (done) {
|
||||
var message = new MyEmail({
|
||||
to: 'to@to.com',
|
||||
from: 'from@from.com',
|
||||
subject: 'subject',
|
||||
text: 'text',
|
||||
html: '<h1>html</h1>'
|
||||
});
|
||||
|
||||
message.send(function (err, mail) {
|
||||
assert(mail.message);
|
||||
assert(mail.envelope);
|
||||
assert(mail.messageId);
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,6 +1,7 @@
|
|||
var User = loopback.User.extend('user');
|
||||
var Session = loopback.Session;
|
||||
var passport = require('passport');
|
||||
var MailConnector = require('../lib/connectors/mail');
|
||||
|
||||
var userMemory = loopback.createDataSource({
|
||||
connector: loopback.Memory
|
||||
|
@ -9,9 +10,13 @@ var userMemory = loopback.createDataSource({
|
|||
|
||||
describe('User', function(){
|
||||
|
||||
var mailDataSource = loopback.createDataSource({
|
||||
connector: MailConnector,
|
||||
transports: [{type: 'STUB'}]
|
||||
});
|
||||
User.attachTo(userMemory);
|
||||
User.session.attachTo(userMemory);
|
||||
User.email.setup({transports: [{type: 'STUB'}]});
|
||||
User.email.attachTo(mailDataSource);
|
||||
|
||||
// allow many User.afterRemote's to be called
|
||||
User.setMaxListeners(0);
|
||||
|
|
Loading…
Reference in New Issue