From f80b17baff65bb0eb85247890ef5e993c712a103 Mon Sep 17 00:00:00 2001 From: Antonella Sgarlatta Date: Fri, 5 Jun 2026 12:57:45 -0300 Subject: [PATCH] chore: add clear login attempts admin endpoint --- packages/auth/src/Bootstrap/Container.ts | 1 + .../AnnotatedAdminController.ts | 18 +++++++++- .../Base/BaseAdminController.ts | 33 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/packages/auth/src/Bootstrap/Container.ts b/packages/auth/src/Bootstrap/Container.ts index 254325b48..738222724 100644 --- a/packages/auth/src/Bootstrap/Container.ts +++ b/packages/auth/src/Bootstrap/Container.ts @@ -1964,6 +1964,7 @@ export class ContainerConfigLoader { container.get(TYPES.Auth_UserRepository), container.get(TYPES.Auth_CreateSubscriptionToken), container.get(TYPES.Auth_CreateOfflineSubscriptionToken), + container.get(TYPES.Auth_ClearLoginAttempts), container.get(TYPES.Auth_ControllerContainer), ), ) diff --git a/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedAdminController.ts b/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedAdminController.ts index 7e4bf6591..d1faf7f9d 100644 --- a/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedAdminController.ts +++ b/packages/auth/src/Infra/InversifyExpressUtils/AnnotatedAdminController.ts @@ -12,6 +12,7 @@ import TYPES from '../../Bootstrap/Types' import { BaseAdminController } from './Base/BaseAdminController' import { CreateOfflineSubscriptionToken } from '../../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken' import { CreateSubscriptionToken } from '../../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken' +import { ClearLoginAttempts } from '../../Domain/UseCase/ClearLoginAttempts' import { DeleteSetting } from '../../Domain/UseCase/DeleteSetting/DeleteSetting' import { GetSetting } from './../../Domain/UseCase/GetSetting/GetSetting' import { UserRepositoryInterface } from '../../Domain/User/UserRepositoryInterface' @@ -25,8 +26,16 @@ export class AnnotatedAdminController extends BaseAdminController { @inject(TYPES.Auth_CreateSubscriptionToken) override createSubscriptionToken: CreateSubscriptionToken, @inject(TYPES.Auth_CreateOfflineSubscriptionToken) override createOfflineSubscriptionToken: CreateOfflineSubscriptionToken, + @inject(TYPES.Auth_ClearLoginAttempts) override clearLoginAttempts: ClearLoginAttempts, ) { - super(doDeleteSetting, doGetSetting, userRepository, createSubscriptionToken, createOfflineSubscriptionToken) + super( + doDeleteSetting, + doGetSetting, + userRepository, + createSubscriptionToken, + createOfflineSubscriptionToken, + clearLoginAttempts, + ) } @httpGet('/user/:email') @@ -60,4 +69,11 @@ export class AnnotatedAdminController extends BaseAdminController { ): Promise { return super.disableEmailBackups(request) } + + @httpDelete('/users/:email/login-attempts') + override async deleteLoginAttempts( + request: Request, + ): Promise { + return super.deleteLoginAttempts(request) + } } diff --git a/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseAdminController.ts b/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseAdminController.ts index ee9340789..54837ef1f 100644 --- a/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseAdminController.ts +++ b/packages/auth/src/Infra/InversifyExpressUtils/Base/BaseAdminController.ts @@ -4,6 +4,7 @@ import { Request } from 'express' import { CreateOfflineSubscriptionToken } from '../../../Domain/UseCase/CreateOfflineSubscriptionToken/CreateOfflineSubscriptionToken' import { CreateSubscriptionToken } from '../../../Domain/UseCase/CreateSubscriptionToken/CreateSubscriptionToken' +import { ClearLoginAttempts } from '../../../Domain/UseCase/ClearLoginAttempts' import { GetSetting } from './../../../Domain/UseCase/GetSetting/GetSetting' import { DeleteSetting } from '../../../Domain/UseCase/DeleteSetting/DeleteSetting' import { UserRepositoryInterface } from '../../../Domain/User/UserRepositoryInterface' @@ -16,6 +17,7 @@ export class BaseAdminController extends BaseHttpController { protected userRepository: UserRepositoryInterface, protected createSubscriptionToken: CreateSubscriptionToken, protected createOfflineSubscriptionToken: CreateOfflineSubscriptionToken, + protected clearLoginAttempts: ClearLoginAttempts, private controllerContainer?: ControllerContainerInterface, ) { super() @@ -26,6 +28,7 @@ export class BaseAdminController extends BaseHttpController { this.controllerContainer.register('admin.createToken', this.createToken.bind(this)) this.controllerContainer.register('admin.createOfflineToken', this.createOfflineToken.bind(this)) this.controllerContainer.register('admin.disableEmailBackups', this.disableEmailBackups.bind(this)) + this.controllerContainer.register('admin.deleteLoginAttempts', this.deleteLoginAttempts.bind(this)) } } @@ -145,4 +148,34 @@ export class BaseAdminController extends BaseHttpController { return this.badRequest('No email backups found') } + + async deleteLoginAttempts(request: Request): Promise { + const { email } = request.params + + if (!email) { + return this.json( + { + error: { + message: 'Missing email parameter.', + }, + }, + 400, + ) + } + + const result = await this.clearLoginAttempts.execute({ email }) + + if (result.isFailed()) { + return this.json( + { + error: { + message: result.getError(), + }, + }, + 400, + ) + } + + return this.ok() + } }