Skip to content

Commit

Permalink
Merge pull request #6 from Countly/lighthouse-useragentdata
Browse files Browse the repository at this point in the history
Added useragentdata for bot detection too
  • Loading branch information
ArtursKadikis authored Jan 4, 2024
2 parents 50cd80b + 8220942 commit 6ea5556
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 18 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 23.12.4

* Enhanced userAgentData detection for bot filtering

## 23.12.3

* Added bot detection for workers
Expand Down
9 changes: 9 additions & 0 deletions cypress/e2e/user_agent.cy.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable cypress/no-unnecessary-waiting */
/* eslint-disable require-jsdoc */
var Countly = require("../../Countly.js");
var Utils = require("../../modules/Utils.js");
var hp = require("../support/helper");

function initMain() {
Expand Down Expand Up @@ -55,11 +56,19 @@ describe("User Agent tests ", () => {
hp.haltAndClearStorage(() => {
initMain();
// setting ua value to strings that can pass the regex test
expect(Countly._internals.userAgentSearchBotDetection("")).to.equal(false);
expect(Countly._internals.userAgentSearchBotDetection("123")).to.equal(false);
expect(Countly._internals.userAgentSearchBotDetection("Googlebot")).to.equal(true);
expect(Countly._internals.userAgentSearchBotDetection("Google")).to.equal(false);
expect(Countly._internals.userAgentSearchBotDetection("HeadlessChrome")).to.equal(true);
expect(Countly._internals.userAgentSearchBotDetection("Chrome-Lighthouse")).to.equal(true);
expect(Countly._internals.userAgentSearchBotDetection("Lighthouse")).to.equal(true);
});
});
// userAgentData is not supported by all browsers yet so it is hard to test with consistency
it("Check if currentUserAgentDataString override works", () => {
hp.haltAndClearStorage(() => {
expect(Utils.currentUserAgentDataString('123')).to.equal("123");
});
});
});
2 changes: 1 addition & 1 deletion modules/Constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ var healthCheckCounterEnum = Object.freeze({
errorMessage: "cly_hc_error_message",
});

var SDK_VERSION = "23.12.3";
var SDK_VERSION = "23.12.4";
var SDK_NAME = "javascript_native_web";

// Using this on document.referrer would return an array with 15 elements in it. The 12th element (array[11]) would be the path we are looking for. Others would be things like password and such (use https://regex101.com/ to check more)
Expand Down
2 changes: 2 additions & 0 deletions modules/CountlyClass.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
add_event_listener,
get_event_target,
currentUserAgentString,
currentUserAgentDataString,
userAgentDeviceDetection,
userAgentSearchBotDetection,
get_page_coord,
Expand Down Expand Up @@ -4624,6 +4625,7 @@ class CountlyClass {
processScrollView: processScrollView,
processScroll: processScroll,
currentUserAgentString: currentUserAgentString,
currentUserAgentDataString: currentUserAgentDataString,
userAgentDeviceDetection: userAgentDeviceDetection,
userAgentSearchBotDetection: userAgentSearchBotDetection,
getRequestQueue: getRequestQueue,
Expand Down
58 changes: 42 additions & 16 deletions modules/Utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,23 +319,39 @@ function currentUserAgentString(uaOverride) {
}

var ua_raw = navigator.userAgent;
// check if userAgentData is supported and userAgent is not available, use it
// check if userAgentData is supported and userAgent is not available, then use it
if (!ua_raw) {
if (navigator.userAgentData) {
// turn brands array into string
ua_raw = navigator.userAgentData.brands.map(function (e) {
return e.brand + ":" + e.version;
}).join();
// add mobile info
ua_raw += (navigator.userAgentData.mobile ? " mobi " : " ");
// add platform info
ua_raw += navigator.userAgentData.platform;
}
ua_raw = currentUserAgentDataString();
}
// RAW USER AGENT STRING
return ua_raw;
}

/**
* Forms user agent string from userAgentData by concatenating brand, version, mobile and platform
* @memberof Countly._internals
* @param {string} uaOverride - a string value to pass instead of ua value
* @returns {string} currentUserAgentString - user agent string from userAgentData
*/
function currentUserAgentDataString(uaOverride) {
if (uaOverride) {
return uaOverride;
}

var ua = "";
if (navigator.userAgentData) {
// turn brands array into string
ua = navigator.userAgentData.brands.map(function (e) {
return e.brand + ":" + e.version;
}).join();
// add mobile info
ua += (navigator.userAgentData.mobile ? " mobi " : " ");
// add platform info
ua += navigator.userAgentData.platform;
}
return ua;
}

/**
* Returns device type information according to user agent string
* @memberof Countly._internals
Expand All @@ -348,7 +364,7 @@ function userAgentDeviceDetection(uaOverride) {
if (uaOverride) {
userAgent = uaOverride;
}
else if (navigator.userAgentData.mobile) {
else if (navigator.userAgentData && navigator.userAgentData.mobile) {
return "phone";
}
else {
Expand Down Expand Up @@ -384,9 +400,18 @@ function userAgentDeviceDetection(uaOverride) {
*/
function userAgentSearchBotDetection(uaOverride) {
// search bot regexp
var searchBotRE = /(CountlySiteBot|nuhk|Googlebot|GoogleSecurityScanner|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver|bingbot|Google Web Preview|Mediapartners-Google|AdsBot-Google|Baiduspider|Ezooms|YahooSeeker|AltaVista|AVSearch|Mercator|Scooter|InfoSeek|Ultraseek|Lycos|Wget|YandexBot|Yandex|YaDirectFetcher|SiteBot|Exabot|AhrefsBot|MJ12bot|TurnitinBot|magpie-crawler|Nutch Crawler|CMS Crawler|rogerbot|Domnutch|ssearch_bot|XoviBot|netseer|digincore|fr-crawler|wesee|AliasIO|contxbot|PingdomBot|BingPreview|HeadlessChrome|Chrome-Lighthouse)/;
// true if the user agent string contains a search bot string pattern
return searchBotRE.test(uaOverride || currentUserAgentString());
const searchBotRE = /(CountlySiteBot|nuhk|Googlebot|GoogleSecurityScanner|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver|bingbot|Google Web Preview|Mediapartners-Google|AdsBot-Google|Baiduspider|Ezooms|YahooSeeker|AltaVista|AVSearch|Mercator|Scooter|InfoSeek|Ultraseek|Lycos|Wget|YandexBot|Yandex|YaDirectFetcher|SiteBot|Exabot|AhrefsBot|MJ12bot|TurnitinBot|magpie-crawler|Nutch Crawler|CMS Crawler|rogerbot|Domnutch|ssearch_bot|XoviBot|netseer|digincore|fr-crawler|wesee|AliasIO|contxbot|PingdomBot|BingPreview|HeadlessChrome|Lighthouse)/;

// check override first
if (uaOverride) {
return searchBotRE.test(uaOverride);
}

// check both userAgent and userAgentData, as one of them might be containing the information we are looking for
const ua_bot = searchBotRE.test(currentUserAgentString());
const uaData_bot = searchBotRE.test(currentUserAgentDataString());

return ua_bot || uaData_bot;
}

/**
Expand Down Expand Up @@ -614,5 +639,6 @@ export {
loadCSS,
showLoader,
checkIfLoggingIsOn,
hideLoader
hideLoader,
currentUserAgentDataString
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "countly-sdk-js",
"version": "23.12.3",
"version": "23.12.4",
"description": "Countly JavaScript SDK",
"type": "module",
"main": "Countly.js",
Expand Down

0 comments on commit 6ea5556

Please sign in to comment.