diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index efa05d85d..f9bca1e35 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -12,18 +12,18 @@ define([ '/common/common-messenger.js', '/common/outer/cursor.js', '/common/outer/onlyoffice.js', - '/common/outer/chainpad-netflux-worker.js', '/common/outer/network-config.js', '/customize/application_config.js', '/bower_components/chainpad-crypto/crypto.js', '/bower_components/chainpad/chainpad.dist.js', + '/bower_components/chainpad-netflux/chainpad-netflux.js', '/bower_components/chainpad-listmap/chainpad-listmap.js', '/bower_components/nthen/index.js', '/bower_components/saferphore/index.js', ], function (Sortify, UserObject, ProxyManager, Migrate, Hash, Util, Constants, Feedback, Realtime, Messaging, Messenger, - Cursor, OnlyOffice, CpNfWorker, NetConfig, AppConfig, - Crypto, ChainPad, Listmap, nThen, Saferphore) { + Cursor, OnlyOffice, NetConfig, AppConfig, + Crypto, ChainPad, CpNetflux, Listmap, nThen, Saferphore) { var create = function () { var Store = window.Cryptpad_Store = {}; @@ -1010,7 +1010,7 @@ define([ }); channel.history.forEach(function (msg) { postMessage(clientId, "PAD_MESSAGE", { - msg: CpNfWorker.removeCp(msg), + msg: CpNetflux.removeCp(msg), user: channel.wc.myID, validateKey: channel.data.validateKey }); @@ -1020,14 +1020,15 @@ define([ return; } var conf = { - onReady: function (padData) { - channel.data = padData || {}; + onReady: function (pad) { + var padData = pad.metadata || {}; + channel.data = padData; if (padData && padData.validateKey && store.messenger) { store.messenger.storeValidateKey(data.channel, padData.validateKey); } postMessage(clientId, "PAD_READY"); }, - onMessage: function (user, m, validateKey, isCp) { + onMessage: function (m, user, validateKey, isCp) { channel.pushHistory(m, isCp); channel.bcast("PAD_MESSAGE", { user: user, @@ -1041,13 +1042,23 @@ define([ onLeave: function (m) { channel.bcast("PAD_LEAVE", m); }, - onDisconnect: function () { + onAbort: function () { channel.bcast("PAD_DISCONNECT"); }, onError: function (err) { channel.bcast("PAD_ERROR", err); - delete channels[data.channel]; // TODO test? + delete channels[data.channel]; }, + onChannelError: function (err) { + channel.bcast("PAD_ERROR", err); + delete channels[data.channel]; + }, + onConnectionChange: function () {}, + crypto: { + encrypt: function (m) { return m; }, + decrypt: function (m) { return m; } + }, + noChainPad: true, channel: data.channel, validateKey: data.validateKey, owners: data.owners, @@ -1060,10 +1071,10 @@ define([ // Send to server sendMessage(msg, function () { // Broadcast to other tabs - channel.pushHistory(CpNfWorker.removeCp(msg), /^cp\|/.test(msg)); + channel.pushHistory(CpNetflux.removeCp(msg), /^cp\|/.test(msg)); channel.bcast("PAD_MESSAGE", { user: wc.myID, - msg: CpNfWorker.removeCp(msg), + msg: CpNetflux.removeCp(msg), validateKey: channel.data.validateKey }, cId); cb(); @@ -1080,7 +1091,7 @@ define([ }); } }; - channel.cpNf = CpNfWorker.start(conf); + channel.cpNf = CpNetflux.start(conf); }; Store.leavePad = function (clientId, data, cb) { var channel = channels[data.channel]; diff --git a/www/common/outer/chainpad-netflux-worker.js b/www/common/outer/chainpad-netflux-worker.js deleted file mode 100644 index 6ac013d51..000000000 --- a/www/common/outer/chainpad-netflux-worker.js +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright 2014 XWiki SAS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -define([], function () { - var USE_HISTORY = true; - - var verbose = function (x) { console.log(x); }; - verbose = function () {}; // comment out to enable verbose logging - - var unBencode = function (str) { return str.replace(/^\d+:/, ''); }; - - var removeCp = function (str) { - return str.replace(/^cp\|([A-Za-z0-9+\/=]{0,20}\|)?/, ''); - }; - - var start = function (conf) { - var channel = conf.channel; - var validateKey = conf.validateKey; - var readOnly = conf.readOnly || false; - var network = conf.network; - var onConnect = conf.onConnect || function () { }; - var onMessage = conf.onMessage; - var onJoin = conf.onJoin; - var onLeave = conf.onLeave; - var onReady = conf.onReady; - var onDisconnect = conf.onDisconnect; - var onError = conf.onError; - var owners = conf.owners; - var password = conf.password; - var expire = conf.expire; - var padData; - conf = undefined; - - var initializing = true; - var stopped = false; - var lastKnownHash; - - var messageFromOuter = function () {}; - - var error = function (err, wc) { - if (onError) { - onError({ - type: err, - loaded: !initializing - }); - if (wc && (err === "EEXPIRED" || err === "EDELETED")) { wc.leave(); } - } - else { console.error(err); } - }; - - var onRdy = function (padData) { - // Trigger onReady only if not ready yet. This is important because the history keeper sends a direct - // message through "network" when it is synced, and it triggers onReady for each channel joined. - if (!initializing) { return; } - onReady(padData); - //sframeChan.event('EV_RT_READY', null); - // we're fully synced - initializing = false; - }; - - // shim between chainpad and netflux - var msgIn = function (peerId, msg) { - // NOTE: Hash version 0 contains a 32 characters nonce followed by a pipe - // at the beginning of each message on the server. - // We have to make sure our regex ignores this nonce using {0,20} (our IDs - // should only be 8 characters long) - return removeCp(msg); - }; - - var msgOut = function (msg) { - if (readOnly) { return; } - return msg; - }; - - var onMsg = function(peer, msg, wc, network, direct) { - // unpack the history keeper from the webchannel - var hk = network.historyKeeper; - - if (direct && peer !== hk) { - return; - } - if (direct) { - var parsed = JSON.parse(msg); - if (parsed.validateKey && parsed.channel) { - if (parsed.channel === wc.id && !validateKey) { - validateKey = parsed.validateKey; - } - if (parsed.channel === wc.id) { - padData = parsed; - } - // We have to return even if it is not the current channel: - // we don't want to continue with other channels messages here - return; - } - if (parsed.state && parsed.state === 1 && parsed.channel) { - if (parsed.channel === wc.id) { - onRdy(padData); - } - // We have to return even if it is not the current channel: - // we don't want to continue with other channels messages here - return; - } - } - if (peer === hk) { - // if the peer is the 'history keeper', extract their message - var parsed1 = JSON.parse(msg); - // First check if it is an error message (EXPIRED/DELETED) - if (parsed1.channel === wc.id && parsed1.error) { - return void error(parsed1.error, wc); - } - - msg = parsed1[4]; - // Check that this is a message for our channel - if (parsed1[3] !== wc.id) { return; } - } - - - lastKnownHash = msg.slice(0,64); - - var isCp = /^cp\|/.test(msg); - var message = msgIn(peer, msg); - - verbose(message); - - // slice off the bencoded header - // Why are we getting bencoded stuff to begin with? - // FIXME this shouldn't be necessary - message = unBencode(message);//.slice(message.indexOf(':[') + 1); - - // pass the message into Chainpad - onMessage(peer, message, validateKey, isCp); - //sframeChan.query('Q_RT_MESSAGE', message, function () { }); - }; - - // We use an object to store the webchannel so that we don't have to push new handlers to chainpad - // and remove the old ones when reconnecting and keeping the same 'realtime' object - // See realtime.onMessage below: we call wc.bcast(...) but wc may change - var wcObject = {}; - var onOpen = function(wc, network, firstConnection) { - wcObject.wc = wc; - channel = wc.id; - - // Add the existing peers in the userList - //TODO sframeChan.event('EV_RT_CONNECT', { myID: wc.myID, members: wc.members, readOnly: readOnly }); - - // Add the handlers to the WebChannel - wc.on('message', function (msg, sender) { //Channel msg - onMsg(sender, msg, wc, network); - }); - wc.on('join', function (m) { onJoin(m); /*sframeChan.event('EV_RT_JOIN', m);*/ }); - wc.on('leave', function (m) { onLeave(m); /*sframeChan.event('EV_RT_LEAVE', m);*/ }); - - if (firstConnection) { - // Sending a message... - messageFromOuter = function(message, cb) { - // Filter messages sent by Chainpad to make it compatible with Netflux - message = msgOut(message); - if (message) { - // Do not remove wcObject, it allows us to use a new 'wc' without changing the handler if we - // want to keep the same chainpad (realtime) object - try { - wcObject.wc.bcast(message).then(function() { - cb(); - }, function(err) { - // The message has not been sent, display the error. - console.error(err); - }); - } catch (e) { - console.log(e); - // Just skip calling back and it will fail on the inside. - } - } - }; - } - - onConnect(wc, messageFromOuter); - - // Get the channel history - if (USE_HISTORY) { - var hk; - - wc.members.forEach(function (p) { - if (p.length === 16) { hk = p; } - }); - network.historyKeeper = hk; - - var cfg = { - validateKey: validateKey, - lastKnownHash: lastKnownHash, - owners: owners, - expire: expire, - password: password - }; - var msg = ['GET_HISTORY', wc.id, cfg]; - // Add the validateKey if we are the channel creator and we have a validateKey - if (hk) { - network.sendto(hk, JSON.stringify(msg)).then(function () { - }, function (err) { - console.error(err); - }); - } - } else { - onRdy(); - } - }; - - /*var isIntentionallyLeaving = false; - window.addEventListener("beforeunload", function () { - isIntentionallyLeaving = true; - });*/ - - var findChannelById = function (webChannels, channelId) { - var webChannel; - - // Array.some terminates once a truthy value is returned - // best case is faster than forEach, though webchannel arrays seem - // to consistently have a length of 1 - webChannels.some(function(chan) { - if(chan.id === channelId) { webChannel = chan; return true;} - }); - return webChannel; - }; - - var connectTo = function (network, firstConnection) { - // join the netflux network, promise to handle opening of the channel - network.join(channel || null).then(function(wc) { - onOpen(wc, network, firstConnection); - }, function(err) { - console.error(err); - if (onError) { - onError({ - type: err && (err.type || err), - loaded: !initializing - }); - } - }); - }; - - network.on('disconnect', function (reason) { - //if (isIntentionallyLeaving) { return; } - if (reason === "network.disconnect() called") { return; } - onDisconnect(); - //sframeChan.event('EV_RT_DISCONNECT'); - }); - - network.on('reconnect', function () { - if (stopped) { return; } - initializing = true; - connectTo(network, false); - }); - - network.on('message', function (msg, sender) { // Direct message - if (stopped) { return; } - var wchan = findChannelById(network.webChannels, channel); - if (wchan) { - onMsg(sender, msg, wchan, network, true); - } - }); - - connectTo(network, true); - - return { - stop: function () { - var wchan = findChannelById(network.webChannels, channel); - if (wchan) { wchan.leave(''); } - stopped = true; - } - }; - }; - - return { - start: start, - removeCp: removeCp - /*function (config) { - config.sframeChan.whenReg('EV_RT_READY', function () { - start(config); - }); - }*/ - }; -}); -