diff --git a/src/dao/mongo.js b/src/dao/mongo.js index 2463a22..2bea667 100644 --- a/src/dao/mongo.js +++ b/src/dao/mongo.js @@ -26,9 +26,9 @@ class Mongo { /** * Create an instance of the MongoDB client. - * @param {String} options.uri The mongodb uri - * @param {String} options.user The databse user - * @param {String} options.password The database user's password + * @param {String} uri The mongodb uri + * @param {String} user The databse user + * @param {String} password The database user's password */ constructor(options) { this._uri = 'mongodb://' + options.user + ':' + options.password + '@' + options.uri; diff --git a/src/service/public-key.js b/src/service/public-key.js index 616e476..8488308 100644 --- a/src/service/public-key.js +++ b/src/service/public-key.js @@ -109,9 +109,9 @@ class PublicKey { /** * Fetch a verified public key from the database. Either the key id or the * email address muss be provided. - * @param {String} options.keyid (optional) The public key id - * @param {String} options.email (optional) The user's email address - * @yield {Object} The public key document + * @param {String} keyid (optional) The public key id + * @param {String} email (optional) The user's email address + * @yield {Object} The public key document */ *get(options) { let keyid = options.keyid, email = options.email; @@ -135,7 +135,7 @@ class PublicKey { /** * Delete a public key document and its corresponding user id documents. - * @param {String} options.keyid The key id + * @param {String} keyid The key id * @yield {undefined} */ *remove(options) { diff --git a/src/service/user-id.js b/src/service/user-id.js index 0e8a6be..4f37460 100644 --- a/src/service/user-id.js +++ b/src/service/user-id.js @@ -47,11 +47,11 @@ class UserId { } /** - * Store a list of user ids. There can only be one verified user ID for - * an email address at any given time. - * @param {String} options.keyid The public key id - * @param {Array} options.userIds The userIds to persist - * @yield {Array} A list of user ids with generated nonces + * Generate nonces for verification and store a list of user ids. There + * can only be one verified user ID for an email address at any given time. + * @param {String} keyid The public key id + * @param {Array} userIds The userIds to persist + * @yield {Array} A list of user ids with generated nonces */ *batch(options) { let userIds = options.userIds, keyid = options.keyid; @@ -73,7 +73,7 @@ class UserId { * @yield {undefined} */ *verify(options) { - let uid = this._mongo.get(options, DB_TYPE); + let uid = yield this._mongo.get(options, DB_TYPE); if (!uid) { util.throw(404, 'User id not found'); } @@ -84,25 +84,21 @@ class UserId { * Get a verified user IDs either by key id or email address. * There can only be one verified user ID for an email address * at any given time. - * @param {String} options.keyid The public key id - * @param {String} options.userIds A list of user ids to check - * @yield {Object} The verified user ID document + * @param {String} keyid The public key id + * @param {String} userIds A list of user ids to check + * @yield {Object} The verified user ID document */ *getVerfied(options) { let keyid = options.keyid, userIds = options.userIds; if (keyid) { - // try by key id - let uids = yield this._mongo.list({ keyid }, DB_TYPE); - let verified = uids.find(u => u.verified); + let verified = yield this._mongo.get({ keyid, verified:true }, DB_TYPE); if (verified) { return verified; } } if (userIds) { - // try by email addresses for (let uid of userIds) { - let uids = yield this._mongo.list({ email:uid.email }, DB_TYPE); - let verified = uids.find(u => u.verified); + let verified = yield this._mongo.get({ email:uid.email, verified:true }, DB_TYPE); if (verified) { return verified; } @@ -112,7 +108,7 @@ class UserId { /** * Remove all user ids matching a certain query - * @param {String} options.keyid The public key id + * @param {String} keyid The public key id * @yield {undefined} */ *remove(options) { diff --git a/test/integration/user-id-test.js b/test/integration/user-id-test.js new file mode 100644 index 0000000..d634a4e --- /dev/null +++ b/test/integration/user-id-test.js @@ -0,0 +1,113 @@ +'use strict'; + +require('co-mocha')(require('mocha')); // monkey patch mocha for generators + +const log = require('npmlog'); +const UserId = require('../../src/service/user-id'); +const Mongo = require('../../src/dao/mongo'); +const expect = require('chai').expect; + +describe('User ID Integration Tests', function() { + this.timeout(20000); + + const DB_TYPE = 'userid'; + let mongo, userId, uid1, uid2; + + before(function *() { + let credentials; + try { + credentials = require('../../credentials.json'); + } catch(e) { + log.info('mongo-test', 'No credentials.json found ... using environment vars.'); + } + mongo = new Mongo({ + uri: process.env.MONGO_URI || credentials.mongo.uri, + user: process.env.MONGO_USER || credentials.mongo.user, + password: process.env.MONGO_PASS || credentials.mongo.pass + }); + yield mongo.connect(); + userId = new UserId(mongo); + }); + + beforeEach(function *() { + uid1 = { + name: 'name1', + email: 'email1' + }; + uid2 = { + name: 'name2', + email: 'email2' + }; + yield mongo.clear(DB_TYPE); + }); + + afterEach(function() {}); + + after(function *() { + yield mongo.clear(DB_TYPE); + yield mongo.disconnect(); + }); + + describe("batch", function() { + it('should persist all the things', function *() { + let uids = yield userId.batch({ userIds:[uid1, uid2], keyid:'0123456789ABCDEF' }); + expect(uids[0].keyid).to.equal('0123456789ABCDEF'); + expect(uids[1].keyid).to.equal('0123456789ABCDEF'); + expect(uids[0].nonce).to.exist; + expect(uids[1].nonce).to.exist; + expect(uids[0]._id).to.exist; + expect(uids[1]._id).to.exist; + let gotten = yield mongo.list({ keyid:'0123456789ABCDEF' }, DB_TYPE); + expect(gotten).to.deep.equal(uids); + }); + }); + + describe("verify", function() { + it('should update the document', function *() { + let uids = yield userId.batch({ userIds:[uid1], keyid:'0123456789ABCDEF' }); + yield userId.verify({ keyid:'0123456789ABCDEF', nonce:uids[0].nonce }); + let gotten = yield mongo.get({ _id:uid1._id }, DB_TYPE); + expect(gotten.verified).to.be.true; + expect(gotten.nonce).to.be.null; + }); + + it('should not find the document', function *() { + yield userId.batch({ userIds:[uid1], keyid:'0123456789ABCDEF' }); + try { + yield userId.verify({ keyid:'0123456789ABCDEF', nonce:'fake_nonce' }); + } catch(e) { + expect(e.status).to.equal(404); + } + let gotten = yield mongo.get({ _id:uid1._id }, DB_TYPE); + expect(gotten.verified).to.be.undefined; + expect(gotten.nonce).to.exist; + }); + }); + + describe("getVerfied", function() { + beforeEach(function *() { + let uids = yield userId.batch({ userIds:[uid1], keyid:'0123456789ABCDEF' }); + yield userId.verify({ keyid:'0123456789ABCDEF', nonce:uids[0].nonce }); + }); + + it('should find verified by key id', function *() { + let gotten = yield userId.getVerfied({ keyid:uid1.keyid }); + expect(gotten).to.exist; + }); + + it('should find verified by email address', function *() { + let gotten = yield userId.getVerfied({ userIds:[uid2,uid1] }); + expect(gotten).to.exist; + }); + }); + + describe("remove", function() { + it('should delete all documents', function *() { + yield userId.batch({ userIds:[uid1, uid2], keyid:'0123456789ABCDEF' }); + yield userId.remove({ keyid:uid1.keyid }); + let gotten = yield mongo.get({ keyid:'0123456789ABCDEF' }, DB_TYPE); + expect(gotten).to.not.exist; + }); + }); + +}); \ No newline at end of file