Registration process consumes the token so that it can only be used once

pull/7/head
Clement Michaud 2017-01-22 18:06:12 +01:00
parent d3db94105e
commit 804039b6aa
4 changed files with 36 additions and 9 deletions

View File

@ -26,8 +26,8 @@ function register_handler_get(req, res) {
var user_data_store = req.app.get('user data store');
logger.debug('U2F register_handler: verify token validity');
user_data_store.verify_u2f_registration_token(registration_token)
logger.debug('U2F register_handler: verify token validity and consume it');
user_data_store.consume_u2f_registration_token(registration_token)
.then(function() {
res.render('u2f_register');
})

View File

@ -51,9 +51,10 @@ UserDataStore.prototype.save_u2f_registration_token = function(userid, token, ma
return this._u2f_registration_tokens_collection.insertAsync(newDocument);
}
UserDataStore.prototype.verify_u2f_registration_token = function(token) {
UserDataStore.prototype.consume_u2f_registration_token = function(token) {
var query = {};
query.token = token;
var that = this;
return this._u2f_registration_tokens_collection.findOneAsync(query)
.then(function(doc) {
@ -68,5 +69,8 @@ UserDataStore.prototype.verify_u2f_registration_token = function(token) {
}
return Promise.resolve();
})
.then(function() {
return that._u2f_registration_tokens_collection.removeAsync(query);
});
}

View File

@ -29,7 +29,7 @@ describe('test register handle', function() {
user_data_store.set_u2f_meta = sinon.stub().returns(Promise.resolve({}));
user_data_store.get_u2f_meta = sinon.stub().returns(Promise.resolve({}));
user_data_store.save_u2f_registration_token = sinon.stub().returns(Promise.resolve({}));
user_data_store.verify_u2f_registration_token = sinon.stub().returns(Promise.resolve({}));
user_data_store.consume_u2f_registration_token = sinon.stub().returns(Promise.resolve({}));
req.app.get.withArgs('user data store').returns(user_data_store);
res = {};
@ -107,7 +107,7 @@ describe('test register handle', function() {
req.params = {};
req.params.registration_token = 'token';
user_data_store.verify_u2f_registration_token = sinon.stub().returns(Promise.reject('Not valid anymore'));
user_data_store.consume_u2f_registration_token = sinon.stub().returns(Promise.reject('Not valid anymore'));
u2f_register.register_handler_get(req, res);
});

View File

@ -99,7 +99,7 @@ function test_u2f_registration_token() {
});
});
it('should save u2f registration token and verify it', function(done) {
it('should save u2f registration token and consume it', function(done) {
var options = {};
options.inMemoryOnly = true;
@ -111,7 +111,7 @@ function test_u2f_registration_token() {
data_store.save_u2f_registration_token(userid, token, max_age)
.then(function(document) {
return data_store.verify_u2f_registration_token(token);
return data_store.consume_u2f_registration_token(token);
})
.then(function() {
done();
@ -121,6 +121,29 @@ function test_u2f_registration_token() {
});
});
it('should not be able to consume registration token twice', function(done) {
var options = {};
options.inMemoryOnly = true;
var data_store = new UserDataStore(DataStore, options);
var userid = 'user';
var token = 'token';
var max_age = 50;
data_store.save_u2f_registration_token(userid, token, max_age)
.then(function(document) {
return data_store.consume_u2f_registration_token(token);
})
.then(function(document) {
return data_store.consume_u2f_registration_token(token);
})
.catch(function(err) {
console.error(err);
done();
});
});
it('should fail when token does not exist', function() {
var options = {};
options.inMemoryOnly = true;
@ -129,7 +152,7 @@ function test_u2f_registration_token() {
var token = 'token';
return data_store.verify_u2f_registration_token(token)
return data_store.consume_u2f_registration_token(token)
.then(function(document) {
return Promise.reject();
})
@ -152,7 +175,7 @@ function test_u2f_registration_token() {
data_store.save_u2f_registration_token(userid, token, max_age)
.then(function() {
MockDate.set('1/2/2000');
return data_store.verify_u2f_registration_token(token);
return data_store.consume_u2f_registration_token(token);
})
.catch(function(err) {
MockDate.reset();