Compare commits

..

2 commits

Author SHA1 Message Date
nocci
37de92c92e fix: handle epic login captcha manually in legacy/new flows
Some checks failed
build-and-push / lint (push) Failing after 1s
build-and-push / sonar (push) Has been skipped
build-and-push / docker (push) Has been skipped
2025-12-31 13:50:14 +00:00
nocci
728d08e551 fix: retry continue/submit on epic password and otp steps 2025-12-31 13:33:49 +00:00
2 changed files with 17 additions and 22 deletions

View file

@ -125,7 +125,7 @@ const ensureLoggedIn = async (page, context) => {
if (!cfg.eg_email || !cfg.eg_password) return false; if (!cfg.eg_email || !cfg.eg_password) return false;
try { try {
await page.goto('https://www.epicgames.com/id/login?lang=en-US&noHostRedirect=true&redirectUrl=' + URL_CLAIM, { waitUntil: 'domcontentloaded' }); await page.goto('https://www.epicgames.com/id/login?lang=en-US&noHostRedirect=true&redirectUrl=' + URL_CLAIM, { waitUntil: 'domcontentloaded' });
const emailField = page.locator('input[name="email"], input#email'); const emailField = page.locator('input[name="email"], input#email, input[aria-label="Sign in with email"]');
const passwordField = page.locator('input[name="password"], input#password'); const passwordField = page.locator('input[name="password"], input#password');
const continueBtn = page.locator('button:has-text("Continue"), button#continue, button[type="submit"]'); const continueBtn = page.locator('button:has-text("Continue"), button#continue, button[type="submit"]');
@ -140,7 +140,9 @@ const ensureLoggedIn = async (page, context) => {
await passwordField.fill(cfg.eg_password); await passwordField.fill(cfg.eg_password);
const rememberMe = page.locator('input[name="rememberMe"], #rememberMe'); const rememberMe = page.locator('input[name="rememberMe"], #rememberMe');
if (await rememberMe.count()) await rememberMe.check().catch(() => {}); if (await rememberMe.count()) await rememberMe.check().catch(() => {});
await page.click('button[type="submit"]'); await continueBtn.first().click().catch(async () => {
await page.click('button[type="submit"]').catch(() => {});
});
// MFA step // MFA step
try { try {
@ -156,7 +158,9 @@ const ensureLoggedIn = async (page, context) => {
} else { } else {
await page.locator('input[name="code-input-0"]').pressSequentially(otp.toString()); await page.locator('input[name="code-input-0"]').pressSequentially(otp.toString());
} }
await page.click('button[type="submit"]'); await continueBtn.first().click().catch(async () => {
await page.click('button[type="submit"]').catch(() => {});
});
} catch { } catch {
// no MFA // no MFA
} }

View file

@ -104,27 +104,18 @@ try {
process.exit(1); process.exit(1);
} }
}; };
// If captcha or "Incorrect response" is visible, do not auto-submit; wait for manual solve.
const hasCaptcha = await page.locator('.h_captcha_challenge iframe, text=Incorrect response').count() > 0;
if (hasCaptcha) {
console.warn('Captcha/Incorrect response detected. Please solve manually in the browser.');
await notify('epic-games: captcha encountered; please solve manually in browser.');
await page.waitForTimeout(cfg.login_timeout);
continue;
}
const email = cfg.eg_email || await prompt({ message: 'Enter email' }); const email = cfg.eg_email || await prompt({ message: 'Enter email' });
if (email) { if (email) {
const watchCaptchaChallenge = async () => {
try {
await page.waitForSelector('.h_captcha_challenge iframe', { timeout: 15000 });
console.error('Got a captcha during login (likely due to too many attempts)! You may solve it in the browser, get a new IP or try again in a few hours.');
await notify('epic-games: got captcha during login. Please check.');
} catch {
return;
}
};
const watchCaptchaIncorrect = async () => {
try {
await page.waitForSelector('p:has-text("Incorrect response.")', { timeout: 15000 });
console.error('Incorrect response for captcha!');
} catch {
return;
}
};
watchCaptchaChallenge();
watchCaptchaIncorrect();
await page.fill('#email', email); await page.fill('#email', email);
const password = cfg.eg_password || await prompt({ type: 'password', message: 'Enter password' }); const password = cfg.eg_password || await prompt({ type: 'password', message: 'Enter password' });
if (password) { if (password) {