mirror of
https://github.com/TheNetsky/Microsoft-Rewards-Script.git
synced 2026-01-19 22:43:58 +00:00
141 lines
5.1 KiB
TypeScript
141 lines
5.1 KiB
TypeScript
import rebrowser, { BrowserContext } from 'patchright'
|
|
import { newInjectedContext } from 'fingerprint-injector'
|
|
import { BrowserFingerprintWithHeaders, FingerprintGenerator } from 'fingerprint-generator'
|
|
|
|
import type { MicrosoftRewardsBot } from '../index'
|
|
import { loadSessionData, saveFingerprintData } from '../util/Load'
|
|
import { UserAgentManager } from './UserAgent'
|
|
|
|
import type { Account, AccountProxy } from '../interface/Account'
|
|
|
|
/* Test Stuff
|
|
https://abrahamjuliot.github.io/creepjs/
|
|
https://botcheck.luminati.io/
|
|
https://fv.pro/
|
|
https://pixelscan.net/
|
|
https://www.browserscan.net/
|
|
*/
|
|
|
|
interface BrowserCreationResult {
|
|
context: BrowserContext
|
|
fingerprint: BrowserFingerprintWithHeaders
|
|
}
|
|
|
|
class Browser {
|
|
private readonly bot: MicrosoftRewardsBot
|
|
private static readonly BROWSER_ARGS = [
|
|
'--no-sandbox',
|
|
'--mute-audio',
|
|
'--disable-setuid-sandbox',
|
|
'--ignore-certificate-errors',
|
|
'--ignore-certificate-errors-spki-list',
|
|
'--ignore-ssl-errors',
|
|
'--no-first-run',
|
|
'--no-default-browser-check',
|
|
'--disable-user-media-security=true',
|
|
'--disable-blink-features=Attestation',
|
|
'--disable-features=WebAuthentication,PasswordManagerOnboarding,PasswordManager,EnablePasswordsAccountStorage,Passkeys',
|
|
'--disable-save-password-bubble'
|
|
] as const
|
|
|
|
constructor(bot: MicrosoftRewardsBot) {
|
|
this.bot = bot
|
|
}
|
|
|
|
async createBrowser(account: Account): Promise<BrowserCreationResult> {
|
|
let browser: rebrowser.Browser
|
|
try {
|
|
const proxyConfig = account.proxy.url
|
|
? {
|
|
server: this.formatProxyServer(account.proxy),
|
|
...(account.proxy.username &&
|
|
account.proxy.password && {
|
|
username: account.proxy.username,
|
|
password: account.proxy.password
|
|
})
|
|
}
|
|
: undefined
|
|
|
|
browser = await rebrowser.chromium.launch({
|
|
headless: this.bot.config.headless,
|
|
...(proxyConfig && { proxy: proxyConfig }),
|
|
args: [...Browser.BROWSER_ARGS]
|
|
})
|
|
} catch (error) {
|
|
const errorMessage = error instanceof Error ? error.message : String(error)
|
|
this.bot.logger.error(this.bot.isMobile, 'BROWSER', `Launch failed: ${errorMessage}`)
|
|
throw error
|
|
}
|
|
|
|
try {
|
|
const sessionData = await loadSessionData(
|
|
this.bot.config.sessionPath,
|
|
account.email,
|
|
account.saveFingerprint,
|
|
this.bot.isMobile
|
|
)
|
|
|
|
const fingerprint = sessionData.fingerprint ?? (await this.generateFingerprint(this.bot.isMobile))
|
|
|
|
const context = await newInjectedContext(browser as any, { fingerprint })
|
|
|
|
await context.addInitScript(() => {
|
|
Object.defineProperty(navigator, 'credentials', {
|
|
value: {
|
|
create: () => Promise.reject(new Error('WebAuthn disabled')),
|
|
get: () => Promise.reject(new Error('WebAuthn disabled'))
|
|
}
|
|
})
|
|
})
|
|
|
|
context.setDefaultTimeout(this.bot.utils.stringToNumber(this.bot.config?.globalTimeout ?? 30000))
|
|
|
|
await context.addCookies(sessionData.cookies)
|
|
|
|
if (
|
|
(account.saveFingerprint.mobile && this.bot.isMobile) ||
|
|
(account.saveFingerprint.desktop && !this.bot.isMobile)
|
|
) {
|
|
await saveFingerprintData(this.bot.config.sessionPath, account.email, this.bot.isMobile, fingerprint)
|
|
}
|
|
|
|
this.bot.logger.info(
|
|
this.bot.isMobile,
|
|
'BROWSER',
|
|
`Created browser with User-Agent: "${fingerprint.fingerprint.navigator.userAgent}"`
|
|
)
|
|
this.bot.logger.debug(this.bot.isMobile, 'BROWSER-FINGERPRINT', JSON.stringify(fingerprint))
|
|
|
|
return { context: context as unknown as BrowserContext, fingerprint }
|
|
} catch (error) {
|
|
await browser.close().catch(() => {})
|
|
throw error
|
|
}
|
|
}
|
|
|
|
private formatProxyServer(proxy: AccountProxy): string {
|
|
try {
|
|
const urlObj = new URL(proxy.url)
|
|
const protocol = urlObj.protocol.replace(':', '')
|
|
return `${protocol}://${urlObj.hostname}:${proxy.port}`
|
|
} catch {
|
|
return `${proxy.url}:${proxy.port}`
|
|
}
|
|
}
|
|
|
|
async generateFingerprint(isMobile: boolean) {
|
|
const fingerPrintData = new FingerprintGenerator().getFingerprint({
|
|
devices: isMobile ? ['mobile'] : ['desktop'],
|
|
operatingSystems: isMobile ? ['android', 'ios'] : ['windows', 'linux'],
|
|
browsers: [{ name: 'edge' }]
|
|
})
|
|
|
|
const userAgentManager = new UserAgentManager(this.bot)
|
|
const updatedFingerPrintData = await userAgentManager.updateFingerprintUserAgent(fingerPrintData, isMobile)
|
|
|
|
return updatedFingerPrintData
|
|
}
|
|
}
|
|
|
|
export default Browser
|