diff --git a/src/modules/parcel-sync/services/epay-client.ts b/src/modules/parcel-sync/services/epay-client.ts index 3402ac1..94003f2 100644 --- a/src/modules/parcel-sync/services/epay-client.ts +++ b/src/modules/parcel-sync/services/epay-client.ts @@ -132,43 +132,41 @@ export class EpayClient { const body = `IDToken1=${encodeURIComponent(this.username)}&IDToken2=${encodeURIComponent(this.password)}`; - // Step 1: POST login — don't follow redirects so we capture cookies + // POST login — follow all redirects, let cookie jar capture everything const response = await this.client.post(loginUrlFull, body, { headers: { "Content-Type": "application/x-www-form-urlencoded", Referer: loginUrlFull, }, timeout: DEFAULT_TIMEOUT_MS, - maxRedirects: 0, - validateStatus: () => true, // accept 302 + maxRedirects: 10, + validateStatus: () => true, }); + const finalUrl = + response.request?.res?.responseUrl ?? + response.request?.responseURL ?? + response.config?.url ?? + ""; + const html = typeof response.data === "string" ? response.data : ""; + console.log( - `[epay] Login response: status=${response.status}, ` + - `location=${response.headers?.location ?? "none"}`, + `[epay] Login: status=${response.status}, finalUrl=${finalUrl.slice(0, 100)}`, ); - // Check for auth failure — OpenAM returns 200 with login form on failure - const html = typeof response.data === "string" ? response.data : ""; + // Auth failure: OpenAM returns login form again if ( - response.status === 200 && - (html.includes("Authentication Failed") || - html.includes("Autentificare esuata") || - (html.includes("IDToken1") && html.includes("IDToken2"))) + html.includes("Authentication Failed") || + html.includes("Autentificare esuata") || + (finalUrl.includes("/openam/UI/Login") && + html.includes("IDToken1") && + html.includes("IDToken2")) ) { throw new Error("ePay login failed (invalid credentials)"); } - // Step 2: Follow redirect to ePay to establish JSESSIONID - const location = response.headers?.location; - if (location) { - await this.client.get(location, { - timeout: DEFAULT_TIMEOUT_MS, - maxRedirects: 5, - validateStatus: () => true, - }); - } else if (response.status === 200) { - // No redirect but 200 — try navigating to ePay directly + // After redirect chain, navigate to ePay explicitly to ensure JSESSIONID + if (!finalUrl.includes("epay.ancpi.ro")) { await this.client.get(`${BASE_URL}/LogIn.action`, { timeout: DEFAULT_TIMEOUT_MS, maxRedirects: 5, @@ -176,24 +174,54 @@ export class EpayClient { }); } - // Verify we have session cookies on any relevant domain - const epayDomain = "https://epay.ancpi.ro"; - const oasslDomain = "https://oassl.ancpi.ro"; - const allCookies = [ - ...(await this.jar.getCookies(epayDomain)), - ...(await this.jar.getCookies(oasslDomain)), - ...(await this.jar.getCookies(BASE_URL)), + // Log all cookies for debugging + const domains = [ + "https://epay.ancpi.ro", + "https://oassl.ancpi.ro", + "http://epay.ancpi.ro", + BASE_URL, ]; + const allCookies: Array<{ domain: string; key: string; value: string }> = []; + for (const domain of domains) { + try { + const cookies = await this.jar.getCookies(domain); + for (const c of cookies) { + allCookies.push({ + domain, + key: c.key, + value: c.value.slice(0, 15) + "...", + }); + } + } catch { + // domain not applicable + } + } - const hasSession = - allCookies.some((c) => c.key === "iPlanetDirectoryPro") || - allCookies.some((c) => c.key === "JSESSIONID"); + console.log( + `[epay] Cookies after login (${allCookies.length}):`, + JSON.stringify(allCookies), + ); + + const hasSession = allCookies.some( + (c) => c.key === "iPlanetDirectoryPro" || c.key === "JSESSIONID", + ); if (!hasSession) { - console.error( - "[epay] No session cookie found. Cookies:", - allCookies.map((c) => `${c.key}=${c.value.slice(0, 10)}...`), + // Last resort: try the full HTML for credit info — if we can see credits, we're logged in + const checkResponse = await this.client.get( + `${BASE_URL}/LogIn.action`, + { + timeout: DEFAULT_TIMEOUT_MS, + maxRedirects: 5, + validateStatus: () => true, + }, ); + const checkHtml = String(checkResponse.data ?? ""); + if (checkHtml.includes("puncte de credit")) { + console.log("[epay] Login successful (verified via credit check)."); + return; + } + throw new Error("ePay login failed (no session cookie)"); }