Skip to content

Commit

Permalink
[ENG-1037] - Forgot password emailing working with smtp, SES and test
Browse files Browse the repository at this point in the history
  • Loading branch information
Phara0h committed Aug 23, 2019
1 parent 969aa85 commit eef0724
Show file tree
Hide file tree
Showing 10 changed files with 257 additions and 48 deletions.
7 changes: 3 additions & 4 deletions include/database/index.js
Expand Up @@ -91,18 +91,17 @@ class Database {
return user;
}

static async forgotPassword(email) {
static async forgotPassword(email, ip) {
var user = await User.findLimtedBy({email:email},'AND',1);
if(user && user.length > 0) {
user = user[0];

var rt = await Email.getRecoveryToken();
user.reset_password_token = rt.secret;
console.log(user)

await user.save();

// @TODO send the email;
Email.sendPasswordRecovery(user.email, rt.token);
Email.sendPasswordRecovery(user, ip, user.email, rt.token);
}
}

Expand Down
4 changes: 1 addition & 3 deletions include/routes/v1/auth.js
Expand Up @@ -160,7 +160,7 @@ module.exports = function(app, opts, done) {
});
} else {
res.code(200).send();
Database.forgotPassword(req.body.email);
Database.forgotPassword(req.body.email, req.ip);
}
});

