From 120a5f0a556857fa0755343e55d795c67e5e17ff Mon Sep 17 00:00:00 2001 From: udaycodespace Date: Wed, 27 May 2026 11:14:45 +0530 Subject: [PATCH 1/2] fix(auth): add timeout handling for oauth fetch requests --- .../src/controllers/auth.controller.js | 43 +++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/apps/dashboard-api/src/controllers/auth.controller.js b/apps/dashboard-api/src/controllers/auth.controller.js index 798114692..834314ad1 100644 --- a/apps/dashboard-api/src/controllers/auth.controller.js +++ b/apps/dashboard-api/src/controllers/auth.controller.js @@ -14,6 +14,7 @@ const { resetPasswordSchema, verifyOtpSchema } = require("@urbackend/common"); +const AppError = require("@urbackend/common/src/utils/AppError"); const { emitEvent } = require('../utils/emitEvent'); const ACCESS_TOKEN_EXPIRES_IN = '15m'; @@ -87,20 +88,38 @@ const clearGithubStateCookie = (res) => { }); }; +const OAUTH_FETCH_TIMEOUT_MS = 10000; + const fetchJson = async (url, options, defaultMessage) => { - const response = await fetch(url, options); - const payload = await response.json().catch(() => null); - - if (!response.ok) { - const message = - payload?.error_description || - payload?.error || - payload?.message || - defaultMessage; - throw new Error(message); - } + // Prevent OAuth requests from hanging forever + const controller = new AbortController(); + const timeout = setTimeout(() => controller.abort(), OAUTH_FETCH_TIMEOUT_MS); - return payload; + try { + const response = await fetch(url, { + ...(options || {}), + signal: controller.signal, + }); + const payload = await response.json().catch(() => null); + + if (!response.ok) { + const message = + payload?.error_description || + payload?.error || + payload?.message || + defaultMessage; + throw new AppError(message, response.status || 502); + } + + return payload; + } catch (err) { + if (err.name === 'AbortError') { + throw new AppError('OAuth request timed out.', 504); + } + throw err; + } finally { + clearTimeout(timeout); + } }; const exchangeGithubCodeForToken = async ({ code, req }) => { From e5bf0a26a5a72b732195f18bbfbc22708db7e38c Mon Sep 17 00:00:00 2001 From: udaycodespace Date: Wed, 27 May 2026 23:20:17 +0530 Subject: [PATCH 2/2] fix(auth): align AppError import with repo conventions --- apps/dashboard-api/src/controllers/auth.controller.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/dashboard-api/src/controllers/auth.controller.js b/apps/dashboard-api/src/controllers/auth.controller.js index 834314ad1..0bb10fedb 100644 --- a/apps/dashboard-api/src/controllers/auth.controller.js +++ b/apps/dashboard-api/src/controllers/auth.controller.js @@ -12,9 +12,9 @@ const { deleteAccountSchema, onlyEmailSchema, resetPasswordSchema, - verifyOtpSchema + verifyOtpSchema, + AppError } = require("@urbackend/common"); -const AppError = require("@urbackend/common/src/utils/AppError"); const { emitEvent } = require('../utils/emitEvent'); const ACCESS_TOKEN_EXPIRES_IN = '15m';