From c5762411043e38ff361513ac1b1e0021e84ac1ce Mon Sep 17 00:00:00 2001 From: Yann Flory Date: Thu, 10 Mar 2016 18:48:38 +0100 Subject: [PATCH] Add a Chainpad adapter to make Chainpad know the userList --- ChainPadSrv.js | 2 + npm-debug.log | 49 ++++++++ www/common/realtime-input.js | 234 ++++++++++++++++++++++------------- 3 files changed, 200 insertions(+), 85 deletions(-) create mode 100644 npm-debug.log diff --git a/ChainPadSrv.js b/ChainPadSrv.js index 4ed6ff840..c73fe9e3e 100644 --- a/ChainPadSrv.js +++ b/ChainPadSrv.js @@ -49,6 +49,7 @@ var popPassword = function (msg) { }; var sendMsg = function (msg, socket) { + console.log('>> '+msg); socket.send(msg); }; @@ -108,6 +109,7 @@ var dropClient = function (ctx, userpass) { }; var handleMessage = function (ctx, socket, msg) { + console.log('<< '+msg); var parsed = parseMessage(msg); var userPass = parsed.user + ':' + parsed.pass; msg = popPassword(msg); diff --git a/npm-debug.log b/npm-debug.log new file mode 100644 index 000000000..036f8d58e --- /dev/null +++ b/npm-debug.log @@ -0,0 +1,49 @@ +0 info it worked if it ends with ok +1 verbose cli [ 'C:\\Program Files\\nodejs\\node.exe', +1 verbose cli 'C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js', +1 verbose cli 'run-script', +1 verbose cli 'lint' ] +2 info using npm@3.6.0 +3 info using node@v5.6.0 +4 verbose run-script [ 'prelint', 'lint', 'postlint' ] +5 info lifecycle cryptpad@0.1.0~prelint: cryptpad@0.1.0 +6 silly lifecycle cryptpad@0.1.0~prelint: no script for prelint, continuing +7 info lifecycle cryptpad@0.1.0~lint: cryptpad@0.1.0 +8 verbose lifecycle cryptpad@0.1.0~lint: unsafe-perm in lifecycle true +9 verbose lifecycle cryptpad@0.1.0~lint: PATH: C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bin;C:\Users\Yann\Documents\Git projects\cryptpad\node_modules\.bin;C:\Users\Yann\bin;C:\Program Files\Git\mingw64\bin;C:\Program Files\Git\usr\local\bin;C:\Program Files\Git\usr\bin;C:\Program Files\Git\usr\bin;C:\Program Files\Git\mingw64\bin;C:\Program Files\Git\usr\bin;C:\Users\Yann\bin;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0;E:\apache-maven-3.3.9\bin;C:\Program Files (x86)\Skype\Phone;C:\Program Files (x86)\GNU\GnuPG\pub;C:\Users\Yann\.gnupg;C:\Program Files\nodejs;C:\Users\Yann\AppData\Roaming\npm;C:\Program Files\Git\usr\bin\vendor_perl;C:\Program Files\Git\usr\bin\core_perl +10 verbose lifecycle cryptpad@0.1.0~lint: CWD: C:\Users\Yann\Documents\Git projects\cryptpad +11 silly lifecycle cryptpad@0.1.0~lint: Args: [ '/d /s /c', +11 silly lifecycle 'jshint --config .jshintrc --exclude-path .jshintignore .' ] +12 silly lifecycle cryptpad@0.1.0~lint: Returned: code: 2 signal: null +13 info lifecycle cryptpad@0.1.0~lint: Failed to exec lint script +14 verbose stack Error: cryptpad@0.1.0 lint: `jshint --config .jshintrc --exclude-path .jshintignore .` +14 verbose stack Exit status 2 +14 verbose stack at EventEmitter. (C:\Program Files\nodejs\node_modules\npm\lib\utils\lifecycle.js:232:16) +14 verbose stack at emitTwo (events.js:100:13) +14 verbose stack at EventEmitter.emit (events.js:185:7) +14 verbose stack at ChildProcess. (C:\Program Files\nodejs\node_modules\npm\lib\utils\spawn.js:24:14) +14 verbose stack at emitTwo (events.js:100:13) +14 verbose stack at ChildProcess.emit (events.js:185:7) +14 verbose stack at maybeClose (internal/child_process.js:827:16) +14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:211:5) +15 verbose pkgid cryptpad@0.1.0 +16 verbose cwd C:\Users\Yann\Documents\Git projects\cryptpad +17 error Windows_NT 10.0.10586 +18 error argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "run-script" "lint" +19 error node v5.6.0 +20 error npm v3.6.0 +21 error code ELIFECYCLE +22 error cryptpad@0.1.0 lint: `jshint --config .jshintrc --exclude-path .jshintignore .` +22 error Exit status 2 +23 error Failed at the cryptpad@0.1.0 lint script 'jshint --config .jshintrc --exclude-path .jshintignore .'. +23 error Make sure you have the latest version of node.js and npm installed. +23 error If you do, this is most likely a problem with the cryptpad package, +23 error not with npm itself. +23 error Tell the author that this fails on your system: +23 error jshint --config .jshintrc --exclude-path .jshintignore . +23 error You can get information on how to open an issue for this project with: +23 error npm bugs cryptpad +23 error Or if that isn't available, you can get their info via: +23 error npm owner ls cryptpad +23 error There is likely additional logging output above. +24 verbose exit [ 1, true ] diff --git a/www/common/realtime-input.js b/www/common/realtime-input.js index 620bfa1f3..2c96e0ffa 100644 --- a/www/common/realtime-input.js +++ b/www/common/realtime-input.js @@ -72,14 +72,14 @@ define([ onEvent, unbind); }; - + var getParameterByName = function (name, url) { - if (!url) url = window.location.href; + if (!url) { url = window.location.href; } name = name.replace(/[\[\]]/g, "\\$&"); var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), results = regex.exec(url); - if (!results) return null; - if (!results[2]) return ''; + if (!results) { return null; } + if (!results[2]) { return ''; } return decodeURIComponent(results[2].replace(/\+/g, " ")); }; @@ -112,12 +112,66 @@ define([ var initializing = true; var bump = function () {}; - + var messagesHistory = []; + var mkMessage = function (user, channel, content) { + content = JSON.stringify(content); + return user.length + ':' + user + + channel.length + ':' + channel + + content.length + ':' + content; + }; + + var chainpadAdapter = { + usernamesMapping : {}, + msgIn : function(peerId, msg) { + console.log('RECU : '+ msg); + var parsed = parseMessage(msg); + if(parsed.content[0] === 0) { + if(peerId) { + this.usernamesMapping[peerId] = parsed.user; + } + } + // Remove the password from the message + var passLen = msg.substring(0,msg.indexOf(':')); + var message = msg.substring(passLen.length+1 + Number(passLen)); + try { + var decryptedMsg = Crypto.decrypt(message, cryptKey); + messagesHistory.push(decryptedMsg); + return decryptedMsg; + } catch (err) { + return message; + } + + }, + msgOut : function(msg) { + console.log('ENVOI : '+ msg); + var parsed = parseMessage(msg); + if(parsed.content[0] === 0) { // Someone is registering + onMessage('', '1:y'+mkMessage('', channel, [1,0])); + onMessage('', '1:y'+mkMessage('', channel, [3,0])); + return msg; + } + if(parsed.content[0] === 4) { // Someone is registering + console.log('ping'); + console.log(parsed); + parsed.content[0] = 5; + onMessage('', '1:y'+mkMessage(parsed.user, parsed.channelId, parsed.content)); + return; + } + return Crypto.encrypt(msg, cryptKey); + } + leaving : function(peerId) { + if(this.usernamesMapping[peerId]) { + var chainpadUser = this.usernamesMapping[peerId] + onMessage('', '1:y'+mkMessage(chainpadUser, channel, [3,0])); + } + } + }; + var options = { key: channel - } + }; var rtc = true; var connected = false; @@ -135,6 +189,86 @@ define([ options.signaling = webrtcUrl; } + var createRealtime = function() { + return ChainPad.create(userName, + passwd, + channel, + $(textarea).val(), + { + transformFunction: config.transformFunction + }); + }; + + var onOpen = function(wc) { + // Add the handlers to the WebChannel + wc.onmessage = onMessage; // On receiving message + wc.onJoining = onJoining; // On user joining the session + wc.onLeaving = onLeaving; // On user leaving the session + wc.onPeerMessage = function(peerId, type) { + onPeerMessage(peerId, type, wc); + } + + // Open a Chainpad session + realtime = createRealtime(); + + if(config.onInit) { + config.onInit({ + realtime: realtime + }); + } + + // we're fully synced + initializing = false; + + // execute an onReady callback if one was supplied + if (config.onReady) { + config.onReady(); + } + + // On sending message + realtime.onMessage(function(message) { + // Prevent Chainpad from sending authentication messages since it is handled by Netflux + message = chainpadAdapter.msgOut(message); + if(message) { + wc.send(message).then(function() { + // Send the message back to Chainpad once it is sent to all peers if using the WebRTC protocol + if(rtc) { onMessage('', message); } + }); + } + }); + + // Get the channel history + var hc; + if(rtc) { + for (let c of wc.channels) { hc = c; break; } + if(hc) { + wc.getHistory(hc.peerID); + } + } + else { + // TODO : Improve WebSocket service to use the latest Netflux's API + wc.peers.forEach(function (p) { if (!hc || p.linkQuality > hc.linkQuality) { hc = p; } }); + hc.send(JSON.stringify(['GET_HISTORY', wc.id])); + } + + // Check the connection to the channel + if(!rtc) { + // TODO + // checkConnection(wc); + } + + bindAllEvents(textarea, doc, onEvent, false); + + sharejs.attach(textarea, realtime); + bump = realtime.bumpSharejs; + + realtime.start(); + + // window.setInterval(function() { + // console.log(realtime.getLag()); + // }, 1000); + }; + if(rtc) { // Check if the WebRTC channel exists and create it if necessary var webchannel = Netflux.create(); @@ -154,83 +288,12 @@ define([ warn(error); }); } - - var onOpen = function(wc) { - // Add the handlers to the WebChannel - wc.onmessage = onMessage; // On receiving message - wc.onJoining = onJoining; // On user joining the session - wc.onLeaving = onLeaving; // On user leaving the session - wc.onPeerMessage = function(peerId, type) { - onPeerMessage(peerId, type, wc); - } - // Open a Chainpad session - realtime = createRealtime(); - - // we're fully synced - initializing = false; - - // execute an onReady callback if one was supplied - if (config.onReady) { - config.onReady(); - } - - // On sending message - realtime.onMessage(function(message) { - // Prevent Chainpad from sending authentication messages since it is handled by Netflux - var parsed = parseMessage(message); - if (parsed.content[0] !== 0) { - message = Crypto.encrypt(message, cryptKey); - wc.send(message).then(function() { - // Send the message back to Chainpad once it is sent to all peers if using the WebRTC protocol - if(rtc) { onMessage('', message); } - }); - } - }); - - // Get the channel history - var hc; - if(rtc) { - for (let c of wc.channels) { hc = c; break; } - if(hc) { - wc.getHistory(hc.peerID); - } - } - else { - // TODO : Improve WebSocket service to use the latest Netflux's API - wc.peers.forEach(function (p) { if (!hc || p.linkQuality > hc.linkQuality) { hc = p; } }); - hc.send(JSON.stringify(['GET_HISTORY', wc.id])); - } - - // Check the connection to the channel - if(!rtc) { - // TODO - // checkConnection(wc); - } - - bindAllEvents(textarea, doc, onEvent, false); - - sharejs.attach(textarea, realtime); - bump = realtime.bumpSharejs; - - realtime.start(); - - } - - var createRealtime = function() { - return ChainPad.create(userName, - passwd, - channel, - $(textarea).val(), - { - transformFunction: config.transformFunction - }); - } var whoami = new RegExp(userName.replace(/[\/\+]/g, function (c) { return '\\' +c; })); - + var onPeerMessage = function(peerID, type, wc) { if(type === 6) { messagesHistory.forEach(function(msg) { @@ -241,14 +304,13 @@ define([ }; var onMessage = function(peer, msg) { - + // remove the password - messagesHistory.push(msg); - var passLen = msg.substring(0,msg.indexOf(':')); - var message = msg.substring(passLen.length+1 + Number(passLen)); - message = Crypto.decrypt(message, cryptKey); + + message = chainpadAdapter.msgIn(peer, msg); + verbose(message); allMessages.push(message); if (!initializing) { @@ -256,6 +318,7 @@ define([ onEvent(); } } + console.log(message); realtime.message(message); if (/\[5,/.test(message)) { verbose("pong"); } @@ -272,12 +335,13 @@ define([ } } } - + var onJoining = function(peer, channel) { console.log('Someone joined : '+peer) } var onLeaving = function(peer, channel) { + chainpadAdapter.leaving(peer); console.log('Someone left : '+peer) } @@ -285,7 +349,7 @@ define([ if(wc.channels && wc.channels.size > 0) { var channels = Array.from(wc.channels); var channel = channels[0]; - + var socketChecker = setInterval(function () { if (channel.checkSocket(realtime)) { warn("Socket disconnected!");