const express = require("express"); const router = express.Router(); const https = require("https"); const querystring = require("querystring"); const zlib = require("zlib"); const { verifyToken } = require("../lib/jwtUtils"); function getRandomElement(array) { const randomIndex = Math.floor(Math.random() * array.length); return array[randomIndex]; } function parseBaJsonResponse(response, rawBuffer) { const encoding = String(response.headers["content-encoding"] || "") .trim() .toLowerCase(); let buf = rawBuffer; if (encoding === "gzip") { buf = zlib.gunzipSync(buf); } else if (encoding === "deflate") { buf = zlib.inflateSync(buf); } else if (encoding === "br") { buf = zlib.brotliDecompressSync(buf); } return JSON.parse(buf.toString("utf8")); } async function performLogin() { const getOptions = { hostname: "ba124.ir", path: "/Account/Login", method: "GET", headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36", Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.9,fa-IR;q=0.8,fa;q=0.7", Connection: "keep-alive", "Sec-Fetch-Dest": "document", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-Site": "none", "Sec-Fetch-User": "?1", "Upgrade-Insecure-Requests": "1", }, }; const loginPageCookies = await new Promise((resolve, reject) => { const request = https.request(getOptions, (response) => { let data = ""; response.on("data", (chunk) => { data += chunk; }); response.on("end", () => { const csrfMatch = data.match( / cookie.split(";")[0]) .join("; "); resolve({ csrfToken, cookieString }); }); }); request.on("error", (error) => { reject(error); }); request.end(); }); const randomUser = getRandomElement([ 4072893341, 4072452238, 4070413170, 4189617652, 4071417919, 4172069355, ]); const postData = querystring.stringify({ NationalId: randomUser, Password: randomUser, __RequestVerificationToken: loginPageCookies.csrfToken, }); const postOptions = { hostname: "ba124.ir", path: "/Account/Login", method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Content-Length": Buffer.byteLength(postData), "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36", Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.9,fa-IR;q=0.8,fa;q=0.7", Connection: "keep-alive", Cookie: loginPageCookies.cookieString, Host: "ba124.ir", Origin: "https://ba124.ir", Referer: "https://ba124.ir/Account/Login", "Sec-Fetch-Dest": "document", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-Site": "same-origin", "Sec-Fetch-User": "?1", "Upgrade-Insecure-Requests": "1", }, }; const finalCookie = await new Promise((resolve, reject) => { const request = https.request(postOptions, (response) => { response.on("data", () => {}); response.on("end", () => { const cookies = response.headers["set-cookie"] || []; const cookieString = cookies .map((cookie) => cookie.split(";")[0]) .join("; "); const combinedCookie = loginPageCookies.cookieString ? `${loginPageCookies.cookieString}; ${cookieString}` : cookieString; resolve(combinedCookie); }); }); request.on("error", (error) => { reject(error); }); request.write(postData); request.end(); }); return finalCookie; } async function makeInquiryRequest(info, type, cookie) { const payloadData = type === "person" ? querystring.stringify({ nationalCode: info, birthDateString: "1404/08/12", }) : type === "unit" ? querystring.stringify({ NationalCode: info, }) : JSON.stringify({ NationaId: info, }); const requestOptions = { hostname: "ba124.ir", path: type === "person" ? "/Inquiries/PersonInfo" : type === "unit" ? "/Inquiries/CallGetLegalPersonInfoByNationalCode" : "/Inquiries/AsnafGWLicenseInquiry", method: "POST", headers: { "Content-Type": type === "person" || type === "unit" ? "application/x-www-form-urlencoded; charset=UTF-8" : "application/json; charset=UTF-8", "Content-Length": Buffer.byteLength(payloadData), "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36", Accept: "application/json, text/javascript, */*; q=0.01", Accept_Encoding: "gzip, deflate, br, zstd", Accept_Language: "en-US,en;q=0.9,fa-IR;q=0.8,fa;q=0.7", Connection: "keep-alive", Cookie: cookie, Host: "ba124.ir", Origin: "https://ba124.ir", Referer: type === "person" ? "https://ba124.ir/Inquiries/PersonInfo" : type === "unit" ? "https://ba124.ir/Inquiries/GetLegalPersonInfoByNationalCode" : "https://ba124.ir/Inquiries/AsnafGWLicenseInquiry", "Sec-Ch-Ua": '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"', "Sec-Ch-Ua-Mobile": "?0", "Sec-Ch-Ua-Platform": '"Windows"', "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-origin", "X-Requested-With": "XMLHttpRequest", }, }; const finalInfo = await new Promise((resolve, reject) => { const request = https.request(requestOptions, (response) => { const chunks = []; response.on("data", (chunk) => { chunks.push(chunk); }); response.on("end", () => { try { const raw = Buffer.concat(chunks); const jsonData = parseBaJsonResponse(response, raw); resolve(jsonData); } catch (error) { reject(new Error(`Invalid JSON response: ${error.message}`)); } }); }); request.on("error", (error) => { reject(error); }); request.write(payloadData); request.end(); }); return finalInfo; } async function makeLadingRequest(start, end, postal, cookie) { const payloadData = JSON.stringify({ FromIssuDate: start, ToIssuDate: end, CodePosti: postal, MabdaYaMaghsad: 3, }); const requestOptions = { hostname: "ba124.ir", path: "/Inquiries/CallGetBarnamehInfoByCodePosti", method: "POST", headers: { "Content-Type": "application/json; charset=UTF-8", "Content-Length": Buffer.byteLength(payloadData), "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36", Accept: "application/json, text/javascript, */*; q=0.01", Accept_Encoding: "gzip, deflate, br, zstd", Accept_Language: "en-US,en;q=0.9,fa-IR;q=0.8,fa;q=0.7,ar-AE;q=0.6,ar;q=0.5,en-GB;q=0.4", Connection: "keep-alive", Cookie: cookie, Host: "ba124.ir", Origin: "https://ba124.ir", Referer: "https://ba124.ir/Inquiries/GetBarnamehInfoByCodePosti", "Sec-Ch-Ua": '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"', "Sec-Ch-Ua-Mobile": "?0", "Sec-Ch-Ua-Platform": '"Linux"', "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-origin", "X-Requested-With": "XMLHttpRequest", }, }; const finalInfo = await new Promise((resolve, reject) => { const request = https.request(requestOptions, (response) => { const chunks = []; response.on("data", (chunk) => { chunks.push(chunk); }); response.on("end", () => { try { const raw = Buffer.concat(chunks); const jsonData = parseBaJsonResponse(response, raw); resolve(jsonData); } catch (error) { reject(new Error(`Invalid JSON response: ${error.message}`)); } }); }); request.on("error", (error) => { reject(error); }); request.write(payloadData); request.end(); }); return finalInfo; } async function makeVeterinaryTransferRequest(trIDCode, cookie) { const payloadData = querystring.stringify({ trIDCode, }); const requestOptions = { hostname: "ba124.ir", path: "/Inquiries/CallVeterinaryTransfer", method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Content-Length": Buffer.byteLength(payloadData), "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36", Accept: "application/json, text/javascript, */*; q=0.01", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en-US,en;q=0.9,fa-IR;q=0.8,fa;q=0.7,ar-AE;q=0.6,ar;q=0.5,en-GB;q=0.4", Connection: "keep-alive", Cookie: cookie, Host: "ba124.ir", Origin: "https://ba124.ir", Referer: "https://ba124.ir/Inquiries/VeterinaryTransfer", "Sec-Ch-Ua": '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"', "Sec-Ch-Ua-Mobile": "?0", "Sec-Ch-Ua-Platform": '"Linux"', "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-origin", "X-Requested-With": "XMLHttpRequest", }, }; const finalInfo = await new Promise((resolve, reject) => { const request = https.request(requestOptions, (response) => { const chunks = []; response.on("data", (chunk) => { chunks.push(chunk); }); response.on("end", () => { try { const raw = Buffer.concat(chunks); const jsonData = parseBaJsonResponse(response, raw); resolve(jsonData); } catch (error) { reject(new Error(`Invalid JSON response: ${error.message}`)); } }); }); request.on("error", (error) => { reject(error); }); request.write(payloadData); request.end(); }); return finalInfo; } async function makePostcodeInquiryRequest(postcode, cookie) { const payloadData = querystring.stringify({ postcode, }); const requestOptions = { hostname: "ba124.ir", path: "/Inquiries/CallAddressWithPostcodeInquiry", method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Content-Length": Buffer.byteLength(payloadData), "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36", Accept: "application/json, text/javascript, */*; q=0.01", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en-US,en;q=0.9,fa-IR;q=0.8,fa;q=0.7,ar-AE;q=0.6,ar;q=0.5,en-GB;q=0.4", Connection: "keep-alive", Cookie: cookie, Host: "ba124.ir", Origin: "https://ba124.ir", Referer: "https://ba124.ir/Inquiries/AddressWithPostcodeInquiry", "Sec-Ch-Ua": '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"', "Sec-Ch-Ua-Mobile": "?0", "Sec-Ch-Ua-Platform": '"Linux"', "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-origin", "X-Requested-With": "XMLHttpRequest", }, }; const finalInfo = await new Promise((resolve, reject) => { const request = https.request(requestOptions, (response) => { const chunks = []; response.on("data", (chunk) => { chunks.push(chunk); }); response.on("end", () => { try { const raw = Buffer.concat(chunks); const jsonData = parseBaJsonResponse(response, raw); resolve(jsonData); } catch (error) { reject(new Error(`Invalid JSON response: ${error.message}`)); } }); }); request.on("error", (error) => { reject(error); }); request.write(payloadData); request.end(); }); return finalInfo; } async function makeAgriWindowsUnitsRequest(PartIdCode, cookie) { const payloadData = querystring.stringify({ PartIdCode, }); const requestOptions = { hostname: "ba124.ir", path: "/Inquiries/CallAgriWindowsUnits", method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Content-Length": Buffer.byteLength(payloadData), "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36", Accept: "application/json, text/javascript, */*; q=0.01", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en-US,en;q=0.9,fa-IR;q=0.8,fa;q=0.7,ar-AE;q=0.6,ar;q=0.5,en-GB;q=0.4", Connection: "keep-alive", Cookie: cookie, Host: "ba124.ir", Origin: "https://ba124.ir", Referer: "https://ba124.ir/Inquiries/VeterinaryTransfer", "Sec-Ch-Ua": '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"', "Sec-Ch-Ua-Mobile": "?0", "Sec-Ch-Ua-Platform": '"Linux"', "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-origin", "X-Requested-With": "XMLHttpRequest", }, }; const finalInfo = await new Promise((resolve, reject) => { const request = https.request(requestOptions, (response) => { const chunks = []; response.on("data", (chunk) => { chunks.push(chunk); }); response.on("end", () => { try { const raw = Buffer.concat(chunks); const jsonData = parseBaJsonResponse(response, raw); resolve(jsonData); } catch (error) { reject(new Error(`Invalid JSON response: ${error.message}`)); } }); }); request.on("error", (error) => { reject(error); }); request.write(payloadData); request.end(); }); return finalInfo; } router.use(verifyToken); router.get("/national-documents", async (req, res) => { const { info, type } = req.query; if (!info) { return res.status(400).json({ error: "Missing required field: info", }); } try { let finalCookie = await performLogin(); let finalInfo = await makeInquiryRequest(info, type, finalCookie); while (finalInfo && finalInfo.error) { console.log("Session expired, retrying login and request..."); finalCookie = await performLogin(); finalInfo = await makeInquiryRequest(info, type, finalCookie); } res.json(finalInfo); } catch (error) { res.status(500).json({ error: "Failed to fetch person info", message: error.message, }); } }); router.get("/ladinginfo", async (req, res) => { const { start, end, postal } = req.query; if (!start || !end || !postal) { return res.status(400).json({ error: "Missing required fields: start, end, and postal are required", }); } try { let finalCookie = await performLogin(); let finalInfo = await makeLadingRequest(start, end, postal, finalCookie); while (finalInfo && finalInfo.error) { console.log("Session expired, retrying login and request..."); finalCookie = await performLogin(); finalInfo = await makeLadingRequest(start, end, postal, finalCookie); } res.json(finalInfo); } catch (error) { res.status(500).json({ error: "Failed to fetch lading info", message: error.message, }); } }); router.get("/veterinary-transfer", async (req, res) => { const { trIDCode } = req.query; if (!trIDCode) { return res.status(400).json({ error: "Missing required field: trIDCode", }); } try { let finalCookie = await performLogin(); let finalInfo = await makeVeterinaryTransferRequest(trIDCode, finalCookie); while (finalInfo && finalInfo.error) { console.log("Session expired, retrying login and request..."); finalCookie = await performLogin(); finalInfo = await makeVeterinaryTransferRequest(trIDCode, finalCookie); } res.json(finalInfo); } catch (error) { res.status(500).json({ error: "Failed to fetch veterinary transfer info", message: error.message, }); } }); router.get("/inquiry-farm", async (req, res) => { const { PartIdCode } = req.query; if (!PartIdCode) { return res.status(400).json({ error: "Missing required field: PartIdCode", }); } try { let finalCookie = await performLogin(); let finalInfo = await makeAgriWindowsUnitsRequest(PartIdCode, finalCookie); while (finalInfo && finalInfo.error) { console.log("Session expired, retrying login and request..."); finalCookie = await performLogin(); finalInfo = await makeAgriWindowsUnitsRequest(PartIdCode, finalCookie); } res.json(finalInfo); } catch (error) { res.status(500).json({ error: "Failed to fetch inquiry farm info", message: error.message, }); } }); router.get("/postcode-inquiry", async (req, res) => { const { postcode } = req.query; if (!postcode) { return res.status(400).json({ error: "Missing required field: postcode", }); } try { let finalCookie = await performLogin(); let finalInfo = await makePostcodeInquiryRequest(postcode, finalCookie); while (finalInfo && finalInfo.error) { console.log("Session expired, retrying login and request..."); finalCookie = await performLogin(); finalInfo = await makePostcodeInquiryRequest(postcode, finalCookie); } res.json(finalInfo); } catch (error) { res.status(500).json({ error: "Failed to fetch postcode inquiry info", message: error.message, }); } }); module.exports = router;