mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-02 12:05:57 +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.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);
|
||||||
});
|
});
|
||||||
|
|||||||
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