diff --git a/src/modules/parcel-sync/services/epay-client.ts b/src/modules/parcel-sync/services/epay-client.ts index b8045f2..3402ac1 100644 --- a/src/modules/parcel-sync/services/epay-client.ts +++ b/src/modules/parcel-sync/services/epay-client.ts @@ -127,39 +127,74 @@ export class EpayClient { /* ── Auth ───────────────────────────────────────────────────── */ private async login(): Promise { + // Full login URL with module + goto params (required by OpenAM) + const loginUrlFull = `${LOGIN_URL}?module=SelfRegistration&goto=${encodeURIComponent("http://epay.ancpi.ro:80/epay/LogIn.action")}`; + const body = `IDToken1=${encodeURIComponent(this.username)}&IDToken2=${encodeURIComponent(this.password)}`; - const response = await this.client.post(LOGIN_URL, body, { - headers: { "Content-Type": "application/x-www-form-urlencoded" }, + // Step 1: POST login — don't follow redirects so we capture cookies + const response = await this.client.post(loginUrlFull, body, { + headers: { + "Content-Type": "application/x-www-form-urlencoded", + Referer: loginUrlFull, + }, timeout: DEFAULT_TIMEOUT_MS, - maxRedirects: 10, - validateStatus: () => true, // don't throw on redirects + maxRedirects: 0, + validateStatus: () => true, // accept 302 }); - // Check if login succeeded — after redirects we should land on ePay - const finalUrl = response.request?.res?.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"}`, + ); + // Check for auth failure — OpenAM returns 200 with login form on failure + const html = typeof response.data === "string" ? response.data : ""; if ( - finalUrl.includes("/openam/UI/Login") || - html.includes("Authentication Failed") || - html.includes("IDToken1") + response.status === 200 && + (html.includes("Authentication Failed") || + html.includes("Autentificare esuata") || + (html.includes("IDToken1") && html.includes("IDToken2"))) ) { throw new Error("ePay login failed (invalid credentials)"); } - // Verify we have session cookies - const cookies = await this.jar.getCookies(BASE_URL); - const hasCookies = - cookies.some((c) => c.key === "JSESSIONID") || - cookies.some((c) => c.key === "iPlanetDirectoryPro"); + // 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 + await this.client.get(`${BASE_URL}/LogIn.action`, { + timeout: DEFAULT_TIMEOUT_MS, + maxRedirects: 5, + validateStatus: () => true, + }); + } - if (!hasCookies) { - // Check oassl domain too - const oasslCookies = await this.jar.getCookies(LOGIN_URL); - if (!oasslCookies.some((c) => c.key === "iPlanetDirectoryPro")) { - throw new Error("ePay login failed (no session cookie)"); - } + // 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)), + ]; + + const hasSession = + allCookies.some((c) => c.key === "iPlanetDirectoryPro") || + allCookies.some((c) => c.key === "JSESSIONID"); + + if (!hasSession) { + console.error( + "[epay] No session cookie found. Cookies:", + allCookies.map((c) => `${c.key}=${c.value.slice(0, 10)}...`), + ); + throw new Error("ePay login failed (no session cookie)"); } console.log("[epay] Login successful.");