https://github.com/codesplinta/zhorn
realtime page bot detection, XSS detection and performance analytics tracker for the web
https://github.com/codesplinta/zhorn
bot-detection instrumentation monkey-patching performance-analytics xss-prevention xxs-detection
Last synced: 10 months ago
JSON representation
realtime page bot detection, XSS detection and performance analytics tracker for the web
- Host: GitHub
- URL: https://github.com/codesplinta/zhorn
- Owner: codesplinta
- License: apache-2.0
- Created: 2023-08-23T14:38:37.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-04-12T23:48:23.000Z (almost 2 years ago)
- Last Synced: 2024-04-14T10:25:08.930Z (almost 2 years ago)
- Topics: bot-detection, instrumentation, monkey-patching, performance-analytics, xss-prevention, xxs-detection
- Language: JavaScript
- Homepage:
- Size: 113 KB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://shields.io/) [](https://shields.io/)  [](http://makeapullrequest.com) [](https://standardjs.com) [](https://github.com/acekyd/made-in-nigeria)
# zhorn
realtime page bot detection, XSS detection and performance analytics tracker for the web
## Installation
>Install using `npm`
```bash
npm install zhorn
```
>Or install using `yarn`
```bash
yarn add zhorn
```
### Browser
> Using a `script` tag directly inside a web page
```html
```
### CommonJS
```js
const { initializeBotDetector } = require('zhorn')
```
## Getting Started
You need to add the `` tag (as specified below) to enable **Trusted Types** from the frontend or enable from the backend using [CSP Response Headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP).
```html
```
Afterwards, you can import the project and begin the further setup
```javascript
import {
initializeBotDetector,
initializeXSSDetector,
initializeNavigatorMetricsTracker
} from "zhorn";
const { destroy: destroyBotDetector } = initializeBotDetector(
1500 /* :botCheckTimeout: */
)
const { destroy: destroyXSSDetector } = initializeXSSDetector(
/* @HINT: You need to extract the whilelisted URLs from CSP white list */
/* @HINT: The CSP whitelist from the `` tag or the CSP Response Headers */
[
"https://code.tidio.co",
"http://code.tidio.co",
"https://widget-v4.tidiochat.com",
"https://fonts.googleapis.com",
"https://maxst.icons8.com",
"https://cdnjs.cloudflare.com",
"https://tidio-images-messenger.s3.amazonaws.com",
"https://fonts.gstatic.com",
"https://gatedapi.mysaasapp.com",
"https://apis.google-analytics.com"
],
(URISanity, payload) => {
const { origin } = new URL(payload.endpoint);
/* @HINT: Check that only the request params we need are attached */
/* @HINT: Any other extra params should not be allowed */
if (origin.includes('.google-analytics.')) {
if (URISanity.checkParamsOverWhiteList(
payload.endpoint,
['tid', 'cid'],
payload.data
)) {
return;
}
throw new Error("URL query string not valid")
}
}
);
const { getInstance, destroy: destroyTracker } = initializeNavigatorMetricsTracker(
10000 /* :maxMeasureTime: */
)
const tracker = getInstance();
window.addEventListener('beforeunload', function onBeforeUnLoad (event) {
/* @HINT: Free up memory */
destroyBotDetector()
destroyXSSDetector()
destroyTracker()
/* @HINT: Preserve the BF Cache */
/* @CHECK: https://web.dev/articles/bfcache */
window.removeEventListener('beforeunload', onBeforeUnLoad);
event.preventDefault();
event.returnValue = undefined;
return;
});
```
Or you could create a ReactJS hook: **useZhornTracker()**
```javascript
import { useState, useMemo } from "react";
import { useBeforePageUnload } from "react-busser";
import {
initializeBotDetector,
initializeXSSDetector,
initializeNavigatorMetricsTracker
} from "zhorn";
export const useZhornTracker = (botCheckTimeout = 1500, maxMetricsMeasureTime = 10000, cspWhiteList = []) => {
const [{ destroy: destroyBotDetector }] = useState(() => initializeBotDetector(
botCheckTimeout /* :botCheckTimeout: */
));
const [{ getInstance, destroy: destroyTracker }] = useState(() => initializeNavigatorMetricsTracker(
maxMetricsMeasureTime /* :maxMeasureTime: */
));
const [{ destroy: destroyXSSDetector }] = useState(() => initializeXSSDetector(
/* @HINT: You need to extract the whilelisted URLs from CSP white list */
/* @HINT: The CSP whitelist from the `` tag or the CSP Response Headers */
cspWhiteList,
(URISanity, payload) => {
const { origin } = new URL(payload.endpoint);
/* @HINT: Check that only the request params we need are attached */
/* @HINT: Any other extra params should not be allowed */
if (origin.includes('.google-analytics.')) {
if (URISanity.checkParamsOverWhiteList(
payload.endpoint,
['tid', 'cid'],
payload.data
)) {
return;
}
throw new Error("URL query string not valid")
}
}
));
useBeforePageUnload(() => {
const isClosed = window.closed;
setTimeout(() => {
if (isClosed || !window || window.closed) {
destroyBotDetector();
destroyTracker();
destroyXSSDetector();
}
}, 0);
return undefined;
}, { when: true });
return useMemo(() => getInstance(), []);
};
```
## License
Apache 2.0 License
## Browser Support
- IE 11.0+
- Edge 16.0+
- Chrome 44.0+
- Firefox 45.0+
- Safari 12.0+
- Opera 28.0+
- Samsung Internet 4.0+
## Contributing
If you wish to contribute to this project, you are very much welcome. Please, create an issue first before you proceed to create a PR (either to propose a feature or fix a bug). Make sure to clone the repo, checkout to a contribution branch and build the project before making modifications to the codebase.
Run all the following command (in order they appear) below:
```bash
$ npm run lint
$ npm run build
$ npm run test
```