timing out reset codes, enhancing template replace so that a single placeholder can be used multiple times

v1.18.x
Julian Lam 12 years ago
parent dea9a707dc
commit 5369be0397

@ -21,7 +21,7 @@
document.getElementById('reset').onclick = function() {
if (inputEl.value.length > 0 && inputEl.value.indexOf('@') !== -1) {
socket.emit('user.send_reset', { email: inputEl.value });
socket.emit('user:reset.send', { email: inputEl.value });
} else {
jQuery('#success').hide();
jQuery(errorEl).show();

@ -5,10 +5,16 @@
<strong>Password Changed</strong>
<p></p>
</div>
<label>New Password</label><input type="password" placeholder="A new password" id="password" /><br />
<label>... and again</label><input type="password" placeholder="" id="repeat" /><br />
<input type="hidden" value="{reset_code}" />
<button class="btn btn-primary" id="reset" type="submit">Reset Password</button>
<div class="alert alert-error" id="error" style="display:none">
<strong>Incrrect Reset Code</strong>
<p>The reset code received was incorrect. Please try again, or <a href="/reset">request a new reset code</a></p>
</div>
<div id="reset-form">
<label for="password">New Password</label><input type="password" placeholder="A new password" id="password" /><br />
<label for="repeat">... and again</label><input type="password" placeholder="The same password" id="repeat" /><br />
<input type="hidden" value="{reset_code}" />
<button class="btn btn-primary" id="reset" type="submit" disabled>Reset Password</button>
</div>
</div>
<script type="text/javascript">
(function() {
@ -21,6 +27,19 @@
alert("match");
}
}, false);
// Enable the form if the code is valid
socket.emit('user:reset.valid', { code: '{reset_code}' });
socket.on('user:reset.valid', function(data) {
if (!!data.valid) resetEl.disabled = false;
else {
var formEl = document.getElementById('reset-form');
// Show error message
$('#error').show();
formEl.parentNode.removeChild(formEl);
}
})
// socket.on('user.password.reset', function(data) {
// if (data.success === 'ok') {
// ajaxify.go('/');

@ -29,7 +29,8 @@ var fs = require('fs');
var parse = function(data) {
function replace(key, value, template) {
return template.replace("{" + key + "}", value);
var searchRegex = new RegExp('{' + key + '}', 'g');
return template.replace(searchRegex, value);
}
function makeRegex(block) {

@ -109,54 +109,66 @@ var config = require('../config.js'),
RDB.get('email:' + email, callback)
};
User.send_reset = function(email) {
User.get_uid_by_email(email, function(uid) {
if (uid !== null) {
// Generate a new reset code
var reset_code = utils.generateUUID();
RDB.set('reset:' + reset_code + ':uid', uid);
// RDB.set('reset:' + reset_code + ':expiry', expiry);
var reset_link = config.url + 'reset/' + reset_code,
reset_email = global.templates['emails/reset'].parse({'RESET_LINK': reset_link}),
reset_email_plaintext = global.templates['emails/reset_plaintext'].parse({ 'RESET_LINK': reset_link });
var message = emailjs.message.create({
text: reset_email_plaintext,
from: config.mailer.from,
to: email,
subject: 'Password Reset Requested',
attachment: [
{
data: reset_email,
alternative: true
User.reset = {
validate: function(code) {
RDB.get('reset:' + code + ':uid', function(uid) {
if (uid !== null) {
RDB.get('reset:' + code + ':expiry', function(expiry) {
if (expiry >= +new Date()/1000|0) global.socket.emit('user:reset.valid', { valid: true });
else global.socket.emit('user:reset.valid', { valid: false });
});
} else global.socket.emit('user:reset.valid', { valid: false });
});
},
send: function(email) {
User.get_uid_by_email(email, function(uid) {
if (uid !== null) {
// Generate a new reset code
var reset_code = utils.generateUUID();
RDB.set('reset:' + reset_code + ':uid', uid);
RDB.set('reset:' + reset_code + ':expiry', (60*60)+new Date()/1000|0); // Active for one hour
var reset_link = config.url + 'reset/' + reset_code,
reset_email = global.templates['emails/reset'].parse({'RESET_LINK': reset_link}),
reset_email_plaintext = global.templates['emails/reset_plaintext'].parse({ 'RESET_LINK': reset_link });
var message = emailjs.message.create({
text: reset_email_plaintext,
from: config.mailer.from,
to: email,
subject: 'Password Reset Requested',
attachment: [
{
data: reset_email,
alternative: true
}
]
});
emailjsServer.send(message, function(err, success) {
if (err === null) {
global.socket.emit('user.send_reset', {
status: "ok",
message: "code-sent",
email: email
});
} else {
global.socket.emit('user.send_reset', {
status: "error",
message: "send-failed"
});
throw new Error(err);
}
]
});
emailjsServer.send(message, function(err, success) {
if (err === null) {
global.socket.emit('user.send_reset', {
status: "ok",
message: "code-sent",
email: email
});
} else {
global.socket.emit('user.send_reset', {
status: "error",
message: "send-failed"
});
throw new Error(err);
}
});
} else {
global.socket.emit('user.send_reset', {
status: "error",
message: "invalid-email",
email: email
});
}
});
});
} else {
global.socket.emit('user.send_reset', {
status: "error",
message: "invalid-email",
email: email
});
}
});
}
}
User.email = {

@ -45,8 +45,12 @@ var SocketIO = require('socket.io').listen(global.server);
modules.user.email.exists(data.email);
});
socket.on('user.send_reset', function(data) {
modules.user.send_reset(data.email);
socket.on('user:reset.send', function(data) {
modules.user.reset.send(data.email);
});
socket.on('user:reset.valid', function(data) {
modules.user.reset.validate(data.code);
});
});

Loading…
Cancel
Save