mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 19:46:01 +01:00
closed #2708
This commit is contained in:
@@ -13,6 +13,10 @@
|
||||
"reset.text2": "To continue with the password reset, please click on the following link:",
|
||||
"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.latest_topics": "Latest topics from %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_address": "Enter Email Address",
|
||||
"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() {
|
||||
if (password.val().length < 6) {
|
||||
$('#error').addClass('hide').hide();
|
||||
noticeEl.find('strong').html('Invalid Password');
|
||||
noticeEl.find('p').html('The password entered is too short, please pick a different password.');
|
||||
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'});
|
||||
app.alertError('[[reset_password:password_too_short]]');
|
||||
} else if (password.val() !== repeat.val()) {
|
||||
app.alertError('[[reset_password:passwords_do_not_match]]');
|
||||
} else {
|
||||
resetEl.prop('disabled', true).html('<i class="fa fa-spin fa-refresh"></i> Changing Password');
|
||||
socket.emit('user.reset.commit', {
|
||||
code: reset_code,
|
||||
password: password.val()
|
||||
}, function(err) {
|
||||
if(err) {
|
||||
if (err) {
|
||||
ajaxify.refresh();
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
$('#error').addClass('hide').hide();
|
||||
$('#notice').addClass('hide').hide();
|
||||
$('#success').removeClass('hide').addClass('show').show();
|
||||
|
||||
window.location.href = RELATIVE_PATH + '/login';
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
socket.emit('user.reset.valid', reset_code, function(err, valid) {
|
||||
if(err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
// socket.emit('user.reset.valid', reset_code, function(err, valid) {
|
||||
// if(err) {
|
||||
// return app.alertError(err.message);
|
||||
// }
|
||||
|
||||
if (valid) {
|
||||
resetEl.prop('disabled', false);
|
||||
} else {
|
||||
var formEl = $('#reset-form');
|
||||
// Show error message
|
||||
$('#error').show();
|
||||
formEl.remove();
|
||||
}
|
||||
});
|
||||
// if (valid) {
|
||||
// resetEl.prop('disabled', false);
|
||||
// } else {
|
||||
// var formEl = $('#reset-form');
|
||||
// // Show error message
|
||||
// $('#error').show();
|
||||
// formEl.remove();
|
||||
// }
|
||||
// });
|
||||
};
|
||||
|
||||
return ResetCode;
|
||||
|
||||
@@ -106,10 +106,13 @@ Controllers.home = function(req, res, next) {
|
||||
|
||||
Controllers.reset = function(req, res, next) {
|
||||
if (req.params.code) {
|
||||
user.reset.validate(req.params.code, function(err, valid) {
|
||||
res.render('reset_code', {
|
||||
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 {
|
||||
res.render('reset', {
|
||||
reset_code: req.params.code ? req.params.code : null,
|
||||
|
||||
@@ -13,6 +13,8 @@ var async = require('async'),
|
||||
websockets = require('./index'),
|
||||
meta = require('../meta'),
|
||||
events = require('../events'),
|
||||
emailer = require('../emailer'),
|
||||
db = require('../database'),
|
||||
SocketUser = {};
|
||||
|
||||
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) {
|
||||
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) {
|
||||
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({
|
||||
type: 'password-reset',
|
||||
uid: socket.uid,
|
||||
ip: socket.ip
|
||||
});
|
||||
callback();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ var db = require('./database'),
|
||||
schemaDate, thisSchemaDate,
|
||||
|
||||
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema
|
||||
latestSchema = Date.UTC(2015, 0, 30);
|
||||
latestSchema = Date.UTC(2015, 1, 8);
|
||||
|
||||
Upgrade.check = function(callback) {
|
||||
db.get('schemaDate', function(err, value) {
|
||||
@@ -807,6 +807,26 @@ Upgrade.upgrade = function(callback) {
|
||||
winston.info('[2015/01/30] Adding group member counts skipped');
|
||||
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
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var async = require('async'),
|
||||
@@ -21,19 +20,13 @@ var async = require('async'),
|
||||
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) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
if (parseInt(expiry, 10) >= Date.now() / 1000) {
|
||||
callback(null, true);
|
||||
} else {
|
||||
// Expired, delete from db
|
||||
db.deleteObjectField('reset:uid', code);
|
||||
db.deleteObjectField('reset:expiry', code);
|
||||
callback(null, false);
|
||||
}
|
||||
callback(null, parseInt(issueDate, 10) > (Date.now() - (1000*60*120)));
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -46,7 +39,7 @@ var async = require('async'),
|
||||
|
||||
var reset_code = utils.generateUUID();
|
||||
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;
|
||||
|
||||
@@ -85,7 +78,7 @@ var async = require('async'),
|
||||
user.setUserField(uid, 'password', hash);
|
||||
|
||||
db.deleteObjectField('reset:uid', code);
|
||||
db.deleteObjectField('reset:expiry', code);
|
||||
db.sortedSetRemove('reset:issueDate', code);
|
||||
|
||||
user.auth.resetLockout(uid, callback);
|
||||
});
|
||||
|
||||
10
src/views/emails/reset_notify.tpl
Normal file
10
src/views/emails/reset_notify.tpl
Normal file
@@ -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>
|
||||
8
src/views/emails/reset_notify_plaintext.tpl
Normal file
8
src/views/emails/reset_notify_plaintext.tpl
Normal file
@@ -0,0 +1,8 @@
|
||||
[[email:greeting_with_name, {username}]],
|
||||
|
||||
[[email:reset.notify.text1, {date}]]
|
||||
|
||||
[[email:reset.notify.text2]]
|
||||
|
||||
[[email:closing]]
|
||||
{site_title}
|
||||
Reference in New Issue
Block a user