Skip to content

Commit

Permalink
abort captcha (#234)
Browse files Browse the repository at this point in the history
  • Loading branch information
hajonsoft authored Dec 5, 2024
1 parent c9b7acc commit 88d313b
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 58 deletions.
36 changes: 23 additions & 13 deletions src/nsh.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const { fetchOTPFromNusuk } = require("./lib/imap");
const { nusukNationalities: nationalities } = require("./data/nationalities");
const childProcess = require("child_process");
const sharp = require("sharp");
const abortController = new AbortController();

let page;
let data;
Expand Down Expand Up @@ -369,6 +370,8 @@ async function pageContentHandler(currentConfig) {
case "verify-register-email":
emailCodeCounter = 0;
clearTimeout(timerHandler);
// stop captcha attempts
abortController.abort();

await page.waitForSelector(
"#otp-inputs > input.form-control.signup-otp.me-1",
Expand Down Expand Up @@ -413,6 +416,11 @@ async function pageContentHandler(currentConfig) {
"body > main > div.signup > div > div.container-lg.container-fluid.position-relative.h-100 > div > div > div.row > div > form > button";

await util.clickWhenReady(createAccountSelector, page);
// save the email only at this stage
kea.updatePassenger(data.system.accountId, passenger.passportNumber, {
email: passenger.email,
phone: passenger.phone,
});
clicked[currentConfig.name] = {};
clicked[currentConfig.name][passenger.passportNumber] = true;
}
Expand Down Expand Up @@ -973,15 +981,9 @@ async function signup_step1(selectedTraveler) {
const passenger = data.travellers[selectedTraveler];
emailAddress = suggestEmail(selectedTraveler);
telephoneNumber = suggestPhoneNumber(selectedTraveler);
console.log(
"📢[nsh.js:489]: emailAddress and Telephone: ",
emailAddress,
telephoneNumber
);
await kea.updatePassenger(data.system.accountId, passenger.passportNumber, {
email: emailAddress,
phone: telephoneNumber,
});
// store temporarily in the passenger object
passenger.email = emailAddress;
passenger.phone = telephoneNumber;
const nationality = getNationalityUUID(nationalities, data.system.country.name);

await util.commit(
Expand All @@ -1008,7 +1010,8 @@ async function signup_step1(selectedTraveler) {
const captchaCode = await util.SolveIamNotARobot(
"#g-recaptcha-response",
URLS.SIGN_UP,
"6LcNy-0jAAAAAJDOXjYW4z7yV07DWyivFD1mmjek"
"6LcNy-0jAAAAAJDOXjYW4z7yV07DWyivFD1mmjek",
abortController.signal
);

if (captchaCode) {
Expand Down Expand Up @@ -1055,7 +1058,8 @@ async function loginPassenger(selectedTraveler) {
const loginCaptchaValue = await util.SolveIamNotARobot(
"#g-recaptcha-response",
URLS.LOGIN,
"6LcNy-0jAAAAAJDOXjYW4z7yV07DWyivFD1mmjek"
"6LcNy-0jAAAAAJDOXjYW4z7yV07DWyivFD1mmjek",
abortController.signal
);
if (!loginCaptchaValue) {
util.infoMessage(page, `Manual captcha required`);
Expand Down Expand Up @@ -1238,6 +1242,12 @@ async function uploadFakePassport() {
await util.commitFile("#passportPhoto", blankPassportPath);
}

function formatTime(seconds) {
const minutes = Math.floor(seconds / 60).toString().padStart(2, "0");
const secs = (seconds % 60).toString().padStart(2, "0");
return `00:${minutes}:${secs}`;
}

async function pasteOTPCode(err, code) {
if (err === "no-code") {
setTimeout(async () => {
Expand All @@ -1256,8 +1266,8 @@ async function pasteOTPCode(err, code) {
await page.$eval(
"#hajonsoft-commander-alert",
(el, i) =>
(el.innerText = `Checking email 00:00:${i*30}/00:02:30 فحص البريد `),
emailCodeCounter
(el.innerText = `Checking email ${i}/00:02:30 فحص البريد`),
formatTime(emailCodeCounter * 3)
);
} catch { }
getOTPCode();
Expand Down
85 changes: 40 additions & 45 deletions src/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ const imgurClient = new ImgurClient({

let page;
let browser;

function getChromePath() {
switch (os.platform()) {
case "darwin":
Expand Down Expand Up @@ -227,7 +226,7 @@ async function initPage(config, onContentLoaded, data) {
}

const launchOptions = {
headless: process.argv.includes("--debug") ? false : isCloudRun || isHeadless,
headless: process.argv.includes("--debug") ? false : isCloudRun || isHeadless,
ignoreHTTPSErrors: true,
defaultViewport,
args,
Expand All @@ -246,7 +245,7 @@ async function initPage(config, onContentLoaded, data) {
await pauseMessage(page, 5);
try {
await dialog.accept();
} catch {}
} catch { }
});

if (process.argv.length > 2) {
Expand Down Expand Up @@ -279,7 +278,7 @@ async function initPage(config, onContentLoaded, data) {
} else {
fs.readdir(vaccineFolder, (err, files) => {
for (const file of files) {
fs.unlink(path.join(vaccineFolder, file), (err) => {});
fs.unlink(path.join(vaccineFolder, file), (err) => { });
}
});
}
Expand All @@ -302,7 +301,7 @@ async function createControlsFile(
url,
container,
xPath,
fieldFunction = async () => {}
fieldFunction = async () => { }
) {
const logFolder = getPath("log");
if (!fs.existsSync(logFolder)) {
Expand Down Expand Up @@ -392,8 +391,7 @@ function findConfig(url, config) {
if (urlConfig) {
infoMessage(
page,
`✈️ Workflow: ${urlConfig.name} ${
urlConfig.url || urlConfig.regex
`✈️ Workflow: ${urlConfig.name} ${urlConfig.url || urlConfig.regex
} ${timeElapsed()} seconds`,
2
);
Expand Down Expand Up @@ -569,7 +567,7 @@ function getMofaImportString(passenger) {
const importJSON = JSON.parse(importContent);
return " - MOFA: " + importJSON?.status;
}
} catch {}
} catch { }
return "";
}

Expand All @@ -578,19 +576,16 @@ function getOptionNode(passenger, cursor) {
<div style="width: 100%; display: flex; align-items: center; gap: 1rem; background-color: yellow; height: 200px;">
<div>${cursor + 1}- </div>
<div>
${
passenger.nationality?.isArabic
? passenger?.nameArabic?.given + " " + passenger.nameArabic.last
: passenger.name.full
} - ${passenger.passportNumber} - ${passenger?.nationality?.name} - ${
passenger?.gender || "gender"
} - ${passenger?.dob?.age || "age"} years old${getMofaImportString(
passenger
)}${
passenger.email?.includes(".companion") || passenger.isCompanion
${passenger.nationality?.isArabic
? passenger?.nameArabic?.given + " " + passenger.nameArabic.last
: passenger.name.full
} - ${passenger.passportNumber} - ${passenger?.nationality?.name} - ${passenger?.gender || "gender"
} - ${passenger?.dob?.age || "age"} years old${getMofaImportString(
passenger
)}${passenger.email?.includes(".companion") || passenger.isCompanion
? "(companion)"
: ""
}
}
</div>
</div>
`;
Expand Down Expand Up @@ -619,8 +614,7 @@ async function controller(page, structure, travellers) {
// .filter((t) => !t.email.includes(".companion"))
.map(
(traveller, cursor) =>
`<option value="${cursor}" ${
cursor == lastTraveler ? "selected" : ""
`<option value="${cursor}" ${cursor == lastTraveler ? "selected" : ""
}>
${getOptionNode(traveller, cursor)}
</option>`
Expand All @@ -629,9 +623,8 @@ async function controller(page, structure, travellers) {

try {
await page.waitForSelector(structure.controller.selector);
const controllerHandleMethod = `handleEagle${
structure.controller.name || "Send"
}Click`;
const controllerHandleMethod = `handleEagle${structure.controller.name || "Send"
}Click`;
const htmlFileName = path.join(__dirname, "assets", "controller.html");
let html = fs.readFileSync(htmlFileName, "utf8");

Expand All @@ -654,9 +647,9 @@ async function controller(page, structure, travellers) {
.replace(/{pax}/, pax.length)
.replace(/{current}/, (parseInt(lastTraveler) + 1).toString())
.replace(/{mokhaa}/, controller.mokhaa ? "block" : "none")}`.replace(
/{sendall}/,
"Continuous مستمر"
);
/{sendall}/,
"Continuous مستمر"
);
},
[
structure,
Expand Down Expand Up @@ -688,27 +681,27 @@ async function controller(page, structure, travellers) {
await page.exposeFunction("getVisaCount", getVisaCount);
await page.exposeFunction(
"handleWTUClick",
structure.controller.wtuAction || (() => {})
structure.controller.wtuAction || (() => { })
);
await page.exposeFunction(
"handleGMAClick",
structure.controller.gmaAction || (() => {})
structure.controller.gmaAction || (() => { })
);
await page.exposeFunction(
"handleBAUClick",
structure.controller.bauAction || (() => {})
structure.controller.bauAction || (() => { })
);
await page.exposeFunction(
"handleTWFClick",
structure.controller.twfAction || (() => {})
structure.controller.twfAction || (() => { })
);
await page.exposeFunction(
"handleLoadImportedOnlyClick",
handleLoadImportedOnlyClick
);
await page.exposeFunction(
"handleNSKClick",
structure.controller.nskAction || (() => {})
structure.controller.nskAction || (() => { })
);
await page.exposeFunction("closeBrowser", closeBrowser);
}
Expand All @@ -723,7 +716,7 @@ function registerLoop() {
}
function unregisterLoop() {
if (fs.existsSync(getPath("loop.txt"))) {
fs.unlink(getPath("loop.txt"), (err) => {});
fs.unlink(getPath("loop.txt"), (err) => { });
}
}
function getVisaCount() {
Expand All @@ -750,9 +743,8 @@ async function commander(page, structure, travellers) {

try {
await page.waitForSelector(structure.controller.selector);
const controllerHandleMethod = `handleEagle${
structure.controller.name || "Budgie"
}Click`;
const controllerHandleMethod = `handleEagle${structure.controller.name || "Budgie"
}Click`;
const isLoop = fs.existsSync(getPath("loop.txt"));

const htmlFileName = path.join(__dirname, "assets", "commander.html");
Expand All @@ -776,8 +768,8 @@ async function commander(page, structure, travellers) {
.replace(
/{title}/g,
structureParam.controller.title +
" " +
structureParam.controller.arabicTitle
" " +
structureParam.controller.arabicTitle
);
container.outerHTML = controller.keepOriginalElement
? `<div>${container.outerHTML}${htmlContent}</div>`
Expand Down Expand Up @@ -842,7 +834,7 @@ async function handleLoadImportedOnlyClick() {
passportNumber: jsonData.passportNumber,
});
}
} catch {}
} catch { }
}

const data = {
Expand Down Expand Up @@ -1029,8 +1021,7 @@ async function downloadAndResizeImage(
let imagePath = path.join(folder, `${passenger.passportNumber}.jpg`);
const resizedPath = path.join(
folder,
`${passenger.passportNumber}_${width ?? ""}x${height ?? ""}.${
convertToPNG ? "png" : "jpg"
`${passenger.passportNumber}_${width ?? ""}x${height ?? ""}.${convertToPNG ? "png" : "jpg"
}`
);

Expand Down Expand Up @@ -1476,7 +1467,7 @@ async function commitCaptchaTokenWithSelector(
}
}

async function SolveIamNotARobot(responseSelector, url, siteKey) {
async function SolveIamNotARobot(responseSelector, url, siteKey, signal) {
const data = await axios.get(
`http://2captcha.com/in.php?key=${global.captchaKey}&method=userrecaptcha&googlekey=${siteKey}&pageurl=${url}`
);
Expand All @@ -1487,6 +1478,10 @@ async function SolveIamNotARobot(responseSelector, url, siteKey) {

try {
for (let i = 0; i < 10; i++) {
if (signal?.aborted) {
console.log("Captcha solving aborted.");
throw new Error("Captcha solving was cancelled.");
}
const res = await axios.get(
`http://2captcha.com/res.php?key=${global.captchaKey}&action=get&id=${id}`
);
Expand All @@ -1506,7 +1501,7 @@ async function SolveIamNotARobot(responseSelector, url, siteKey) {
// wait 5 seconds
await new Promise((resolve) => setTimeout(resolve, 5000));
}
} catch {}
} catch { }
}
const premiumSupportAlert = async (page, selector, data) => {
await page.waitForSelector(selector);
Expand Down Expand Up @@ -1821,8 +1816,8 @@ function generateMRZ(passenger) {
// letters that are a part of the number fields and their check digits.
const compositeCheckDigit = checkDigit(
codeLine2.substring(0, 10) +
codeLine2.substring(13, 20) +
codeLine2.substring(21, 43)
codeLine2.substring(13, 20) +
codeLine2.substring(21, 43)
);
codeLine2 += compositeCheckDigit.replace(/[-]/g, "<");
}
Expand Down

0 comments on commit 88d313b

Please sign in to comment.