v1.18.x
Julian Lam 10 years ago
parent 7f6518e4a6
commit 1843d0364e

@ -13,6 +13,10 @@
"reset.text2": "To continue with the password reset, please click on the following link:", "reset.text2": "To continue with the password reset, please click on the following link:",
"reset.cta": "Click here to reset your password", "reset.cta": "Click here to reset your password",
"reset.notify.subject": "Password successfully changed",
"reset.notify.text1": "We are notifying you that on %1, your password was changed successfully.",
"reset.notify.text2": "If you did not authorise this, please notify an administrator immediately.",
"digest.notifications": "You have unread notifications from %1:", "digest.notifications": "You have unread notifications from %1:",
"digest.latest_topics": "Latest topics from %1", "digest.latest_topics": "Latest topics from %1",
"digest.cta": "Click here to visit %1", "digest.cta": "Click here to visit %1",

@ -10,5 +10,7 @@
"enter_email": "Please enter your <strong>email address</strong> and we will send you an email with instructions on how to reset your account.", "enter_email": "Please enter your <strong>email address</strong> and we will send you an email with instructions on how to reset your account.",
"enter_email_address": "Enter Email Address", "enter_email_address": "Enter Email Address",
"password_reset_sent": "Password Reset Sent", "password_reset_sent": "Password Reset Sent",
"invalid_email": "Invalid Email / Email does not exist!" "invalid_email": "Invalid Email / Email does not exist!",
"password_too_short": "The password entered is too short, please pick a different password.",
"passwords_do_not_match": "The two passwords you've entered do not match."
} }

@ -11,44 +11,39 @@ define('forum/reset_code', function() {
resetEl.on('click', function() { resetEl.on('click', function() {
if (password.val().length < 6) { if (password.val().length < 6) {
$('#error').addClass('hide').hide(); app.alertError('[[reset_password:password_too_short]]');
noticeEl.find('strong').html('Invalid Password'); } else if (password.val() !== repeat.val()) {
noticeEl.find('p').html('The password entered is too short, please pick a different password.'); app.alertError('[[reset_password:passwords_do_not_match]]');
noticeEl.removeClass('hide').css({display: 'block'});
} else if (password.value !== repeat.value) {
$('#error').hide();
noticeEl.find('strong').html('Invalid Password');
noticeEl.find('p').html('The two passwords you\'ve entered do not match.');
noticeEl.removeClass('hide').css({display: 'block'});
} else { } else {
resetEl.prop('disabled', true).html('<i class="fa fa-spin fa-refresh"></i> Changing Password');
socket.emit('user.reset.commit', { socket.emit('user.reset.commit', {
code: reset_code, code: reset_code,
password: password.val() password: password.val()
}, function(err) { }, function(err) {
if(err) { if (err) {
ajaxify.refresh();
return app.alertError(err.message); return app.alertError(err.message);
} }
$('#error').addClass('hide').hide();
$('#notice').addClass('hide').hide(); window.location.href = RELATIVE_PATH + '/login';
$('#success').removeClass('hide').addClass('show').show();
}); });
} }
}); });
socket.emit('user.reset.valid', reset_code, function(err, valid) { // socket.emit('user.reset.valid', reset_code, function(err, valid) {
if(err) { // if(err) {
return app.alertError(err.message); // return app.alertError(err.message);
} // }
if (valid) { // if (valid) {
resetEl.prop('disabled', false); // resetEl.prop('disabled', false);
} else { // } else {
var formEl = $('#reset-form'); // var formEl = $('#reset-form');
// Show error message // // Show error message
$('#error').show(); // $('#error').show();
formEl.remove(); // formEl.remove();
} // }
}); // });
}; };
return ResetCode; return ResetCode;

