
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
cheatingtracker
Advanced tools
CheatingTracker - is a JavaScript library for tracking suspicious actions on the part of the client
The CheatingTracker package It contains functionality for tracking changes in page focus.
createScreenTracker - Creates definition pressed ScreenShots on keyboard and type Operating System
title and time{
title: '',
time: null,
}
Returns:
type Nullable<T> = T | null
interface IScreenDetect {
title: string;
time: Nullable<string>;
}
{
lastEvent: () => IScreenDetect;
events: () => IScreenDetect[];
cleanup: () => void;
}
import React, { useState, useEffect, useRef } from 'react';
import { createScreenTracker } from 'cheatingtracker';
const Home = () => {
const [events, setEvents] = useState([]);
const [lastEvent, setLastEvent] = useState(null);
const screenTrackerRef = useRef(null);
useEffect(() => {
const screenTracker = createScreenTracker((newEvents) => {
setEvents(newEvents);
if (screenTrackerRef.current) {
const last = screenTrackerRef.current.lastEvent();
setLastEvent(last);
}
});
screenTrackerRef.current = screenTracker;
return () => {
screenTracker.cleanup();
};
}, []);
return (
<div>
<h2>Events:</h2>
<ul>
{events.map((event, index) => (
<li key={index}>
{event.title} at {event.time}
</li>
))}
</ul>
<h2>Last Event:</h2>
{lastEvent && (
<p>{lastEvent.title} at {lastEvent.time}</p>
)}
</div>
);
};
export default Home;
import { createScreenTracker } from 'cheatingtracker';
const tracker = createScreenTracker();
const btn = document.getElementById('btn')
btn.addEventListener('click', () => {
console.log(tracker.events());
console.log(tracker.lastEvent());
})
createBlurTracker - Creates a focus loss tracker.
Returns:
{
getCount: () => number;
cleanup: () => void;
}
import React, { useEffect, useState } from 'react';
import { createBlurTracker } from 'cheatingtracker';
const Reviews = () => {
const [count, setCount] = useState(0);
useEffect(() => {
const tracker = createBlurTracker(setCount);
return () => {
tracker.cleanup();
};
}, []);
return (
<div>
<h1>REVIEWS</h1>
<h2>Blur Count: {count}</h2>
</div>
);
};
export default Reviews;
import { createBlurTracker } from 'cheatingtracker';
const tracker = createBlurTracker(0);
const btn = document.getElementById('btn')
btn.addEventListener('click', () => {
console.log(tracker.getCount());
})
createAltTabTracker - Determines whether the Alt+Tab key combination or a similar focus switch was performed in combination with the pressed Alt. It also records what time it happened and how long the user was absent from the page.
alt + tabalt + tabtype Nullable<T> = T | null;
interface IAltTabEvent {
at: string;
durationMs: Nullable<number>;
}
{
lastEvent: () => IAltTabEvent;
events: () => IAltTabEvent[];
destroy: () => void;
}
Returns:
lastEvent: () => IAltTabEvent;
This method returns an object with the last Alt+Tab event (or a similar focus switch) fixed during operation.
The returned object has the following contents:
{
at: string; // example: "02:23:50".
durationMs: Nullable<number>; // duration: `1583`
}
at: is the time when the event occurred. This time is in the hh:mm:ss format, for example: 02:23:50.
durationMs – length of time during which there was no focus on the page (in milliseconds). If focus has been restored, the value will be specified, if not, it will be null.
examples:
{
at: '02:23:50',
durationMs: 1500
}
or
{
at: '',
durationMs: null
}
events: () => IAltTabEvent[];
This method returns an array of all Alt+Tab (or similar focus switches) that have been captured.
The returned array contains objects in the following format:
{
at: string; // example: "02:23:50".
durationMs: Nullable<number>; // duration: `1583`
}
[
{ at: '02:23:50', durationMs: 1500 },
{ at: '03:15:42', durationMs: 1200 },
]
import { createAltTabTracker } from "./src/altTab/altTab.js";
const btn = document.getElementById('btn');
const tracker = createAltTabTracker();
btn.addEventListener('click', () => {
console.log(tracker.events());
console.log(tracker.lastEvent());
});
import React, { useEffect, useState, useRef } from 'react';
import { createAltTabTracker } from 'cheatingtracker';
const AltTabLog = () => {
const [events, setEvents] = useState([]);
const [lastEvent, setLastEvent] = useState(null);
const trackerRef = useRef(null);
useEffect(() => {
const tracker = createAltTabTracker(() => {
const all = tracker.events();
setEvents(all);
setLastEvent(tracker.lastEvent());
});
trackerRef.current = tracker;
return () => {
tracker.destroy();
};
}, []);
return (
<div>
<h3>Alt+Tab events:</h3>
<ul>
{events.map((e, idx) => (
<li key={idx}>
{e.at} ({e.durationMs} мс)
</li>
))}
</ul>
<h4>Last Event:</h4>
{lastEvent && (
<p>{lastEvent.at} ({lastEvent.durationMs} мс)</p>
)}
</div>
);
};
export default AltTabLog;
createInactivityTracker - Creates and returns a tracker object that tracks the user's periods of inactivity on a web page. If the user is inactive for a set number of seconds and the page is active, information about inactivity is recorded in the console and an array of events, and then about the moment when they return to activity.
Returned methods:
start()
Starts tracking. It attaches listeners to activity events and monitors the visibility of the page.
stop()
Stops tracking. Deletes all listeners and clears the timer.
getEvents()
Returns an array of all recorded events of inactivity and return to activity.
{
type: 'inactivity',
time: '03:05:23',
message: 'Пользователь был бездействующим 5 секунд',
activityAfterSeconds: 7,
activityType: 'mousemove'
}
type: Type of eventtime: The time when inactivity was recorded (local)message: messageactivityAfterSeconds: How many seconds after inactivity did the user become activeactivityType: Activity type: mousemove, keydown, etc.Behaviour:
Listens to the following activities: mousemove, keydown, mousedown, touchstart.
Counts only when the page is active
Activity events are displayed in the console, but only if they occurred after a period of inactivity.
All events are saved to an array accessible via getEvents().
Notes:
import { createInactivityTracker } from "./src/inactivity/inactivity.js";
const tracker = createInactivityTracker(30 );
tracker.start();
const start = document.getElementById('start')
const end = document.getElementById('end')
start.addEventListener('click', () => {
console.log(tracker.events())
})
end.addEventListener('click', () => {
tracker.stop();
})
import React, { useEffect, useState } from 'react';
import { createInactivityTracker } from 'cheatingtracker';
export default function App() {
const [events, setEvents] = useState([]);
useEffect(() => {
const tracker = createInactivityTracker(5); // 5-second timeout
tracker.start();
return () => {
tracker.stop();
clearInterval(interval);
};
}, []);
return (
<div>
<h1>🛑 Inactivity Tracker</h1>
<p>Try not moving your mouse or pressing keys for 5 seconds...</p>
<ul>
{events.map((event, index) => (
<li key={index}>
<strong>{event.time}</strong> — {event.message}
{event.activityAfterSeconds !== undefined && (
<div>
↪ Activity: <em>{event.activityType}</em> after{' '}
<strong>{event.activityAfterSeconds}</strong> sec.
</div>
)}
</li>
))}
</ul>
</div>
);
}
createInactivityTracker - Creates and returns a tracker object that listens to the user's copy actions on the page.
Returned methods:
start()
Starts tracking. It attaches listeners to activity events and monitors the copy of the page.
stop()
Stops tracking. Deletes all listeners and clears the timer.
getEvents()
Returns an array of all recorded events of copy and return to activity.
{
type: 'question' | 'answer',
copiedText: string,
time: '13:42:08' // (local time, formatted as HH:MM:SS)
}
type: What was copied — either a question or an answer optioncopiedText: The actual string that was copied by the usertime: '13:42:08' // (local time, formatted as HH:MM:SS)Behaviour:
import React, { useEffect, useState } from 'react';
import { createQuestionCopyTracker } from 'cheatingtracker';
const questions = [
{
question: 'What is the color of the sky?',
options: ['a. Blue', 'b. Green', 'c. Red', 'd. Black'],
},
{
question: 'How many legs does a spider have?',
options: ['a. 4', 'b. 6', 'c. 8', 'd. 10'],
},
];
const QuestionPage = () => {
const [showLogs, setShowLogs] = useState(false);
const [logs, setLogs] = useState([]);
useEffect(() => {
const tracker = createQuestionCopyTracker(questions, (newEvent) => {
setLogs(prevLogs => [...prevLogs, newEvent]);
});
tracker.start();
return () => {
tracker.stop();
};
}, []);
const handleAnswerClick = () => {
setShowLogs(true);
};
const handleLogClick = () => {
console.log(logs);
};
return (
<div>
<h1>Online Quiz</h1>
{questions.map((q, index) => (
<div key={index}>
<p><strong>{index + 1}. {q.question}</strong></p>
{q.options.map((opt, i) => (
<div key={i}>
<label>
<input type="checkbox" /> {opt}
</label>
</div>
))}
</div>
))}
<button onClick={handleAnswerClick}>Answer</button>
<button onClick={handleLogClick}>Log</button>
{showLogs && (
<div>
<h2>Copy Logs:</h2>
<pre>
{logs.length > 0 ? (
logs.map((log, idx) => (
<div key={idx}>
{log.time} — {log.type === 'question' ? 'Question: ' : 'Answer: '} {log.copiedText}
</div>
))
) : (
<p>No logs</p>
)}
</pre>
</div>
)}
</div>
);
};
export default QuestionPage;
SimpleCaptcha - Creates and returns a tracker object that makes captcha
Returned methods:
showCaptcha()
Manually triggers the CAPTCHA overlay.
destroy()
Removes CAPTCHA overlay and detaches listeners.
events
Logs of all successful CAPTCHA completions. Each entry includes: at (time), timeIsCorrect (attempts), howLongIsCorrect (ms to solve).
{
at: string,
timeIsCorrect: number,
howLongIsCorrect: number,
}
at - the time when the CAPTCHA was created
timeIsCorrect - how many times was the CAPTCHA correctly solved
timeIsCorrect - time how long did it take to solve it
import { SimpleCaptcha } from 'cheatingtracker';
const captcha = SimpleCaptcha.create('captcha', 10000);
const button = document.getElementById('btn');
button.addEventListener('click', () => {
console.log(captcha.events);
});
FAQs
Track user behavior during online tests
The npm package cheatingtracker receives a total of 21 weekly downloads. As such, cheatingtracker popularity was classified as not popular.
We found that cheatingtracker demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.