honeypot/assets/js/modules/Logger.js
vlw 0234ef984b refactor: release 2.0.0 (#1)
Baby steps that implements everything from the original [unfinished] version of this project from a bit over 2 years ago. We'll see what fun stuff we can add over time!

Reviewed-on: https://codeberg.org/vlw/honeypot/pulls/1
Co-authored-by: vlw <victor@vlw.se>
Co-committed-by: vlw <victor@vlw.se>
2025-09-23 20:09:41 +02:00

99 lines
No EOL
2.2 KiB
JavaScript

const MOUSE_MOVE_TIMEOUT_MS = 100;
globalThis.Logger = class Logger {
#abort;
#mouseMoveTimeout;
static get url() {
const url = new URL(window.location);
url.pathname = "/log";
return url;
}
/**
* Return a best-effort unique string that identifies this client
* @returns {String}
*/
static async #fingerprint() {
// Create a hash from various identifying browser data
const buffer = await window.crypto.subtle.digest("SHA-1", new TextEncoder().encode(JSON.stringify([
navigator.userAgent,
navigator.buildId,
navigator.languages
])));
return new DataView(buffer).getBigUint64().toString();
}
/**
* Extract desired MouseEvent data into an object literal
* @param {MouseEvent} event
* @returns {Object}
*/
static #mouseEvent(event) {
return {
e: event.type,
w: window.innerWidth,
h: window.innerHeight,
x: event.x,
y: event.y
}
}
/**
* Extract desired KeyboardEvent data into an object literal
* @param {KeyboardEvent} event
* @returns {Object}
*/
static #keyEvent(event) {
return {
e: event.type,
c: event.key,
s: event.shiftKey
}
}
constructor() {}
/**
* Start logging user activities
*/
start() {
this.#abort = new AbortController();
document.addEventListener("keyup", (event) => this.log(Logger.#keyEvent(event)), { signal: this.#abort.signal });
document.addEventListener("keydown", (event) => this.log(Logger.#keyEvent(event)), { signal: this.#abort.signal });
document.addEventListener("click", (event) => this.log(Logger.#mouseEvent(event)), { signal: this.#abort.signal });
document.addEventListener("mousemove", (event) => {
// Throttle mousemove events
clearTimeout(this.#mouseMoveTimeout);
//this.#mouseMoveTimeout = setTimeout(() => this.#log(mouseEvent(event)), MOUSE_MOVE_TIMEOUT_MS);
}, { signal: this.#abort.signal });
}
/**
* Stop logging user activitiers
*/
stop() {
this.#abort.abort();
}
/**
* Log user data
* @param {Object} data
* @returns {Response}
*/
async log(data) {
return await fetch(Logger.url, {
body: JSON.stringify({
client: data,
fingerprint: (await Logger.#fingerprint())
}),
method: "POST",
headers: Object.assign({
"Content-Type": "application/json"
}, VV.header)
});
};
}