From 338f9b75adaddcde24c8abce26e22826116a4228 Mon Sep 17 00:00:00 2001 From: Rayane <77965000+rayane-d@users.noreply.github.com> Date: Wed, 13 May 2026 21:00:10 +0100 Subject: [PATCH 1/4] Add NEEDS_2FA_SETUP constants for jsonCode, error type, error title Introduce named constants for the two server-side 2FA-setup signals so the reauth middleware can detect them --- src/CONST/index.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/CONST/index.ts b/src/CONST/index.ts index d41a326a1db3..0cae7aeb0684 100644 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -2192,6 +2192,7 @@ const CONST = { BAD_REQUEST: 400, INVALID_SEARCH_QUERY: 401, NOT_AUTHENTICATED: 407, + NEEDS_2FA_SETUP: 432, EXP_ERROR: 666, UNABLE_TO_RETRY: 'unableToRetry', UPDATE_REQUIRED: 426, @@ -2236,10 +2237,12 @@ const CONST = { }, ERROR_TYPE: { SOCKET: 'Expensify\\Auth\\Error\\Socket', + NEEDS_2FA_SETUP: 'Expensify\\Error\\Policy\\PolicyRequires2FA', }, ERROR_TITLE: { SOCKET: 'Issue connecting to database', DUPLICATE_RECORD: '400 Unique Constraints Violation', + NEEDS_2FA_SETUP: 'Two-Factor Authentication required', }, NETWORK: { METHOD: { From 62142be16b08bbfc62cd05571a4937aaa65a8053 Mon Sep 17 00:00:00 2001 From: Rayane <77965000+rayane-d@users.noreply.github.com> Date: Wed, 13 May 2026 21:01:57 +0100 Subject: [PATCH 2/4] Recognize 432 and PolicyRequires2FA in the reauth middleware Extend the Reauthentication middleware to recognize both server-side 2FA-setup signals - the "432 Need to set up 2FA" jsonCode and the `PolicyRequires2FA` exception (matched by type or title). Both signals route through the same reauth path the middleware already runs on 407: call Authenticate, which mints a fresh TYPE_TWO_FACTOR_SETUP token and stamps `needsTwoFactorAuthSetup` on the response. NewDot then receives an Onyx merge to update this flag, and the existing RequireTwoFactorAuthenticationOverlay renders. --- src/libs/Middleware/Reauthentication.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libs/Middleware/Reauthentication.ts b/src/libs/Middleware/Reauthentication.ts index 1796d06d74e3..5fd15f918105 100644 --- a/src/libs/Middleware/Reauthentication.ts +++ b/src/libs/Middleware/Reauthentication.ts @@ -61,7 +61,13 @@ const Reauthentication: Middleware = (response, request, isFromSequentialQueue) return; } - if (data.jsonCode === CONST.JSON_CODE.NOT_AUTHENTICATED) { + // Two server-side signals indicate the user must set up 2FA: + // 1. Server throws PolicyRequires2FA error, with 666 jsonCode with the specefic error title or error type. + // 2. Server rejects a stale normal type token whose account now requires 2FA with jsonCode 432. + const is2FASetupRequired = + (data.jsonCode === CONST.JSON_CODE.EXP_ERROR && (data.type === CONST.ERROR_TYPE.NEEDS_2FA_SETUP || data.title === CONST.ERROR_TITLE.NEEDS_2FA_SETUP)) || + data.jsonCode === CONST.JSON_CODE.NEEDS_2FA_SETUP; + if (data.jsonCode === CONST.JSON_CODE.NOT_AUTHENTICATED || is2FASetupRequired) { if (getIsOffline()) { // If we are offline and somehow handling this response we do not want to reauthenticate throw new Error('Unable to reauthenticate because we are offline'); From c4809cdf7f5f3b76b1e3a8cc02f9f4746ef1b820 Mon Sep 17 00:00:00 2001 From: Rayane <77965000+rayane-d@users.noreply.github.com> Date: Wed, 13 May 2026 21:05:06 +0100 Subject: [PATCH 3/4] Add logic to prevent infinite loops when replaying requests after successful re-authentication if 2FA setup is required. --- src/libs/Middleware/Reauthentication.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/libs/Middleware/Reauthentication.ts b/src/libs/Middleware/Reauthentication.ts index 5fd15f918105..798e2134f484 100644 --- a/src/libs/Middleware/Reauthentication.ts +++ b/src/libs/Middleware/Reauthentication.ts @@ -106,6 +106,17 @@ const Reauthentication: Middleware = (response, request, isFromSequentialQueue) return; } + // Replaying the original request after successful re-authentication might hit the same server-side 2FA check and loop indefinitely. So we skip it. + if (is2FASetupRequired) { + if (isFromSequentialQueue) { + return data; + } + if (request.resolve) { + request.resolve(data); + } + return data; + } + if (isFromSequentialQueue || apiRequestType === CONST.API_REQUEST_TYPE.MAKE_REQUEST_WITH_SIDE_EFFECTS) { return processWithMiddleware(request, isFromSequentialQueue); } From a80661d86e6e48cf8cf9e318289395b5ea587610 Mon Sep 17 00:00:00 2001 From: Rayane <77965000+rayane-d@users.noreply.github.com> Date: Wed, 13 May 2026 21:06:02 +0100 Subject: [PATCH 4/4] add comment --- src/libs/Middleware/Reauthentication.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/Middleware/Reauthentication.ts b/src/libs/Middleware/Reauthentication.ts index 798e2134f484..fd15fdd3a34b 100644 --- a/src/libs/Middleware/Reauthentication.ts +++ b/src/libs/Middleware/Reauthentication.ts @@ -107,6 +107,7 @@ const Reauthentication: Middleware = (response, request, isFromSequentialQueue) } // Replaying the original request after successful re-authentication might hit the same server-side 2FA check and loop indefinitely. So we skip it. + // The re-reauth itself refreshes `account.needsTwoFactorAuthSetup` in Onyx via updates sent by server, which is enough to show the 2FA enforcement overlay. if (is2FASetupRequired) { if (isFromSequentialQueue) { return data;