From 1dc3d747439d1d5ebe2fb0e2d6c66d99a6221828 Mon Sep 17 00:00:00 2001 From: James Ketrenos Date: Mon, 1 Oct 2018 14:07:36 -0700 Subject: [PATCH] Email system plumbed to send authentication request. --- package.json | 2 + server/db/users.js | 5 ++- server/routes/users.js | 88 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 83 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 49239dd..08f5d3e 100644 --- a/package.json +++ b/package.json @@ -21,10 +21,12 @@ "exif-reader": "github:paras20xx/exif-reader", "express": "^4.16.2", "express-session": "^1.15.6", + "handlebars": "^4.0.12", "ldapauth-fork": "^4.0.2", "mariasql": "^0.2.6", "moment": "^2.22.2", "morgan": "^1.9.0", + "mustache": "^3.0.0", "nodemailer": "^4.6.8", "qs": "^6.5.2", "sequelize": "^4.28.6", diff --git a/server/db/users.js b/server/db/users.js index 1683ccc..6a92c9c 100644 --- a/server/db/users.js +++ b/server/db/users.js @@ -65,7 +65,10 @@ function init() { key: 'id', } } - }) + }, { + timestamps: false + }); + return db.sequelize.sync({ force: false }).then(function () { diff --git a/server/routes/users.js b/server/routes/users.js index 30b561e..eb8fd08 100755 --- a/server/routes/users.js +++ b/server/routes/users.js @@ -4,13 +4,14 @@ const express = require("express"), config = require("config"), LdapAuth = require("ldapauth-fork"), crypto = require("crypto"), - createTransport = require("nodemailer").createTransport; + createTransport = require("nodemailer").createTransport, + hb = require("handlebars"); const router = express.Router(); let userDB; -let mail = createTransport({ +let transporter = createTransport({ host: config.get("smtp.host"), pool: true, port: config.has("smtp.port") ? config.get("smtp.port") : 25 @@ -34,6 +35,29 @@ router.get("/", function(req, res/*, next*/) { return res.status(200).send({}); }); +const templates = { + "html": [ + "

Dear {{name}},

", + "", + "

Welcome to HTML {{username}}.

", + "", + "

Your secret is: {{secret}}.

", + "", + "

Sincerely,

", + "

James

" + ].join("\n"), + "text": [ + "Dear {{name}},", + "", + "Welcome to TEXT {{username}}.", + "", + "Your secret is: {{secret}}.", + "", + "Sincerely,", + "James" + ].join("\n") +}; + function ldapPromise(username, password) { if (!ldap) { return Promise.reject("LDAP not being used"); @@ -69,8 +93,10 @@ router.post("/create", function(req, res) { return res.status(400).send("Email address already used."); } - let re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + let re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/, + secret = "magic cookie"; if (!re.exec(mail)) { + console.log("Invalid email address: " + mail); return res.status(400).send("Invalid email address."); } @@ -89,20 +115,60 @@ router.post("/create", function(req, res) { "(userId,issued,key,type) VALUES " + "(:userId,CURRENT_TIMESTAMP,:key,'account-setup')", { replacements: { - key: "magic cookie", + key: secret, userId: metadata.lastID } - }).then(function() { + }).catch(function(error) { + console.log(error); + throw error; }); -/* - req.session.user = { - name: name, + }).spread(function(results, metadata) { + let data = { + username: name, mail: mail, - username: username, + secret: secret + }, envelope = { + to: mail, + from: config.get("smtp.sender"), + subject: "Request to create account for " + name, + cc: "", + bcc: "", + text: hb.compile(templates.text)(data), + html: hb.compile(templates.html)(data) }; - return res.status(200).send(req.session.user); -*/ + return new Promise(function (resolve, reject) { + let attempts = 10; + + function send(envelope) { + /* Rate limit to ten per second */ + transporter.sendMail(envelope, function (error, info) { + if (!error) { + console.log('Message sent: ' + info.response); + return resolve(); + } + + if (attempts == 0) { + console.log("Error sending email: ", error) + return reject(error); + } + + attempts--; + console.log("Unable to send mail. Trying again in 100ms (" + attempts + " attempts remain): ", error); + setTimeout(send.bind(undefined, envelope), 100); + }); + } + + send(envelope); + }); }).then(function() { + /* + req.session.user = { + name: name, + mail: mail, + username: username, + }; + return res.status(200).send(req.session.user); + */ req.session.user = {}; return res.status(401).send("Account has not been authenticated."); });