fix(tracker): AV-safe keyboard/mouse activity detection#254
Merged
Conversation
…ivity
node-global-key-listener ships a native hook binary (WinKeyServer.exe) that antivirus (Bitdefender) flags as a keylogger and quarantines, silently zeroing all keyboard/mouse activity counts. Replace it with Electron's built-in powerMonitor.getSystemIdleTime(): while tracking, sample once per second and emit an activity tick per active second. No native binary, no accessibility permission, AV-proof, cross-platform.
Desktop: background.js runs a 1 Hz idle sampler emitting 'activity:tick'; timelog.js setActivityTick buckets ticks per minute as { active: N }; trackerRunning.jsx and tracker.js consume it and strokes carry { active }; package.json drops the dependency. Frontend helper.js surfaces the active value in the existing Keyboard column (Mouse stays 0); old timesheets keep their original keyboard/mouse counts. Backend and DB schema unchanged - strokes are stored opaquely in trackShots.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Refines the powerMonitor approach so the timesheet shows real Keyboard AND Mouse activity instead of one combined value. Each second while tracking, the sampler reads two hook-free signals - powerMonitor.getSystemIdleTime() and screen.getCursorScreenPoint(): cursor moved => mouse activity; input with no cursor movement (typing) => keyboard activity. Still no global input hook, so antivirus does not flag it. A click that does not move the cursor counts as keyboard (acceptable trade-off vs the AV-flagged hook).
Strokes return to the { keyboard, mouse } shape, so the web frontend needs no change: helper.js reverts to its original (reads keyboard/mouse) and the production website displays the data correctly with no deploy.
background.js: cursor-movement + idle sampler emits activity:tick with a type; timelog.js setActivityTick buckets per minute as { keyboard, mouse }; trackerRunning.jsx and tracker.js pass the type and build keyboard/mouse strokes; helper.js reverted to original.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Tracker: AV-safe keyboard/mouse activity detection
Problem
The desktop time tracker used
node-global-key-listener, which ships a native global-hook binary (WinKeyServer.exe). Antivirus (Bitdefender) flags that signature as a keylogger and quarantines it, silently stopping all keyboard/mouse activity — every timesheet showed "Active 0 of N min". This hits any customer running AV, since AlianHub is self-hosted/distributed.Fix
Replace the global hook with two hook-free, built-in OS signals, sampled once per second while tracking:
powerMonitor.getSystemIdleTime()— seconds since last input (keyboard or mouse)screen.getCursorScreenPoint()— current cursor positionClassification: cursor moved this second → mouse activity; input with no cursor movement (typing) → keyboard activity. No native binary, no accessibility permission, AV-proof, cross-platform.
Web frontend unchanged
Strokes stay in the existing
{ keyboard, mouse }shape, sohelper.jsand the timesheet display are untouched — production renders the new data correctly with no web deploy. Net diff is desktop-only.Scope
time-tracker-app/main/background.js— cursor-movement + idle samplertime-tracker-app/renderer/store/timelog.js—setActivityTickbuckets{ keyboard, mouse }per minutetime-tracker-app/renderer/pages/trackerRunning.jsx,controller/tracker/tracker.js— wire activity ticks + strokestime-tracker-app/package.json+ lockfile — dropnode-global-key-listener; bump to 5.0.1Verified
End-to-end local run against production data: both Keyboard and Mouse columns populate with realistic per-minute values; "Active X of Y min" and the activity bar work; AV does not quarantine the build.
Caveats
.exeis unsigned (SmartScreen "unknown publisher"); code-signing is a separate follow-up.🤖 Generated with Claude Code