Expand All @@ -177,7 +177,6 @@ module.exports = function(app, opts, done) {
+ config.password.special + 'special character/s. ',
});
} else {
console.log(req.query.token)
var token = await Email.checkRecoveryToken(req.query.token);

if (!token) {
Expand All @@ -188,7 +187,6 @@ module.exports = function(app, opts, done) {
} else
{
var cPassword = await Database.resetPassword(token, req.body.password);
console.log(cPassword)
if (cPassword) {
res.code(200).send();
} else {
Expand Down
2 changes: 1 addition & 1 deletion include/routes/v1/users.js
Expand Up @@ -6,7 +6,7 @@ module.exports = function(app, opts, done) {

var getUser = async (req, res, resolveGroup = false) => {

if (req.params.username && !regex.safeName.exec(req.params.username) || req.params.id && Number.isNaN(req.params.id)) {
if ((req.params.username && !regex.safeName.exec(req.params.username)) || (req.params.id && Number.isNaN(req.params.id))) {
res.code(400);
return {
type: 'user-find-by-error',
Expand Down
39 changes: 31 additions & 8 deletions include/utils/config.js
@@ -1,22 +1,20 @@
'use strict';

var isSetDefault = function(v, d) {

if(typeof v == 'number')
{
if(typeof v == 'number') {
return (!Number.isNaN(v)) ? v : d;
}
return (v !== null && v !== undefined) ? v : d;
};

console.log(process.env.TRAVELLING_EMAIL_TEST_ENABLE)
const config = {
port: isSetDefault(Number(process.env.TRAVELLING_PORT), 443),
key: process.env.TRAVELLING_KEY,
cert: process.env.TRAVELLING_CERT,
log: {
logger:require(isSetDefault(process.env.TRAVELLING_LOG_LOGGER, 'console')),
requests: isSetDefault(Boolean(process.env.TRAVELLING_LOG_REQUESTS), true),
unauthorizedAccess: isSetDefault(Boolean(process.env.TRAVELLING_LOG_UNAUTHORIZED_ACCESS), true)
requests: isSetDefault(process.env.TRAVELLING_LOG_REQUESTS == 'true', true),
unauthorizedAccess: isSetDefault(process.env.TRAVELLING_LOG_UNAUTHORIZED_ACCESS == 'true', true)
},
portal: {
path: isSetDefault(process.env.TRAVELLING_PORTAL_PATH, '/travelling/portal/'),
Expand All @@ -33,7 +31,7 @@ const config = {
minchar:isSetDefault(Number(process.env.TRAVELLING_USERNAME_MINCHAR), 3),
},
password: {
consecutive: isSetDefault(Boolean(process.env.TRAVELLING_PASSWORD_CONSECUTIVE), true),
consecutive: isSetDefault(process.env.TRAVELLING_PASSWORD_CONSECUTIVE == 'true', true),
minchar: isSetDefault(Number(process.env.TRAVELLING_PASSWORD_MINCHAR), 1),
maxchar: isSetDefault(Number(process.env.TRAVELLING_PASSWORD_MAXCHAR), 100),
special: isSetDefault(Number(process.env.TRAVELLING_PASSWORD_SPECIAL), 0),
Expand All @@ -55,12 +53,37 @@ const config = {
implementation: isSetDefault(process.env.TRAVELLING_PG_CRYPTO_IMPLEMENTATION, './include/utils/cryptointerface'),
secret: isSetDefault(process.env.TRAVELLING_PG_CRYPTO_IMPLEMENTATION_SECRET, null),
salt: isSetDefault(process.env.TRAVELLING_PG_CRYPTO_IMPLEMENTATION_SALT, null),
encryptUserData: isSetDefault(Boolean(process.env.TRAVELLING_PG_CRYPTO_ENCRYPT_USER_DATA), false)
encryptUserData: isSetDefault(process.env.TRAVELLING_PG_CRYPTO_ENCRYPT_USER_DATA == 'true', false)
},
},
email: {
recovery : {
expiration: isSetDefault(Number(process.env.TRAVELLING_EMAIL_RECOVERY_EXPIRATION), 900) //seconds
},
template: {
body:isSetDefault(process.env.TRAVELLING_EMAIL_TEMPLATE_BODY, './templates/email-body.html'),
subject: isSetDefault(process.env.TRAVELLING_EMAIL_TEMPLATE_SUBJECT, './templates/email-subject.html')
},
test: {
enable: isSetDefault(process.env.TRAVELLING_EMAIL_TEST_ENABLE == 'true', false)
},
smtp: {
enable: isSetDefault(process.env.TRAVELLING_EMAIL_SMTP_ENABLE == 'true', false),
host: isSetDefault(process.env.TRAVELLING_EMAIL_SMTP_HOST, "127.0.0.1"),
port: isSetDefault(process.env.TRAVELLING_EMAIL_SMTP_PORT, 465),
secure: isSetDefault(process.env.TRAVELLING_EMAIL_SMTP_SECURE == 'true', true), // use TLS
auth: {
user: isSetDefault(process.env.TRAVELLING_EMAIL_SMTP_AUTH_USER, null),
pass: isSetDefault(process.env.TRAVELLING_EMAIL_SMTP_AUTH_PASSWORD, null),
},
tls: {
// do not fail on invalid certs
rejectUnauthorized: isSetDefault(process.env.TRAVELLING_EMAIL_SMTP_TLS_REJECT_UNAUTHORIZED, false),
}
},
aws : {
enable: isSetDefault(Boolean(process.env.TRAVELLING_EMAIL_AWS_ENABLE), false),
config: isSetDefault(process.env.TRAVELLING_EMAIL_AWS_CONFIG, null),
}
}
};
Expand Down
68 changes: 61 additions & 7 deletions include/utils/email.js
@@ -1,15 +1,54 @@
const crypto = require('crypto');
const Token = require('./token');
const config = require('./config');
const nodemailer = require('nodemailer');
const fs = require('fs');
const Handlebars = require('handlebars');
const Fasquest = require('fasquest');

var transporter = null;
var templates = null;

class Email {
constructor() {
}

static async init() {
if (config.email.test.enable) {
var testAccount = await nodemailer.createTestAccount();

config.log.logger.debug('Test Email Account:',testAccount);

transporter = nodemailer.createTransport({
host: 'smtp.ethereal.email',
port: 587,
secure: false, // true for 465, false for other ports
auth: {
user: testAccount.user, // generated ethereal user
pass: testAccount.pass, // generated ethereal password
},
});
} else if (config.email.smtp.enable) {
transporter = nodemailer.createTransport(config.email.smtp);
} else if (config.email.aws.enable) {
var aws = require('aws-sdk');

aws.config.loadFromPath(config.email.aws.config);
transporter = nodemailer.createTransport({
SES: new aws.SES({apiVersion: '2010-12-01'}),
});
}
templates = {
body: Handlebars.compile(fs.readFileSync(require('path').resolve(config.email.template.body), 'utf-8')),
subject: Handlebars.compile(fs.readFileSync(require('path').resolve(config.email.template.subject), 'utf-8')),
};
}

static async checkRecoveryToken(token) {
try {
var dToken = (await Token.decrypt(token.replace(/-/g,'+').replace(/_/g,'\/'))).split('|');
if ((Date.now() - Number(dToken[1])) < config.email.recovery.expiration * 1000) {
var dToken = (await Token.decrypt(token.replace(/-/g, '+').replace(/_/g, '\/'))).split('|');

if (Date.now() - Number(dToken[1]) < config.email.recovery.expiration * 1000) {
return dToken.join('|'); // secret;
}
return false;
Expand All @@ -30,16 +69,31 @@ class Email {

secret = secret.toString('base64');

resolve({token: (await Token.encrypt(secret)).replace(/\+/g,'-').replace(/\//g,'_'), secret});
resolve({token: (await Token.encrypt(secret)).replace(/\+/g, '-').replace(/\//g, '_'), secret});
});
});

}

static sendPasswordRecovery(email, token) {
console.log(email,token)
}
static async sendPasswordRecovery(user, ip, email, token) {

ip = await Fasquest.request({
uri: `http://ip-api.com/json/${ip}?fields=status,country,regionName,city,isp,query`,
});
var body = templates.body({user, ip, config, token});
var subject = templates.subject({user});

transporter.sendMail({
from: 'jolmodarta@desoz.com',
to: email,
subject: subject,
html: body,
}, (e, r)=>{
if (e) {
config.log.logger.error(e);
}
});
config.log.logger.debug('Password Recovery For: ', email, token);
}
}

module.exports = Email;
2 changes: 2 additions & 0 deletions index.js
Expand Up @@ -34,6 +34,7 @@ const Router = require('./include/server/router');
const router = new Router(app.server);

const auth = require('./include/utils/auth');
const Email = require('./include/utils/email');

const nstats = require('nstats')();

Expand Down Expand Up @@ -103,6 +104,7 @@ async function init() {
await User.createTable();
await Group.createTable();
await Database.initGroups(router);
await Email.init();
app.listen(config.port, '0.0.0.0');

console.log(`Travelling on port ${config.port}`);
Expand Down

0 comments on commit eef0724

Please sign in to comment.