From 609ae48c7343d9c6babd1eb3245d0c354160c7d8 Mon Sep 17 00:00:00 2001 From: Faye Date: Mon, 19 Jan 2026 17:39:12 +0100 Subject: [PATCH] fix: login spam --- src/state/epics/auth.ts | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/state/epics/auth.ts b/src/state/epics/auth.ts index 2381ab7..2a630e1 100644 --- a/src/state/epics/auth.ts +++ b/src/state/epics/auth.ts @@ -1,7 +1,9 @@ import { combineEpics, ofType } from 'redux-observable' -import { concatMap } from 'rxjs/operators' +import { of } from 'rxjs' +import { concatMap, filter } from 'rxjs/operators' import { getUserInfo } from '~/apis/authsrv' import config from '~/config' +import { clearFormCache } from '~/hooks/funnels/form' import type { AppState } from '~/state' import type { AnyAppAction, GetAction } from '~/state/actions' import { @@ -9,12 +11,24 @@ import { LoadUserInfo, LookupUserInfo, } from '~/state/actions/auth' -import { catchAppError } from './operators/catch-app-error' -import { of } from 'rxjs' import { loadAutosave, removeAutosave } from '~/state/models/autosave' -import { clearFormCache } from '~/hooks/funnels/form' +import { load, save } from '~/util/local-storage' +import { catchAppError } from './operators/catch-app-error' import { justDo } from './operators/just-do' +const LAST_LOGIN_ATTEMPT_KEY = 'last-login-attempt' +const LOGIN_THROTTLE_MS = 10_000 // 10 seconds + +const shouldAllowLoginRedirect = (): boolean => { + const lastAttempt = load(LAST_LOGIN_ATTEMPT_KEY) + if (lastAttempt === null) { + return true + } + + const timeSinceLastAttempt = Date.now() - lastAttempt + return timeSinceLastAttempt >= LOGIN_THROTTLE_MS +} + export default combineEpics< GetAction, GetAction, @@ -23,8 +37,9 @@ export default combineEpics< (action$) => action$.pipe( ofType(InitiateLogin.type), + filter(() => shouldAllowLoginRedirect()), justDo(() => { - // eslint-disable-next-line no-process-env + save(LAST_LOGIN_ATTEMPT_KEY, Date.now()) location.href = `${config.apis.authsrv.url}/auth?app_name=${config.apis.authsrv.appName}${process.env.NODE_ENV === 'development' ? '' : `&dropoff_url=${location.href}`}` }) ),