fix: #8991, logout on password reset, dont verify email if password expired

dont allow same password on reset
v1.18.x
Barış Soner Uşaklı 4 years ago
parent 8adbf54ae6
commit 5080f35752

@ -46,6 +46,7 @@
"username-too-long": "Username too long",
"password-too-long": "Password too long",
"reset-rate-limited": "Too many password reset requests (rate limited)",
"reset-same-password": "Please use a password that is different from your current one",
"user-banned": "User banned",
"user-banned-reason": "Sorry, this account has been banned (Reason: %1)",

@ -180,8 +180,9 @@ app.cacheBuster = null;
message = message.message || message;
if (message === '[[error:invalid-session]]') {
app.handleInvalidSession();
app.logout(false);
return app.handleInvalidSession();
return;
}
app.alert({

@ -69,6 +69,9 @@ socket = window.socket;
});
socket.on('event:banned', onEventBanned);
socket.on('event:logout', function () {
app.logout();
});
socket.on('event:alert', function (params) {
app.alert(params);
});

@ -120,6 +120,7 @@ User.forcePasswordReset = async function (socket, uids) {
await db.setObjectField(uids.map(uid => 'user:' + uid), 'passwordExpiry', Date.now());
await user.auth.revokeAllSessions(uids);
uids.forEach(uid => sockets.in('uid_' + uid).emit('event:logout'));
};
User.deleteUsers = async function (socket, uids) {

@ -11,6 +11,7 @@ const batch = require('../batch');
const db = require('../database');
const meta = require('../meta');
const emailer = require('../emailer');
const Password = require('../password');
const UserReset = module.exports;
@ -67,12 +68,28 @@ UserReset.commit = async function (code, password) {
if (!uid) {
throw new Error('[[error:reset-code-not-valid]]');
}
const userData = await db.getObjectFields(
'user:' + uid,
['password', 'passwordExpiry', 'password:shaWrapped']
);
const ok = await Password.compare(password, userData.password, !!parseInt(userData['password:shaWrapped'], 10));
if (ok) {
throw new Error('[[error:reset-same-password]]');
}
const hash = await user.hashPassword(password);
await user.setUserFields(uid, { password: hash, 'email:confirmed': 1, 'password:shaWrapped': 1 });
await groups.join('verified-users', uid);
await groups.leave('unverified-users', uid);
const data = {
password: hash,
'password:shaWrapped': 1,
};
// don't verify email if password reset is due to expiry
const isPasswordExpired = userData.passwordExpiry && userData.passwordExpiry < Date.now();
if (!isPasswordExpired) {
data['email:confirmed'] = 1;
await groups.join('verified-users', uid);
await groups.leave('unverified-users', uid);
}
await user.setUserFields(uid, data);
await db.deleteObjectField('reset:uid', code);
await db.sortedSetRemoveBulk([
['reset:issueDate', code],

@ -628,6 +628,35 @@ describe('User', function () {
},
], done);
});
it('.should error if same password is used for reset', async function () {
const uid = await User.create({ username: 'badmemory', email: 'bad@memory.com', password: '123456' });
const code = await User.reset.generate(uid);
let err;
try {
await User.reset.commit(code, '123456');
} catch (_err) {
err = _err;
}
assert.strictEqual(err.message, '[[error:reset-same-password]]');
});
it('should not validate email if password reset is due to expiry', async function () {
const uid = await User.create({ username: 'resetexpiry', email: 'reset@expiry.com', password: '123456' });
let confirmed = await User.getUserField(uid, 'email:confirmed');
let [verified, unverified] = await groups.isMemberOfGroups(uid, ['verified-users', 'unverified-users']);
assert.strictEqual(confirmed, 0);
assert.strictEqual(verified, false);
assert.strictEqual(unverified, true);
await User.setUserField(uid, 'passwordExpiry', Date.now());
const code = await User.reset.generate(uid);
await User.reset.commit(code, '654321');
confirmed = await User.getUserField(uid, 'email:confirmed');
[verified, unverified] = await groups.isMemberOfGroups(uid, ['verified-users', 'unverified-users']);
assert.strictEqual(confirmed, 0);
assert.strictEqual(verified, false);
assert.strictEqual(unverified, true);
});
});
describe('hash methods', function () {

Loading…
Cancel
Save