├── .gitignore ├── README.md ├── demo.js ├── keyboard.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | node-keyboard 2 | ============= 3 | 4 | Quick & dirty keyboard keylogger for NodeJS & Linux 5 | 6 | Inspired from http://nodebits.org/linux-joystick 7 | 8 | Install 9 | ------- 10 | 11 | ``` 12 | npm install git+https://github.com/Bornholm/node-keyboard.git 13 | ``` 14 | 15 | Usage 16 | ----- 17 | 18 | See demo.js 19 | 20 | ```javascript 21 | var Keyboard = require('./keyboard.js'); 22 | 23 | var k = new Keyboard('event2'); // 'event2' is the file corresponding to my keyboard in /dev/input/ 24 | k.on('keyup', console.log); 25 | k.on('keydown', console.log); 26 | k.on('keypress', console.log); 27 | k.on('error', console.error); 28 | ``` 29 | 30 | Events 31 | 32 | ```javascript 33 | { 34 | timeS: 1347572085, // Timestamp ( Seconds part ) 35 | timeMS: 741381, // Timestamp ( Microseconds part ) 36 | keyCode: 17, // Keyboard code 37 | keyId: 'KEY_W', // Key ID /!\ Qwerty layout ! 38 | type: 'keypress', // Event type 39 | dev: 'event2' // Device 40 | } 41 | ``` 42 | 43 | Licence 44 | ------- 45 | 46 | MIT 47 | -------------------------------------------------------------------------------- /demo.js: -------------------------------------------------------------------------------- 1 | var Keyboard = require('./keyboard.js'); 2 | 3 | var k = new Keyboard('event2'); // 'event2' is the file corresponding to my keyboard in /dev/input/ 4 | k.on('keyup', console.log); 5 | k.on('keydown', console.log); 6 | k.on('keypress', console.log); 7 | 8 | k.on('error', console.error); // Something wrent wrong, keyboard disconnected or something 9 | 10 | -------------------------------------------------------------------------------- /keyboard.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Read Linux Inputs in node.js 3 | * Author: William Petit (william.petit@lookingfora.name) 4 | * 5 | * Adapted from Tim Caswell's nice solution to read a linux joystick 6 | * http://nodebits.org/linux-joystick 7 | * https://github.com/nodebits/linux-joystick 8 | */ 9 | 10 | var fs = require('fs'), 11 | ref = require('ref'), 12 | EventEmitter = require('events').EventEmitter; 13 | 14 | var EV_KEY = 1, 15 | EVENT_TYPES = ['keyup','keypress','keydown']; 16 | 17 | 18 | function Keyboard(dev) { 19 | this.wrap('onOpen'); 20 | this.wrap('onRead'); 21 | this.dev = dev; 22 | this.bufferSize = 24; 23 | this.buf = new Buffer(this.bufferSize); 24 | fs.open('/dev/input/' + this.dev, 'r', this.onOpen); 25 | } 26 | 27 | Keyboard.prototype = Object.create(EventEmitter.prototype, { 28 | constructor: {value: Keyboard} 29 | }); 30 | 31 | Keyboard.prototype.wrap = function(name) { 32 | var self = this; 33 | var fn = this[name]; 34 | this[name] = function (err) { 35 | if (err) return self.emit('error', err); 36 | return fn.apply(self, Array.prototype.slice.call(arguments, 1)); 37 | }; 38 | }; 39 | 40 | Keyboard.prototype.onOpen = function(fd) { 41 | this.fd = fd; 42 | this.startRead(); 43 | }; 44 | 45 | Keyboard.prototype.startRead = function() { 46 | fs.read(this.fd, this.buf, 0, this.bufferSize, null, this.onRead); 47 | }; 48 | 49 | Keyboard.prototype.onRead = function(bytesRead) { 50 | var event = parse(this, this.buf); 51 | if( event ) { 52 | event.dev = this.dev; 53 | this.emit(event.type, event); 54 | } 55 | if (this.fd) this.startRead(); 56 | }; 57 | 58 | Keyboard.prototype.close = function(callback) { 59 | fs.close(this.fd, (function(){console.log(this);})); 60 | this.fd = undefined; 61 | }; 62 | 63 | 64 | /** 65 | * Parse Input data 66 | */ 67 | 68 | function parse(input, buffer) { 69 | 70 | var event, value; 71 | 72 | if( buffer.readUInt16LE(16) === EV_KEY ) { 73 | 74 | event = { 75 | timeS: buffer.readUInt64LE(0), 76 | timeMS: buffer.readUInt64LE(8), 77 | keyCode: buffer.readUInt16LE(18) 78 | }; 79 | 80 | event.keyId = findKeyID(event.keyCode); 81 | event.type = EVENT_TYPES[ buffer.readUInt32LE(20) ]; 82 | 83 | } 84 | 85 | return event; 86 | }; 87 | 88 | // Keys 89 | var Keys = {}; 90 | 91 | Keys["KEY_ESC"] = 1; 92 | Keys["KEY_1"] = 2; 93 | Keys["KEY_2"] = 3; 94 | Keys["KEY_3"] = 4; 95 | Keys["KEY_4"] = 5; 96 | Keys["KEY_5"] = 6; 97 | Keys["KEY_6"] = 7; 98 | Keys["KEY_7"] = 8; 99 | Keys["KEY_8"] = 9; 100 | Keys["KEY_9"] = 10; 101 | Keys["KEY_0"] = 11; 102 | Keys["KEY_MINUS"] = 12; 103 | Keys["KEY_EQUAL"] = 13; 104 | Keys["KEY_BACKSPACE"] = 14; 105 | Keys["KEY_TAB"] = 15; 106 | Keys["KEY_Q"] = 16; 107 | Keys["KEY_W"] = 17; 108 | Keys["KEY_E"] = 18; 109 | Keys["KEY_R"] = 19; 110 | Keys["KEY_T"] = 20; 111 | Keys["KEY_Y"] = 21; 112 | Keys["KEY_U"] = 22; 113 | Keys["KEY_I"] = 23; 114 | Keys["KEY_O"] = 24; 115 | Keys["KEY_P"] = 25; 116 | Keys["KEY_LEFTBRACE"] = 26; 117 | Keys["KEY_RIGHTBRACE"] = 27; 118 | Keys["KEY_ENTER"] = 28; 119 | Keys["KEY_LEFTCTRL"] = 29; 120 | Keys["KEY_A"] = 30; 121 | Keys["KEY_S"] = 31; 122 | Keys["KEY_D"] = 32; 123 | Keys["KEY_F"] = 33; 124 | Keys["KEY_G"] = 34; 125 | Keys["KEY_H"] = 35; 126 | Keys["KEY_J"] = 36; 127 | Keys["KEY_K"] = 37; 128 | Keys["KEY_L"] = 38; 129 | Keys["KEY_SEMICOLON"] = 39; 130 | Keys["KEY_APOSTROPHE"] = 40; 131 | Keys["KEY_GRAVE"] = 41; 132 | Keys["KEY_LEFTSHIFT"] = 42; 133 | Keys["KEY_BACKSLASH"] = 43; 134 | Keys["KEY_Z"] = 44; 135 | Keys["KEY_X"] = 45; 136 | Keys["KEY_C"] = 46; 137 | Keys["KEY_V"] = 47; 138 | Keys["KEY_B"] = 48; 139 | Keys["KEY_N"] = 49; 140 | Keys["KEY_M"] = 50; 141 | Keys["KEY_COMMA"] = 51; 142 | Keys["KEY_DOT"] = 52; 143 | Keys["KEY_SLASH"] = 53; 144 | Keys["KEY_RIGHTSHIFT"] = 54; 145 | Keys["KEY_KPASTERISK"] = 55; 146 | Keys["KEY_LEFTALT"] = 56; 147 | Keys["KEY_SPACE"] = 57; 148 | Keys["KEY_CAPSLOCK"] = 58; 149 | Keys["KEY_F1"] = 59; 150 | Keys["KEY_F2"] = 60; 151 | Keys["KEY_F3"] = 61; 152 | Keys["KEY_F4"] = 62; 153 | Keys["KEY_F5"] = 63; 154 | Keys["KEY_F6"] = 64; 155 | Keys["KEY_F7"] = 65; 156 | Keys["KEY_F8"] = 66; 157 | Keys["KEY_F9"] = 67; 158 | Keys["KEY_F10"] = 68; 159 | Keys["KEY_NUMLOCK"] = 69; 160 | Keys["KEY_SCROLLLOCK"] = 70; 161 | Keys["KEY_KP7"] = 71; 162 | Keys["KEY_KP8"] = 72; 163 | Keys["KEY_KP9"] = 73; 164 | Keys["KEY_KPMINUS"] = 74; 165 | Keys["KEY_KP4"] = 75; 166 | Keys["KEY_KP5"] = 76; 167 | Keys["KEY_KP6"] = 77; 168 | Keys["KEY_KPPLUS"] = 78; 169 | Keys["KEY_KP1"] = 79; 170 | Keys["KEY_KP2"] = 80; 171 | Keys["KEY_KP3"] = 81; 172 | Keys["KEY_KP0"] = 82; 173 | Keys["KEY_KPDOT"] = 83; 174 | Keys["KEY_ZENKAKUHANKAKU"] = 85; 175 | Keys["KEY_102ND"] = 86; 176 | Keys["KEY_F11"] = 87; 177 | Keys["KEY_F12"] = 88; 178 | Keys["KEY_RO"] = 89; 179 | Keys["KEY_KATAKANA"] = 90; 180 | Keys["KEY_HIRAGANA"] = 91; 181 | Keys["KEY_HENKAN"] = 92; 182 | Keys["KEY_KATAKANAHIRAGANA"] = 93; 183 | Keys["KEY_MUHENKAN"] = 94; 184 | Keys["KEY_KPJPCOMMA"] = 95; 185 | Keys["KEY_KPENTER"] = 96; 186 | Keys["KEY_RIGHTCTRL"] = 97; 187 | Keys["KEY_KPSLASH"] = 98; 188 | Keys["KEY_SYSRQ"] = 99; 189 | Keys["KEY_RIGHTALT"] = 100; 190 | Keys["KEY_HOME"] = 102; 191 | Keys["KEY_UP"] = 103; 192 | Keys["KEY_PAGEUP"] = 104; 193 | Keys["KEY_LEFT"] = 105; 194 | Keys["KEY_RIGHT"] = 106; 195 | Keys["KEY_END"] = 107; 196 | Keys["KEY_DOWN"] = 108; 197 | Keys["KEY_PAGEDOWN"] = 109; 198 | Keys["KEY_INSERT"] = 110; 199 | Keys["KEY_DELETE"] = 111; 200 | Keys["KEY_MUTE"] = 113; 201 | Keys["KEY_VOLUMEDOWN"] = 114; 202 | Keys["KEY_VOLUMEUP"] = 115; 203 | Keys["KEY_POWER"] = 116; 204 | Keys["KEY_KPEQUAL"] = 117; 205 | Keys["KEY_PAUSE"] = 119; 206 | Keys["KEY_KPCOMMA"] = 121; 207 | Keys["KEY_HANGUEL"] = 122; 208 | Keys["KEY_HANJA"] = 123; 209 | Keys["KEY_YEN"] = 124; 210 | Keys["KEY_LEFTMETA"] = 125; 211 | Keys["KEY_RIGHTMETA"] = 126; 212 | Keys["KEY_COMPOSE"] = 127; 213 | Keys["KEY_STOP"] = 128; 214 | Keys["KEY_AGAIN"] = 129; 215 | Keys["KEY_PROPS"] = 130; 216 | Keys["KEY_UNDO"] = 131; 217 | Keys["KEY_FRONT"] = 132; 218 | Keys["KEY_COPY"] = 133; 219 | Keys["KEY_OPEN"] = 134; 220 | Keys["KEY_PASTE"] = 135; 221 | Keys["KEY_FIND"] = 136; 222 | Keys["KEY_CUT"] = 137; 223 | Keys["KEY_HELP"] = 138; 224 | Keys["KEY_F13"] = 183; 225 | Keys["KEY_F14"] = 184; 226 | Keys["KEY_F15"] = 185; 227 | Keys["KEY_F16"] = 186; 228 | Keys["KEY_F17"] = 187; 229 | Keys["KEY_F18"] = 188; 230 | Keys["KEY_F19"] = 189; 231 | Keys["KEY_F20"] = 190; 232 | Keys["KEY_F21"] = 191; 233 | Keys["KEY_F22"] = 192; 234 | Keys["KEY_F23"] = 193; 235 | Keys["KEY_F24"] = 194; 236 | Keys["KEY_UNKNOWN"] = 240; 237 | 238 | Keyboard.Keys = Keys; 239 | 240 | /** 241 | * Find Key Id 242 | */ 243 | 244 | function findKeyID( keyCode ) { 245 | var key, value; 246 | for( key in Keys ) { 247 | if ( Keys.hasOwnProperty(key) ) { 248 | if( Keys[key] === keyCode ) { 249 | return key; 250 | } 251 | } 252 | } 253 | } 254 | 255 | module.exports = Keyboard; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-keyboard", 3 | "version": "0.0.0", 4 | "description": "node-keyboard =============", 5 | "main": "keyboard.js", 6 | "dependencies": { 7 | "ref": "~0.1.3" 8 | }, 9 | "devDependencies": {}, 10 | "scripts": { 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/Bornholm/node-keyboard" 16 | }, 17 | "author": "Bornholm", 18 | "license": "ISC", 19 | "bugs": { 20 | "url": "https://github.com/Bornholm/node-keyboard/issues" 21 | }, 22 | "homepage": "https://github.com/Bornholm/node-keyboard" 23 | } 24 | --------------------------------------------------------------------------------