Rename to hkt.sh
This commit is contained in:
254
node_modules/puppeteer-extra-plugin-stealth/evasions/chrome.runtime/index.js
generated
vendored
Normal file
254
node_modules/puppeteer-extra-plugin-stealth/evasions/chrome.runtime/index.js
generated
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
'use strict'
|
||||
|
||||
const { PuppeteerExtraPlugin } = require('puppeteer-extra-plugin')
|
||||
|
||||
const withUtils = require('../_utils/withUtils')
|
||||
|
||||
const STATIC_DATA = require('./staticData.json')
|
||||
|
||||
/**
|
||||
* Mock the `chrome.runtime` object if not available (e.g. when running headless) and on a secure site.
|
||||
*/
|
||||
class Plugin extends PuppeteerExtraPlugin {
|
||||
constructor(opts = {}) {
|
||||
super(opts)
|
||||
}
|
||||
|
||||
get name() {
|
||||
return 'stealth/evasions/chrome.runtime'
|
||||
}
|
||||
|
||||
get defaults() {
|
||||
return { runOnInsecureOrigins: false } // Override for testing
|
||||
}
|
||||
|
||||
async onPageCreated(page) {
|
||||
await withUtils(page).evaluateOnNewDocument(
|
||||
(utils, { opts, STATIC_DATA }) => {
|
||||
if (!window.chrome) {
|
||||
// Use the exact property descriptor found in headful Chrome
|
||||
// fetch it via `Object.getOwnPropertyDescriptor(window, 'chrome')`
|
||||
Object.defineProperty(window, 'chrome', {
|
||||
writable: true,
|
||||
enumerable: true,
|
||||
configurable: false, // note!
|
||||
value: {} // We'll extend that later
|
||||
})
|
||||
}
|
||||
|
||||
// That means we're running headful and don't need to mock anything
|
||||
const existsAlready = 'runtime' in window.chrome
|
||||
// `chrome.runtime` is only exposed on secure origins
|
||||
const isNotSecure = !window.location.protocol.startsWith('https')
|
||||
if (existsAlready || (isNotSecure && !opts.runOnInsecureOrigins)) {
|
||||
return // Nothing to do here
|
||||
}
|
||||
|
||||
window.chrome.runtime = {
|
||||
// There's a bunch of static data in that property which doesn't seem to change,
|
||||
// we should periodically check for updates: `JSON.stringify(window.chrome.runtime, null, 2)`
|
||||
...STATIC_DATA,
|
||||
// `chrome.runtime.id` is extension related and returns undefined in Chrome
|
||||
get id() {
|
||||
return undefined
|
||||
},
|
||||
// These two require more sophisticated mocks
|
||||
connect: null,
|
||||
sendMessage: null
|
||||
}
|
||||
|
||||
const makeCustomRuntimeErrors = (preamble, method, extensionId) => ({
|
||||
NoMatchingSignature: new TypeError(
|
||||
preamble + `No matching signature.`
|
||||
),
|
||||
MustSpecifyExtensionID: new TypeError(
|
||||
preamble +
|
||||
`${method} called from a webpage must specify an Extension ID (string) for its first argument.`
|
||||
),
|
||||
InvalidExtensionID: new TypeError(
|
||||
preamble + `Invalid extension id: '${extensionId}'`
|
||||
)
|
||||
})
|
||||
|
||||
// Valid Extension IDs are 32 characters in length and use the letter `a` to `p`:
|
||||
// https://source.chromium.org/chromium/chromium/src/+/master:components/crx_file/id_util.cc;drc=14a055ccb17e8c8d5d437fe080faba4c6f07beac;l=90
|
||||
const isValidExtensionID = str =>
|
||||
str.length === 32 && str.toLowerCase().match(/^[a-p]+$/)
|
||||
|
||||
/** Mock `chrome.runtime.sendMessage` */
|
||||
const sendMessageHandler = {
|
||||
apply: function(target, ctx, args) {
|
||||
const [extensionId, options, responseCallback] = args || []
|
||||
|
||||
// Define custom errors
|
||||
const errorPreamble = `Error in invocation of runtime.sendMessage(optional string extensionId, any message, optional object options, optional function responseCallback): `
|
||||
const Errors = makeCustomRuntimeErrors(
|
||||
errorPreamble,
|
||||
`chrome.runtime.sendMessage()`,
|
||||
extensionId
|
||||
)
|
||||
|
||||
// Check if the call signature looks ok
|
||||
const noArguments = args.length === 0
|
||||
const tooManyArguments = args.length > 4
|
||||
const incorrectOptions = options && typeof options !== 'object'
|
||||
const incorrectResponseCallback =
|
||||
responseCallback && typeof responseCallback !== 'function'
|
||||
if (
|
||||
noArguments ||
|
||||
tooManyArguments ||
|
||||
incorrectOptions ||
|
||||
incorrectResponseCallback
|
||||
) {
|
||||
throw Errors.NoMatchingSignature
|
||||
}
|
||||
|
||||
// At least 2 arguments are required before we even validate the extension ID
|
||||
if (args.length < 2) {
|
||||
throw Errors.MustSpecifyExtensionID
|
||||
}
|
||||
|
||||
// Now let's make sure we got a string as extension ID
|
||||
if (typeof extensionId !== 'string') {
|
||||
throw Errors.NoMatchingSignature
|
||||
}
|
||||
|
||||
if (!isValidExtensionID(extensionId)) {
|
||||
throw Errors.InvalidExtensionID
|
||||
}
|
||||
|
||||
return undefined // Normal behavior
|
||||
}
|
||||
}
|
||||
utils.mockWithProxy(
|
||||
window.chrome.runtime,
|
||||
'sendMessage',
|
||||
function sendMessage() {},
|
||||
sendMessageHandler
|
||||
)
|
||||
|
||||
/**
|
||||
* Mock `chrome.runtime.connect`
|
||||
*
|
||||
* @see https://developer.chrome.com/apps/runtime#method-connect
|
||||
*/
|
||||
const connectHandler = {
|
||||
apply: function(target, ctx, args) {
|
||||
const [extensionId, connectInfo] = args || []
|
||||
|
||||
// Define custom errors
|
||||
const errorPreamble = `Error in invocation of runtime.connect(optional string extensionId, optional object connectInfo): `
|
||||
const Errors = makeCustomRuntimeErrors(
|
||||
errorPreamble,
|
||||
`chrome.runtime.connect()`,
|
||||
extensionId
|
||||
)
|
||||
|
||||
// Behavior differs a bit from sendMessage:
|
||||
const noArguments = args.length === 0
|
||||
const emptyStringArgument = args.length === 1 && extensionId === ''
|
||||
if (noArguments || emptyStringArgument) {
|
||||
throw Errors.MustSpecifyExtensionID
|
||||
}
|
||||
|
||||
const tooManyArguments = args.length > 2
|
||||
const incorrectConnectInfoType =
|
||||
connectInfo && typeof connectInfo !== 'object'
|
||||
|
||||
if (tooManyArguments || incorrectConnectInfoType) {
|
||||
throw Errors.NoMatchingSignature
|
||||
}
|
||||
|
||||
const extensionIdIsString = typeof extensionId === 'string'
|
||||
if (extensionIdIsString && extensionId === '') {
|
||||
throw Errors.MustSpecifyExtensionID
|
||||
}
|
||||
if (extensionIdIsString && !isValidExtensionID(extensionId)) {
|
||||
throw Errors.InvalidExtensionID
|
||||
}
|
||||
|
||||
// There's another edge-case here: extensionId is optional so we might find a connectInfo object as first param, which we need to validate
|
||||
const validateConnectInfo = ci => {
|
||||
// More than a first param connectInfo as been provided
|
||||
if (args.length > 1) {
|
||||
throw Errors.NoMatchingSignature
|
||||
}
|
||||
// An empty connectInfo has been provided
|
||||
if (Object.keys(ci).length === 0) {
|
||||
throw Errors.MustSpecifyExtensionID
|
||||
}
|
||||
// Loop over all connectInfo props an check them
|
||||
Object.entries(ci).forEach(([k, v]) => {
|
||||
const isExpected = ['name', 'includeTlsChannelId'].includes(k)
|
||||
if (!isExpected) {
|
||||
throw new TypeError(
|
||||
errorPreamble + `Unexpected property: '${k}'.`
|
||||
)
|
||||
}
|
||||
const MismatchError = (propName, expected, found) =>
|
||||
TypeError(
|
||||
errorPreamble +
|
||||
`Error at property '${propName}': Invalid type: expected ${expected}, found ${found}.`
|
||||
)
|
||||
if (k === 'name' && typeof v !== 'string') {
|
||||
throw MismatchError(k, 'string', typeof v)
|
||||
}
|
||||
if (k === 'includeTlsChannelId' && typeof v !== 'boolean') {
|
||||
throw MismatchError(k, 'boolean', typeof v)
|
||||
}
|
||||
})
|
||||
}
|
||||
if (typeof extensionId === 'object') {
|
||||
validateConnectInfo(extensionId)
|
||||
throw Errors.MustSpecifyExtensionID
|
||||
}
|
||||
|
||||
// Unfortunately even when the connect fails Chrome will return an object with methods we need to mock as well
|
||||
return utils.patchToStringNested(makeConnectResponse())
|
||||
}
|
||||
}
|
||||
utils.mockWithProxy(
|
||||
window.chrome.runtime,
|
||||
'connect',
|
||||
function connect() {},
|
||||
connectHandler
|
||||
)
|
||||
|
||||
function makeConnectResponse() {
|
||||
const onSomething = () => ({
|
||||
addListener: function addListener() {},
|
||||
dispatch: function dispatch() {},
|
||||
hasListener: function hasListener() {},
|
||||
hasListeners: function hasListeners() {
|
||||
return false
|
||||
},
|
||||
removeListener: function removeListener() {}
|
||||
})
|
||||
|
||||
const response = {
|
||||
name: '',
|
||||
sender: undefined,
|
||||
disconnect: function disconnect() {},
|
||||
onDisconnect: onSomething(),
|
||||
onMessage: onSomething(),
|
||||
postMessage: function postMessage() {
|
||||
if (!arguments.length) {
|
||||
throw new TypeError(`Insufficient number of arguments.`)
|
||||
}
|
||||
throw new Error(`Attempting to use a disconnected port object`)
|
||||
}
|
||||
}
|
||||
return response
|
||||
}
|
||||
},
|
||||
{
|
||||
opts: this.opts,
|
||||
STATIC_DATA
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function(pluginConfig) {
|
||||
return new Plugin(pluginConfig)
|
||||
}
|
||||
286
node_modules/puppeteer-extra-plugin-stealth/evasions/chrome.runtime/index.test.js
generated
vendored
Normal file
286
node_modules/puppeteer-extra-plugin-stealth/evasions/chrome.runtime/index.test.js
generated
vendored
Normal file
@@ -0,0 +1,286 @@
|
||||
const test = require('ava')
|
||||
|
||||
const {
|
||||
getVanillaFingerPrint,
|
||||
getStealthFingerPrint
|
||||
} = require('../../test/util')
|
||||
|
||||
const { vanillaPuppeteer, addExtra } = require('../../test/util')
|
||||
|
||||
const Plugin = require('.')
|
||||
|
||||
const STATIC_DATA = require('./staticData.json')
|
||||
|
||||
/* global chrome */
|
||||
|
||||
test('vanilla: is chrome false', async t => {
|
||||
const pageFn = async page => await page.evaluate(() => window.chrome) // eslint-disable-line
|
||||
const { pageFnResult: chrome, hasChrome } = await getVanillaFingerPrint(
|
||||
pageFn
|
||||
)
|
||||
t.is(hasChrome, false)
|
||||
t.false(chrome instanceof Object)
|
||||
t.is(chrome, undefined)
|
||||
})
|
||||
|
||||
test('stealth: is chrome true', async t => {
|
||||
const pageFn = async page => await page.evaluate(() => window.chrome) // eslint-disable-line
|
||||
const { pageFnResult: chrome, hasChrome } = await getStealthFingerPrint(
|
||||
Plugin,
|
||||
pageFn
|
||||
)
|
||||
t.is(hasChrome, true)
|
||||
t.true(chrome instanceof Object)
|
||||
})
|
||||
|
||||
test('stealth: will add convincing chrome.runtime object', async t => {
|
||||
const puppeteer = addExtra(vanillaPuppeteer).use(
|
||||
Plugin({
|
||||
runOnInsecureOrigins: true // for testing
|
||||
})
|
||||
)
|
||||
const browser = await puppeteer.launch({ headless: true })
|
||||
const page = await browser.newPage()
|
||||
//
|
||||
|
||||
const results = await page.evaluate(() => {
|
||||
const catchErr = (fn, ...args) => {
|
||||
try {
|
||||
return fn.apply(this, args)
|
||||
} catch (err) {
|
||||
return err.toString()
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
runtime: {
|
||||
exists: window.chrome && 'runtime' in window.chrome,
|
||||
toString: chrome.runtime.toString()
|
||||
},
|
||||
staticData: {
|
||||
OnInstalledReason: chrome.runtime.OnInstalledReason,
|
||||
OnRestartRequiredReason: chrome.runtime.OnRestartRequiredReason,
|
||||
PlatformArch: chrome.runtime.PlatformArch,
|
||||
PlatformNaclArch: chrome.runtime.PlatformNaclArch,
|
||||
PlatformOs: chrome.runtime.PlatformOs,
|
||||
RequestUpdateCheckStatus: chrome.runtime.RequestUpdateCheckStatus
|
||||
},
|
||||
id: {
|
||||
exists: 'id' in chrome.runtime,
|
||||
undefined: chrome.runtime.id === undefined
|
||||
},
|
||||
sendMessage: {
|
||||
exists: 'sendMessage' in chrome.runtime,
|
||||
name: chrome.runtime.sendMessage.name,
|
||||
toString1: chrome.runtime.sendMessage + '',
|
||||
toString2: chrome.runtime.sendMessage.toString(),
|
||||
validIdWorks:
|
||||
chrome.runtime.sendMessage('nckgahadagoaajjgafhacjanaoiihapd', '') ===
|
||||
undefined
|
||||
},
|
||||
sendMessageErrors: {
|
||||
noArg: catchErr(chrome.runtime.sendMessage),
|
||||
singleArg: catchErr(chrome.runtime.sendMessage, ''),
|
||||
tooManyArg: catchErr(
|
||||
chrome.runtime.sendMessage,
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
''
|
||||
),
|
||||
incorrectArg: catchErr(chrome.runtime.sendMessage, '', '', {}, ''),
|
||||
noValidID: catchErr(chrome.runtime.sendMessage, 'foo', '')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const bla = `TypeError: Error in invocation of runtime.sendMessage(optional string extensionId, any message, optional object options, optional function responseCallback)`
|
||||
t.deepEqual(results, {
|
||||
runtime: {
|
||||
exists: true,
|
||||
toString: '[object Object]'
|
||||
},
|
||||
staticData: STATIC_DATA,
|
||||
id: {
|
||||
exists: true,
|
||||
undefined: true
|
||||
},
|
||||
sendMessage: {
|
||||
exists: true,
|
||||
name: 'sendMessage',
|
||||
toString1: 'function sendMessage() { [native code] }',
|
||||
toString2: 'function sendMessage() { [native code] }',
|
||||
validIdWorks: true
|
||||
},
|
||||
sendMessageErrors: {
|
||||
noArg: `${bla}: No matching signature.`,
|
||||
singleArg: `${bla}: chrome.runtime.sendMessage() called from a webpage must specify an Extension ID (string) for its first argument.`,
|
||||
tooManyArg: `${bla}: No matching signature.`,
|
||||
incorrectArg: `${bla}: No matching signature.`,
|
||||
noValidID: `${bla}: Invalid extension id: 'foo'`
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('stealth: will add convincing chrome.runtime.connect', async t => {
|
||||
const puppeteer = addExtra(vanillaPuppeteer).use(
|
||||
Plugin({
|
||||
runOnInsecureOrigins: true // for testing
|
||||
})
|
||||
)
|
||||
const browser = await puppeteer.launch({ headless: true })
|
||||
const page = await browser.newPage()
|
||||
|
||||
const results = await page.evaluate(() => {
|
||||
const catchErr = (fn, ...args) => {
|
||||
try {
|
||||
return fn.apply(this, args)
|
||||
} catch (err) {
|
||||
return err.toString()
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
connect: {
|
||||
exists: 'connect' in chrome.runtime,
|
||||
name: chrome.runtime.connect.name,
|
||||
toString1: chrome.runtime.connect + '',
|
||||
toString2: chrome.runtime.connect.toString(),
|
||||
validIdWorks:
|
||||
chrome.runtime.connect('nckgahadagoaajjgafhacjanaoiihapd') !==
|
||||
undefined
|
||||
},
|
||||
connectErrors: {
|
||||
noArg: catchErr(chrome.runtime.connect),
|
||||
singleArg: catchErr(chrome.runtime.connect, ''),
|
||||
tooManyArg: catchErr(chrome.runtime.connect, '', '', '', '', '', ''),
|
||||
incorrectArg: catchErr(chrome.runtime.connect, '', '', {}, ''),
|
||||
noValidID: catchErr(chrome.runtime.connect, 'foo', ''),
|
||||
connectInfoFirst: {
|
||||
emptyObject: catchErr(chrome.runtime.connect, {}),
|
||||
tooManyArg: catchErr(chrome.runtime.connect, {}, {}),
|
||||
unexpectedProp: catchErr(chrome.runtime.connect, { wtf: true }),
|
||||
invalidName: catchErr(chrome.runtime.connect, { name: 666 }),
|
||||
invalidTLS: catchErr(chrome.runtime.connect, {
|
||||
includeTlsChannelId: 777
|
||||
}),
|
||||
invalidBoth: catchErr(chrome.runtime.connect, {
|
||||
name: 666,
|
||||
includeTlsChannelId: 777
|
||||
}),
|
||||
validName: catchErr(chrome.runtime.connect, { name: 'foo' }),
|
||||
missingExtensionId: catchErr(chrome.runtime.connect, {
|
||||
name: 'bob',
|
||||
includeTlsChannelId: false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const bla = `TypeError: Error in invocation of runtime.connect(optional string extensionId, optional object connectInfo)`
|
||||
t.deepEqual(results, {
|
||||
connect: {
|
||||
exists: true,
|
||||
name: 'connect',
|
||||
toString1: 'function connect() { [native code] }',
|
||||
toString2: 'function connect() { [native code] }',
|
||||
validIdWorks: true
|
||||
},
|
||||
connectErrors: {
|
||||
noArg: `${bla}: chrome.runtime.connect() called from a webpage must specify an Extension ID (string) for its first argument.`,
|
||||
singleArg: `${bla}: chrome.runtime.connect() called from a webpage must specify an Extension ID (string) for its first argument.`,
|
||||
tooManyArg: `${bla}: No matching signature.`,
|
||||
incorrectArg: `${bla}: No matching signature.`,
|
||||
noValidID: `${bla}: Invalid extension id: 'foo'`,
|
||||
connectInfoFirst: {
|
||||
emptyObject: `${bla}: chrome.runtime.connect() called from a webpage must specify an Extension ID (string) for its first argument.`,
|
||||
tooManyArg: `${bla}: No matching signature.`,
|
||||
unexpectedProp: `${bla}: Unexpected property: 'wtf'.`,
|
||||
invalidName: `${bla}: Error at property 'name': Invalid type: expected string, found number.`,
|
||||
invalidTLS: `${bla}: Error at property 'includeTlsChannelId': Invalid type: expected boolean, found number.`,
|
||||
invalidBoth: `${bla}: Error at property 'name': Invalid type: expected string, found number.`,
|
||||
validName: `${bla}: chrome.runtime.connect() called from a webpage must specify an Extension ID (string) for its first argument.`,
|
||||
missingExtensionId: `${bla}: chrome.runtime.connect() called from a webpage must specify an Extension ID (string) for its first argument.`
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('stealth: will add convincing chrome.runtime.connect response', async t => {
|
||||
const puppeteer = addExtra(vanillaPuppeteer).use(
|
||||
Plugin({
|
||||
runOnInsecureOrigins: true // for testing
|
||||
})
|
||||
)
|
||||
const browser = await puppeteer.launch({ headless: true })
|
||||
const page = await browser.newPage()
|
||||
|
||||
const results = await page.evaluate(() => {
|
||||
const connectResponse = chrome.runtime.connect(
|
||||
'nckgahadagoaajjgafhacjanaoiihapd'
|
||||
)
|
||||
|
||||
return {
|
||||
connectResponse: {
|
||||
exists: !!connectResponse,
|
||||
toString1: connectResponse + '',
|
||||
toString2: connectResponse.toString(),
|
||||
nestedToString: connectResponse.onDisconnect.addListener + ''
|
||||
},
|
||||
disconnect: {
|
||||
toString: connectResponse.disconnect + '',
|
||||
noReturn: connectResponse.disconnect() === undefined
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
t.deepEqual(results, {
|
||||
connectResponse: {
|
||||
exists: true,
|
||||
toString1: '[object Object]',
|
||||
toString2: '[object Object]',
|
||||
nestedToString: `function addListener() { [native code] }`
|
||||
},
|
||||
disconnect: {
|
||||
toString: `function disconnect() { [native code] }`,
|
||||
noReturn: true
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// FIXME: This changed in more recent chrome versions
|
||||
// test('stealth: error stack is fine', async t => {
|
||||
// const puppeteer = addExtra(vanillaPuppeteer).use(
|
||||
// Plugin({
|
||||
// runOnInsecureOrigins: true // for testing
|
||||
// })
|
||||
// )
|
||||
// const browser = await puppeteer.launch({ headless: true })
|
||||
// const page = await browser.newPage()
|
||||
|
||||
// const result = await page.evaluate(() => {
|
||||
// const catchErr = (fn, ...args) => {
|
||||
// try {
|
||||
// return fn.apply(this, args)
|
||||
// } catch ({ name, message, stack }) {
|
||||
// return {
|
||||
// name,
|
||||
// message,
|
||||
// stack
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return catchErr(chrome.runtime.connect, '').stack
|
||||
// })
|
||||
|
||||
// /**
|
||||
// * OK:
|
||||
// TypeError: Error in invocation of runtime.connect(optional string extensionId, optional object connectInfo): chrome.runtime.connect() called from a webpage must specify an Extension ID (string) for its first argument.␊
|
||||
// - at catchErr (__puppeteer_evaluation_script__:4:19)␊
|
||||
// - at __puppeteer_evaluation_script__:18:12
|
||||
// */
|
||||
// t.is(result.split('\n').length, 3)
|
||||
// })
|
||||
4
node_modules/puppeteer-extra-plugin-stealth/evasions/chrome.runtime/package.json
generated
vendored
Normal file
4
node_modules/puppeteer-extra-plugin-stealth/evasions/chrome.runtime/package.json
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"private": true,
|
||||
"main": "index.js"
|
||||
}
|
||||
33
node_modules/puppeteer-extra-plugin-stealth/evasions/chrome.runtime/readme.md
generated
vendored
Normal file
33
node_modules/puppeteer-extra-plugin-stealth/evasions/chrome.runtime/readme.md
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
## API
|
||||
|
||||
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
|
||||
|
||||
#### Table of Contents
|
||||
|
||||
- [class: Plugin](#class-plugin)
|
||||
- [sendMessageHandler()](#sendmessagehandler)
|
||||
- [connectHandler()](#connecthandler)
|
||||
|
||||
### class: [Plugin](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/chrome.runtime/index.js#L13-L251)
|
||||
|
||||
- `opts` (optional, default `{}`)
|
||||
|
||||
**Extends: PuppeteerExtraPlugin**
|
||||
|
||||
Mock the `chrome.runtime` object if not available (e.g. when running headless) and on a secure site.
|
||||
|
||||
---
|
||||
|
||||
### [sendMessageHandler()](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/chrome.runtime/index.js#L80-L123)
|
||||
|
||||
Mock `chrome.runtime.sendMessage`
|
||||
|
||||
---
|
||||
|
||||
### [connectHandler()](https://github.com/berstend/puppeteer-extra/blob/e6133619b051febed630ada35241664eba59b9fa/packages/puppeteer-extra-plugin-stealth/evasions/chrome.runtime/index.js#L136-L210)
|
||||
|
||||
Mock `chrome.runtime.connect`
|
||||
|
||||
- **See: <https://developer.chrome.com/apps/runtime#method-connect>**
|
||||
|
||||
---
|
||||
41
node_modules/puppeteer-extra-plugin-stealth/evasions/chrome.runtime/staticData.json
generated
vendored
Normal file
41
node_modules/puppeteer-extra-plugin-stealth/evasions/chrome.runtime/staticData.json
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"OnInstalledReason": {
|
||||
"CHROME_UPDATE": "chrome_update",
|
||||
"INSTALL": "install",
|
||||
"SHARED_MODULE_UPDATE": "shared_module_update",
|
||||
"UPDATE": "update"
|
||||
},
|
||||
"OnRestartRequiredReason": {
|
||||
"APP_UPDATE": "app_update",
|
||||
"OS_UPDATE": "os_update",
|
||||
"PERIODIC": "periodic"
|
||||
},
|
||||
"PlatformArch": {
|
||||
"ARM": "arm",
|
||||
"ARM64": "arm64",
|
||||
"MIPS": "mips",
|
||||
"MIPS64": "mips64",
|
||||
"X86_32": "x86-32",
|
||||
"X86_64": "x86-64"
|
||||
},
|
||||
"PlatformNaclArch": {
|
||||
"ARM": "arm",
|
||||
"MIPS": "mips",
|
||||
"MIPS64": "mips64",
|
||||
"X86_32": "x86-32",
|
||||
"X86_64": "x86-64"
|
||||
},
|
||||
"PlatformOs": {
|
||||
"ANDROID": "android",
|
||||
"CROS": "cros",
|
||||
"LINUX": "linux",
|
||||
"MAC": "mac",
|
||||
"OPENBSD": "openbsd",
|
||||
"WIN": "win"
|
||||
},
|
||||
"RequestUpdateCheckStatus": {
|
||||
"NO_UPDATE": "no_update",
|
||||
"THROTTLED": "throttled",
|
||||
"UPDATE_AVAILABLE": "update_available"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user