@ -106,9 +106,12 @@ Controllers.home = function(req, res, next) {
Controllers.reset = function(req, res, next) { Controllers.reset = function(req, res, next) {
if (req.params.code) { if (req.params.code) {
res.render('reset_code', { user.reset.validate(req.params.code, function(err, valid) {
reset_code: req.params.code ? req.params.code : null, res.render('reset_code', {
breadcrumbs: helpers.buildBreadcrumbs([{text: '[[reset_password:reset_password]]', url: '/reset'}, {text: '[[reset_password:update_password]]'}]) valid: valid,
reset_code: req.params.code ? req.params.code : null,
breadcrumbs: helpers.buildBreadcrumbs([{text: '[[reset_password:reset_password]]', url: '/reset'}, {text: '[[reset_password:update_password]]'}])
});
}); });
} else { } else {
res.render('reset', { res.render('reset', {

@ -13,6 +13,8 @@ var async = require('async'),
websockets = require('./index'), websockets = require('./index'),
meta = require('../meta'), meta = require('../meta'),
events = require('../events'), events = require('../events'),
emailer = require('../emailer'),
db = require('../database'),
SocketUser = {}; SocketUser = {};
SocketUser.exists = function(socket, data, callback) { SocketUser.exists = function(socket, data, callback) {
@ -81,23 +83,34 @@ SocketUser.reset.send = function(socket, email, callback) {
} }
}; };
SocketUser.reset.valid = function(socket, code, callback) {
if (code) {
user.reset.validate(code, callback);
}
};
SocketUser.reset.commit = function(socket, data, callback) { SocketUser.reset.commit = function(socket, data, callback) {
if(data && data.code && data.password) { if(data && data.code && data.password) {
user.reset.commit(data.code, data.password, function(err) { async.series([
async.apply(db.getObjectField, 'reset:uid', data.code),
async.apply(user.reset.commit, data.code, data.password)
], function(err, data) {
if (err) { if (err) {
return callback(err); return callback(err);
} }
var uid = data[0],
now = new Date(),
parsedDate = now.getFullYear() + '/' + (now.getMonth()+1) + '/' + now.getDate();
user.getUserField(uid, 'username', function(err, username) {
emailer.send('reset_notify', uid, {
username: username,
date: parsedDate,
site_title: meta.config.title || 'NodeBB',
subject: '[[email:reset.notify.subject]]'
});
});
events.log({ events.log({
type: 'password-reset', type: 'password-reset',
uid: socket.uid, uid: socket.uid,
ip: socket.ip ip: socket.ip
}); });
callback();
}); });
} }
}; };

@ -21,7 +21,7 @@ var db = require('./database'),
schemaDate, thisSchemaDate, schemaDate, thisSchemaDate,
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema // IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema
latestSchema = Date.UTC(2015, 0, 30); latestSchema = Date.UTC(2015, 1, 8);
Upgrade.check = function(callback) { Upgrade.check = function(callback) {
db.get('schemaDate', function(err, value) { db.get('schemaDate', function(err, value) {
@ -807,6 +807,26 @@ Upgrade.upgrade = function(callback) {
winston.info('[2015/01/30] Adding group member counts skipped'); winston.info('[2015/01/30] Adding group member counts skipped');
next(); next();
} }
},
function(next) {
thisSchemaDate = Date.UTC(2015, 1, 8);
if (schemaDate < thisSchemaDate) {
updatesMade = true;
winston.info('[2015/02/08] Clearing reset tokens');
db.deleteAll(['reset:expiry', 'reset:uid'], function(err) {
if (err) {
winston.error('[2015/02/08] Error encountered while Clearing reset tokens');
return next(err);
}
winston.info('[2015/02/08] Clearing reset tokens done');
Upgrade.update(thisSchemaDate, next);
});
} else {
winston.info('[2015/02/08] Clearing reset tokens skipped');
next();
}
} }
// Add new schema updates here // Add new schema updates here

@ -1,4 +1,3 @@
'use strict'; 'use strict';
var async = require('async'), var async = require('async'),
@ -21,19 +20,13 @@ var async = require('async'),
return callback(err, false); return callback(err, false);
} }
db.getObjectField('reset:expiry', code, function(err, expiry) { db.sortedSetScore('reset:issueDate', code, function(err, issueDate) {
// db.getObjectField('reset:expiry', code, function(err, expiry) {
if (err) { if (err) {
return callback(err); return callback(err);
} }
if (parseInt(expiry, 10) >= Date.now() / 1000) { callback(null, parseInt(issueDate, 10) > (Date.now() - (1000*60*120)));
callback(null, true);
} else {
// Expired, delete from db
db.deleteObjectField('reset:uid', code);
db.deleteObjectField('reset:expiry', code);
callback(null, false);
}
}); });
}); });
}; };
@ -46,7 +39,7 @@ var async = require('async'),
var reset_code = utils.generateUUID(); var reset_code = utils.generateUUID();
db.setObjectField('reset:uid', reset_code, uid); db.setObjectField('reset:uid', reset_code, uid);
db.setObjectField('reset:expiry', reset_code, (60 * 60) + Math.floor(Date.now() / 1000)); db.sortedSetAdd('reset:issueDate', Date.now(), reset_code);
var reset_link = nconf.get('url') + '/reset/' + reset_code; var reset_link = nconf.get('url') + '/reset/' + reset_code;
@ -85,7 +78,7 @@ var async = require('async'),
user.setUserField(uid, 'password', hash); user.setUserField(uid, 'password', hash);
db.deleteObjectField('reset:uid', code); db.deleteObjectField('reset:uid', code);
db.deleteObjectField('reset:expiry', code); db.sortedSetRemove('reset:issueDate', code);
user.auth.resetLockout(uid, callback); user.auth.resetLockout(uid, callback);
}); });

@ -0,0 +1,10 @@
<p>[[email:greeting_with_name, {username}]],</p>
<p>[[email:reset.notify.text1, {date}]]</p>
<p>[[email:reset.notify.text2]]</p>
<p>
[[email:closing]]<br />
<strong>{site_title}</strong>
</p>

@ -0,0 +1,8 @@
[[email:greeting_with_name, {username}]],
[[email:reset.notify.text1, {date}]]
[[email:reset.notify.text2]]
[[email:closing]]
{site_title}
Loading…
Cancel
Save