From d632e7046db985aed26763f253eb2ca190b60186 Mon Sep 17 00:00:00 2001 From: Rishat Valitov Date: Mon, 20 Feb 2023 16:46:58 +0800 Subject: [PATCH 01/18] Add a check for undefined to plugins length signal (#114) * Update README.md Make changes that align more with recent documentation updates * bump version to 1.3.1 * Bump json5 from 2.2.1 to 2.2.3 --- README.md | 2 -- package.json | 2 +- src/sources/plugins_length.ts | 3 +++ yarn.lock | 12 ++++++------ 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 31f15738..46af418c 100644 --- a/README.md +++ b/README.md @@ -76,8 +76,6 @@ botdPromise ## 🤖 Upgrade to Fingerprint Pro Bot Detection to detect sophisticated bots with confidence. -**Free for developers (up to 20K API calls / mo), unlimited free trials available, no credit card needed.** - [Fingerprint Pro Bot Detection](https://fingerprint.com/products/bot-detection/) is a professional bot detection service that processes all information server-side and transmits it securely to your servers using server-to-server APIs. Fingerprint Pro Bot Detection provides both browser and server-side APIs that make the process of bot detection fast and secure. When using the Pro Bot Detection, use the browser JavaScript SDK to obtain the requestID value and then verify this value using our server API. diff --git a/package.json b/package.json index 65307793..77d43049 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@fingerprintjs/botd", - "version": "1.3.0", + "version": "1.3.1", "description": "botd is a browser library for JavaScript bot detection", "keywords": [ "bot", diff --git a/src/sources/plugins_length.ts b/src/sources/plugins_length.ts index 3fcd32b3..10f0dcdd 100644 --- a/src/sources/plugins_length.ts +++ b/src/sources/plugins_length.ts @@ -4,5 +4,8 @@ export default function getPluginsLength(): number { if (navigator.plugins === undefined) { throw new BotdError(State.Undefined, 'navigator.plugins is undefined') } + if (navigator.plugins.length === undefined) { + throw new BotdError(State.UnexpectedBehaviour, 'navigator.plugins.length is undefined') + } return navigator.plugins.length } diff --git a/yarn.lock b/yarn.lock index 810e3c81..3f07245e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3250,9 +3250,9 @@ json-stringify-safe@^5.0.1: integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== json5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== jsonfile@^4.0.0: version "4.0.0" @@ -5032,9 +5032,9 @@ typescript@^4.8.2: integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== ua-parser-js@^0.7.30: - version "0.7.31" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" - integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== + version "0.7.33" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.33.tgz#1d04acb4ccef9293df6f70f2c3d22f3030d8b532" + integrity sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw== unbox-primitive@^1.0.2: version "1.0.2" From 9f8d3075319246860712e9210a38b77e99e8718b Mon Sep 17 00:00:00 2001 From: xnerhu Date: Thu, 23 Feb 2023 09:05:52 +0100 Subject: [PATCH 02/18] bump version to 1.3.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 77d43049..e8fe3b09 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@fingerprintjs/botd", - "version": "1.3.1", + "version": "1.3.2", "description": "botd is a browser library for JavaScript bot detection", "keywords": [ "bot", From 11ca471580037a75e7196c8e0bca25ec0ac8ed29 Mon Sep 17 00:00:00 2001 From: Rishat Valitov Date: Thu, 23 Mar 2023 18:07:27 +0300 Subject: [PATCH 03/18] Update window and document properties check (#118) * migrate configs to .ts * finish updates * lint * Update plugin length signal and bump version (#116) * Add a check for undefined to plugins length signal (#114) * bump version to 1.3.2 --------- Co-authored-by: xnerhu * fix ts-loader parsing * add tests to PR workflow * Revert "add tests to PR workflow" This reverts commit 08647d6d426a8a466221fb876fc4a9d33f9ba8bd. * update broyster to 0.1.2 * pr comments * lint * ci: disable browserstack release test temporarily * restore release workflow * pr comments * add workflow * remove unused terser * remove terser completely * Bump webpack from 5.74.0 to 5.76.0 (#117) Bumps [webpack](https://github.com/webpack/webpack) from 5.74.0 to 5.76.0. - [Release notes](https://github.com/webpack/webpack/releases) - [Commits](https://github.com/webpack/webpack/compare/v5.74.0...v5.76.0) --- updated-dependencies: - dependency-name: webpack dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Replace document and window properties signals with new one * Rename signal --------- Signed-off-by: dependabot[bot] Co-authored-by: fpkamp <117085311+fpkamp@users.noreply.github.com> Co-authored-by: xnerhu Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 6 + karma.conf.js | 143 -------- karma.conf.ts | 158 ++++++++ package.json | 37 +- playground/webpack.config.ts | 2 +- rollup.config.js | 57 --- ...up.config.test.js => rollup.config.test.ts | 0 rollup.config.ts | 66 ++++ src/detectors/distinctive_properties.ts | 8 + src/detectors/document_properties.ts | 36 -- src/detectors/index.ts | 6 +- src/detectors/window_properties.ts | 19 - src/sources/distinctive_properties.ts | 95 +++++ src/sources/document_properties.ts | 9 - src/sources/index.ts | 6 +- src/sources/window_properties.ts | 5 - src/types.ts | 24 +- src/utils/ponyfills.ts | 2 +- tests/integration.test.ts | 2 + tsconfig.json | 11 +- tsconfig.rollupConfig.json | 9 + yarn.lock | 342 +++++++++--------- 22 files changed, 561 insertions(+), 482 deletions(-) delete mode 100644 karma.conf.js create mode 100644 karma.conf.ts delete mode 100644 rollup.config.js rename rollup.config.test.js => rollup.config.test.ts (100%) create mode 100644 rollup.config.ts create mode 100644 src/detectors/distinctive_properties.ts delete mode 100644 src/detectors/document_properties.ts delete mode 100644 src/detectors/window_properties.ts create mode 100644 src/sources/distinctive_properties.ts delete mode 100644 src/sources/document_properties.ts delete mode 100644 src/sources/window_properties.ts create mode 100644 tsconfig.rollupConfig.json diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a3b45be1..501be6d4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -62,3 +62,9 @@ jobs: - name: Build test bundle run: yarn build:test + + - name: Test on BrowserStack + env: + BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} + BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} + run: yarn test:browserstack \ No newline at end of file diff --git a/karma.conf.js b/karma.conf.js deleted file mode 100644 index e0cff239..00000000 --- a/karma.conf.js +++ /dev/null @@ -1,143 +0,0 @@ -// The shapes of these objects are taken from: -// https://github.com/SeleniumHQ/selenium/tree/d8ddb4d83972df0f565ef65264bcb733e7a94584/javascript/node/selenium-webdriver -// It doesn't work, trying to work it out with BrowserStack support. Todo: solve it with the support. -// eslint-disable-next-line no-unused-vars -const chromeIncognitoCapabilities = { - 'goog:chromeOptions': { - args: ['--incognito'], - }, -} -// eslint-disable-next-line no-unused-vars -const firefoxIncognitoCapabilities = { - 'moz:firefoxOptions': { - prefs: { - 'browser.privatebrowsing.autostart': true, - }, - }, -} - -/* - * You can find values for any supported browsers in the interactive form at - * https://www.browserstack.com/docs/automate/javascript-testing/configure-test-run-options - * The keys are arbitrary values. - * - * Only Chrome is supported on Android, only Safari is supported on iOS: https://www.browserstack.com/question/659 - */ -/* eslint-disable max-len */ -// prettier-ignore -const browserstackBrowsers = { - IE11: { os: 'Windows', os_version: '7', browser: 'IE', browser_version: '11.0' }, - Windows11_EdgeLatest: { os: 'Windows', os_version: '11', browser: 'Edge', browser_version: 'latest-beta' }, - Windows10_Chrome49: { os: 'Windows', os_version: '10', browser: 'Chrome', browser_version: '49.0' }, - // Windows10_Chrome49_Incognito: { os: 'Windows', os_version: '10', browser: 'Chrome', browser_version: '49.0', ...chromeIncognitoCapabilities }, - Windows11_ChromeLatest: { os: 'Windows', os_version: '11', browser: 'Chrome', browser_version: 'latest-beta' }, - // Windows11_ChromeLatest_Incognito: { os: 'Windows', os_version: '11', browser: 'Chrome', browser_version: 'latest-beta, ...chromeIncognitoCapabilities }, - Windows10_Firefox52: { os: 'Windows', os_version: '10', browser: 'Firefox', browser_version: '52.0' }, - // Windows10_Firefox52_Incognito: { os: 'Windows', os_version: '10', browser: 'Firefox', browser_version: '52.0', ...firefoxIncognitoCapabilities }, - Windows11_FirefoxLatest: { os: 'Windows', os_version: '11', browser: 'Firefox', browser_version: 'latest-beta' }, - // Windows11_FirefoxLatest_Incognito: { os: 'Windows', os_version: '11', browser: 'Firefox', browser_version: 'latest-beta, ...firefoxIncognitoCapabilities }, - OSXMojave_Safari12: { os: 'OS X', os_version: 'Mojave', browser: 'Safari', browser_version: '12.1' }, - OSXMonterey_Safari15: { os: 'OS X', os_version: 'Monterey', browser: 'Safari', browser_version: '15.0' }, - OSXMonterey_ChromeLatest: { os: 'OS X', os_version: 'Monterey', browser: 'Chrome', browser_version: 'latest-beta' }, - // OSXMonterey_ChromeLatest_Incognito: { os: 'OS X', os_version: 'Monterey', browser: 'Chrome', browser_version: 'latest-beta, ...chromeIncognitoCapabilities }, - OSXMonterey_FirefoxLatest: { os: 'OS X', os_version: 'Monterey', browser: 'Firefox', browser_version: 'latest-beta' }, - // OSXMonterey_FirefoxLatest_Incognito: { os: 'OS X', os_version: 'Monterey', browser: 'Firefox', browser_version: 'latest-beta, ...firefoxIncognitoCapabilities }, - OSXMonterey_EdgeLatest: { os: 'OS X', os_version: 'Monterey', browser: 'Edge', browser_version: 'latest-beta' }, - Android11_ChromeLatest: { device: 'Google Pixel 4', os: 'Android', os_version: '11.0', browser: 'Chrome', browser_version: 'latest-beta' }, - iOS10_Safari: { device: 'iPhone 7', os: 'iOS', os_version: '10', browser: 'Safari' }, - iOS11_Safari: { device: 'iPhone 8 Plus', os: 'iOS', os_version: '11', browser: 'Safari' }, - iOS12_Safari: { device: 'iPhone XS', os: 'iOS', os_version: '12', browser: 'Safari' }, - iOS13_Safari: { device: 'iPhone 11 Pro', os: 'iOS', os_version: '13', browser: 'Safari' }, - iOS14_Safari: { device: 'iPhone 11', os: 'iOS', os_version: '14', browser: 'Safari' }, - // iOS15_Safari: { device: 'iPhone 11 Pro', os: 'iOS', os_version: '15', browser: 'Safari' } -} -/* eslint-enable max-len */ - -function makeBuildNumber() { - return `No CI ${Math.floor(Math.random() * 1e10)}` -} - -function setupLocal(config) { - config.set({ - frameworks: ['jasmine', 'karma-typescript'], - files: [ - // The polyfills are required for old supported browsers. - // They should be removed when the old browser support is dropped. - 'node_modules/promise-polyfill/dist/polyfill.js', - - 'src/**/*.ts', - 'tests/**/*.ts', - 'test-dist/botd.min.js', - ], - preprocessors: { - '**/*.ts': 'karma-typescript', - }, - reporters: ['spec', 'summary'], - browsers: ['ChromeHeadless', 'FirefoxHeadless'], - concurrency: 3, - - karmaTypescriptConfig: { - compilerOptions: { - ...require('./tsconfig.json').compilerOptions, - module: 'commonjs', - sourceMap: true, - }, - }, - - specReporter: { - suppressSummary: true, - suppressErrorSummary: true, - suppressPassed: true, - suppressSkipped: true, - }, - - summaryReporter: { - show: 'skipped', // To know that some tests are skipped exactly where they are supposed to be skipped - }, - }) -} - -function setupBrowserstack(config) { - setupLocal(config) - - const customLaunchers = {} - for (const [key, data] of Object.entries(browserstackBrowsers)) { - customLaunchers[key] = { - base: 'BrowserStack', - name: key.replace(/_/g, ' '), - ...data, - } - } - - config.set({ - reporters: [...config.reporters, 'BrowserStack'], - browsers: Object.keys(customLaunchers), - customLaunchers, - concurrency: 5, - failOnEmptyTestSuite: false, - - browserStack: { - project: 'BotD', - // A build number is required to group testing sessions in the BrowserStack UI. - // GitHub Actions will add a value for GITHUB_RUN_ID. More on the environment variables: - // https://docs.github.com/en/free-pro-team@latest/actions/reference/environment-variables#default-environment-variables - build: process.env.GITHUB_RUN_ID || makeBuildNumber(), - // The timeout is reduced for testing sessions to not hold the BrowserStack queue long in case of problems. - timeout: 120, - }, - }) -} - -/** - * Add `--preset local` or `--preset browserstack` to the Karma command to choose where to run the tests. - */ -module.exports = (config) => { - switch (config.preset) { - case 'local': - return setupLocal(config) - case 'browserstack': - return setupBrowserstack(config) - default: - throw new Error('No --preset option is set or an unknown value is set') - } -} diff --git a/karma.conf.ts b/karma.conf.ts new file mode 100644 index 00000000..8a075faa --- /dev/null +++ b/karma.conf.ts @@ -0,0 +1,158 @@ +import { Config, CustomLauncher } from 'karma' +import { KarmaTypescriptConfig } from 'karma-typescript/dist/api/configuration' +import { karmaPlugin, setHttpsAndServerForKarma } from '@fpjs-incubator/broyster/node' + +declare module 'karma' { + interface ConfigOptions { + karmaTypescriptConfig?: KarmaTypescriptConfig | undefined + } + + interface Config { + preset?: string + reporters: ConfigOptions['reporters'] + } +} + +// The shapes of these objects are taken from: +// https://github.com/SeleniumHQ/selenium/tree/d8ddb4d83972df0f565ef65264bcb733e7a94584/javascript/node/selenium-webdriver +// It doesn't work, trying to work it out with BrowserStack support. Todo: solve it with the support. +/* +const chromeIncognitoCapabilities = { + 'goog:chromeOptions': { + args: ['--incognito'], + }, +} +const firefoxIncognitoCapabilities = { + 'moz:firefoxOptions': { + prefs: { + 'browser.privatebrowsing.autostart': true, + }, + }, +} +*/ + +/* + * You can find values for any supported browsers in the interactive form at + * https://www.browserstack.com/docs/automate/javascript-testing/configure-test-run-options + * The keys are arbitrary values. + * + * Only Chrome is supported on Android, only Safari is supported on iOS: https://www.browserstack.com/question/659 + */ +/* eslint-disable max-len */ +// prettier-ignore +const browserstackBrowsers = { + Windows10_Chrome57: { platform: 'Windows', osVersion: '10', browserName: 'Chrome', browserVersion: '57', useHttps: true }, + // Windows10_Chrome57_Incognito: { platform: 'Windows', osVersion: '10', browserName: 'Chrome', browserVersion: '57', ...chromeIncognitoCapabilities }, + Windows11_ChromeLatest: { platform: 'Windows', osVersion: '11', browserName: 'Chrome', browserVersion: 'latest-beta', useHttps: true }, + // Windows11_ChromeLatest_Incognito: { platform: 'Windows', osVersion: '11', browserName: 'Chrome', browserVersion: 'latest-beta, ...chromeIncognitoCapabilities }, + Windows10_Firefox67: { platform: 'Windows', osVersion: '10', browserName: 'Firefox', browserVersion: '67', useHttps: true }, + // Windows10_Firefox67_Incognito: { platform: 'Windows', osVersion: '10', browserName: 'Firefox', browserVersion: '67', ...firefoxIncognitoCapabilities }, + Windows11_FirefoxLatest: { platform: 'Windows', osVersion: '11', browserName: 'Firefox', browserVersion: 'latest-beta', useHttps: true }, + // Windows11_FirefoxLatest_Incognito: { platform: 'Windows', osVersion: '11', browserName: 'Firefox', browserVersion: 'latest-beta, ...firefoxIncognitoCapabilities }, + Windows11_EdgeLatest: { platform: 'Windows', osVersion: '11', browserName: 'Edge', browserVersion: 'latest-beta', useHttps: true }, + 'OSX10.14_Safari12': { platform: 'OS X', osVersion: 'Mojave', browserName: 'Safari', browserVersion: '12', useHttps: true }, + OSX12_Safari15: { platform: 'OS X', osVersion: 'Monterey', browserName: 'Safari', browserVersion: '15', useHttps: false }, + OSX13_Safari16: { platform: 'OS X', osVersion: 'Ventura', browserName: 'Safari', browserVersion: '16', useHttps: false }, + OSX13_ChromeLatest: { platform: 'OS X', osVersion: 'Ventura', browserName: 'Chrome', browserVersion: 'latest-beta', useHttps: true }, + // OSX13_ChromeLatest_Incognito: { platform: 'OS X', osVersion: 'Ventura', browserName: 'Chrome', browserVersion: 'latest-beta, ...chromeIncognitoCapabilities }, + OSX13_FirefoxLatest: { platform: 'OS X', osVersion: 'Ventura', browserName: 'Firefox', browserVersion: 'latest-beta', useHttps: true }, + // OSX13_FirefoxLatest_Incognito: { platform: 'OS X', osVersion: 'Ventura', browserName: 'Firefox', browserVersion: 'latest-beta, ...firefoxIncognitoCapabilities }, + OSX13_EdgeLatest: { platform: 'OS X', osVersion: 'Ventura', browserName: 'Edge', browserVersion: 'latest-beta', useHttps: true }, + Android13_ChromeLatest: { deviceName: ['Google Pixel 7', 'Google Pixel 7 Pro', 'Google Pixel 6 Pro'], platform: 'Android', osVersion: '13.0', browserName: 'Chrome', browserVersion: 'latest-beta', useHttps: true }, + iOS11_Safari: { deviceName: ['iPhone 8 Plus', 'iPhone 6S', 'iPhone 8', 'iPhone 6'], platform: 'iOS', osVersion: '11', browserName: 'Safari', useHttps: true }, + iOS12_Safari: { deviceName: ['iPhone XS', 'iPhone 6S', 'iPhone 8 Plus', 'iPhone XR'], platform: 'iOS', osVersion: '12', browserName: 'Safari', useHttps: true }, + iOS13_Safari: { deviceName: ['iPhone 11 Pro', 'iPhone 8', 'iPhone XS', 'iPhone 11 Pro Max'], platform: 'iOS', osVersion: '13', browserName: 'Safari', useHttps: true }, + iOS14_Safari: { deviceName: ['iPhone 11', 'iPhone XS', 'iPhone 12 Pro', 'iPhone 12 mini'], platform: 'iOS', osVersion: '14', browserName: 'Safari', useHttps: true }, + iOS15_Safari: { deviceName: ['iPhone 13', 'iPhone 13 Mini', 'iPhone 11 Pro', 'iPhone 11'], platform: 'iOS', osVersion: '15', browserName: 'Safari', useHttps: true }, + iOS16_Safari: { deviceName: ['iPhone 14', 'iPhone 14 Pro Max', 'iPhone 14 Pro', 'iPhone 14 Plus'], platform: 'iOS', osVersion: '16', browserName: 'Safari', useHttps: true}, +} + +/* eslint-enable max-len */ + +function makeBuildNumber() { + return `No CI ${Math.floor(Math.random() * 1e10)}` +} + +function setupLocal(config: Config) { + const files = ['src/**/*.ts', 'tests/**/*.ts', 'test-dist/botd.min.js'] + + config.set({ + frameworks: ['jasmine', 'karma-typescript'], + files, + preprocessors: { + '**/*.ts': 'karma-typescript', + }, + reporters: ['spec', 'summary'], + browsers: ['ChromeHeadless', 'FirefoxHeadless'], + concurrency: 3, + + karmaTypescriptConfig: { + tsconfig: 'tsconfig.json', + compilerOptions: { + module: 'commonjs', + sourceMap: true, + }, + include: files, + }, + + specReporter: { + suppressSummary: true, + suppressErrorSummary: true, + suppressPassed: true, + suppressSkipped: true, + }, + + summaryReporter: { + show: 'skipped', // To know that some tests are skipped exactly where they are supposed to be skipped + }, + }) +} + +function setupBrowserstack(config: Config) { + setupLocal(config) + + const customLaunchers: Record = {} + for (const [key, data] of Object.entries(browserstackBrowsers)) { + customLaunchers[key] = { + base: 'BrowserStack', + name: key.replace(/_/g, ' '), + ...data, + } + } + + config.set({ + reporters: [...(config.reporters || []), 'BrowserStack'], + plugins: [karmaPlugin, 'karma-*'], + browsers: Object.keys(customLaunchers), + customLaunchers, + concurrency: 5, + failOnEmptyTestSuite: false, + retryLimit: 3, + captureTimeout: 15_000, + browserStack: { + project: 'BotD', + // A build number is required to group testing sessions in the BrowserStack UI. + // GitHub Actions will add a value for GITHUB_RUN_ID. More on the environment variables: + // https://docs.github.com/en/free-pro-team@latest/actions/reference/environment-variables#default-environment-variables + build: process.env.GITHUB_RUN_ID || makeBuildNumber(), + // The timeout is reduced for testing sessions to not hold the BrowserStack queue long in case of problems. + idleTimeout: 20_000, + queueTimeout: 300_000, + }, + }) + setHttpsAndServerForKarma(config) +} + +/** + * Add `--preset local` or `--preset browserstack` to the Karma command to choose where to run the tests. + */ +module.exports = (config: Config) => { + switch (config.preset) { + case 'local': + return setupLocal(config) + case 'browserstack': + return setupBrowserstack(config) + default: + throw new Error('No --preset option is set or an unknown value is set') + } +} diff --git a/package.json b/package.json index e8fe3b09..ae197957 100644 --- a/package.json +++ b/package.json @@ -34,8 +34,8 @@ "cover 96% in us, not IE < 11" ], "scripts": { - "build": "rimraf dist && rollup -c rollup.config.js", - "build:test": "rimraf test-dist && rollup -c rollup.config.test.js", + "build": "rimraf dist && rollup -c rollup.config.ts --configPlugin '@rollup/plugin-typescript={tsconfig:`tsconfig.rollupConfig.json`}'", + "build:test": "rimraf test-dist && rollup -c rollup.config.test.ts --configPlugin '@rollup/plugin-typescript={tsconfig:`tsconfig.rollupConfig.json`}'", "dev:playground": "cross-env DEV=1 webpack serve --config ./playground/webpack.config.ts", "build:playground": "rimraf ./playground/dist && webpack --config ./playground/webpack.config.ts", "lint": "eslint src playground", @@ -46,11 +46,14 @@ "check:ssr": "node --require ./dist/botd.cjs.js --eval '' || (echo \"The distributive files can't be used with server side rendering. Make sure the code doesn't use browser API until an exported function is called.\" && exit 1)" }, "devDependencies": { - "@rollup/plugin-commonjs": "^22.0.2", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^14.1.0", - "@rollup/plugin-typescript": "^8.5.0", + "@fpjs-incubator/broyster": "^0.1.2", + "@rollup/plugin-json": "^5.0.1", + "@rollup/plugin-node-resolve": "^15.0.1", + "@rollup/plugin-typescript": "^10.0.1", "@types/jasmine": "^3.5.14", + "@types/karma": "^6.3.3", + "@types/karma-spec-reporter": "^0.0.3", + "@types/karma-summary-reporter": "^3.1.0", "@types/webpack": "^5.28.0", "@typescript-eslint/eslint-plugin": "^5.40.1", "@typescript-eslint/parser": "^5.40.1", @@ -61,25 +64,25 @@ "eslint-config-prettier": "^8.2.0", "eslint-plugin-prettier": "^3.3.1", "html-webpack-plugin": "^5.5.0", - "karma": "^6.3.2", - "karma-browserstack-launcher": "^1.6.0", - "karma-chrome-launcher": "^3.1.0", - "karma-firefox-launcher": "^2.1.0", - "karma-jasmine": "^4.0.1", + "karma": "^6.4.1", + "karma-chrome-launcher": "^3.1.1", + "karma-firefox-launcher": "^2.1.2", + "karma-jasmine": "^4.0.2", "karma-spec-reporter": "^0.0.34", - "karma-summary-reporter": "^2.0.2", - "karma-typescript": "^5.5.1", + "karma-summary-reporter": "^3.1.1", + "karma-typescript": "^5.5.3", "license-webpack-plugin": "^4.0.2", "prettier": "^2.2.1", "promise-polyfill": "^8.2.0", "rimraf": "^3.0.2", - "rollup": "^2.79.1", - "rollup-plugin-dts": "^4.2.2", - "rollup-plugin-license": "^2.8.1", + "rollup": "^3.3.0", + "rollup-plugin-dts": "^5.1.0", + "rollup-plugin-license": "^3.0.1", "style-loader": "^3.3.1", + "terser-webpack-plugin": "^5.3.6", "ts-loader": "^9.4.1", "ts-node": "^10.9.1", - "typescript": "^4.8.2", + "typescript": "^4.9.3", "webpack": "^5.74.0", "webpack-cli": "^4.10.0", "webpack-dev-server": "^4.11.0", diff --git a/playground/webpack.config.ts b/playground/webpack.config.ts index 1941b3a2..6966df46 100644 --- a/playground/webpack.config.ts +++ b/playground/webpack.config.ts @@ -22,7 +22,7 @@ const config: Configuration = { rules: [ { test: /\.ts?$/, - use: 'ts-loader', + loader: 'ts-loader', exclude: /node_modules/, }, { diff --git a/rollup.config.js b/rollup.config.js deleted file mode 100644 index 4c9ed83c..00000000 --- a/rollup.config.js +++ /dev/null @@ -1,57 +0,0 @@ -import typescript from '@rollup/plugin-typescript' -import jsonPlugin from '@rollup/plugin-json' -import dtsPlugin from 'rollup-plugin-dts' -import licensePlugin from 'rollup-plugin-license' -import commonjs from '@rollup/plugin-commonjs' -import resolve from '@rollup/plugin-node-resolve' -import { join } from 'path' -import { dependencies } from './package.json' - -const inputFile = 'src/index.ts' -const outputDirectory = 'dist' - -const commonBanner = licensePlugin({ - banner: { - content: { - file: join(__dirname, 'resources', 'license_banner.txt'), - }, - }, -}) - -export const commonInput = { - input: inputFile, - plugins: [resolve(), commonjs(), jsonPlugin(), typescript(), commonBanner], -} - -export const commonOutput = { - name: 'BotD', - exports: 'named', -} - -// NPM bundles. They have all the dependencies excluded for end code size optimization. -export default [ - { - ...commonInput, - external: Object.keys(dependencies), - output: [ - { - ...commonOutput, - file: `${outputDirectory}/botd.cjs.js`, - format: 'cjs', - }, - { - ...commonOutput, - file: `${outputDirectory}/botd.esm.js`, - format: 'es', - }, - ], - }, - { - input: inputFile, - output: { - file: `${outputDirectory}/botd.d.ts`, - format: 'es', - }, - plugins: [dtsPlugin(), commonBanner], - }, -] diff --git a/rollup.config.test.js b/rollup.config.test.ts similarity index 100% rename from rollup.config.test.js rename to rollup.config.test.ts diff --git a/rollup.config.ts b/rollup.config.ts new file mode 100644 index 00000000..b29fb2c2 --- /dev/null +++ b/rollup.config.ts @@ -0,0 +1,66 @@ +import * as fs from 'fs' +import type { RollupOptions } from 'rollup' +import jsonPlugin from '@rollup/plugin-json' +import nodeResolvePlugin from '@rollup/plugin-node-resolve' +import typescriptPlugin from '@rollup/plugin-typescript' +import dtsPlugin from 'rollup-plugin-dts' +import licensePlugin from 'rollup-plugin-license' + +const { dependencies } = JSON.parse(fs.readFileSync('package.json', 'utf8')) + +const outputDirectory = 'dist' + +export const commonInput = { + input: 'src/index.ts', + plugins: [nodeResolvePlugin(), jsonPlugin(), typescriptPlugin()], +} + +export const commonOutput = { + name: 'BotD', + exports: 'named' as const, + plugins: [ + licensePlugin({ + banner: { + content: { + file: 'resources/license_banner.txt', + }, + }, + }), + ], +} + +const config: RollupOptions[] = [ + // NPM bundles. They have all the dependencies excluded for end code size optimization. + { + ...commonInput, + external: Object.keys(dependencies), + output: [ + // CJS for usage with `require()` + { + ...commonOutput, + file: `${outputDirectory}/botd.cjs.js`, + format: 'cjs', + }, + + // ESM for usage with `import` + { + ...commonOutput, + file: `${outputDirectory}/botd.esm.js`, + format: 'esm', + }, + ], + }, + + // TypeScript definition + { + ...commonInput, + plugins: [dtsPlugin()], + output: { + ...commonOutput, + file: `${outputDirectory}/botd.d.ts`, + format: 'esm', + }, + }, +] + +export default config diff --git a/src/detectors/distinctive_properties.ts b/src/detectors/distinctive_properties.ts new file mode 100644 index 00000000..5375a9b1 --- /dev/null +++ b/src/detectors/distinctive_properties.ts @@ -0,0 +1,8 @@ +import { BotKind, ComponentDict, DetectorResponse, State } from '../types' + +export function detectDistinctiveProperties({ distinctiveProps }: ComponentDict): DetectorResponse { + if (distinctiveProps.state !== State.Success) return false + const value = distinctiveProps.value + let bot: BotKind + for (bot in value) if (value[bot]) return bot +} diff --git a/src/detectors/document_properties.ts b/src/detectors/document_properties.ts deleted file mode 100644 index 8696022e..00000000 --- a/src/detectors/document_properties.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { BotKind, ComponentDict, DetectorResponse, State } from '../types' -import { includes } from '../utils/misc' - -export function detectDocumentProperties({ documentProps }: ComponentDict): DetectorResponse { - if (documentProps.state !== State.Success) return false - if ( - includes( - documentProps.value, - 'selenium', - '__fxdriver_unwrapped', - '__selenium_unwrapped', - '__webdriver_evaluate', - '__driver_evaluate', - '__webdriver_unwrapped', - '__driver_unwrapped', - '__selenium_evaluate', - '__webdriver_script_function', - '__webdriver_script_func', - '__webdriver_script_fn', - '__fxdriver_evaluate', - '__webdriverFunc', - '$chrome_asyncScriptInfo', - '__$webdriverAsyncExecutor', - '__lastWatirAlert', - '__lastWatirConfirm', - '__lastWatirPrompt', - '_WEBDRIVER_ELEM_CACHE', - 'ChromeDriverw', - 'selenium-evaluate', - '_Selenium_IDE_Recorder', - /^([a-z]){3}_.*_(Array|Promise|Symbol)$/, - ) - ) { - return BotKind.Selenium - } -} diff --git a/src/detectors/index.ts b/src/detectors/index.ts index c37b03bc..243b67b0 100644 --- a/src/detectors/index.ts +++ b/src/detectors/index.ts @@ -1,6 +1,5 @@ import { detectAppVersion } from './app_version' import { detectDocumentAttributes } from './document_element_keys' -import { detectDocumentProperties } from './document_properties' import { detectErrorTrace } from './error_trace' import { detectEvalLengthInconsistency } from './eval_length' import { detectFunctionBind } from './function_bind' @@ -15,14 +14,13 @@ import { detectUserAgent } from './user_agent' import { detectWebDriver } from './webdriver' import { detectWebGL } from './webgl' import { detectWindowExternal } from './window_external' -import { detectWindowProperties } from './window_properties' import { detectWindowSize } from './window_size' +import { detectDistinctiveProperties } from './distinctive_properties' // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export const detectors = { detectAppVersion, detectDocumentAttributes, - detectDocumentProperties, detectErrorTrace, detectEvalLengthInconsistency, detectFunctionBind, @@ -35,8 +33,8 @@ export const detectors = { detectWebDriver, detectWebGL, detectWindowExternal, - detectWindowProperties, detectWindowSize, detectMimeTypesConsistent, detectProductSub, + detectDistinctiveProperties, } diff --git a/src/detectors/window_properties.ts b/src/detectors/window_properties.ts deleted file mode 100644 index 232e7aca..00000000 --- a/src/detectors/window_properties.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { BotKind, ComponentDict, DetectorResponse, State } from '../types' -import { includes } from '../utils/misc' - -export function detectWindowProperties({ windowProps }: ComponentDict): DetectorResponse { - if (windowProps.state !== State.Success) return false - if (includes(windowProps.value, 'webdriver', 'domAutomation', 'domAutomationController')) { - return BotKind.HeadlessChrome - } - if (includes(windowProps.value, '_selenium', '_Selenium_IDE_Recorder', 'callSelenium')) { - return BotKind.Selenium - } - if (includes(windowProps.value, 'callPhantom', '_phantom')) { - return BotKind.PhantomJS - } - if (includes(windowProps.value, '__nightmare')) return BotKind.Nightmare - if (includes(windowProps.value, 'emit')) return BotKind.CouchJS - if (includes(windowProps.value, 'spawn')) return BotKind.Rhino - if (includes(windowProps.value, 'CefSharp')) return BotKind.CefSharp -} diff --git a/src/sources/distinctive_properties.ts b/src/sources/distinctive_properties.ts new file mode 100644 index 00000000..5b7dd494 --- /dev/null +++ b/src/sources/distinctive_properties.ts @@ -0,0 +1,95 @@ +import { BotKind } from '../types' +import { getObjectProps, includes } from '../utils/misc' + +export type DistinctivePropertiesPayload = Partial> + +export default function checkDistinctiveProperties(): DistinctivePropertiesPayload { + type PropsList = Partial> + // The order in the following list matters, because specific types of bots come first, followed by automation technologies. + const distinctivePropsList: Partial> = { + [BotKind.Awesomium]: { + window: ['awesomium'], + }, + [BotKind.Cef]: { + window: ['RunPerfTest'], + }, + [BotKind.CefSharp]: { + window: ['CefSharp'], + }, + [BotKind.CoachJS]: { + window: ['emit'], + }, + [BotKind.FMiner]: { + window: ['fmget_targets'], + }, + [BotKind.Geb]: { + window: ['geb'], + }, + [BotKind.NightmareJS]: { + window: ['__nightmare', 'nightmare'], + }, + [BotKind.Phantomas]: { + window: ['__phantomas'], + }, + [BotKind.PhantomJS]: { + window: ['callPhantom', '_phantom'], + }, + [BotKind.Rhino]: { + window: ['spawn'], + }, + [BotKind.Selenium]: { + window: ['_Selenium_IDE_Recorder', '_selenium', 'calledSelenium', /^([a-z]){3}_.*_(Array|Promise|Symbol)$/], + document: ['__selenium_evaluate', 'selenium-evaluate', '__selenium_unwrapped'], + }, + [BotKind.WebDriverIO]: { + window: ['wdioElectron'], + }, + [BotKind.WebDriver]: { + window: [ + 'webdriver', + '__webdriverFunc', + '__lastWatirAlert', + '__lastWatirConfirm', + '__lastWatirPrompt', + '_WEBDRIVER_ELEM_CACHE', + 'ChromeDriverw', + ], + document: [ + '__webdriver_script_fn', + '__driver_evaluate', + '__webdriver_evaluate', + '__fxdriver_evaluate', + '__driver_unwrapped', + '__webdriver_unwrapped', + '__fxdriver_unwrapped', + '__webdriver_script_fn', + '__webdriver_script_func', + '__webdriver_script_function', + '$cdc_asdjflasutopfhvcZLmcf', + '$cdc_asdjflasutopfhvcZLmcfl_', + '$chrome_asyncScriptInfo', + '__$webdriverAsyncExecutor', + ], + }, + [BotKind.HeadlessChrome]: { + window: ['domAutomation', 'domAutomationController'], + }, + } + let botName: BotKind + const result: DistinctivePropertiesPayload = {} + const windowProps = getObjectProps(window) + let documentProps: string[] = [] + if (window.document !== undefined) documentProps = getObjectProps(window.document) + + for (botName in distinctivePropsList) { + const props = distinctivePropsList[botName] + if (props !== undefined) { + const windowContains = props.window === undefined ? false : includes(windowProps, ...props.window) + const documentContains = + props.document === undefined || !documentProps.length ? false : includes(documentProps, ...props.document) + result[botName] = windowContains || documentContains + } + } + + return result +} diff --git a/src/sources/document_properties.ts b/src/sources/document_properties.ts deleted file mode 100644 index 66489d71..00000000 --- a/src/sources/document_properties.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { BotdError, State } from '../types' -import { getObjectProps } from '../utils/misc' - -export default function getDocumentProperties(): string[] { - if (window.document === undefined) { - throw new BotdError(State.Undefined, 'window.document is undefined') - } - return getObjectProps(window.document) -} diff --git a/src/sources/index.ts b/src/sources/index.ts index bca0df5b..0e995f22 100644 --- a/src/sources/index.ts +++ b/src/sources/index.ts @@ -1,6 +1,5 @@ import getAppVersion from './app_version' import getDocumentElementKeys from './document_element_keys' -import getDocumentProperties from './document_properties' import getErrorTrace from './error_trace' import getEvalLength from './eval_length' import getFunctionBind from './function_bind' @@ -16,8 +15,8 @@ import getUserAgent from './user_agent' import getWebDriver from './webdriver' import getWebGL from './webgl' import getWindowExternal from './window_external' -import getWindowProperties from './window_properties' import getWindowSize, { WindowSizePayload } from './window_size' +import checkDistinctiveProperties from './distinctive_properties' export const sources = { userAgent: getUserAgent, @@ -38,8 +37,7 @@ export const sources = { documentElementKeys: getDocumentElementKeys, functionBind: getFunctionBind, process: getProcess, - documentProps: getDocumentProperties, - windowProps: getWindowProperties, + distinctiveProps: checkDistinctiveProperties, } export { WindowSizePayload, ProcessPayload } diff --git a/src/sources/window_properties.ts b/src/sources/window_properties.ts deleted file mode 100644 index 0dc62b65..00000000 --- a/src/sources/window_properties.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { getObjectProps } from '../utils/misc' - -export default function getWindowProperties(): string[] { - return getObjectProps(window) -} diff --git a/src/types.ts b/src/types.ts index bd7cccb0..be15fe49 100644 --- a/src/types.ts +++ b/src/types.ts @@ -17,7 +17,6 @@ export type BotDetectionResult = * @enum {number} */ export const enum State { - Unexpected = -100, Success = 0, Undefined = -1, NotFunction = -2, @@ -27,22 +26,31 @@ export const enum State { /** * Enum for types of bots. + * Specific types of bots come first, followed by automation technologies. * * @readonly * @enum {string} */ export const enum BotKind { - Unknown = 'unknown', - HeadlessChrome = 'headless_chrome', - PhantomJS = 'phantomjs', - Nightmare = 'nightmare', - Selenium = 'selenium', + Awesomium = 'awesomium', + Cef = 'cef', + CefSharp = 'cefsharp', + CoachJS = 'coachjs', Electron = 'electron', + FMiner = 'fminer', + Geb = 'geb', + NightmareJS = 'nightmarejs', + Phantomas = 'phantomas', + PhantomJS = 'phantomjs', Rhino = 'rhino', - CouchJS = 'couchjs', + Selenium = 'selenium', Sequentum = 'sequentum', SlimerJS = 'slimerjs', - CefSharp = 'cefsharp', + WebDriverIO = 'webdriverio', + + WebDriver = 'webdriver', + HeadlessChrome = 'headless_chrome', + Unknown = 'unknown', } export type DetectorResponse = boolean | BotKind | undefined diff --git a/src/utils/ponyfills.ts b/src/utils/ponyfills.ts index ad1bf72b..e4e9f039 100644 --- a/src/utils/ponyfills.ts +++ b/src/utils/ponyfills.ts @@ -8,7 +8,7 @@ export function strIncludes(str: string, value: string): boolean { export function arrayFind(array: T[], callback: (value: T, index: number, array: T[]) => boolean): T | undefined { if ('find' in array) return array.find(callback) - for (let i = 0; i < array.length; i++) { + for (let i = 0; i < (array as Array).length; i++) { if (callback(array[i], i, array)) return array[i] } return undefined diff --git a/tests/integration.test.ts b/tests/integration.test.ts index 5ba13d35..b68cdc75 100644 --- a/tests/integration.test.ts +++ b/tests/integration.test.ts @@ -1,10 +1,12 @@ import * as BotDModule from '../src' +import { retryFailedTests } from '@fpjs-incubator/broyster/browser' /* * Checks that the distributive file works in a browser. * Build the minified script before running this test. */ +retryFailedTests(3, 100) declare const BotD: typeof BotDModule describe('Integration', () => { diff --git a/tsconfig.json b/tsconfig.json index 658c4e06..ecf9cfe7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "module": "esnext", - "moduleResolution": "node", + "moduleResolution": "node16", "target": "es5", "removeComments": false, "resolveJsonModule": true, @@ -18,9 +18,16 @@ "node_modules", "playground/dist" ], + // It must include everything that Rollup will encounter, + // and preferably nothing else in order not to compile excess files + "include": [ + "src/index.ts", + "src/**/*.d.ts" + ], "ts-node": { "compilerOptions": { - "module": "commonjs" + "module": "commonjs", + "target": "es2021" } } } diff --git a/tsconfig.rollupConfig.json b/tsconfig.rollupConfig.json new file mode 100644 index 00000000..8605fd99 --- /dev/null +++ b/tsconfig.rollupConfig.json @@ -0,0 +1,9 @@ +// Used by Rollup to load its own configuration file +{ + "extends": "./tsconfig.json", + "include": [ + "rollup.config.ts", + "rollup.config.test.ts" + ] + } + \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 3f07245e..d7b97f93 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17,7 +17,7 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.16.7", "@babel/code-frame@^7.18.6": +"@babel/code-frame@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== @@ -242,6 +242,17 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@fpjs-incubator/broyster@^0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@fpjs-incubator/broyster/-/broyster-0.1.2.tgz#43bfd5f701fb36a56cf273f60e23723e7692739f" + integrity sha512-nCLgGinzjxIyYagEvDf1iHQj3fsDCCJj5ovD7wrrC6y9LJKFc35pRLkFbKVbj2SQOeHzDOnFBXTXrZDDboUG4A== + dependencies: + async-lock "^1.4.0" + browserstack "~1.5.1" + browserstack-local "^1.5.1" + selenium-webdriver "^4.7.0" + tslib "^2.4.1" + "@istanbuljs/schema@^0.1.2": version "0.1.3" resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" @@ -282,7 +293,7 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/sourcemap-codec@^1.4.10": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13": version "1.4.14" resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== @@ -329,54 +340,41 @@ "@nodelib/fs.scandir" "2.1.4" fastq "^1.6.0" -"@rollup/plugin-commonjs@^22.0.2": - version "22.0.2" - resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-22.0.2.tgz#ee8ca8415cda30d383b4096aad5222435b4b69b6" - integrity sha512-//NdP6iIwPbMTcazYsiBMbJW7gfmpHom33u1beiIoHDEM0Q9clvtQB1T0efvMqHeKsGohiHo97BCPCkBXdscwg== - dependencies: - "@rollup/pluginutils" "^3.1.0" - commondir "^1.0.1" - estree-walker "^2.0.1" - glob "^7.1.6" - is-reference "^1.2.1" - magic-string "^0.25.7" - resolve "^1.17.0" - -"@rollup/plugin-json@^4.1.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-4.1.0.tgz#54e09867ae6963c593844d8bd7a9c718294496f3" - integrity sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw== +"@rollup/plugin-json@^5.0.1": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-5.0.2.tgz#d7dbbac62ff74064876b3e5d0d863cb3ad1e7cdb" + integrity sha512-D1CoOT2wPvadWLhVcmpkDnesTzjhNIQRWLsc3fA49IFOP2Y84cFOOJ+nKGYedvXHKUsPeq07HR4hXpBBr+CHlA== dependencies: - "@rollup/pluginutils" "^3.0.8" + "@rollup/pluginutils" "^5.0.1" -"@rollup/plugin-node-resolve@^14.1.0": - version "14.1.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-14.1.0.tgz#f2fa475405cd7fed6420bf438fe393f988a9bc96" - integrity sha512-5G2niJroNCz/1zqwXtk0t9+twOSDlG00k1Wfd7bkbbXmwg8H8dvgHdIWAun53Ps/rckfvOC7scDBjuGFg5OaWw== +"@rollup/plugin-node-resolve@^15.0.1": + version "15.0.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz#72be449b8e06f6367168d5b3cd5e2802e0248971" + integrity sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg== dependencies: - "@rollup/pluginutils" "^3.1.0" - "@types/resolve" "1.17.1" + "@rollup/pluginutils" "^5.0.1" + "@types/resolve" "1.20.2" deepmerge "^4.2.2" - is-builtin-module "^3.1.0" + is-builtin-module "^3.2.0" is-module "^1.0.0" - resolve "^1.19.0" + resolve "^1.22.1" -"@rollup/plugin-typescript@^8.5.0": - version "8.5.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-8.5.0.tgz#7ea11599a15b0a30fa7ea69ce3b791d41b862515" - integrity sha512-wMv1/scv0m/rXx21wD2IsBbJFba8wGF3ErJIr6IKRfRj49S85Lszbxb4DCo8iILpluTjk2GAAu9CoZt4G3ppgQ== +"@rollup/plugin-typescript@^10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-10.0.1.tgz#270b515b116ea28320e6bb62451c4767d49072d6" + integrity sha512-wBykxRLlX7EzL8BmUqMqk5zpx2onnmRMSw/l9M1sVfkJvdwfxogZQVNUM9gVMJbjRLDR5H6U0OMOrlDGmIV45A== dependencies: - "@rollup/pluginutils" "^3.1.0" - resolve "^1.17.0" + "@rollup/pluginutils" "^5.0.1" + resolve "^1.22.1" -"@rollup/pluginutils@^3.0.8", "@rollup/pluginutils@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" - integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== +"@rollup/pluginutils@^5.0.1": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz#012b8f53c71e4f6f9cb317e311df1404f56e7a33" + integrity sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA== dependencies: - "@types/estree" "0.0.39" - estree-walker "^1.0.1" - picomatch "^2.2.2" + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^2.3.1" "@socket.io/component-emitter@~3.1.0": version "3.1.0" @@ -459,15 +457,10 @@ "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*": - version "0.0.50" - resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.50.tgz" - integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== - -"@types/estree@0.0.39": - version "0.0.39" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" - integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== +"@types/estree@*", "@types/estree@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" + integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== "@types/estree@^0.0.51": version "0.0.51" @@ -515,6 +508,28 @@ resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== +"@types/karma-spec-reporter@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@types/karma-spec-reporter/-/karma-spec-reporter-0.0.3.tgz#f70bad339e2f84ad3dac995f41f67c74a68308cf" + integrity sha512-ol9pUJxw5hHyNOGaAhJULMNXEhUyJUh5G7sLTMvWzMmEgRsqX+nOMfwGluftJd++6Vu6f4SS7LPuMF6TKlQ5Dw== + dependencies: + "@types/karma" "*" + +"@types/karma-summary-reporter@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@types/karma-summary-reporter/-/karma-summary-reporter-3.1.0.tgz#78770cdb689506eb649042c951a13ad5327c2bcf" + integrity sha512-pO+qcPpYx/MakkH9XzOMPNKrlv5LFU6o4vgVHGFNAMf1ptQ+FXvbQ4FUQ36RmtztBqIXG5Asglgzwf2bAFZUEw== + dependencies: + "@types/karma" "*" + +"@types/karma@*", "@types/karma@^6.3.3": + version "6.3.3" + resolved "https://registry.yarnpkg.com/@types/karma/-/karma-6.3.3.tgz#fc48cc53d13ec9beeea3a2a47a2036ed7647ba29" + integrity sha512-nRMec4mTCt+tkpRqh5/pAxmnjzEgAaalIq7mdfLFH88gSRC8+bxejLiSjHMMT/vHIhJHqg4GPIGCnCFbwvDRww== + dependencies: + "@types/node" "*" + log4js "^6.4.1" + "@types/mime@*": version "3.0.1" resolved "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz" @@ -535,12 +550,10 @@ resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== -"@types/resolve@1.17.1": - version "1.17.1" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" - integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== - dependencies: - "@types/node" "*" +"@types/resolve@1.20.2": + version "1.20.2" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975" + integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== "@types/retry@0.12.0": version "0.12.0" @@ -1010,6 +1023,11 @@ astral-regex@^2.0.0: resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== +async-lock@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.4.0.tgz#c8b6630eff68fbbdd8a5b6eb763dac3bfbb8bf02" + integrity sha512-coglx5yIWuetakm3/1dsX9hxCNox22h7+V80RQOu2XUUMidtArxKoZoOtHUPuR84SycKTXzgGzAUR5hJxujyJQ== + async@^3.0.1: version "3.2.4" resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" @@ -1194,17 +1212,7 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.14.5: - version "4.21.3" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz" - integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== - dependencies: - caniuse-lite "^1.0.30001370" - electron-to-chromium "^1.4.202" - node-releases "^2.0.6" - update-browserslist-db "^1.0.5" - -browserslist@^4.21.3: +browserslist@^4.14.5, browserslist@^4.21.3: version "4.21.4" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== @@ -1214,7 +1222,7 @@ browserslist@^4.21.3: node-releases "^2.0.6" update-browserslist-db "^1.0.9" -browserstack-local@^1.3.7: +browserstack-local@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/browserstack-local/-/browserstack-local-1.5.1.tgz#0d424474cc2b74a9d9a22d00a2282941ff636f34" integrity sha512-T/wxyWDzvBHbDvl7fZKpFU7mYze6nrUkBhNy+d+8bXBqgQX10HTYvajIGO0wb49oGSLCPM0CMZTV/s7e6LF0sA== @@ -1291,11 +1299,6 @@ camel-case@^4.1.2: pascal-case "^3.1.2" tslib "^2.0.3" -caniuse-lite@^1.0.30001370: - version "1.0.30001393" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001393.tgz" - integrity sha512-N/od11RX+Gsk+1qY/jbPa0R6zJupEa0lxeBG598EbrtblxVCTJsQwbRBm6+V+rxpc5lHKdsXb9RY83cZIPLseA== - caniuse-lite@^1.0.30001400: version "1.0.30001418" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz#5f459215192a024c99e3e3a53aac310fc7cf24e6" @@ -1448,11 +1451,6 @@ commenting@~1.1.0: resolved "https://registry.yarnpkg.com/commenting/-/commenting-1.1.0.tgz#fae14345c6437b8554f30bc6aa6c1e1633033590" integrity sha512-YeNK4tavZwtH7jEgK1ZINXzLKm6DZdEMfsaaieOsCAN0S8vsY7UeuO3Q7d/M018EFgE+IeUAuBOKkFccBZsUZA== -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== - compressible@~2.0.16: version "2.0.18" resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz" @@ -1882,11 +1880,6 @@ ee-first@1.1.1: resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.4.202: - version "1.4.244" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.244.tgz" - integrity sha512-E21saXLt2eTDaTxgUtiJtBUqanF9A32wZasAwDZ8gvrqXoxrBrbwtDCx7c/PQTLp81wj4X0OLDeoGQg7eMo3+w== - electron-to-chromium@^1.4.251: version "1.4.275" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.275.tgz#db25c8e39c9cc910a996d1ec9b73eee834cb0ac1" @@ -2172,12 +2165,7 @@ estraverse@^5.1.0, estraverse@^5.2.0: resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== -estree-walker@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" - integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== - -estree-walker@^2.0.1: +estree-walker@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== @@ -2854,6 +2842,11 @@ ignore@^5.2.0: resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" @@ -2953,10 +2946,10 @@ is-boolean-object@^1.1.0: dependencies: call-bind "^1.0.0" -is-builtin-module@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.0.tgz#bb0310dfe881f144ca83f30100ceb10cf58835e0" - integrity sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw== +is-builtin-module@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" + integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== dependencies: builtin-modules "^3.3.0" @@ -3055,13 +3048,6 @@ is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-reference@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" - integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== - dependencies: - "@types/estree" "*" - is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -3261,23 +3247,24 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" -karma-browserstack-launcher@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/karma-browserstack-launcher/-/karma-browserstack-launcher-1.6.0.tgz#2f6000647073e77ae296653b8830b279669766ef" - integrity sha512-Y/UWPdHZkHIVH2To4GWHCTzmrsB6H7PBWy6pw+TWz5sr4HW2mcE+Uj6qWgoVNxvQU1Pfn5LQQzI6EQ65p8QbiQ== +jszip@^3.10.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2" + integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g== dependencies: - browserstack "~1.5.1" - browserstack-local "^1.3.7" - q "~1.5.0" + lie "~3.3.0" + pako "~1.0.2" + readable-stream "~2.3.6" + setimmediate "^1.0.5" -karma-chrome-launcher@^3.1.0: +karma-chrome-launcher@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/karma-chrome-launcher/-/karma-chrome-launcher-3.1.1.tgz#baca9cc071b1562a1db241827257bfe5cab597ea" integrity sha512-hsIglcq1vtboGPAN+DGCISCFOxW+ZVnIqhDQcCMqqCp+4dmJ0Qpq5QAjkbA0X2L9Mi6OBkHi2Srrbmm7pUKkzQ== dependencies: which "^1.2.1" -karma-firefox-launcher@^2.1.0: +karma-firefox-launcher@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/karma-firefox-launcher/-/karma-firefox-launcher-2.1.2.tgz#9a38cc783c579a50f3ed2a82b7386186385cfc2d" integrity sha512-VV9xDQU1QIboTrjtGVD4NCfzIH7n01ZXqy/qpBhnOeGVOkG5JYPEm8kuSd7psHE6WouZaQ9Ool92g8LFweSNMA== @@ -3285,7 +3272,7 @@ karma-firefox-launcher@^2.1.0: is-wsl "^2.2.0" which "^2.0.1" -karma-jasmine@^4.0.1: +karma-jasmine@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/karma-jasmine/-/karma-jasmine-4.0.2.tgz#386db2a3e1acc0af5265c711f673f78f1e4938de" integrity sha512-ggi84RMNQffSDmWSyyt4zxzh2CQGwsxvYYsprgyR1j8ikzIduEdOlcLvXjZGwXG/0j41KUXOWsUCBfbEHPWP9g== @@ -3299,14 +3286,14 @@ karma-spec-reporter@^0.0.34: dependencies: colors "1.4.0" -karma-summary-reporter@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/karma-summary-reporter/-/karma-summary-reporter-2.0.3.tgz#c379dcc1852b554201a5d4236eadc294ae1fc6c7" - integrity sha512-BBaT9rRaeLr5j6qklnnfJgZ5FYLY/cQkxbiVmHx5+WRQLfWE9YnWJmyQYZ3gB5/PHKx0dMykf6CxKnLZQoRHnA== +karma-summary-reporter@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/karma-summary-reporter/-/karma-summary-reporter-3.1.1.tgz#53d31560a8196027a88c01ae9ac69029286a3da8" + integrity sha512-7MkR8aXBZh5e773SDyzgAQhFg1FsAb4xYi7HYIludpYCPRVS+JxF8Qjxnix7OVVMDArq+prXzVNn+2U5+h1U1w== dependencies: chalk "^4.0.0" -karma-typescript@^5.5.1: +karma-typescript@^5.5.3: version "5.5.3" resolved "https://registry.yarnpkg.com/karma-typescript/-/karma-typescript-5.5.3.tgz#29c04d9677f8bd78dfacd89e8fa6f475dd25aba2" integrity sha512-l1FHurolXEBIzRa9ExpNtjzysAhsi/vLpTazpwLHWWK86mknvVpqor6pRZ5Nid7jvOPrTBqAq0JRuLgiCdRkFw== @@ -3355,7 +3342,7 @@ karma-typescript@^5.5.1: util "^0.12.1" vm-browserify "^1.1.2" -karma@^6.3.2: +karma@^6.4.1: version "6.4.1" resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.1.tgz#f2253716dd3a41aaa813fa9f54b6ee047e1127d9" integrity sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA== @@ -3405,6 +3392,13 @@ license-webpack-plugin@^4.0.2: dependencies: webpack-sources "^3.0.0" +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== + dependencies: + immediate "~3.0.5" + loader-runner@^4.2.0: version "4.3.0" resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz" @@ -3467,14 +3461,14 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -magic-string@^0.25.7: - version "0.25.9" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" - integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== +magic-string@^0.29.0: + version "0.29.0" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.29.0.tgz#f034f79f8c43dba4ae1730ffb5e8c4e084b16cf3" + integrity sha512-WcfidHrDjMY+eLjlU+8OvwREqHwpgCeKVBUpQ3OhYYuvfaYCUgcbuBzappNzZvg/v8onU3oQj+BYpkOJe9Iw4Q== dependencies: - sourcemap-codec "^1.4.8" + "@jridgewell/sourcemap-codec" "^1.4.13" -magic-string@^0.26.1, magic-string@~0.26.2: +magic-string@~0.26.2: version "0.26.4" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.26.4.tgz#3d057d3d0234c3b179aa3f421b33fe5d8a4044a8" integrity sha512-e5uXtVJ22aEpK9u1+eQf0fSxHeqwyV19K+uGnlROCxUhzwRip9tBsaMViK/0vC3viyPd5Gtucp3UmEp/Q2cPTQ== @@ -3845,7 +3839,7 @@ pad@^3.2.0: dependencies: wcwidth "^1.0.1" -pako@~1.0.5: +pako@~1.0.2, pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== @@ -3947,7 +3941,7 @@ picocolors@^1.0.0: resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.2, picomatch@^2.3.1: +picomatch@^2.0.4, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -4096,11 +4090,6 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -q@~1.5.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" - integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw== - qjobs@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/qjobs/-/qjobs-1.2.0.tgz#c45e9c61800bd087ef88d7e256423bdd49e5d071" @@ -4165,10 +4154,10 @@ raw-body@2.5.1: iconv-lite "0.4.24" unpipe "1.0.0" -readable-stream@^2.0.1: - version "2.3.7" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== +readable-stream@^2.0.1, readable-stream@~2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -4268,7 +4257,7 @@ resolve-from@^5.0.0: resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve@^1.17.0, resolve@^1.19.0, resolve@^1.9.0: +resolve@^1.17.0, resolve@^1.22.1, resolve@^1.9.0: version "1.22.1" resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz" integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== @@ -4314,19 +4303,19 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" -rollup-plugin-dts@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/rollup-plugin-dts/-/rollup-plugin-dts-4.2.2.tgz#82876b8784213af29b02cf260b45e404ff835ce1" - integrity sha512-A3g6Rogyko/PXeKoUlkjxkP++8UDVpgA7C+Tdl77Xj4fgEaIjPSnxRmR53EzvoYy97VMVwLAOcWJudaVAuxneQ== +rollup-plugin-dts@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-dts/-/rollup-plugin-dts-5.2.0.tgz#1970edb69cfa3ead285ff4289d8fe273b87a5af3" + integrity sha512-B68T/haEu2MKcz4kNUhXB8/h5sq4gpplHAJIYNHbh8cp4ZkvzDvNca/11KQdFrB9ZeKucegQIotzo5T0JUtM8w== dependencies: - magic-string "^0.26.1" + magic-string "^0.29.0" optionalDependencies: - "@babel/code-frame" "^7.16.7" + "@babel/code-frame" "^7.18.6" -rollup-plugin-license@^2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/rollup-plugin-license/-/rollup-plugin-license-2.8.1.tgz#3709ef8b59675e0162a27ea7bba10ee523f8289e" - integrity sha512-VYd9pzaNL7NN6xQp93XiiCV2UoduXgSmTcz6rl9bHPdiifT6yH3Zw/omEr73Rq8TIyN4nqJACBbKIT/2eE66wg== +rollup-plugin-license@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/rollup-plugin-license/-/rollup-plugin-license-3.0.1.tgz#e54d9464971dc2c5282b74c00cee09091b329054" + integrity sha512-/lec6Y94Y3wMfTDeYTO/jSXII0GQ/XkDZCiqkMKxyU5D5nGPaxr/2JNYvAgYsoCYuOLGOanKDPjCCQiTT96p7A== dependencies: commenting "~1.1.0" glob "~7.2.0" @@ -4338,10 +4327,10 @@ rollup-plugin-license@^2.8.1: spdx-expression-validate "~2.0.0" spdx-satisfies "~5.0.1" -rollup@^2.79.1: - version "2.79.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.1.tgz#bedee8faef7c9f93a2647ac0108748f497f081c7" - integrity sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw== +rollup@^3.3.0: + version "3.17.2" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.17.2.tgz#a4ecd29c488672a0606e41ef57474fad715750a9" + integrity sha512-qMNZdlQPCkWodrAZ3qnJtvCAl4vpQ8q77uEujVCCbC/6CLB7Lcmvjq7HyiOSnf4fxTT9XgsE36oLHJBH49xjqA== optionalDependencies: fsevents "~2.3.2" @@ -4400,6 +4389,15 @@ select-hose@^2.0.0: resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz" integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== +selenium-webdriver@^4.7.0: + version "4.8.1" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.8.1.tgz#4b0a546c4ea747c44e9688c108f7a46b8d8244ab" + integrity sha512-p4MtfhCQdcV6xxkS7eI0tQN6+WNReRULLCAuT4RDGkrjfObBNXMJ3WT8XdK+aXTr5nnBKuh+PxIevM0EjJgkxA== + dependencies: + jszip "^3.10.0" + tmp "^0.2.1" + ws ">=8.11.0" + selfsigned@^2.0.1: version "2.1.1" resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz" @@ -4482,7 +4480,7 @@ serve-static@1.15.0: parseurl "~1.3.3" send "0.18.0" -setimmediate@^1.0.4: +setimmediate@^1.0.4, setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== @@ -4883,7 +4881,7 @@ temp-fs@^0.9.9: dependencies: rimraf "~2.5.2" -terser-webpack-plugin@^5.1.3: +terser-webpack-plugin@^5.1.3, terser-webpack-plugin@^5.3.6: version "5.3.6" resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz" integrity sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ== @@ -4895,9 +4893,9 @@ terser-webpack-plugin@^5.1.3: terser "^5.14.1" terser@^5.10.0, terser@^5.14.1: - version "5.15.0" - resolved "https://registry.npmjs.org/terser/-/terser-5.15.0.tgz" - integrity sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA== + version "5.16.4" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.4.tgz#51284b440b93242291a98f2a9903c024cfb70e6e" + integrity sha512-5yEGuZ3DZradbogeYQ1NaGz7rXVBDWujWlx1PT8efXO6Txn+eWbfKqB2bTDVmFXmePFkoLU6XI8UektMIEA0ug== dependencies: "@jridgewell/source-map" "^0.3.2" acorn "^8.5.0" @@ -4984,10 +4982,10 @@ tslib@^1.8.1: resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.3, tslib@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== +tslib@^2.0.3, tslib@^2.4.0, tslib@^2.4.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" + integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== tsutils@^3.21.0: version "3.21.0" @@ -5026,10 +5024,10 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" -typescript@^4.8.2: - version "4.8.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" - integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== +typescript@^4.9.3: + version "4.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== ua-parser-js@^0.7.30: version "0.7.33" @@ -5056,14 +5054,6 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -update-browserslist-db@^1.0.5: - version "1.0.7" - resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.7.tgz" - integrity sha512-iN/XYesmZ2RmmWAiI4Z5rq0YqSiv0brj9Ce9CfhNE4xIW2h+MFxcgkxIzZ+ShkFPUkjU3gQ+3oypadD3RAMtrg== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - update-browserslist-db@^1.0.9: version "1.0.10" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" @@ -5244,9 +5234,9 @@ webpack-sources@^3.0.0, webpack-sources@^3.2.3: integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== webpack@^5, webpack@^5.74.0: - version "5.74.0" - resolved "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz" - integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== + version "5.76.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.0.tgz#f9fb9fb8c4a7dbdcd0d56a98e56b8a942ee2692c" + integrity sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" @@ -5348,10 +5338,10 @@ wrappy@1: resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -ws@^8.4.2: - version "8.8.1" - resolved "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz" - integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA== +ws@>=8.11.0, ws@^8.4.2: + version "8.12.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.12.1.tgz#c51e583d79140b5e42e39be48c934131942d4a8f" + integrity sha512-1qo+M9Ba+xNhPB+YTWUlK6M17brTut5EXbcBaMRN5pH5dFrXz7lzz1ChFSUq3bOUl8yEvSenhHmYUNJxFzdJew== ws@~8.2.3: version "8.2.3" From 74c3c773ad563fd09c85e9f3cb1173db762a66f1 Mon Sep 17 00:00:00 2001 From: xnerhu Date: Thu, 23 Mar 2023 18:18:56 +0100 Subject: [PATCH 04/18] bump version to 1.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ae197957..645ee7e6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@fingerprintjs/botd", - "version": "1.3.2", + "version": "1.4.0", "description": "botd is a browser library for JavaScript bot detection", "keywords": [ "bot", From 15c689bcc75f77d81a0db9eba3f3301fa5a3f522 Mon Sep 17 00:00:00 2001 From: xnerhu Date: Sat, 29 Apr 2023 15:09:03 +0200 Subject: [PATCH 05/18] export types --- src/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 536c6432..3247e2c1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,6 @@ import { version } from '../package.json' import BotDetector from './detector' import { sources, WindowSizePayload, ProcessPayload } from './sources' -import { BotdError, BotDetectorInterface } from './types' /** * Options for BotD loading @@ -46,4 +45,4 @@ export default { load } // The exports below are for private usage. They may change unexpectedly. Use them at your own risk. /** Not documented, out of Semantic Versioning, usage is at your own risk */ -export { sources, BotdError, WindowSizePayload, ProcessPayload } +export * from './types' From 0bf3fdda3146b921c8b94885bd55475ba1bb13a9 Mon Sep 17 00:00:00 2001 From: xnerhu Date: Sat, 29 Apr 2023 15:09:24 +0200 Subject: [PATCH 06/18] bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 645ee7e6..a1445fde 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@fingerprintjs/botd", - "version": "1.4.0", + "version": "1.5.0", "description": "botd is a browser library for JavaScript bot detection", "keywords": [ "bot", From 39a73861a889f8df6ba2d1cde90ea938b236fbb3 Mon Sep 17 00:00:00 2001 From: xnerhu Date: Sat, 29 Apr 2023 15:11:28 +0200 Subject: [PATCH 07/18] fix ci --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 3247e2c1..8687dd89 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ import { version } from '../package.json' import BotDetector from './detector' -import { sources, WindowSizePayload, ProcessPayload } from './sources' +import { BotDetectorInterface } from './types' /** * Options for BotD loading From 21797504ec9653490108dcfa1fae874c3f0cb1c7 Mon Sep 17 00:00:00 2001 From: xnerhu Date: Sat, 29 Apr 2023 15:15:12 +0200 Subject: [PATCH 08/18] enable skipLibCheck --- tsconfig.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index ecf9cfe7..f14618ce 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,8 @@ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "allowSyntheticDefaultImports": true + "allowSyntheticDefaultImports": true, + "skipLibCheck": true }, "exclude": [ "dist", From ae41383172c7a4b08348d885c83ec187db4b70f0 Mon Sep 17 00:00:00 2001 From: xnerhu Date: Sat, 29 Apr 2023 15:16:54 +0200 Subject: [PATCH 09/18] export BotDetectionResult and BotKind --- src/index.ts | 5 +++-- tsconfig.json | 3 +-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/index.ts b/src/index.ts index 8687dd89..efba36de 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,7 @@ import { version } from '../package.json' import BotDetector from './detector' -import { BotDetectorInterface } from './types' +import { sources, WindowSizePayload, ProcessPayload } from './sources' +import { BotdError, BotDetectorInterface, BotKind, BotDetectionResult } from './types' /** * Options for BotD loading @@ -45,4 +46,4 @@ export default { load } // The exports below are for private usage. They may change unexpectedly. Use them at your own risk. /** Not documented, out of Semantic Versioning, usage is at your own risk */ -export * from './types' +export { sources, BotdError, WindowSizePayload, ProcessPayload, BotDetectionResult, BotKind } diff --git a/tsconfig.json b/tsconfig.json index f14618ce..ecf9cfe7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,8 +11,7 @@ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "allowSyntheticDefaultImports": true, - "skipLibCheck": true + "allowSyntheticDefaultImports": true }, "exclude": [ "dist", From a50326ed1263f260bc245b50ae87973a078dc8e9 Mon Sep 17 00:00:00 2001 From: xnerhu Date: Sat, 29 Apr 2023 15:21:20 +0200 Subject: [PATCH 10/18] use normal enum instread of const enum for BotKind --- src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.ts b/src/types.ts index be15fe49..8e74c001 100644 --- a/src/types.ts +++ b/src/types.ts @@ -31,7 +31,7 @@ export const enum State { * @readonly * @enum {string} */ -export const enum BotKind { +export enum BotKind { Awesomium = 'awesomium', Cef = 'cef', CefSharp = 'cefsharp', From 9ab2b9107b9a4831e92d09474039fd7e06002baa Mon Sep 17 00:00:00 2001 From: xnerhu Date: Tue, 2 May 2023 11:00:32 +0200 Subject: [PATCH 11/18] use enum instead of cost enum in all files --- src/types.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/types.ts b/src/types.ts index 8e74c001..9989d7c0 100644 --- a/src/types.ts +++ b/src/types.ts @@ -16,7 +16,7 @@ export type BotDetectionResult = * @readonly * @enum {number} */ -export const enum State { +export enum State { Success = 0, Undefined = -1, NotFunction = -2, @@ -148,14 +148,14 @@ export class BotdError extends Error { } } -export const enum BrowserEngineKind { +export enum BrowserEngineKind { Unknown = 'unknown', Chromium = 'chromium', Gecko = 'gecko', Webkit = 'webkit', } -export const enum BrowserKind { +export enum BrowserKind { Unknown = 'unknown', Chrome = 'chrome', Firefox = 'firefox', From 67ed6d1c53157bfb934c8ac2687b755f3bc79673 Mon Sep 17 00:00:00 2001 From: xnerhu Date: Tue, 16 May 2023 11:50:39 +0200 Subject: [PATCH 12/18] test --- .github/workflows/check_upcoming_browser_versions.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check_upcoming_browser_versions.yml b/.github/workflows/check_upcoming_browser_versions.yml index 543fcda6..c6a00340 100644 --- a/.github/workflows/check_upcoming_browser_versions.yml +++ b/.github/workflows/check_upcoming_browser_versions.yml @@ -6,9 +6,14 @@ name: Check upcoming browser versions +# on: +# schedule: +# - cron: '0 19 ? * MON-FRI' on: - schedule: - - cron: '0 19 ? * MON-FRI' + push: + branches: + - dev + - main env: BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} From ef3b791edd515ddc6edc09d2b10179146e9ced98 Mon Sep 17 00:00:00 2001 From: xnerhu Date: Tue, 16 May 2023 11:54:17 +0200 Subject: [PATCH 13/18] revert previous commit --- .github/workflows/check_upcoming_browser_versions.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/check_upcoming_browser_versions.yml b/.github/workflows/check_upcoming_browser_versions.yml index c6a00340..543fcda6 100644 --- a/.github/workflows/check_upcoming_browser_versions.yml +++ b/.github/workflows/check_upcoming_browser_versions.yml @@ -6,14 +6,9 @@ name: Check upcoming browser versions -# on: -# schedule: -# - cron: '0 19 ? * MON-FRI' on: - push: - branches: - - dev - - main + schedule: + - cron: '0 19 ? * MON-FRI' env: BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} From a2cee825fb960d39182f831f87a55d28777322fa Mon Sep 17 00:00:00 2001 From: xnerhu Date: Thu, 24 Aug 2023 13:41:28 +0200 Subject: [PATCH 14/18] change env to dev --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 22621e88..a3fb6da0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,7 @@ jobs: release: runs-on: ubuntu-20.04 timeout-minutes: 15 - environment: main + environment: dev steps: - name: Cancel Previous Runs From bfc36e8d50db8b74cf992b50c0559580885376a6 Mon Sep 17 00:00:00 2001 From: Leo Developer Date: Sun, 5 Nov 2023 13:36:52 +0100 Subject: [PATCH 15/18] feat: expose detectors and separate detect and collect functions (#144) --- src/api.ts | 74 ++++++++++++++++++++ src/detector.ts | 82 ++--------------------- src/detectors/eval_length.ts | 26 ++++--- src/detectors/notification_permissions.ts | 9 +-- src/detectors/plugins_inconsistency.ts | 25 +++++-- src/detectors/product_sub.ts | 14 ++-- src/detectors/rtt.ts | 7 +- src/detectors/window_size.ts | 7 +- src/index.ts | 5 ++ src/sources/index.ts | 5 ++ src/types.ts | 9 ++- 11 files changed, 146 insertions(+), 117 deletions(-) create mode 100644 src/api.ts diff --git a/src/api.ts b/src/api.ts new file mode 100644 index 00000000..0bced46f --- /dev/null +++ b/src/api.ts @@ -0,0 +1,74 @@ +import { + AbstractDetectorDict, + AbstractSourceDict, + BotdError, + BotDetectionResult, + BotKind, + Component, + ComponentDict, + DetectionDict, + State, +} from './types' + +export function detect>( + components: T, + detectors: K, +): [DetectionDict, BotDetectionResult] { + const detections = {} as DetectionDict + let finalDetection: BotDetectionResult = { + bot: false, + } + + for (const detectorName in detectors) { + const detector = detectors[detectorName as keyof typeof detectors] + const detectorRes = detector(components) + + let detection: BotDetectionResult = { bot: false } + + if (typeof detectorRes === 'string') { + detection = { bot: true, botKind: detectorRes } + } else if (detectorRes) { + detection = { bot: true, botKind: BotKind.Unknown } + } + + detections[detectorName as keyof typeof detectors] = detection + + if (detection.bot) { + finalDetection = detection + } + } + + return [detections, finalDetection] +} + +export async function collect(sources: T): Promise> { + const components = {} as ComponentDict + const sourcesKeys = Object.keys(sources) as (keyof typeof sources)[] + + await Promise.all( + sourcesKeys.map(async (sourceKey) => { + const res = sources[sourceKey] + + try { + components[sourceKey] = ({ + value: await res(), + state: State.Success, + } as Component) as any + } catch (error) { + if (error instanceof BotdError) { + components[sourceKey] = { + state: error.state, + error: `${error.name}: ${error.message}`, + } + } else { + components[sourceKey] = { + state: State.UnexpectedBehaviour, + error: error instanceof Error ? `${error.name}: ${error.message}` : String(error), + } + } + } + }), + ) + + return components +} diff --git a/src/detector.ts b/src/detector.ts index 6d5b476e..7d0793c9 100644 --- a/src/detector.ts +++ b/src/detector.ts @@ -1,15 +1,7 @@ +import { BotDetectionResult, BotDetectorInterface, ComponentDict, DetectionDict } from './types' +import { collect, detect } from './api' import { detectors } from './detectors' import { sources } from './sources' -import { - BotdError, - BotDetectionResult, - BotDetectorInterface, - BotKind, - Component, - ComponentDict, - DetectionDict, - State, -} from './types' /** * Class representing a bot detector. @@ -30,16 +22,6 @@ export default class BotDetector implements BotDetectorInterface { return this.detections } - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - protected getSources() { - return sources - } - - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types - protected getDetectors() { - return detectors - } - /** * @inheritdoc */ @@ -48,35 +30,9 @@ export default class BotDetector implements BotDetectorInterface { throw new Error("BotDetector.detect can't be called before BotDetector.collect") } - const components = this.components - const detectors = this.getDetectors() - - const detections = {} as DetectionDict - let finalDetection: BotDetectionResult = { - bot: false, - } - - for (const detectorName in detectors) { - const detector = detectors[detectorName as keyof typeof detectors] - const detectorRes = detector(components) - - let detection: BotDetectionResult = { bot: false } - - if (typeof detectorRes === 'string') { - detection = { bot: true, botKind: detectorRes } - } else if (detectorRes) { - detection = { bot: true, botKind: BotKind.Unknown } - } - - detections[detectorName as keyof typeof detectors] = detection - - if (detection.bot) { - finalDetection = detection - } - } + const [detections, finalDetection] = detect(this.components, detectors) this.detections = detections - return finalDetection } @@ -84,37 +40,7 @@ export default class BotDetector implements BotDetectorInterface { * @inheritdoc */ public async collect(): Promise { - const sources = this.getSources() - const components = {} as ComponentDict - - const sourcesKeys = Object.keys(sources) as (keyof typeof sources)[] - - await Promise.all( - sourcesKeys.map(async (sourceKey) => { - const res = sources[sourceKey] - - try { - components[sourceKey] = ({ - value: await res(), - state: State.Success, - } as Component) as any - } catch (error) { - if (error instanceof BotdError) { - components[sourceKey] = { - state: error.state, - error: `${error.name}: ${error.message}`, - } - } else { - components[sourceKey] = { - state: State.UnexpectedBehaviour, - error: error instanceof Error ? `${error.name}: ${error.message}` : String(error), - } - } - } - }), - ) - - this.components = components + this.components = await collect(sources) return this.components } } diff --git a/src/detectors/eval_length.ts b/src/detectors/eval_length.ts index 741aa652..85f96312 100644 --- a/src/detectors/eval_length.ts +++ b/src/detectors/eval_length.ts @@ -1,18 +1,24 @@ import { arrayIncludes } from '../utils/ponyfills' import { BrowserEngineKind, BrowserKind, ComponentDict, DetectorResponse, State } from '../types' -import { getBrowserEngineKind, getBrowserKind } from '../utils/browser' -export function detectEvalLengthInconsistency({ evalLength }: ComponentDict): DetectorResponse { - if (evalLength.state !== State.Success) return +export function detectEvalLengthInconsistency({ + evalLength, + browserKind, + browserEngineKind, +}: ComponentDict): DetectorResponse { + if ( + evalLength.state !== State.Success || + browserKind.state !== State.Success || + browserEngineKind.state !== State.Success + ) + return + const length = evalLength.value - const browser = getBrowserKind() - const browserEngine = getBrowserEngineKind() - if (browserEngine == BrowserEngineKind.Unknown) { + if (browserEngineKind.value === BrowserEngineKind.Unknown) return false - } return ( - (length === 37 && !arrayIncludes([BrowserEngineKind.Webkit, BrowserEngineKind.Gecko], browserEngine)) || - (length === 39 && !arrayIncludes([BrowserKind.IE], browser)) || - (length === 33 && !arrayIncludes([BrowserEngineKind.Chromium], browserEngine)) + (length === 37 && !arrayIncludes([BrowserEngineKind.Webkit, BrowserEngineKind.Gecko], browserEngineKind.value)) || + (length === 39 && !arrayIncludes([BrowserKind.IE], browserKind.value)) || + (length === 33 && !arrayIncludes([BrowserEngineKind.Chromium], browserEngineKind.value)) ) } diff --git a/src/detectors/notification_permissions.ts b/src/detectors/notification_permissions.ts index d6a6d2de..dbf63416 100644 --- a/src/detectors/notification_permissions.ts +++ b/src/detectors/notification_permissions.ts @@ -1,9 +1,10 @@ import { BotKind, BrowserKind, ComponentDict, DetectorResponse, State } from '../types' -import { getBrowserKind } from '../utils/browser' -export function detectNotificationPermissions({ notificationPermissions }: ComponentDict): DetectorResponse { - const browserKind = getBrowserKind() - if (browserKind !== BrowserKind.Chrome) return false +export function detectNotificationPermissions({ + notificationPermissions, + browserKind, +}: ComponentDict): DetectorResponse { + if (browserKind.state !== State.Success || browserKind.value !== BrowserKind.Chrome) return false if (notificationPermissions.state === State.Success && notificationPermissions.value) { return BotKind.HeadlessChrome diff --git a/src/detectors/plugins_inconsistency.ts b/src/detectors/plugins_inconsistency.ts index 8249e1cf..69d5eebb 100644 --- a/src/detectors/plugins_inconsistency.ts +++ b/src/detectors/plugins_inconsistency.ts @@ -1,10 +1,23 @@ import { BotKind, BrowserEngineKind, BrowserKind, ComponentDict, DetectorResponse, State } from '../types' -import { getBrowserEngineKind, getBrowserKind, isAndroid } from '../utils/browser' -export function detectPluginsLengthInconsistency({ pluginsLength }: ComponentDict): DetectorResponse { - if (pluginsLength.state !== State.Success) return - const browserKind = getBrowserKind() - const browserEngineKind = getBrowserEngineKind() - if (browserKind !== BrowserKind.Chrome || isAndroid() || browserEngineKind !== BrowserEngineKind.Chromium) return +export function detectPluginsLengthInconsistency({ + pluginsLength, + android, + browserKind, + browserEngineKind, +}: ComponentDict): DetectorResponse { + if ( + pluginsLength.state !== State.Success || + android.state !== State.Success || + browserKind.state !== State.Success || + browserEngineKind.state !== State.Success + ) + return + if ( + browserKind.value !== BrowserKind.Chrome || + android.value || + browserEngineKind.value !== BrowserEngineKind.Chromium + ) + return if (pluginsLength.value === 0) return BotKind.HeadlessChrome } diff --git a/src/detectors/product_sub.ts b/src/detectors/product_sub.ts index 238cc0dd..c7d9c079 100644 --- a/src/detectors/product_sub.ts +++ b/src/detectors/product_sub.ts @@ -1,14 +1,12 @@ import { BotKind, BrowserKind, ComponentDict, DetectorResponse, State } from '../types' -import { getBrowserKind } from '../utils/browser' -export function detectProductSub({ productSub }: ComponentDict): DetectorResponse { - if (productSub.state !== State.Success) return false - const browserKind = getBrowserKind() +export function detectProductSub({ productSub, browserKind }: ComponentDict): DetectorResponse { + if (productSub.state !== State.Success || browserKind.state !== State.Success) return false if ( - (browserKind === BrowserKind.Chrome || - browserKind === BrowserKind.Safari || - browserKind === BrowserKind.Opera || - browserKind === BrowserKind.WeChat) && + (browserKind.value === BrowserKind.Chrome || + browserKind.value === BrowserKind.Safari || + browserKind.value === BrowserKind.Opera || + browserKind.value === BrowserKind.WeChat) && productSub.value !== '20030107' ) return BotKind.Unknown diff --git a/src/detectors/rtt.ts b/src/detectors/rtt.ts index 6195cbe2..9237658a 100644 --- a/src/detectors/rtt.ts +++ b/src/detectors/rtt.ts @@ -1,9 +1,8 @@ import { BotKind, ComponentDict, DetectorResponse, State } from '../types' -import { isAndroid } from '../utils/browser' -export function detectRTT({ rtt }: ComponentDict): DetectorResponse { - if (rtt.state !== State.Success) return +export function detectRTT({ rtt, android }: ComponentDict): DetectorResponse { + if (rtt.state !== State.Success || android.state !== State.Success) return // Rtt is 0 on android webview - if (isAndroid()) return + if (android.value) return if (rtt.value === 0) return BotKind.HeadlessChrome } diff --git a/src/detectors/window_size.ts b/src/detectors/window_size.ts index 2a08d155..80b87a17 100644 --- a/src/detectors/window_size.ts +++ b/src/detectors/window_size.ts @@ -1,10 +1,9 @@ import { BotKind, ComponentDict, DetectorResponse, State } from '../types' -import { getDocumentFocus } from '../utils/browser' -export function detectWindowSize({ windowSize }: ComponentDict): DetectorResponse { - if (windowSize.state !== State.Success) return false +export function detectWindowSize({ windowSize, documentFocus }: ComponentDict): DetectorResponse { + if (windowSize.state !== State.Success || documentFocus.state !== State.Success) return false const { outerWidth, outerHeight } = windowSize.value // When a page is opened in a new tab without focusing it right away, the window outer size is 0x0 - if (!getDocumentFocus()) return + if (!documentFocus.value) return if (outerWidth === 0 && outerHeight === 0) return BotKind.HeadlessChrome } diff --git a/src/index.ts b/src/index.ts index 7960f33a..25340970 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,9 @@ import { version } from '../package.json' import BotDetector from './detector' import { sources, WindowSizePayload, ProcessPayload, DistinctivePropertiesPayload } from './sources' +import { detectors } from './detectors' import { BotdError, BotDetectorInterface, BotKind, BotDetectionResult } from './types' +import { collect, detect } from './api' /** * Sends an unpersonalized AJAX request to collect installation statistics @@ -37,6 +39,9 @@ export default { load } /** Not documented, out of Semantic Versioning, usage is at your own risk */ export { sources, + detectors, + collect, + detect, BotdError, WindowSizePayload, ProcessPayload, diff --git a/src/sources/index.ts b/src/sources/index.ts index 8db41ca0..1dddac88 100644 --- a/src/sources/index.ts +++ b/src/sources/index.ts @@ -17,8 +17,13 @@ import getWebGL from './webgl' import getWindowExternal from './window_external' import getWindowSize, { WindowSizePayload } from './window_size' import checkDistinctiveProperties, { DistinctivePropertiesPayload } from './distinctive_properties' +import { getBrowserEngineKind, getBrowserKind, getDocumentFocus, isAndroid } from '../utils/browser' export const sources = { + android: isAndroid, + browserKind: getBrowserKind, + browserEngineKind: getBrowserEngineKind, + documentFocus: getDocumentFocus, userAgent: getUserAgent, appVersion: getAppVersion, rtt: getRTT, diff --git a/src/types.ts b/src/types.ts index 537ba3d9..28e767de 100644 --- a/src/types.ts +++ b/src/types.ts @@ -87,11 +87,11 @@ export type DefaultDetectorDict = typeof detectors */ export type SourceResponse = T extends (...args: any[]) => any ? Awaited> : T -export type AbstractDetector = (...args: any[]) => DetectorResponse +export type AbstractDetector = (components: T) => DetectorResponse export type AbstractSourceDict = Record> -export type AbstractDetectorDict = Record +export type AbstractDetectorDict = Record> export type AbstractComponentDict = Record> @@ -100,7 +100,10 @@ export type AbstractDetectionsDict = Record /** * Represents a dictionary of detectors detection. */ -export type DetectionDict = Record +export type DetectionDict = DefaultDetectorDict> = Record< + keyof T, + BotDetectionResult +> /** * Dictionary of components. From d76a9fee500c29a3d1bb962b619b40946055cf6f Mon Sep 17 00:00:00 2001 From: xnerhu Date: Sun, 5 Nov 2023 13:40:34 +0100 Subject: [PATCH 16/18] lint --- src/detectors/eval_length.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/detectors/eval_length.ts b/src/detectors/eval_length.ts index 85f96312..bdae192b 100644 --- a/src/detectors/eval_length.ts +++ b/src/detectors/eval_length.ts @@ -14,8 +14,7 @@ export function detectEvalLengthInconsistency({ return const length = evalLength.value - if (browserEngineKind.value === BrowserEngineKind.Unknown) - return false + if (browserEngineKind.value === BrowserEngineKind.Unknown) return false return ( (length === 37 && !arrayIncludes([BrowserEngineKind.Webkit, BrowserEngineKind.Gecko], browserEngineKind.value)) || (length === 39 && !arrayIncludes([BrowserKind.IE], browserKind.value)) || From d2dbee0e6cdbb28000e055f2be3b5fae8e951628 Mon Sep 17 00:00:00 2001 From: xnerhu Date: Sun, 5 Nov 2023 13:56:47 +0100 Subject: [PATCH 17/18] add edge browserkind --- src/types.ts | 1 + src/utils/browser.ts | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/types.ts b/src/types.ts index 28e767de..c1bdecbc 100644 --- a/src/types.ts +++ b/src/types.ts @@ -170,4 +170,5 @@ export const enum BrowserKind { Safari = 'safari', IE = 'internet_explorer', WeChat = 'wechat', + Edge = 'edge', } diff --git a/src/utils/browser.ts b/src/utils/browser.ts index aefb336d..375358b5 100644 --- a/src/utils/browser.ts +++ b/src/utils/browser.ts @@ -52,7 +52,13 @@ export function getBrowserEngineKind(): BrowserEngineKind { export function getBrowserKind(): BrowserKind { const userAgent = navigator.userAgent?.toLowerCase() - if (strIncludes(userAgent, 'wechat')) { + if (strIncludes(userAgent, 'edg/')) { + return BrowserKind.Edge + } else if (strIncludes(userAgent, 'safari')) { + return BrowserKind.Safari + } else if (strIncludes(userAgent, 'trident') || strIncludes(userAgent, 'msie')) { + return BrowserKind.IE + } else if (strIncludes(userAgent, 'wechat')) { return BrowserKind.WeChat } else if (strIncludes(userAgent, 'firefox')) { return BrowserKind.Firefox @@ -60,10 +66,6 @@ export function getBrowserKind(): BrowserKind { return BrowserKind.Opera } else if (strIncludes(userAgent, 'chrome')) { return BrowserKind.Chrome - } else if (strIncludes(userAgent, 'safari')) { - return BrowserKind.Safari - } else if (strIncludes(userAgent, 'trident') || strIncludes(userAgent, 'msie')) { - return BrowserKind.IE } else { return BrowserKind.Unknown } From 02bd5b6f0618b97b194d81dadb6f0e4adba44d39 Mon Sep 17 00:00:00 2001 From: xnerhu Date: Sun, 5 Nov 2023 14:33:41 +0100 Subject: [PATCH 18/18] revert back edge browserk ind --- src/types.ts | 1 - src/utils/browser.ts | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/types.ts b/src/types.ts index c1bdecbc..28e767de 100644 --- a/src/types.ts +++ b/src/types.ts @@ -170,5 +170,4 @@ export const enum BrowserKind { Safari = 'safari', IE = 'internet_explorer', WeChat = 'wechat', - Edge = 'edge', } diff --git a/src/utils/browser.ts b/src/utils/browser.ts index 375358b5..fc78635f 100644 --- a/src/utils/browser.ts +++ b/src/utils/browser.ts @@ -52,9 +52,7 @@ export function getBrowserEngineKind(): BrowserEngineKind { export function getBrowserKind(): BrowserKind { const userAgent = navigator.userAgent?.toLowerCase() - if (strIncludes(userAgent, 'edg/')) { - return BrowserKind.Edge - } else if (strIncludes(userAgent, 'safari')) { + if (strIncludes(userAgent, 'safari')) { return BrowserKind.Safari } else if (strIncludes(userAgent, 'trident') || strIncludes(userAgent, 'msie')) { return BrowserKind.IE