Clean Sonar issues in store scripts
This commit is contained in:
parent
397871b012
commit
5f919039ab
6 changed files with 172 additions and 187 deletions
|
|
@ -1,6 +1,3 @@
|
|||
// TODO This is mostly a copy of epic-games.js
|
||||
// New assets to claim every first Tuesday of a month.
|
||||
|
||||
import { firefox } from 'playwright-firefox'; // stealth plugin needs no outdated playwright-extra
|
||||
import { authenticator } from 'otplib';
|
||||
import path from 'node:path';
|
||||
|
|
@ -21,8 +18,7 @@ const db = await jsonDb('unrealengine.json', {});
|
|||
const context = await firefox.launchPersistentContext(cfg.dir.browser, {
|
||||
headless: cfg.headless,
|
||||
viewport: { width: cfg.width, height: cfg.height },
|
||||
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.83 Safari/537.36', // see replace of Headless in util.newStealthContext. TODO Windows UA enough to avoid 'device not supported'? update if browser is updated?
|
||||
// userAgent for firefox: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:106.0) Gecko/20100101 Firefox/106.0
|
||||
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.83 Safari/537.36', // Windows UA avoids "device not supported"; update when browser version changes
|
||||
locale: 'en-US', // ignore OS locale to be sure to have english text for locators
|
||||
recordVideo: cfg.record ? { dir: 'data/record/', size: { width: cfg.width, height: cfg.height } } : undefined, // will record a .webm video for each page navigated; without size, video would be scaled down to fit 800x800
|
||||
recordHar: cfg.record ? { path: `data/record/ue-${filenamify(datetime())}.har` } : undefined, // will record a HAR file with network requests and responses; can be imported in Chrome devtools
|
||||
|
|
@ -36,8 +32,7 @@ await stealth(context);
|
|||
if (!cfg.debug) context.setDefaultTimeout(cfg.timeout);
|
||||
|
||||
const page = context.pages().length ? context.pages()[0] : await context.newPage(); // should always exist
|
||||
await page.setViewportSize({ width: cfg.width, height: cfg.height }); // TODO workaround for https://github.com/vogler/free-games-claimer/issues/277 until Playwright fixes it
|
||||
// console.debug('userAgent:', await page.evaluate(() => navigator.userAgent));
|
||||
await page.setViewportSize({ width: cfg.width, height: cfg.height }); // workaround for https://github.com/vogler/free-games-claimer/issues/277 until Playwright fixes it
|
||||
|
||||
const notify_games = [];
|
||||
let user;
|
||||
|
|
@ -60,23 +55,26 @@ try {
|
|||
const email = cfg.eg_email || await prompt({ message: 'Enter email' });
|
||||
const password = email && (cfg.eg_password || await prompt({ type: 'password', message: 'Enter password' }));
|
||||
if (email && password) {
|
||||
// await page.click('text=Sign in with Epic Games');
|
||||
await page.fill('#email', email);
|
||||
await page.click('button[type="submit"]');
|
||||
await page.fill('#password', password);
|
||||
await page.click('button[type="submit"]');
|
||||
page.waitForSelector('#h_captcha_challenge_login_prod iframe').then(() => {
|
||||
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.');
|
||||
notify('unrealengine: got captcha during login. Please check.');
|
||||
}).catch(_ => { });
|
||||
// handle MFA, but don't await it
|
||||
page.waitForURL('**/id/login/mfa**').then(async () => {
|
||||
console.log('Enter the security code to continue - This appears to be a new device, browser or location. A security code has been sent to your email address at ...');
|
||||
// TODO locator for text (email or app?)
|
||||
const otp = cfg.eg_otpkey && authenticator.generate(cfg.eg_otpkey) || await prompt({ type: 'text', message: 'Enter two-factor sign in code', validate: n => n.toString().length == 6 || 'The code must be 6 digits!' }); // can't use type: 'number' since it strips away leading zeros and codes sometimes have them
|
||||
await page.locator('input[name="code-input-0"]').pressSequentially(otp.toString());
|
||||
await page.click('button[type="submit"]');
|
||||
}).catch(_ => { });
|
||||
void (async () => {
|
||||
try {
|
||||
await page.waitForSelector('#h_captcha_challenge_login_prod 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.');
|
||||
notify('unrealengine: got captcha during login. Please check.');
|
||||
} catch {}
|
||||
})();
|
||||
void (async () => {
|
||||
try {
|
||||
await page.waitForURL('**/id/login/mfa**', { timeout: cfg.login_timeout });
|
||||
console.log('Enter the security code to continue - This appears to be a new device, browser or location. A security code has been sent to your email address at ...');
|
||||
const otp = cfg.eg_otpkey && authenticator.generate(cfg.eg_otpkey) || await prompt({ type: 'text', message: 'Enter two-factor sign in code', validate: n => n.toString().length == 6 || 'The code must be 6 digits!' }); // can't use type: 'number' since it strips away leading zeros and codes sometimes have them
|
||||
await page.locator('input[name="code-input-0"]').pressSequentially(otp.toString());
|
||||
await page.click('button[type="submit"]');
|
||||
} catch {}
|
||||
})();
|
||||
} else {
|
||||
console.log('Waiting for you to login in the browser.');
|
||||
await notify('unrealengine: no longer signed in and not enough options set for automatic login.');
|
||||
|
|
@ -135,18 +133,19 @@ try {
|
|||
notify('unrealengine: ' + err);
|
||||
process.exit(1);
|
||||
}
|
||||
// await page.pause();
|
||||
console.log('Click shopping cart');
|
||||
await page.locator('.shopping-cart').click();
|
||||
// await page.waitForTimeout(2000);
|
||||
await page.locator('button.checkout').click();
|
||||
console.log('Click checkout');
|
||||
// maybe: Accept End User License Agreement
|
||||
page.locator('[name=accept-label]').check().then(() => {
|
||||
console.log('Accept End User License Agreement');
|
||||
page.locator('span:text-is("Accept")').click(); // otherwise matches 'Accept All Cookies'
|
||||
}).catch(_ => { });
|
||||
await page.waitForSelector('#webPurchaseContainer iframe'); // TODO needed?
|
||||
void (async () => {
|
||||
try {
|
||||
await page.locator('[name=accept-label]').check({ timeout: 10000 });
|
||||
console.log('Accept End User License Agreement');
|
||||
await page.locator('span:text-is("Accept")').click(); // otherwise matches 'Accept All Cookies'
|
||||
} catch {}
|
||||
})();
|
||||
await page.waitForSelector('#webPurchaseContainer iframe');
|
||||
const iframe = page.frameLocator('#webPurchaseContainer iframe');
|
||||
|
||||
if (cfg.debug) await page.pause();
|
||||
|
|
@ -161,14 +160,21 @@ try {
|
|||
|
||||
// I Agree button is only shown for EU accounts! https://github.com/vogler/free-games-claimer/pull/7#issuecomment-1038964872
|
||||
const btnAgree = iframe.locator('button:has-text("I Agree")');
|
||||
btnAgree.waitFor().then(() => btnAgree.click()).catch(_ => { }); // EU: wait for and click 'I Agree'
|
||||
void (async () => {
|
||||
try {
|
||||
await btnAgree.waitFor({ timeout: 10000 });
|
||||
await btnAgree.click();
|
||||
} catch {}
|
||||
})(); // EU: wait for and click 'I Agree'
|
||||
try {
|
||||
// context.setDefaultTimeout(100 * 1000); // give time to solve captcha, iframe goes blank after 60s?
|
||||
const captcha = iframe.locator('#h_captcha_challenge_checkout_free_prod iframe');
|
||||
captcha.waitFor().then(async () => { // don't await, since element may not be shown
|
||||
// console.info(' Got hcaptcha challenge! NopeCHA extension will likely solve it.')
|
||||
console.error(' Got hcaptcha challenge! Lost trust due to too many login attempts? You can solve the captcha in the browser or get a new IP address.');
|
||||
}).catch(_ => { }); // may time out if not shown
|
||||
void (async () => {
|
||||
try {
|
||||
await captcha.waitFor({ timeout: 10000 });
|
||||
console.error(' Got hcaptcha challenge! Lost trust due to too many login attempts? You can solve the captcha in the browser or get a new IP address.');
|
||||
} catch {}
|
||||
})(); // may time out if not shown
|
||||
await page.waitForSelector('text=Thank you');
|
||||
for (const id of ids) {
|
||||
db.data[user][id].status = 'claimed';
|
||||
|
|
@ -176,16 +182,12 @@ try {
|
|||
}
|
||||
notify_games.forEach(g => g.status == 'failed' && (g.status = 'claimed'));
|
||||
console.log('Claimed successfully!');
|
||||
// context.setDefaultTimeout(cfg.timeout);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
// console.error(' Failed to claim! Try again if NopeCHA timed out. Click the extension to see if you ran out of credits (refill after 24h). To avoid captchas try to get a new IP or set a cookie from https://www.hcaptcha.com/accessibility');
|
||||
console.error(' Failed to claim! To avoid captchas try to get a new IP address.');
|
||||
await page.screenshot({ path: screenshot('failed', `${filenamify(datetime())}.png`), fullPage: true });
|
||||
// db.data[user][id].status = 'failed';
|
||||
notify_games.forEach(g => g.status = 'failed');
|
||||
}
|
||||
// notify_game.status = db.data[user][game_id].status; // claimed or failed
|
||||
|
||||
if (notify_games.length) await page.screenshot({ path: screenshot(`${filenamify(datetime())}.png`), fullPage: false }); // fullPage is quite long...
|
||||
console.log('Done');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue