Merge branch 'cpnetflux' into staging

pull/1/head
yflory 6 years ago
commit 11b57cddb1

@ -13,18 +13,18 @@ define([
'/common/outer/cursor.js',
'/common/outer/onlyoffice.js',
'/common/outer/mailbox.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, Mailbox, CpNfWorker, NetConfig, AppConfig,
Crypto, ChainPad, Listmap, nThen, Saferphore) {
Cursor, OnlyOffice, Mailbox, NetConfig, AppConfig,
Crypto, ChainPad, CpNetflux, Listmap, nThen, Saferphore) {
var create = function () {
var Store = window.Cryptpad_Store = {};
@ -1018,7 +1018,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
});
@ -1028,14 +1028,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,
@ -1049,13 +1050,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,
@ -1068,10 +1079,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();
@ -1088,7 +1099,7 @@ define([
});
}
};
channel.cpNf = CpNfWorker.start(conf);
channel.cpNf = CpNetflux.start(conf);
};
Store.leavePad = function (clientId, data, cb) {
var channel = channels[data.channel];

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
});
}*/
};
});
Loading…
Cancel
Save