From 0bf367ffec2899434547a4cada1bd2a92baa78aa Mon Sep 17 00:00:00 2001 From: barsa Date: Tue, 3 Mar 2026 14:13:24 +0900 Subject: [PATCH] refactor: update rate limiting configuration and enhance account event handling - Increased default login rate limit from 5 to 20 and adjusted TTL from 15 to 5 minutes for improved security. - Updated login captcha threshold from 3 to 5 attempts to enhance user experience. - Modified AccountEventsListener to invalidate additional queries for account updates and support case changes, improving responsiveness to real-time events. --- .../infra/rate-limiting/auth-rate-limit.service.ts | 6 +++--- .../realtime/components/AccountEventsListener.tsx | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/apps/bff/src/modules/auth/infra/rate-limiting/auth-rate-limit.service.ts b/apps/bff/src/modules/auth/infra/rate-limiting/auth-rate-limit.service.ts index 049e64e7..492fdca8 100644 --- a/apps/bff/src/modules/auth/infra/rate-limiting/auth-rate-limit.service.ts +++ b/apps/bff/src/modules/auth/infra/rate-limiting/auth-rate-limit.service.ts @@ -44,8 +44,8 @@ export class AuthRateLimitService { private readonly configService: ConfigService, @Inject(Logger) private readonly logger: Logger ) { - const loginLimit = this.configService.get("LOGIN_RATE_LIMIT_LIMIT", 5); - const loginTtlMs = this.configService.get("LOGIN_RATE_LIMIT_TTL", 900000); + const loginLimit = this.configService.get("LOGIN_RATE_LIMIT_LIMIT", 20); + const loginTtlMs = this.configService.get("LOGIN_RATE_LIMIT_TTL", 300000); const signupLimit = this.configService.get("SIGNUP_RATE_LIMIT_LIMIT", 5); const signupTtlMs = this.configService.get("SIGNUP_RATE_LIMIT_TTL", 900000); @@ -59,7 +59,7 @@ export class AuthRateLimitService { const refreshLimit = this.configService.get("AUTH_REFRESH_RATE_LIMIT_LIMIT", 10); const refreshTtlMs = this.configService.get("AUTH_REFRESH_RATE_LIMIT_TTL", 300000); - this.loginCaptchaThreshold = this.configService.get("LOGIN_CAPTCHA_AFTER_ATTEMPTS", 3); + this.loginCaptchaThreshold = this.configService.get("LOGIN_CAPTCHA_AFTER_ATTEMPTS", 5); this.captchaAlwaysOn = this.configService.get("AUTH_CAPTCHA_ALWAYS_ON", "false") === "true"; this.loginLimiter = this.createLimiter("auth-login", loginLimit, loginTtlMs); diff --git a/apps/portal/src/features/realtime/components/AccountEventsListener.tsx b/apps/portal/src/features/realtime/components/AccountEventsListener.tsx index 2accf5df..2a104f72 100644 --- a/apps/portal/src/features/realtime/components/AccountEventsListener.tsx +++ b/apps/portal/src/features/realtime/components/AccountEventsListener.tsx @@ -42,9 +42,13 @@ export function AccountEventsListener() { const parsed = JSON.parse(event.data) as RealtimeEventEnvelope; if (!parsed || typeof parsed !== "object") return; - if (parsed.event === "services.eligibility.changed") { - logger.info("Received services.eligibility.changed; invalidating services queries"); + if (parsed.event === "account.updated") { + logger.info("Received account.updated; invalidating services + verification queries"); void queryClient.invalidateQueries({ queryKey: queryKeys.services.all() }); + void queryClient.invalidateQueries({ + queryKey: queryKeys.verification.residenceCard(), + }); + void queryClient.invalidateQueries({ queryKey: queryKeys.me.status() }); return; } @@ -54,6 +58,12 @@ export function AccountEventsListener() { return; } + if (parsed.event === "support.case.changed") { + logger.info("Received support.case.changed; invalidating support queries"); + void queryClient.invalidateQueries({ queryKey: queryKeys.support.cases() }); + return; + } + if (parsed.event === "orders.changed") { logger.info("Received orders.changed; invalidating orders + dashboard queries"); void queryClient.invalidateQueries({ queryKey: queryKeys.orders.list() });