From 8a63cf96deb670e56898ebfd2a039952b5b8b060 Mon Sep 17 00:00:00 2001 From: Adam Mcgrath Date: Thu, 9 Feb 2023 07:22:38 -0400 Subject: [PATCH] Add DELETE /api/v2/users/{id}/authenticators (#785) --- src/management/UsersManager.js | 25 +++++++++++++ test/management/users.tests.js | 65 ++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/src/management/UsersManager.js b/src/management/UsersManager.js index 0d7e22383..ee247787a 100644 --- a/src/management/UsersManager.js +++ b/src/management/UsersManager.js @@ -85,6 +85,13 @@ class UsersManager extends BaseManager { */ this.permissions = this._getRestClient('/users/:id/permissions'); + /** + * For CRUD on user's authenticators + * + * @type {external:RestClient} + */ + this.authenticators = this._getRestClient('/users/:id/authenticators'); + this.organizations = this._getRestClient('/users/:id/organizations'); } @@ -742,6 +749,24 @@ class UsersManager extends BaseManager { return this.permissions.delete(query, data); } + deleteAllAuthenticators(params, cb) { + const query = params || {}; + + // Require a user ID. + if (!query.id) { + throw new ArgumentError('The user_id cannot be null or undefined'); + } + if (typeof query.id !== 'string') { + throw new ArgumentError('The user_id has to be a string'); + } + + if (cb && cb instanceof Function) { + return this.authenticators.delete(query, cb); + } + + return this.authenticators.delete(query); + } + /** * Get a list of organizations for a user. * diff --git a/test/management/users.tests.js b/test/management/users.tests.js index 9c0ab1dea..55a3664a2 100644 --- a/test/management/users.tests.js +++ b/test/management/users.tests.js @@ -1489,6 +1489,71 @@ describe('UsersManager', () => { }); }); + describe('#deleteAllAuthenticators', () => { + let params; + let scope; + + beforeEach(() => { + params = { + id: 'user_id', + }; + + scope = nock(API_URL).delete(`/users/${params.id}/authenticators`).reply(200); + }); + + it('should validate empty user_id', () => { + expect(() => { + usersManager.deleteAllAuthenticators({ id: null }, () => {}); + }).to.throw('The user_id cannot be null or undefined'); + }); + + it('should validate non-string user_id', () => { + expect(() => { + usersManager.deleteAllAuthenticators({ id: 123 }, () => {}); + }).to.throw('The user_id has to be a string'); + }); + + it('should accept a callback', (done) => { + usersManager.deleteAllAuthenticators(params, (err) => { + expect(err).to.be.null; + done(); + }); + }); + + it('should return a promise if no callback is given', () => { + expect(usersManager.deleteAllAuthenticators(params, {})).instanceOf(Promise); + }); + + it('should pass any errors to the promise catch handler', async () => { + nock.cleanAll(); + + nock(API_URL).post(`/users/${params.id}/authenticators`).reply(500); + + try { + await usersManager.deleteAllAuthenticators(params, {}); + } catch (err) { + expect(err).to.exist; + } + }); + + it('should perform a DELETE request to /api/v2/users/user_id/authenticators', async () => { + await usersManager.deleteAllAuthenticators(params, {}); + expect(scope.isDone()).to.be.true; + }); + + it('should include the token in the Authorization header', async () => { + nock.cleanAll(); + + const request = nock(API_URL) + .delete(`/users/${params.id}/authenticators`) + .matchHeader('Authorization', `Bearer ${token}`) + .reply(200); + + await usersManager.deleteAllAuthenticators(params, {}); + expect(request.isDone()).to.be.true; + }); + }); + describe('#getUserOrganizations', () => { const data = { id: 'user_id',