Skip to content

Instantly share code, notes, and snippets.

@vikasjayaram
Last active November 30, 2018 22:15
Show Gist options
  • Save vikasjayaram/4569e2a29d3b303161f7bd0842315ed7 to your computer and use it in GitHub Desktop.
Save vikasjayaram/4569e2a29d3b303161f7bd0842315ed7 to your computer and use it in GitHub Desktop.
To send a verification email during rule execution.

Settings (Values stored here will be available to all rules, via the global configuration object.)

  • SMTP_HOST
  • SMTP_PORT
  • SMTP_USERNAME
  • SMTP_PASSWORD
  • AUTH0_DOMAIN
  • AUTH0_CLIENT_ID
  • AUTH0_CLIENT_SECRET

Scopes required for AUTH0_CLIENT_ID

Make sure the AUTH0_CLIENT_ID has client_credentials grant.

read:users
update:users
update:users_app_metadata
create:user_tickets
read:email_templates
function sendVerificationEmail(user, context, callback) {
// Perform any asynchronous actions, e.g. send notification to Slack.
var nodemailer = require('nodemailer');
var tools = require('auth0-extension-tools@1.3.1');
var async = require('async');
var Liquid = require("liquid-node");
var engine = new Liquid.Engine();
/*
* Constants
*/
var EMAIL_FROM = "{REPLACE_WITH_EMAIL_FROM_ADDRESS}";
var EMAIL_SUBJECT = "Verify your Email";
/*
* SMTP Transport object
*/
var smtpConfig = {
host: configuration.SMTP_HOST,
port: configuration.SMTP_PORT,
secure: false, // upgrade later with STARTTLS
auth: {
user: configuration.SMTP_USERNAME,
pass: configuration.SMTP_PASSWORD
}
};
var CLIENTS_TO_SEND_VERIFICATION_EMAIL = ['REPLACE_WITH_YOUR_CLIENT_ID'];
// run only for the specified clients
if (CLIENTS_TO_SEND_VERIFICATION_EMAIL.indexOf(context.clientID) !== -1 && user.email_verified === false) {
// init workflow
workflow(user, context, callback);
} else {
callback(null, user, context);
}
var transporter = nodemailer.createTransport(smtpConfig);
var user_id = user.user_id;
/*
* 1. Get Auth0 Management Token
* 2. Update user app_metadata
* 3. create verification email ticket
* 4. get verification email template
* 5. populate template with data
* 6. send email
*/
function callAuth0ManagementApi(stage, options, cb) {
tools.managementApi.getClient({domain: configuration.AUTH0_DOMAIN, clientId: configuration.AUTH0_CLIENT_ID, clientSecret: configuration.AUTH0_CLIENT_SECRET})
.then(function(client) {
switch (stage) {
case 'update_user':
var app_metadata = user.app_metadata || {};
var code = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
var codeDate = new Date();
app_metadata.code = code;
app_metadata.codeDate = codeDate;
user.app_metadata = app_metadata;
client.users.updateAppMetadata({id: user_id}, app_metadata, function (error, u) {
if (error) return callback(error);
return cb(null, options);
});
break;
case 'create_verification_ticket':
var data = {};
data.user_id = user_id;
if (options.template.resultUrl) {
data.result_url = options.template.resultUrl;
}
console.log(data);
client.tickets.verifyEmail(data, function (error, ticket) {
if (error) return callback(error);
options.ticket = ticket;
return cb(null, options);
});
break;
case 'get_verification_email_template':
client.emailTemplates.get({name: "verify_email"}, function (error, template) {
if (error) return callback(error);
options.template = template;
return cb(null, options);
});
break;
}
})
.catch(error => console.log(error));
}
function updateUserAppMetadata(options, cb) {
console.log("3. updateUserAppMetadata>>>");
callAuth0ManagementApi('update_user', options, cb);
}
function getVerifyEmailTemplate(options, cb) {
console.log("2. getVerifyEmailTemplate>>>");
callAuth0ManagementApi('get_verification_email_template', options, cb);
}
function createVerificationTicket (options, cb) {
/*
* https://auth0.com/docs/api/management/v2#!/Tickets/post_email_verification
* var data = {
* user_id: '{USER_ID}',
* result_url: '{REDIRECT_URL}' // Optional redirect after the ticket is used.
* };
*/
console.log("4. createVerificationTicket>>>");
callAuth0ManagementApi('create_verification_ticket', options, cb);
}
function populateEmailTemplate(options, cb) {
engine
.parseAndRender(options.template.body, { url: options.ticket.ticket, user: user })
.then(function(renderedTemplate) {
console.log(renderedTemplate);
options.renderedTemplate = renderedTemplate;
cb(null, options);
})
.catch(error => cb(error));
}
function sendVerificationEmail(options, cb) {
var mailOptions = {
from : EMAIL_FROM,
to: user.email,
subject: EMAIL_SUBJECT,
html: options.renderedTemplate
};
transporter.sendMail(mailOptions, function(error, response){
if(error){
console.log(error);
callback(error);
}else{
console.log("Message sent: " + response.message);
cb(null, 'done');
}
// if you don't want to use this transport object anymore, uncomment following line
//smtpTransport.close(); // shut down the connection pool, no more messages
});
}
function workflow(user, context, cb) {
async.waterfall([
async.apply(updateUserAppMetadata, {}),
getVerifyEmailTemplate,
createVerificationTicket,
populateEmailTemplate,
sendVerificationEmail
], function (err, result) {
console.log('err', err);
console.log('result: ', result);
});
return cb(new UnauthorizedError('We have sent you a email to confirm your identity. Please verify your email and login.'));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment