From 946eafc96d86902adc8f4ed2c0bc0285cd7b3df8 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Wed, 10 Dec 2014 12:22:12 -0300 Subject: [PATCH] added expiration date to email validation --- plugins/emailstore.js | 79 +++++++++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 25 deletions(-) diff --git a/plugins/emailstore.js b/plugins/emailstore.js index 59f6f01..46f93f5 100644 --- a/plugins/emailstore.js +++ b/plugins/emailstore.js @@ -13,6 +13,7 @@ var levelup = require('levelup'); var nodemailer = require('nodemailer'); var querystring = require('querystring'); + var moment = require('moment'); var logger = require('../lib/logger').logger; var globalConfig = require('../config/config'); @@ -50,7 +51,11 @@ OVER_QUOTA: { code: 406, message: 'User quota exceeded', - } + }, + REGISTRATION_EXPIRED: { + code: 400, + message: 'Registration expired', + }, }; var EMAIL_TO_PASSPHRASE = 'email-to-passphrase-'; @@ -69,6 +74,8 @@ var POST_LIMIT = 1024 * 300 /* Max POST 300 kb */ ; + var DAYS_TO_EXPIRATION = 7; // An email can be awaiting validation for this long before expiring + var valueKey = function(email, key) { return STORED_VALUE + bitcore.util.twoSha256(email + SEPARATOR + key).toString('hex'); }; @@ -361,9 +368,20 @@ */ emailPlugin.createVerificationSecret = function(email, callback) { emailPlugin.db.get(pendingKey(email), function(err, value) { - if (err && err.notFound) { + var available = false; + + var notFound = err && err.notFound; + var expired = !err && _.isObject(value) && moment().isAfter(value.expires); + + var available = notFound || expired; + + if (available) { var secret = emailPlugin.crypto.randomBytes(16).toString('hex'); - emailPlugin.db.put(pendingKey(email), secret, function(err) { + var value = { + secret: secret, + expires: moment().add(DAYS_TO_EXPIRATION, 'days'), + }; + emailPlugin.db.put(pendingKey(email), value, function(err) { if (err) { logger.error('error saving pending data:', email, secret); return callback(emailPlugin.errors.INTERNAL_ERROR); @@ -741,29 +759,40 @@ code: 500, message: err }, response); - } else if (value !== secret) { - return emailPlugin.returnError(emailPlugin.errors.INVALID_CODE, response); - } else { - emailPlugin.db.put(validatedKey(email), true, function(err, value) { - if (err) { - return emailPlugin.returnError({ - code: 500, - message: err - }, response); - } else { - emailPlugin.db.del(pendingKey(email), function(err, value) { - if (err) { - return emailPlugin.returnError({ - code: 500, - message: err - }, response); - } else { - response.redirect(emailPlugin.redirectUrl); - } - }); - } - }); } + + var secret; + if (_.isObject(value)) { + if (moment().isAfter(value.expires)) { + return emailPlugin.returnError(emailPlugin.errors.REGISTRATION_EXPIRED, response); + } else { + value = value.secret; + } + } + + if (value !== secret) { + return emailPlugin.returnError(emailPlugin.errors.INVALID_CODE, response); + } + + emailPlugin.db.put(validatedKey(email), true, function(err, value) { + if (err) { + return emailPlugin.returnError({ + code: 500, + message: err + }, response); + } else { + emailPlugin.db.del(pendingKey(email), function(err, value) { + if (err) { + return emailPlugin.returnError({ + code: 500, + message: err + }, response); + } else { + response.redirect(emailPlugin.redirectUrl); + } + }); + } + }); }); };