diff --git a/package.json b/package.json index b436390..b0fef84 100644 --- a/package.json +++ b/package.json @@ -32,9 +32,10 @@ "cheerio": "^1.0.0-rc.12", "eslint": "^8.49.0", "eslint-plugin-modules-newline": "^0.0.6", + "fingerprint-generator": "^2.1.42", + "fingerprint-injector": "^2.1.42", "puppeteer": "^21.4.1", "puppeteer-extra": "^3.3.6", - "puppeteer-extra-plugin-stealth": "^2.11.2", "ts-node": "^10.9.1" } } diff --git a/src/browser/Browser.ts b/src/browser/Browser.ts index 43cf742..4857ee6 100644 --- a/src/browser/Browser.ts +++ b/src/browser/Browser.ts @@ -1,13 +1,16 @@ import puppeteer from 'puppeteer-extra' -import stealthPlugin from 'puppeteer-extra-plugin-stealth' +import { FingerprintInjector } from 'fingerprint-injector' +import { FingerprintGenerator } from 'fingerprint-generator' import { MicrosoftRewardsBot } from '../index' -import { getUserAgent } from '../util/UserAgent' - import { AccountProxy } from '../interface/Account' -puppeteer.use(stealthPlugin()) +/* Test Stuff +https://abrahamjuliot.github.io/creepjs/ +https://botcheck.luminati.io/ +http://f.vision/ +*/ class Browser { @@ -18,7 +21,7 @@ class Browser { } async createBrowser(email: string, proxy: AccountProxy, isMobile: boolean) { - const userAgent = await getUserAgent(isMobile) + // const userAgent = await getUserAgent(isMobile) const browser = await puppeteer.launch({ headless: this.bot.config.headless, @@ -27,14 +30,28 @@ class Browser { '--no-sandbox', '--mute-audio', '--disable-setuid-sandbox', - `--user-agent=${userAgent.userAgent}`, - isMobile ? '--window-size=568,1024' : '', proxy.url ? `--proxy-server=${proxy.url}:${proxy.port}` : '' ] }) + const { fingerprint, headers } = new FingerprintGenerator().getFingerprint({ + devices: isMobile ? ['mobile'] : ['desktop'], + operatingSystems: isMobile ? ['android'] : ['windows'], + browsers: ['edge'], + browserListQuery: 'last 2 Edge versions' + }) + + // Modify the newPage function to attach the fingerprint + const originalNewPage = browser.newPage + browser.newPage = async function () { + const page = await originalNewPage.apply(browser) + await new FingerprintInjector().attachFingerprintToPuppeteer(page, { fingerprint, headers }) + return page + } + return browser } + } export default Browser \ No newline at end of file diff --git a/src/browser/BrowserFunc.ts b/src/browser/BrowserFunc.ts index a8a7712..5094a97 100644 --- a/src/browser/BrowserFunc.ts +++ b/src/browser/BrowserFunc.ts @@ -206,7 +206,7 @@ export default class BrowserFunc { async waitForQuizRefresh(page: Page): Promise { try { - await page.waitForSelector('#rqHeaderCredits', { visible: true, timeout: 5000 }) + await page.waitForSelector('#rqHeaderCredits', { visible: true, timeout: 10_000 }) await this.bot.utils.wait(2000) return true @@ -218,7 +218,7 @@ export default class BrowserFunc { async checkQuizCompleted(page: Page): Promise { try { - await page.waitForSelector('#quizCompleteContainer', { visible: true, timeout: 1000 }) + await page.waitForSelector('#quizCompleteContainer', { visible: true, timeout: 2000 }) await this.bot.utils.wait(2000) return true diff --git a/src/functions/Login.ts b/src/functions/Login.ts index 853c91c..d851013 100644 --- a/src/functions/Login.ts +++ b/src/functions/Login.ts @@ -22,10 +22,10 @@ export class Login { // Navigate to the Bing login page await page.goto('https://login.live.com/') - const isLoggedIn = await page.waitForSelector('html[data-role-name="MeePortal"]', { timeout: 5000 }).then(() => true).catch(() => false) + const isLoggedIn = await page.waitForSelector('html[data-role-name="MeePortal"]', { timeout: 10_000 }).then(() => true).catch(() => false) if (!isLoggedIn) { - const isLocked = await page.waitForSelector('.serviceAbusePageContainer', { visible: true, timeout: 5000 }).then(() => true).catch(() => false) + const isLocked = await page.waitForSelector('.serviceAbusePageContainer', { visible: true, timeout: 10_000 }).then(() => true).catch(() => false) if (isLocked) { this.bot.log('LOGIN', 'This account has been locked!', 'error') throw new Error('Account has been locked!') @@ -123,7 +123,7 @@ export class Login { private async checkBingLoginStatus(page: Page): Promise { try { - await page.waitForSelector('#id_n', { timeout: 5000 }) + await page.waitForSelector('#id_n', { timeout: 10_000 }) return true } catch (error) { return false diff --git a/src/functions/Workers.ts b/src/functions/Workers.ts index f9f3bb9..2dfdab7 100644 --- a/src/functions/Workers.ts +++ b/src/functions/Workers.ts @@ -108,7 +108,7 @@ export class Workers { } // Wait for element to load - await page.waitForSelector(selector, { timeout: 5000 }) + await page.waitForSelector(selector, { timeout: 10_000 }) // Click element, it will be opened in a new tab await page.click(selector) diff --git a/src/functions/activities/ABC.ts b/src/functions/activities/ABC.ts index d64ed05..4aa02cf 100644 --- a/src/functions/activities/ABC.ts +++ b/src/functions/activities/ABC.ts @@ -15,18 +15,18 @@ export class ABC extends Workers { const maxIterations = 15 let i for (i = 0; i < maxIterations && !$('span.rw_icon').length; i++) { - await page.waitForSelector('.wk_OptionClickClass', { visible: true, timeout: 5000 }) + await page.waitForSelector('.wk_OptionClickClass', { visible: true, timeout: 10_000 }) const answers = $('.wk_OptionClickClass') const answer = answers[this.bot.utils.randomNumber(0, 2)]?.attribs['id'] - await page.waitForSelector(`#${answer}`, { visible: true, timeout: 5000 }) + await page.waitForSelector(`#${answer}`, { visible: true, timeout: 10_000 }) await this.bot.utils.wait(2000) await page.click(`#${answer}`) // Click answer await this.bot.utils.wait(4000) - await page.waitForSelector('div.wk_button', { visible: true, timeout: 5000 }) + await page.waitForSelector('div.wk_button', { visible: true, timeout: 10_000 }) await page.click('div.wk_button') // Click next question button page = await this.bot.browser.utils.getLatestTab(page) diff --git a/src/functions/activities/Poll.ts b/src/functions/activities/Poll.ts index ad1d850..7c462a6 100644 --- a/src/functions/activities/Poll.ts +++ b/src/functions/activities/Poll.ts @@ -11,7 +11,7 @@ export class Poll extends Workers { try { const buttonId = `#btoption${Math.floor(this.bot.utils.randomNumber(0, 1))}` - await page.waitForSelector(buttonId, { visible: true, timeout: 5000 }) + await page.waitForSelector(buttonId, { visible: true, timeout: 10_000 }) await this.bot.utils.wait(2000) await page.click(buttonId) diff --git a/src/functions/activities/Quiz.ts b/src/functions/activities/Quiz.ts index 3c53e9c..2b48dde 100644 --- a/src/functions/activities/Quiz.ts +++ b/src/functions/activities/Quiz.ts @@ -29,7 +29,7 @@ export class Quiz extends Workers { const answers: string[] = [] for (let i = 0; i < quizData.numberOfOptions; i++) { - const answerSelector = await page.waitForSelector(`#rqAnswerOption${i}`, { visible: true, timeout: 5000 }) + const answerSelector = await page.waitForSelector(`#rqAnswerOption${i}`, { visible: true, timeout: 10_000 }) const answerAttribute = await answerSelector?.evaluate(el => el.getAttribute('iscorrectoption')) if (answerAttribute && answerAttribute.toLowerCase() === 'true') { @@ -59,7 +59,7 @@ export class Quiz extends Workers { for (let i = 0; i < quizData.numberOfOptions; i++) { - const answerSelector = await page.waitForSelector(`#rqAnswerOption${i}`, { visible: true, timeout: 5000 }) + const answerSelector = await page.waitForSelector(`#rqAnswerOption${i}`, { visible: true, timeout: 10_000 }) const dataOption = await answerSelector?.evaluate(el => el.getAttribute('data-option')) if (dataOption === correctOption) { diff --git a/src/functions/activities/Search.ts b/src/functions/activities/Search.ts index c50abb2..f7a4bb3 100644 --- a/src/functions/activities/Search.ts +++ b/src/functions/activities/Search.ts @@ -10,6 +10,8 @@ import { GoogleSearch } from '../../interface/Search' export class Search extends Workers { + private searchPageURL = 'https://bing.com' + public async doSearch(page: Page, data: DashboardData, mobile: boolean) { this.bot.log('SEARCH-BING', 'Starting bing searches') @@ -38,7 +40,7 @@ export class Search extends Workers { const searchPage = await browser.newPage() // Go to bing - await searchPage.goto('https://bing.com') + await searchPage.goto(this.searchPageURL) let maxLoop = 0 // If the loop hits 10 this when not gaining any points, we're assuming it's stuck. If it ddoesn't continue after 5 more searches with alternative queries, abort search @@ -289,7 +291,7 @@ export class Search extends Workers { // If "goBack" didn't return to search listing (due to redirects) if (lastTabURL.hostname !== searchListingURL.hostname) { - await lastTab.goto(searchListingURL.href) + await lastTab.goto(this.searchPageURL) } } else { // No longer on bing, likely opened a new tab, close this tab @@ -314,14 +316,15 @@ export class Search extends Workers { // If "goBack" didn't return to search listing (due to redirects) if (lastTabURL.hostname !== searchListingURL.hostname) { - await lastTab.goto(searchListingURL.href) + await lastTab.goto(this.searchPageURL) } } } + lastTab = await this.bot.browser.utils.getLatestTab(page) // Finally update the lastTab var again + i++ } - lastTab = await this.bot.browser.utils.getLatestTab(page) // Finally update the lastTab var again - i++ + } } catch (error) { this.bot.log('SEARCH-RANDOM-CLICK', 'An error occurred:' + error, 'error')