Skip to content

Commit

Permalink
fix: touch screen devices forged user operation
Browse files Browse the repository at this point in the history
  • Loading branch information
kkoooqq committed Nov 9, 2021
1 parent b3dd647 commit db871a3
Show file tree
Hide file tree
Showing 6 changed files with 348 additions and 119 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fakebrowser",
"version": "0.0.52",
"version": "0.0.53",
"description": "🤖 Fake fingerprints to bypass anti-bot systems. Simulate mouse and keyboard operations to make behavior like a real person.",
"repository": {
"type": "git",
Expand Down
10 changes: 8 additions & 2 deletions src/core/DeviceDescriptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ export interface DeviceDescriptor {
"state"?: string,
"exType"?: string,
"msg"?: string,
}>
}>,
}

export type ChromeUACHHeaders = {
Expand Down Expand Up @@ -261,7 +261,7 @@ export default class DeviceDescriptorHelper {
* Check device descriptor legal based on attributes
* @param e
*/
static checkLegal(e: DeviceDescriptor) {
static checkLegal(e: DeviceDescriptor): boolean {
if (!e) {
throw new Error('DeviceDescriptor empty')
}
Expand Down Expand Up @@ -291,6 +291,10 @@ export default class DeviceDescriptorHelper {
if (e.navigator.maxTouchPoints != 0) {
throw new Error('Desktop browsers cannot have touchscreens')
}
} else {
if (e.navigator.maxTouchPoints === 0) {
throw new Error('Mobile devices must have touch screen')
}
}

if (e.window.innerHeight > e.screen.availHeight
Expand Down Expand Up @@ -344,6 +348,8 @@ export default class DeviceDescriptorHelper {
if (!e.permissions || Object.keys(e.permissions).length === 0) {
throw new Error('permissions cannot be empty')
}

return true
}

/**
Expand Down
107 changes: 55 additions & 52 deletions src/core/FakeBrowser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {UserAgentHelper} from "./UserAgentHelper";
import {FakeUserAction} from "./FakeUserAction";
import {BrowserLauncher} from "./BrowserLauncher";
import {BrowserBuilder} from "./BrowserBuilder";
import {Touchscreen} from "./TouchScreen";

export const kDefaultWindowsDD = require(path.resolve(__dirname, '../../device-hub/Windows.json'))

Expand Down Expand Up @@ -139,51 +140,30 @@ export class FakeBrowser {
defaultLaunchArgs: kDefaultLaunchArgs,
}

private readonly _driverParams: DriverParameters
private readonly _vanillaBrowser: Browser
private readonly _pptrExtra: PuppeteerExtra
private readonly _bindingTime: number
private readonly _uuid: string
private readonly _userAction: FakeUserAction
readonly driverParams: DriverParameters
readonly vanillaBrowser: Browser
readonly pptrExtra: PuppeteerExtra
/**
* Browser instance launch time or connection time
*/
readonly bindingTime: number
readonly uuid: string
readonly isMobileBrowser: boolean
readonly userAction: FakeUserAction

// friend to FakeUserAction
private _zombie: boolean

// private readonly _workerUrls: string[]

get driverParams(): DriverParameters {
return this._driverParams
}

get launchParams(): LaunchParameters {
assert((this._driverParams as LaunchParameters).launchOptions)
return this._driverParams as LaunchParameters
assert((this.driverParams as LaunchParameters).launchOptions)
return this.driverParams as LaunchParameters
}

get connectParams(): ConnectParameters {
assert((this._driverParams as ConnectParameters).connectOptions)
return this._driverParams as ConnectParameters
}

get vanillaBrowser(): Browser {
return this._vanillaBrowser
}

get pptrExtra(): PuppeteerExtra {
return this._pptrExtra
}

/**
* Browser instance launch time or connection time
*/
get bindingTime(): number {
return this._bindingTime
}

get uuid(): string {
return this._uuid
}

get userAction(): FakeUserAction {
return this._userAction
assert((this.driverParams as ConnectParameters).connectOptions)
return this.driverParams as ConnectParameters
}

private async beforeShutdown() {
Expand All @@ -201,7 +181,7 @@ export class FakeBrowser {
}

async getActivePage(): Promise<Page | null> {
const result = await PptrToolkit.getActivePage(this._vanillaBrowser)
const result = await PptrToolkit.getActivePage(this.vanillaBrowser)
return result
}

Expand All @@ -212,16 +192,24 @@ export class FakeBrowser {
bindingTime: number,
uuid: string,
) {
this._driverParams = params
this._vanillaBrowser = vanillaBrowser
this._pptrExtra = pptrExtra
this._bindingTime = bindingTime
this._uuid = uuid
this.driverParams = params
this.vanillaBrowser = vanillaBrowser
this.pptrExtra = pptrExtra
this.bindingTime = bindingTime

assert(
params.deviceDesc
&& params.deviceDesc.navigator
&& params.deviceDesc.navigator.userAgent
)

this.isMobileBrowser = UserAgentHelper.isMobile(params.deviceDesc.navigator.userAgent)
this.uuid = uuid
this.userAction = new FakeUserAction(this)

this._zombie = false
// this._workerUrls = []

this._userAction = new FakeUserAction(this)

vanillaBrowser.on('targetcreated', this.onTargetCreated.bind(this))
vanillaBrowser.on('disconnected', this.onDisconnected.bind(this))
}
Expand Down Expand Up @@ -272,26 +260,41 @@ export class FakeBrowser {
// console.log('inject page')
let cdpSession: CDPSession | null = null

const fakeDD = this._driverParams.fakeDeviceDesc
const fakeDD = this.driverParams.fakeDeviceDesc
assert(fakeDD)

// if there is an account password that proxy needs to log in
if (
this._driverParams.proxy &&
this._driverParams.proxy.username &&
this._driverParams.proxy.password
this.driverParams.proxy &&
this.driverParams.proxy.username &&
this.driverParams.proxy.password
) {
await page.authenticate({
username: this._driverParams.proxy.username,
password: this._driverParams.proxy.password,
username: this.driverParams.proxy.username,
password: this.driverParams.proxy.password,
});
}

// cdp
try {
await page['_client'].send('ServiceWorker.setForceUpdateOnPageLoad', {forceUpdateOnPageLoad: true})
} catch (ex: any) {
console.warn('ServiceWorker.setForceUpdateOnPageLoad exception', ex)
console.warn('CDP ServiceWorker.setForceUpdateOnPageLoad exception', ex)
}

// touch
if (this.isMobileBrowser) {
try {
await page['_client'].send('Emulation.setEmitTouchEventsForMouse', {
enabled: true,
})
} catch (ex: any) {
console.warn('CDP Emulation.setEmitTouchEventsForMouse exception', ex)
}

Object.defineProperty(page, '_patchTouchscreen', {
value: new Touchscreen(page['_client'], page.keyboard)
})
}

// intercept worker
Expand Down
Loading

0 comments on commit db871a3

Please sign in to comment.