diff --git a/src/service/user-id.js b/src/service/user-id.js index 4f37460..98b4c4a 100644 --- a/src/service/user-id.js +++ b/src/service/user-id.js @@ -55,10 +55,10 @@ class UserId { */ *batch(options) { let userIds = options.userIds, keyid = options.keyid; - userIds.forEach(u => { - u.keyid = keyid; // set keyid on docs - u.nonce = uuid.v4(); // generate nonce for verification - }); + for (let uid of userIds) { + uid.keyid = keyid; // set keyid on docs + uid.nonce = uuid.v4(); // generate nonce for verification + } let r = yield this._mongo.batch(userIds, DB_TYPE); if (r.insertedCount !== userIds.length) { util.throw(500, 'Failed to persist user ids'); @@ -73,7 +73,8 @@ class UserId { * @yield {undefined} */ *verify(options) { - let uid = yield this._mongo.get(options, DB_TYPE); + let keyid = options.keyid, nonce = options.nonce; + let uid = yield this._mongo.get({ keyid, nonce }, DB_TYPE); if (!uid) { util.throw(404, 'User id not found'); } @@ -107,12 +108,30 @@ class UserId { } /** - * Remove all user ids matching a certain query + * Flag all user IDs of a key for removal by generating a new nonce and + * saving it. + * @param {String} keyid The public key id + * @yield {Array} A list of user ids with nonces + */ + *flagForRemove(options) { + let keyid = options.keyid; + let uids = yield this._mongo.list({ keyid }, DB_TYPE); + for (let uid of uids) { + let nonce = uuid.v4(); + yield this._mongo.update(uid, { nonce }, DB_TYPE); + uid.nonce = nonce; + } + return uids; + } + + /** + * Remove all user ids for a public key. * @param {String} keyid The public key id * @yield {undefined} */ *remove(options) { - yield this._mongo.remove({ keyid:options.keyid }, DB_TYPE); + let keyid = options.keyid; + yield this._mongo.remove({ keyid }, DB_TYPE); } } diff --git a/test/integration/user-id-test.js b/test/integration/user-id-test.js index d634a4e..77f643e 100644 --- a/test/integration/user-id-test.js +++ b/test/integration/user-id-test.js @@ -11,6 +11,7 @@ describe('User ID Integration Tests', function() { this.timeout(20000); const DB_TYPE = 'userid'; + const keyid = '0123456789ABCDEF'; let mongo, userId, uid1, uid2; before(function *() { @@ -50,31 +51,31 @@ describe('User ID Integration Tests', function() { 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'); + let uids = yield userId.batch({ userIds:[uid1, uid2], keyid }); + expect(uids[0].keyid).to.equal(keyid); + expect(uids[1].keyid).to.equal(keyid); 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); + let gotten = yield mongo.list({ keyid }, 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 uids = yield userId.batch({ userIds:[uid1], keyid }); + yield userId.verify({ keyid, 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' }); + yield userId.batch({ userIds:[uid1], keyid }); try { - yield userId.verify({ keyid:'0123456789ABCDEF', nonce:'fake_nonce' }); + yield userId.verify({ keyid, nonce:'fake_nonce' }); } catch(e) { expect(e.status).to.equal(404); } @@ -86,12 +87,12 @@ describe('User ID Integration Tests', function() { describe("getVerfied", function() { beforeEach(function *() { - let uids = yield userId.batch({ userIds:[uid1], keyid:'0123456789ABCDEF' }); - yield userId.verify({ keyid:'0123456789ABCDEF', nonce:uids[0].nonce }); + let uids = yield userId.batch({ userIds:[uid1], keyid }); + yield userId.verify({ keyid, nonce:uids[0].nonce }); }); it('should find verified by key id', function *() { - let gotten = yield userId.getVerfied({ keyid:uid1.keyid }); + let gotten = yield userId.getVerfied({ keyid }); expect(gotten).to.exist; }); @@ -101,11 +102,22 @@ describe('User ID Integration Tests', function() { }); }); + describe("flagForRemove", function() { + it('should flag all documents', function *() { + let stored = yield userId.batch({ userIds:[uid1, uid2], keyid }); + let flagged = yield userId.flagForRemove({ keyid }); + expect(flagged[0]._id.toHexString()).to.equal(stored[0]._id.toHexString()); + expect(flagged[0].nonce).to.not.equal(stored[0].nonce); + let gotten = yield mongo.list({ keyid }, DB_TYPE); + expect(gotten).to.deep.equal(flagged); + }); + }); + 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); + yield userId.batch({ userIds:[uid1, uid2], keyid }); + yield userId.remove({ keyid }); + let gotten = yield mongo.get({ keyid }, DB_TYPE); expect(gotten).to.not.exist; }); });