Also allow email to be used for login next to username

Fixes #192
This commit is contained in:
Johannes Zellner
2015-02-18 21:15:08 +01:00
parent 091c341c2b
commit df9e143369
4 changed files with 87 additions and 11 deletions
+17 -7
View File
@@ -42,13 +42,23 @@ function initialize(callback) {
});
passport.use(new LocalStrategy(function (username, password, callback) {
user.verify(username, password, function (error, result) {
if (error && error.reason === UserError.NOT_FOUND) return callback(null, false);
if (error && error.reason === UserError.WRONG_PASSWORD) return callback(null, false);
if (error) return callback(error);
if (!result) return callback(null, false);
callback(null, database.removePrivates(result));
});
if (username.indexOf('@') === -1) {
user.verify(username, password, function (error, result) {
if (error && error.reason === UserError.NOT_FOUND) return callback(null, false);
if (error && error.reason === UserError.WRONG_PASSWORD) return callback(null, false);
if (error) return callback(error);
if (!result) return callback(null, false);
callback(null, database.removePrivates(result));
});
} else {
user.verifyWithEmail(username, password, function (error, result) {
if (error && error.reason === UserError.NOT_FOUND) return callback(null, false);
if (error && error.reason === UserError.WRONG_PASSWORD) return callback(null, false);
if (error) return callback(error);
if (!result) return callback(null, false);
callback(null, database.removePrivates(result));
});
}
}));
passport.use(new BasicStrategy(function (username, password, callback) {
+1 -1
View File
@@ -10,7 +10,7 @@
<form action="/api/v1/session/login" method="post">
<input type="hidden" name="_csrf" value="<%= csrf %>"/>
<div class="form-group">
<label class="control-label" for="inputUsername">Username</label>
<label class="control-label" for="inputUsername">Username or Email</label>
<input type="text" class="form-control" id="inputUsername" name="username" autofocus required>
</div>
<div class="form-group">
+44
View File
@@ -149,6 +149,50 @@ describe('User', function () {
});
});
describe('verifyWithEmail', function () {
before(createUser);
after(cleanupUsers);
it('fails due to non existing user', function (done) {
user.verifyWithEmail(EMAIL+EMAIL, PASSWORD, function (error, result) {
expect(error).to.be.ok();
expect(result).to.not.be.ok();
expect(error.reason).to.equal(UserError.NOT_FOUND);
done();
});
});
it('fails due to empty password', function (done) {
user.verifyWithEmail(EMAIL, '', function (error, result) {
expect(error).to.be.ok();
expect(result).to.not.be.ok();
expect(error.reason).to.equal(UserError.WRONG_PASSWORD);
done();
});
});
it('fails due to wrong password', function (done) {
user.verifyWithEmail(EMAIL, PASSWORD+PASSWORD, function (error, result) {
expect(error).to.be.ok();
expect(result).to.not.be.ok();
expect(error.reason).to.equal(UserError.WRONG_PASSWORD);
done();
});
});
it('succeeds', function (done) {
user.verifyWithEmail(EMAIL, PASSWORD, function (error, result) {
expect(error).to.not.be.ok();
expect(result).to.be.ok();
done();
});
});
});
describe('retrieving', function () {
before(createUser);
after(cleanupUsers);
+25 -3
View File
@@ -7,7 +7,8 @@ exports = module.exports = {
list: listUsers,
create: createUser,
verify: verifyUser,
verify: verify,
verifyWithEmail: verifyWithEmail,
remove: removeUser,
get: getUser,
getByResetToken: getByResetToken,
@@ -152,7 +153,7 @@ function createUser(username, password, email, admin, callback) {
});
}
function verifyUser(username, password, callback) {
function verify(username, password, callback) {
assert(typeof username === 'string');
assert(typeof password === 'string');
assert(typeof callback === 'function');
@@ -173,6 +174,27 @@ function verifyUser(username, password, callback) {
});
}
function verifyWithEmail(email, password, callback) {
assert(typeof email === 'string');
assert(typeof password === 'string');
assert(typeof callback === 'function');
userdb.getByEmail(email, function (error, user) {
if (error && error.reason == DatabaseError.NOT_FOUND) return callback(new UserError(UserError.NOT_FOUND));
if (error) return callback(new UserError(UserError.INTERNAL_ERROR, error));
var saltBinary = new Buffer(user._salt, 'hex');
crypto.pbkdf2(password, saltBinary, CRYPTO_ITERATIONS, CRYPTO_KEY_LENGTH, function (error, derivedKey) {
if (error) return callback(new UserError(UserError.INTERNAL_ERROR, error));
var derivedKeyHex = new Buffer(derivedKey, 'binary').toString('hex');
if (derivedKeyHex !== user._password) return callback(new UserError(UserError.WRONG_PASSWORD));
callback(null, user);
});
});
}
function removeUser(username, callback) {
assert(typeof username === 'string');
assert(typeof callback === 'function');
@@ -302,7 +324,7 @@ function changePassword(username, oldPassword, newPassword, callback) {
var error = validatePassword(newPassword);
if (error) return callback(error);
verifyUser(username, oldPassword, function (error, user) {
verify(username, oldPassword, function (error, user) {
if (error) return callback(error);
setPassword(user.id, newPassword, callback);