fix(auth): add login lock to prevent concurrent Playwright login attempts

This commit is contained in:
JamesFlare1212
2026-04-06 18:25:52 -04:00
parent 480ba14688
commit 0b9a42c7f3
2 changed files with 29 additions and 3 deletions

View File

@@ -3,6 +3,7 @@ import axios from 'axios';
import { logger } from '../utils/logger'; import { logger } from '../utils/logger';
import { import {
loginWithPlaywright, loginWithPlaywright,
ensureSingleLogin,
loadCachedCookies, loadCachedCookies,
saveCookiesToCache, saveCookiesToCache,
clearCookieCache, clearCookieCache,
@@ -90,18 +91,18 @@ async function testCookieValidityWithApi(cookieString: string): Promise<boolean>
} }
/** /**
* Get complete cookies using Playwright * Get complete cookies using Playwright with single login lock
*/ */
async function getCompleteCookies(userName: string, userPwd: string): Promise<string> { async function getCompleteCookies(userName: string, userPwd: string): Promise<string> {
logger.info('Attempting to get complete cookie string using Playwright login...'); logger.info('Attempting to get complete cookie string using Playwright login...');
const cookies = await loginWithPlaywright(userName, userPwd); const cookies = await ensureSingleLogin(userName, userPwd);
if (!cookies || cookies.length === 0) { if (!cookies || cookies.length === 0) {
throw new Error("Login failed: Could not obtain cookies."); throw new Error("Login failed: Could not obtain cookies.");
} }
const cookieString = cookies.map(c => `${c.name}=${c.value}`).join('; '); const cookieString = cookies.map((c: any) => `${c.name}=${c.value}`).join('; ');
return cookieString; return cookieString;
} }

View File

@@ -8,10 +8,35 @@ const COOKIE_FILE_PATH = resolve(import.meta.dir, 'cookies.json');
let _inMemoryCookies: Cookie[] | null = null; let _inMemoryCookies: Cookie[] | null = null;
// Login lock to prevent concurrent login attempts
let _loginLock: Promise<Cookie[]> | null = null;
// Proxy configuration // Proxy configuration
const USE_PROXY = process.env.USE_PROXY === 'true'; const USE_PROXY = process.env.USE_PROXY === 'true';
const PROXY_SERVER = process.env.ALL_PROXY || process.env.HTTP_PROXY || `http://host.docker.internal:9091`; const PROXY_SERVER = process.env.ALL_PROXY || process.env.HTTP_PROXY || `http://host.docker.internal:9091`;
/**
* Ensure only one login process runs at a time
*/
export async function ensureSingleLogin(username: string, password: string): Promise<Cookie[]> {
// Wait for any existing login to complete
if (_loginLock) {
logger.info('Login in progress, waiting for existing login to complete...');
await _loginLock;
}
// Create new lock promise for this login attempt
_loginLock = (async () => {
try {
return await loginWithPlaywright(username, password);
} finally {
_loginLock = null;
}
})();
return await _loginLock;
}
/** /**
* Login using Playwright and extract cookies * Login using Playwright and extract cookies
*/ */