diff --git a/www/common/onlyoffice/inner.js b/www/common/onlyoffice/inner.js index 0281b37c5..bfbecbff1 100644 --- a/www/common/onlyoffice/inner.js +++ b/www/common/onlyoffice/inner.js @@ -56,10 +56,13 @@ define([ var toolbar; var andThen = function (common) { + var sframeChan = common.getSframeChannel(); + var metadataMgr = common.getMetadataMgr(); var readOnly = false; var locked = false; var config = {}; var hashes = []; + var channel; var getFileType = function () { var type = common.getMetadataMgr().getPrivateData().ooType; @@ -85,17 +88,86 @@ define([ return file; }; - var openRtChannel = function (data) { - // XXX - var channel = Hash.createChannelId(); - ctx.sframeChan.query('Q_OO_OPENCHANNEL', { + var now = function () { return +new Date(); }; + + var getLastCp = function () { + if (!hashes || !hashes.length) { return; } + var last = hashes.slice().pop(); + var parsed = Hash.parsePadUrl(last); + var secret = Hash.getSecrets('file', parsed.hash); + if (!secret || !secret.channel) { return; } + return 'cp|' + secret.channel.slice(0,8); + }; + + var rtChannel = { + ready: false, + readyCb: undefined, + sendCmd: function (data, cb) { + sframeChan.query('Q_OO_COMMAND', data, cb); + }, + sendMsg: function (msg, cp, cb) { + rtChannel.sendCmd({ + cmd: 'SEND_MESSAGE', + data: { + msg: msg, + isCp: cp + } + }, cb); + }, + }; + + var ooChannel = { + ready: false, + queue: [], + send: function () {} + }; + + var openRtChannel = function (cb) { + if (rtChannel.ready) { return; } + var chan = channel || Hash.createChannelId(); + if (!channel) { + channel = chan; + APP.onLocal(); + } + sframeChan.query('Q_OO_OPENCHANNEL', { channel: channel, - lastCp: data.lastCp + lastCp: getLastCp() }, function (err, obj) { if (err || (obj && obj.error)) { console.error(err || (obj && obj.error)); } }); + sframeChan.on('EV_OO_EVENT', function (data) { + switch (data.ev) { + case 'READY': + rtChannel.ready = true; + break; + case 'MESSAGE': + if (ooChannel.ready) { + ooChannel.send(data.data); + } else { + ooChannel.queue.push(data.data); + } + break; + } + }); + cb(); }; + var parseChanges = function (changes) { + try { + changes = JSON.parse(changes); + } catch (e) { + return []; + } + return changes.map(function (change) { + return { + docid: "fresh", + change: '"' + change + '"', + time: now(), + user: "test", // XXX get username + useridoriginal: "test" // get user id from worker? + }; + }); + }; var mkChannel = function () { var msgEv = Util.mkEvent(); var iframe = $('#cp-app-oo-container > iframe')[0].contentWindow; @@ -108,11 +180,83 @@ define([ }; Channel.create(msgEv, postMsg, function (chan) { APP.chan = chan; - chan.on('CMDFROMOO', function (data) { - console.log('command from oo', data); - setTimeout(function () { - chan.event('RTMSG', 'Pewpewpew'); - }, 2000); + + var send = ooChannel.send = function (obj) { + chan.event('CMD', obj); + }; + + chan.on('CMD', function (obj) { + var msg, msg2; + switch (obj.type) { + case "auth": + ooChannel.ready = true; + send({ + type: "auth", + result: 1, + sessionId: "08e77705-dc5c-477d-b73a-b1a7cbca1e9b", + participants: [{ + id: "myid1", + idOriginal: "myid", + username: "User", + indexUser: 1, + view: false + }], + locks: [], + changes: [], + changesIndex: 0, + indexUser: 1, + "g_cAscSpellCheckUrl": "/spellchecker" + }); + send({ + type: "documentOpen", + data: {"type":"open","status":"ok","data":{"Editor.bin":obj.openCmd.url}} + }); + setTimeout(function () { + if (ooChannel.queue) { + ooChannel.queue.forEach(function (msg) { + send(msg); + }); + } + }, 2000); + break; + case "isSaveLock": + msg = { + type: "saveLock", + saveLock: false + } + send(msg); + break; + case "getLock": + msg = { + type: "getLock", + locks: [{ + time: now(), + user: "myid1", + block: obj.block && obj.block[0], + sessionId: "08e77705-dc5c-477d-b73a-b1a7cbca1e9b" + }] + } + send(msg); + break; + case "getMessages": + send({ type: "message" }); + break; + case "saveChanges": + // XXX lock + send({ + type: "unSaveLock", + index: -1, + }); + rtChannel.sendMsg({ + type: "saveChanges", + changes: parseChanges(obj.changes), + changesIndex: 2, + locks: [], // XXX take from userdoc? + excelAdditionalInfo: null + }, null, function () { + }); + break; + } }); }); }; @@ -120,7 +264,7 @@ define([ var startOO = function (blob, file) { if (APP.ooconfig) { return void console.error('already started'); } var url = URL.createObjectURL(blob); - var lock = locked !== common.getMetadataMgr().getNetfluxId() || + var lock = /*locked !== common.getMetadataMgr().getNetfluxId() ||*/ !common.isLoggedIn(); // Config @@ -144,20 +288,13 @@ define([ } }, "user": { - "id": "", //"c0c3bf82-20d7-4663-bf6d-7fa39c598b1d", - "name": "", //"John Smith" + "id": "myid", //"c0c3bf82-20d7-4663-bf6d-7fa39c598b1d", + "name": "User", //"John Smith" }, "mode": readOnly || lock ? "view" : "edit" }, "events": { - "onDocumentStateChange": function (evt) { - if (evt.data) { - console.log('in change (local)'); - return; - } - console.log("in change (remote)"); - }, - "onReady": function(/*evt*/) { + "onAppReady": function(/*evt*/) { var $tb = $('iframe[name="frameEditor"]').contents().find('head'); var css = '#id-toolbar-full .toolbar-group:nth-child(2), #id-toolbar-full .separator:nth-child(3) { display: none; }' + '#fm-btn-save { display: none !important; }' + @@ -169,8 +306,6 @@ define([ }); } }, - "onAppReady": function(/*evt*/) { console.log("in onAppReady"); }, - "onDownloadAs": function (evt) { console.log("in onDownloadAs", evt); } } }; window.onbeforeunload = function () { @@ -202,8 +337,10 @@ define([ return void UI.alert(Messages.oo_saveError); } hashes.push(data.url); - UI.log(Messages.saved); APP.onLocal(); + rtChannel.sendMsg(null, getLastCp(), function () { + UI.log(Messages.saved); + }); }); } }; @@ -248,7 +385,6 @@ define([ var loadDocument = function (newPad) { var type = common.getMetadataMgr().getPrivateData().ooType; var file = getFileType(); - console.log(newPad); if (!newPad) { return void loadLastDocument(); } @@ -274,7 +410,6 @@ define([ var $bar = $('#cp-toolbar'); var Title; var cpNfInner; - var metadataMgr = common.getMetadataMgr(); config = { patchTransformer: ChainPad.NaiveJSONTransformer, @@ -298,8 +433,9 @@ define([ var stringifyInner = function () { var obj = { content: { + channel: channel, hashes: hashes || [], - locked: locked + //locked: locked }, metadata: metadataMgr.getMetadataLazy() }; @@ -385,7 +521,8 @@ define([ throw new Error(errorText); } hashes = hjson.content && hjson.content.hashes; - locked = hjson.content && hjson.content.locked; + //locked = hjson.content && hjson.content.locked; + channel = hjson.content && hjson.content.channel; newDoc = !hashes || hashes.length === 0; } else { Title.updateTitle(Title.defaultTitle); @@ -393,7 +530,7 @@ define([ if (!readOnly) { // Check if the editor has left - var me = common.getMetadataMgr().getNetfluxId(); + /*var me = common.getMetadataMgr().getNetfluxId(); var members = common.getMetadataMgr().getChannelMembers(); if (locked) { if (members.indexOf(locked) === -1) { @@ -409,15 +546,17 @@ define([ UI.alert(Messages.oo_locked + Messages.oo_locked_unregistered); } else if (locked !== me) { UI.alert(Messages.oo_locked + Messages.oo_locked_edited); - } + }*/ } + openRtChannel(function () { + loadDocument(newDoc); - loadDocument(newDoc); + initializing = false; + setEditable(!readOnly); + UI.removeLoadingScreen(); + }); - initializing = false; - setEditable(!readOnly); - UI.removeLoadingScreen(); }; var reloadDisplayed = false; @@ -428,6 +567,7 @@ define([ if (json.metadata) { metadataMgr.updateMetadata(json.metadata); } + /* var newHashes = (json.content && json.content.hashes) || []; if (newHashes.length !== hashes.length || stringify(newHashes) !== stringify(hashes)) { @@ -440,6 +580,7 @@ define([ common.gotoURL(); }); } + */ }; config.onAbort = function () { diff --git a/www/common/onlyoffice/main.js b/www/common/onlyoffice/main.js index 11f797936..3188da5a2 100644 --- a/www/common/onlyoffice/main.js +++ b/www/common/onlyoffice/main.js @@ -56,6 +56,7 @@ define([ }); }); sframeChan.on('Q_OO_OPENCHANNEL', function (data, cb) { + console.log(data); Cryptpad.onlyoffice.execCommand({ cmd: 'OPEN_CHANNEL', data: { @@ -69,14 +70,22 @@ define([ }, cb); }); sframeChan.on('Q_OO_COMMAND', function (obj, cb) { - if (obj.cmd === 'SEND_MESSAGE' && !obj.data.isCp) { - obj.data.msg = crypto.encrypt(obj.data.msg); + if (obj.cmd === 'SEND_MESSAGE') { + if (obj.data.isCp) { + obj.data.isCp += '|' + crypto.encrypt('cp'); + } else { + obj.data.msg = crypto.encrypt(JSON.stringify(obj.data.msg)); + } } Cryptpad.onlyoffice.execCommand(obj, cb); }); Cryptpad.onlyoffice.onEvent.reg(function (obj) { if (obj.ev === 'MESSAGE') { - obj.data = crypto.decrypt(obj.data, Utils.secret.keys.validateKeys); + try { + obj.data = JSON.parse(crypto.decrypt(obj.data, Utils.secret.keys.validateKey)); + } catch (e) { + console.error(e); + } } sframeChan.event('EV_OO_EVENT', obj); }); diff --git a/www/common/onlyoffice/sdkjs/cell/sdk-all-min.js b/www/common/onlyoffice/sdkjs/cell/sdk-all-min.js index d412cdd3a..4bd4331a2 100644 --- a/www/common/onlyoffice/sdkjs/cell/sdk-all-min.js +++ b/www/common/onlyoffice/sdkjs/cell/sdk-all-min.js @@ -4206,8 +4206,8 @@ AscBrowser.convertToRetinaValue = function(value, isScale) light: false, trial: false, rights: 1, - buildVersion: "4.3.3", - buildNumber: 4, + buildVersion: "5.2.6", + buildNumber: 5, branding: false } }; @@ -4228,12 +4228,8 @@ AscBrowser.convertToRetinaValue = function(value, isScale) p.postMessage(data, '*'); }; Channel.create(msgEv, postMsg, function (chan) { - console.log('created', chan); channel = chan; send(license); - chan.on('RTMSG', function (data) { - console.log('receiving RTMSG', data); - }); chan.on('CMD', function (obj) { send(obj); }); @@ -4258,33 +4254,9 @@ AscBrowser.convertToRetinaValue = function(value, isScale) console.error(e); return; } - var msg, msg2; - switch (obj.type) { - case 'auth': - msg = { - "type":"auth", - "result":1, - "sessionId":"08e77705-dc5c-477d-b73a-b1a7cbca1e9b", - "sessionTimeConnect":+new Date(), - "participants":[] - }; - msg2 = { - "type":"documentOpen", - "data":{"type":"open","status":"ok","data":{"Editor.bin":obj.openCmd.url}} - }; - send(msg); - send(msg2); - if (channel) { channel.event('CMDFROMOO', 'Hey'); } - break; - case 'getMessages': - msg = {}; - break; - default: - if (channel) { - channel.event('CMD', obj); - } - break - } + if (channel) { + channel.event('CMD', obj); + } }; sockjs.onmessage = function (e) { diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 50a136b81..d1b63ae05 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -932,7 +932,7 @@ define([ Store.onlyoffice = { execCommand: function (clientId, data, cb) { if (!store.onlyoffice) { return void cb({error: 'OnlyOffice is disabled'}); } - store.onlyoffice.execCommand(data, cb); + store.onlyoffice.execCommand(clientId, data, cb); } }; diff --git a/www/common/outer/onlyoffice.js b/www/common/outer/onlyoffice.js index ea98d4033..b465eff43 100644 --- a/www/common/outer/onlyoffice.js +++ b/www/common/outer/onlyoffice.js @@ -30,6 +30,9 @@ define([ if (!c.id) { c.id = chan.wc.myID + '-' + client; } /// XXX send chan.history to client + chan.history.forEach(function (msg) { + ctx.emit('MESSAGE', msg, [client]); + }); // ==> And push the new tab to the list chan.clients.push(client); @@ -38,7 +41,9 @@ define([ var onOpen = function (wc) { - ctx.channels[channel] = ctx.channels[channel] || {}; + ctx.channels[channel] = ctx.channels[channel] || { + history: [] + }; chan = ctx.channels[channel]; @@ -61,15 +66,24 @@ define([ wc.on('leave', function (peer) { // XXX }); - wc.on('message', function (cryptMsg) { - ctx.emit('MESSAGE', cryptMsg, chan.clients); + wc.on('message', function (msg) { + if (/^cp\|/.test(msg)) { + chan.history = []; + } else { + chan.history.push(msg); + } + ctx.emit('MESSAGE', msg, chan.clients); }); chan.wc = wc; chan.sendMsg = function (msg, cb) { cb = cb || function () {}; - var cmsg = chan.encryptor.encrypt(msg); - wc.bcast(cmsg).then(function () { + wc.bcast(msg).then(function () { + if (/^cp\|/.test(msg)) { + chan.history = []; + } else { + chan.history.push(msg); + } cb(); }, function (err) { cb({error: err}); @@ -118,7 +132,7 @@ define([ if (parsed.validateKey && parsed.channel) { return; } // End of history: emit READY if (parsed.state && parsed.state === 1 && parsed.channel) { - ctx.emit('READY', ''); + ctx.emit('READY', '', chan.clients); return; } if (parsed.error && parsed.channel) { return; } @@ -126,20 +140,24 @@ define([ var msg = parsed[4]; // Keep only the history for our channel - if (msg[3] !== channel) { return; } + if (parsed[3] !== channel) { return; } if (chan.lastCp) { - if (chan.lastCp === msg) { + if (chan.lastCp === msg.slice(0, 11)) { delete chan.lastCp; } return; } var isCp = /^cp\|/.test(msg); - if (isCp) { return; } + if (isCp) { + chan.history = []; + return; + } chan.lastKnownHash = msg.slice(0,64); ctx.emit('MESSAGE', msg, chan.clients); + chan.history.push(msg); }); network.join(channel).then(onOpen, function (err) { @@ -163,6 +181,9 @@ define([ return void chan.sendMsg(data.isCp, cb); } chan.sendMsg(data.msg, cb); + ctx.emit('MESSAGE', data.msg, chan.clients.filter(function (cl) { + return cl !== clientId; + })); }; var leaveChannel = function (ctx, padChan) { @@ -224,7 +245,7 @@ define([ } }; - return cursor; + return oo; }; return OO;