From cb27c0fc8bef5324b57eb8599cfd3ae5f7819f9d Mon Sep 17 00:00:00 2001 From: Adam Mcgrath Date: Fri, 19 May 2023 11:53:05 +0100 Subject: [PATCH 1/3] Fix void response types --- playground/handlers.ts | 116 ++++++++++++++---- playground/index.ts | 7 ++ .../managers/attack-protection-manager.ts | 34 ++--- .../managers/client-grants-manager.ts | 4 +- .../managers/resource-servers-manager.ts | 8 +- .../__generated/managers/users-manager.ts | 8 +- 6 files changed, 132 insertions(+), 45 deletions(-) diff --git a/playground/handlers.ts b/playground/handlers.ts index a2eb9b2db..29148c471 100644 --- a/playground/handlers.ts +++ b/playground/handlers.ts @@ -65,6 +65,89 @@ export async function actions() { console.log('Removed the action: ' + updatedAction.name); } +export async function attackProtection() { + const mgmntClient = new ManagementClient(program.opts()); + + const { data: breachedPasswordDetectionSettings } = + await mgmntClient.attackProtection.getBreachedPasswordDetectionConfig(); + console.log( + 'Got Breached password detection settings, enabled', + breachedPasswordDetectionSettings.enabled + ); + + const { data: updatedBreachedPasswordDetectionSettings } = + await mgmntClient.attackProtection.updateBreachedPasswordDetectionConfig({ + enabled: !breachedPasswordDetectionSettings.enabled, + }); + console.log( + 'Updated Breached password detection settings, enabled, from', + breachedPasswordDetectionSettings.enabled, + 'to', + updatedBreachedPasswordDetectionSettings.enabled + ); + + const { data: revertedBreachedPasswordDetectionSettings } = + await mgmntClient.attackProtection.updateBreachedPasswordDetectionConfig({ + enabled: !updatedBreachedPasswordDetectionSettings.enabled, + }); + console.log( + 'Reverted Breached password detection settings, enabled, from', + updatedBreachedPasswordDetectionSettings.enabled, + 'to', + revertedBreachedPasswordDetectionSettings.enabled + ); + + const { data: bruteForceConfig } = await mgmntClient.attackProtection.getBruteForceConfig(); + console.log('Got Suspicious IP throttling config, enabled', bruteForceConfig.enabled); + + const { data: updatedBruteForceConfig } = + await mgmntClient.attackProtection.updateBruteForceConfig({ + enabled: !bruteForceConfig.enabled, + }); + console.log( + 'Updated Breached password detection settings, enabled, from', + bruteForceConfig.enabled, + 'to', + updatedBruteForceConfig.enabled + ); + + const { data: revertedBruteForceConfig } = + await mgmntClient.attackProtection.updateBruteForceConfig({ + enabled: !updatedBruteForceConfig.enabled, + }); + console.log( + 'Reverted Breached password detection settings, enabled, from', + updatedBruteForceConfig.enabled, + 'to', + revertedBruteForceConfig.enabled + ); + + const { data: suspiciousIpThrottlingConfig } = + await mgmntClient.attackProtection.getSuspiciousIpThrottlingConfig(); + console.log('Got Suspicious IP throttling config, enabled', suspiciousIpThrottlingConfig.enabled); + + const { data: updatedSuspiciousIpThrottlingConfig } = + await mgmntClient.attackProtection.updateSuspiciousIpThrottlingConfig({ + enabled: !suspiciousIpThrottlingConfig.enabled, + }); + console.log( + 'Updated Breached password detection settings, enabled, from', + suspiciousIpThrottlingConfig.enabled, + 'to', + updatedSuspiciousIpThrottlingConfig.enabled + ); + + const { data: revertedSuspiciousIpThrottlingConfig } = + await mgmntClient.attackProtection.updateSuspiciousIpThrottlingConfig({ + enabled: !updatedSuspiciousIpThrottlingConfig.enabled, + }); + console.log( + 'Reverted Breached password detection settings, enabled, from', + updatedSuspiciousIpThrottlingConfig.enabled, + 'to', + revertedSuspiciousIpThrottlingConfig.enabled + ); +} export async function anomaly() { const mgmntClient = new ManagementClient(program.opts()); try { @@ -207,21 +290,21 @@ export async function clientGrants() { (api) => api.identifier === 'ClientGrantTests' ); - await mgmntClient.clientGrants.create({ + const { data: clientGrant } = await mgmntClient.clientGrants.create({ client_id: program.opts().clientId, audience: api?.identifier as string, scope: ['openid'], }); + console.log(`Created client grant ${clientGrant.id}`); - const { data: newClientGrant } = await mgmntClient.clientGrants.getAll({ - audience: api?.identifier as string, + const { data: clientGrants } = await mgmntClient.clientGrants.getAll({ client_id: program.opts().clientId, }); - console.log(`Created client grant ${newClientGrant[0].id}`); + console.log(`Got client grants ${clientGrants.map((clientGrant) => clientGrant.id)}`); const { data: updatedClientGrant } = await mgmntClient.clientGrants.update( - { id: newClientGrant[0].id as string }, + { id: clientGrant.id as string }, { scope: ['openid', 'profile'] } ); @@ -230,8 +313,8 @@ export async function clientGrants() { // Delete API for testing await mgmntClient.resourceServers.delete({ id: api?.id as string }); - await mgmntClient.clientGrants.delete({ id: newClientGrant[0].id as string }); - console.log('Removed the client grant: ' + newClientGrant[0].id); + await mgmntClient.clientGrants.delete({ id: clientGrant.id as string }); + console.log('Removed the client grant: ' + clientGrant.id); } export async function clients() { @@ -636,7 +719,7 @@ export async function jobs() { const usersFilePath = path.join(__dirname, '../test/data/users.json'); const { data: createImportJob } = await mgmntClient.jobs.importUsers({ - users: fs.createReadStream(usersFilePath), + users: fs.createReadStream(usersFilePath) as any, connection_id: connection.id as string, }); @@ -957,13 +1040,10 @@ export async function resourceServers() { const mgmntClient = new ManagementClient(program.opts()); const apiId = `api_${uuid()}`; - await mgmntClient.resourceServers.create({ + const { data: createdApi } = await mgmntClient.resourceServers.create({ identifier: apiId, scopes: [{ value: 'foo' }], }); - const createdApi = (await mgmntClient.resourceServers.getAll()).data.find( - (api) => api.identifier === apiId - ) as ResourceServer; console.log('Created api:', createdApi.id); try { @@ -978,15 +1058,12 @@ export async function resourceServers() { gotApis.map((api) => api.id) ); - await mgmntClient.resourceServers.update( + const { data: gotUpdatedApi } = await mgmntClient.resourceServers.update( { id: createdApi.id as string, }, { token_lifetime: (createdApi.token_lifetime as number) + 1 } ); - const { data: gotUpdatedApi } = await mgmntClient.resourceServers.get({ - id: createdApi.id as string, - }); console.log( 'Updated API token_lifetime from:', createdApi.token_lifetime, @@ -1340,7 +1417,7 @@ export async function users() { ); console.log('Updated name on auth method:', createdAuthMethod.name, 'to', 'bar'); - await mgmntClient.users.updateAuthenticationMethods( + const { data: updatedAuthMethods } = await mgmntClient.users.updateAuthenticationMethods( { id: updatedUser.user_id as string, }, @@ -1354,12 +1431,9 @@ export async function users() { } as PutAuthenticationMethodsRequestInner; }) ); - const { data: updatedAuthMethods } = await mgmntClient.users.getAuthenticationMethods({ - id: updatedUser.user_id as string, - }); console.log( 'Updated all auth methods to names:', - updatedAuthMethods.map((x) => x.name) + updatedAuthMethods.map((x: any) => x.name) ); await mgmntClient.users.deleteAuthenticationMethod({ diff --git a/playground/index.ts b/playground/index.ts index 39ee9dfd0..b25625e2d 100644 --- a/playground/index.ts +++ b/playground/index.ts @@ -7,6 +7,7 @@ dotenv.config({ import { program } from 'commander'; import { actions, + attackProtection, anomaly, blacklists, branding, @@ -51,6 +52,7 @@ program .description('Test all endpoints') .action(async () => { await actions(); + await attackProtection(); await anomaly(); await blacklists(); await branding(); @@ -81,6 +83,11 @@ program program.command('actions').description('Test CRUD on the actions endpoints').action(actions); +program + .command('attack-protection') + .description('Test CRUD on the attack protection endpoints') + .action(attackProtection); + program.command('anomaly').description('Test the anomaly endpoints').action(anomaly); program.command('blacklists').description('Test the blacklists endpoints').action(blacklists); diff --git a/src/management/__generated/managers/attack-protection-manager.ts b/src/management/__generated/managers/attack-protection-manager.ts index cbd7fdf50..f8389047b 100644 --- a/src/management/__generated/managers/attack-protection-manager.ts +++ b/src/management/__generated/managers/attack-protection-manager.ts @@ -19,7 +19,7 @@ export class AttackProtectionManager extends BaseAPI { */ async getBreachedPasswordDetectionConfig( initOverrides?: InitOverride - ): Promise> { + ): Promise> { const response = await this.request( { path: `/attack-protection/breached-password-detection`, @@ -28,7 +28,7 @@ export class AttackProtectionManager extends BaseAPI { initOverrides ); - return runtime.VoidApiResponse.fromResponse(response); + return runtime.JSONApiResponse.fromResponse(response); } /** @@ -36,7 +36,9 @@ export class AttackProtectionManager extends BaseAPI { * * @throws {RequiredError} */ - async getBruteForceConfig(initOverrides?: InitOverride): Promise> { + async getBruteForceConfig( + initOverrides?: InitOverride + ): Promise> { const response = await this.request( { path: `/attack-protection/brute-force-protection`, @@ -45,7 +47,7 @@ export class AttackProtectionManager extends BaseAPI { initOverrides ); - return runtime.VoidApiResponse.fromResponse(response); + return runtime.JSONApiResponse.fromResponse(response); } /** @@ -53,7 +55,9 @@ export class AttackProtectionManager extends BaseAPI { * * @throws {RequiredError} */ - async getBruteForceDefaults(initOverrides?: InitOverride): Promise> { + async getBruteForceDefaults( + initOverrides?: InitOverride + ): Promise> { const response = await this.request( { path: `/attack-protection/brute-force-protection/defaults`, @@ -62,7 +66,7 @@ export class AttackProtectionManager extends BaseAPI { initOverrides ); - return runtime.VoidApiResponse.fromResponse(response); + return runtime.JSONApiResponse.fromResponse(response); } /** @@ -70,7 +74,9 @@ export class AttackProtectionManager extends BaseAPI { * * @throws {RequiredError} */ - async getSuspiciousIpThrottlingConfig(initOverrides?: InitOverride): Promise> { + async getSuspiciousIpThrottlingConfig( + initOverrides?: InitOverride + ): Promise> { const response = await this.request( { path: `/attack-protection/suspicious-ip-throttling`, @@ -79,7 +85,7 @@ export class AttackProtectionManager extends BaseAPI { initOverrides ); - return runtime.VoidApiResponse.fromResponse(response); + return runtime.JSONApiResponse.fromResponse(response); } /** @@ -90,7 +96,7 @@ export class AttackProtectionManager extends BaseAPI { async updateBreachedPasswordDetectionConfig( bodyParameters: PatchBreachedPasswordDetectionRequest, initOverrides?: InitOverride - ): Promise> { + ): Promise> { const headerParameters: runtime.HTTPHeaders = {}; headerParameters['Content-Type'] = 'application/json'; @@ -105,7 +111,7 @@ export class AttackProtectionManager extends BaseAPI { initOverrides ); - return runtime.VoidApiResponse.fromResponse(response); + return runtime.JSONApiResponse.fromResponse(response); } /** @@ -116,7 +122,7 @@ export class AttackProtectionManager extends BaseAPI { async updateBruteForceConfig( bodyParameters: PatchBruteForceProtectionRequest, initOverrides?: InitOverride - ): Promise> { + ): Promise> { const headerParameters: runtime.HTTPHeaders = {}; headerParameters['Content-Type'] = 'application/json'; @@ -131,7 +137,7 @@ export class AttackProtectionManager extends BaseAPI { initOverrides ); - return runtime.VoidApiResponse.fromResponse(response); + return runtime.JSONApiResponse.fromResponse(response); } /** @@ -142,7 +148,7 @@ export class AttackProtectionManager extends BaseAPI { async updateSuspiciousIpThrottlingConfig( bodyParameters: PatchSuspiciousIpThrottlingRequest, initOverrides?: InitOverride - ): Promise> { + ): Promise> { const headerParameters: runtime.HTTPHeaders = {}; headerParameters['Content-Type'] = 'application/json'; @@ -157,6 +163,6 @@ export class AttackProtectionManager extends BaseAPI { initOverrides ); - return runtime.VoidApiResponse.fromResponse(response); + return runtime.JSONApiResponse.fromResponse(response); } } diff --git a/src/management/__generated/managers/client-grants-manager.ts b/src/management/__generated/managers/client-grants-manager.ts index 5c3c5c5cb..1217f9202 100644 --- a/src/management/__generated/managers/client-grants-manager.ts +++ b/src/management/__generated/managers/client-grants-manager.ts @@ -139,7 +139,7 @@ export class ClientGrantsManager extends BaseAPI { async create( bodyParameters: ClientGrantCreate, initOverrides?: InitOverride - ): Promise> { + ): Promise> { const headerParameters: runtime.HTTPHeaders = {}; headerParameters['Content-Type'] = 'application/json'; @@ -154,6 +154,6 @@ export class ClientGrantsManager extends BaseAPI { initOverrides ); - return runtime.VoidApiResponse.fromResponse(response); + return runtime.JSONApiResponse.fromResponse(response); } } diff --git a/src/management/__generated/managers/resource-servers-manager.ts b/src/management/__generated/managers/resource-servers-manager.ts index 1870ac9e7..3369cbc94 100644 --- a/src/management/__generated/managers/resource-servers-manager.ts +++ b/src/management/__generated/managers/resource-servers-manager.ts @@ -137,7 +137,7 @@ export class ResourceServersManager extends BaseAPI { requestParameters: PatchResourceServersByIdRequest, bodyParameters: ResourceServerUpdate, initOverrides?: InitOverride - ): Promise> { + ): Promise> { runtime.validateRequiredRequestParams(requestParameters, ['id']); const headerParameters: runtime.HTTPHeaders = {}; @@ -157,7 +157,7 @@ export class ResourceServersManager extends BaseAPI { initOverrides ); - return runtime.VoidApiResponse.fromResponse(response); + return runtime.JSONApiResponse.fromResponse(response); } /** @@ -169,7 +169,7 @@ export class ResourceServersManager extends BaseAPI { async create( bodyParameters: PostResourceServersRequest, initOverrides?: InitOverride - ): Promise> { + ): Promise> { const headerParameters: runtime.HTTPHeaders = {}; headerParameters['Content-Type'] = 'application/json'; @@ -184,6 +184,6 @@ export class ResourceServersManager extends BaseAPI { initOverrides ); - return runtime.VoidApiResponse.fromResponse(response); + return runtime.JSONApiResponse.fromResponse(response); } } diff --git a/src/management/__generated/managers/users-manager.ts b/src/management/__generated/managers/users-manager.ts index f7255b7b5..69d32fa1d 100644 --- a/src/management/__generated/managers/users-manager.ts +++ b/src/management/__generated/managers/users-manager.ts @@ -692,7 +692,7 @@ export class UsersManager extends BaseAPI { requestParameters: PatchAuthenticationMethodsByAuthenticationMethodIdOperationRequest, bodyParameters: PatchAuthenticationMethodsByAuthenticationMethodIdRequest, initOverrides?: InitOverride - ): Promise> { + ): Promise> { runtime.validateRequiredRequestParams(requestParameters, ['id', 'authentication_method_id']); const headerParameters: runtime.HTTPHeaders = {}; @@ -714,7 +714,7 @@ export class UsersManager extends BaseAPI { initOverrides ); - return runtime.VoidApiResponse.fromResponse(response); + return runtime.JSONApiResponse.fromResponse(response); } /** @@ -1061,7 +1061,7 @@ export class UsersManager extends BaseAPI { requestParameters: PutAuthenticationMethodsRequest, bodyParameters: Array, initOverrides?: InitOverride - ): Promise> { + ): Promise>> { runtime.validateRequiredRequestParams(requestParameters, ['id']); const headerParameters: runtime.HTTPHeaders = {}; @@ -1081,6 +1081,6 @@ export class UsersManager extends BaseAPI { initOverrides ); - return runtime.VoidApiResponse.fromResponse(response); + return runtime.JSONApiResponse.fromResponse(response); } } From f9c46f6aff322f8c3135eb70f6c0af124aaa2c7e Mon Sep 17 00:00:00 2001 From: Adam Mcgrath Date: Fri, 19 May 2023 12:03:27 +0100 Subject: [PATCH 2/3] Fix tests --- test/management/attack-protection.tests.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/management/attack-protection.tests.ts b/test/management/attack-protection.tests.ts index a9db91291..e7962ad8d 100644 --- a/test/management/attack-protection.tests.ts +++ b/test/management/attack-protection.tests.ts @@ -115,7 +115,7 @@ describe('AttackProtectionManager', () => { const request = nock(API_URL) .get(bruteForcePath) .matchHeader('Authorization', `Bearer ${token}`) - .reply(200); + .reply(200, {}); attackProtection.getBruteForceConfig().then(() => { expect(request.isDone()).to.be.true; @@ -175,7 +175,7 @@ describe('AttackProtectionManager', () => { const request = nock(API_URL) .patch(bruteForcePath) .matchHeader('Authorization', `Bearer ${token}`) - .reply(200); + .reply(200, {}); attackProtection.updateBruteForceConfig(data).then(() => { expect(request.isDone()).to.be.true; @@ -245,7 +245,7 @@ describe('AttackProtectionManager', () => { const request = nock(API_URL) .get(suspiciousIpPath) .matchHeader('Authorization', `Bearer ${token}`) - .reply(200); + .reply(200, {}); attackProtection.getSuspiciousIpThrottlingConfig().then(() => { expect(request.isDone()).to.be.true; @@ -307,7 +307,7 @@ describe('AttackProtectionManager', () => { const request = nock(API_URL) .patch(suspiciousIpPath) .matchHeader('Authorization', `Bearer ${token}`) - .reply(200); + .reply(200, {}); attackProtection.updateSuspiciousIpThrottlingConfig(data).then(() => { expect(request.isDone()).to.be.true; @@ -369,7 +369,7 @@ describe('AttackProtectionManager', () => { const request = nock(API_URL) .get(breachedPasswordDetectionPath) .matchHeader('Authorization', `Bearer ${token}`) - .reply(200); + .reply(200, {}); attackProtection.getBreachedPasswordDetectionConfig().then(() => { expect(request.isDone()).to.be.true; @@ -431,7 +431,7 @@ describe('AttackProtectionManager', () => { const request = nock(API_URL) .patch(breachedPasswordDetectionPath) .matchHeader('Authorization', `Bearer ${token}`) - .reply(200); + .reply(200, {}); attackProtection.updateBreachedPasswordDetectionConfig({}, data).then(() => { expect(request.isDone()).to.be.true; From f62f448b584a74c2beaac62e96d9b4d8d8a7ab7c Mon Sep 17 00:00:00 2001 From: Adam Mcgrath Date: Fri, 19 May 2023 12:20:43 +0100 Subject: [PATCH 3/3] Add missing tests and update TODOs --- test/management/attack-protection.tests.ts | 66 ++++++++++++++++++---- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/test/management/attack-protection.tests.ts b/test/management/attack-protection.tests.ts index e7962ad8d..74615217a 100644 --- a/test/management/attack-protection.tests.ts +++ b/test/management/attack-protection.tests.ts @@ -125,6 +125,57 @@ describe('AttackProtectionManager', () => { }); }); + describe('#getBruteForceDefaults', () => { + let request: Scope; + + beforeEach(function () { + request = nock(API_URL).get(`${bruteForcePath}/defaults`).reply(200, data); + }); + + it('should pass any errors to the promise catch handler', function (done) { + nock.cleanAll(); + + nock(API_URL).get(bruteForcePath).reply(500); + + attackProtection.getBruteForceDefaults().catch((err) => { + expect(err).to.exist; + + done(); + }); + }); + + it('should pass the body of the response to the "then" handler', function (done) { + attackProtection.getBruteForceDefaults().then((bruteForceConfig) => { + expect(bruteForceConfig.data).to.deep.equal(data); + + done(); + }); + }); + + it(`should perform a GET request to /api/v2${bruteForcePath}`, function (done) { + attackProtection.getBruteForceDefaults().then(() => { + expect(request.isDone()).to.be.true; + + done(); + }); + }); + + it('should include the token in the Authorization header', function (done) { + nock.cleanAll(); + + const request = nock(API_URL) + .get(bruteForcePath) + .matchHeader('Authorization', `Bearer ${token}`) + .reply(200, {}); + + attackProtection.getBruteForceConfig().then(() => { + expect(request.isDone()).to.be.true; + + done(); + }); + }); + }); + describe('#updateBruteForceConfig', () => { let request: Scope; @@ -162,8 +213,7 @@ describe('AttackProtectionManager', () => { it('should pass the body of the response to the "then" handler', function (done) { attackProtection.updateBruteForceConfig(data).then((bruteForceConfig) => { - // TODO: body should contain data - // expect(bruteForceConfig).to.deep.equal(data); + expect(bruteForceConfig.data).to.deep.equal(data); done(); }); @@ -224,8 +274,7 @@ describe('AttackProtectionManager', () => { it('should pass the body of the response to the "then" handler', function (done) { attackProtection.getSuspiciousIpThrottlingConfig().then((suspiciousIpThrottlingConfig) => { - // TODO: body should contain data - // expect(suspiciousIpThrottlingConfig).to.deep.equal(data); + expect(suspiciousIpThrottlingConfig.data).to.deep.equal(data); done(); }); @@ -294,8 +343,7 @@ describe('AttackProtectionManager', () => { attackProtection .updateSuspiciousIpThrottlingConfig(data) .then((suspiciousIpThrottlingConfig) => { - // TODO: body should contain data - // expect(suspiciousIpThrottlingConfig).to.deep.equal(data); + expect(suspiciousIpThrottlingConfig.data).to.deep.equal(data); done(); }); @@ -348,8 +396,7 @@ describe('AttackProtectionManager', () => { attackProtection .getBreachedPasswordDetectionConfig() .then((breachedPasswordDetectionConfig) => { - // TODO: body should contain data - // expect(breachedPasswordDetectionConfig).to.deep.equal(data); + expect(breachedPasswordDetectionConfig.data).to.deep.equal(data); done(); }); @@ -418,8 +465,7 @@ describe('AttackProtectionManager', () => { attackProtection .updateBreachedPasswordDetectionConfig({}, data) .then((breachedPasswordDetectionConfig) => { - // TODO: body should contain data - // expect(breachedPasswordDetectionConfig).to.deep.equal(data); + expect(breachedPasswordDetectionConfig.data).to.deep.equal(data); done(); });