first commit
This commit is contained in:
543
routes/nationalDocumentsRoutes.js
Normal file
543
routes/nationalDocumentsRoutes.js
Normal file
@@ -0,0 +1,543 @@
|
||||
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(
|
||||
/<input name="__RequestVerificationToken" type="hidden" value="([^"]+)"/
|
||||
);
|
||||
const csrfToken = csrfMatch ? csrfMatch[1] : null;
|
||||
|
||||
if (!csrfToken) {
|
||||
reject(new Error("Could not extract CSRF token"));
|
||||
return;
|
||||
}
|
||||
|
||||
const cookies = response.headers["set-cookie"] || [];
|
||||
const cookieString = cookies
|
||||
.map((cookie) => 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 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,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user