From c4ac858f5d14a5575a313e956a3d5203854a8436 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 26 Apr 2019 15:17:20 +0200 Subject: [PATCH 01/25] Remove chainpad-netflux-outer --- www/common/outer/async-store.js | 35 ++- www/common/outer/chainpad-netflux-worker.js | 294 -------------------- 2 files changed, 23 insertions(+), 306 deletions(-) delete mode 100644 www/common/outer/chainpad-netflux-worker.js 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); - }); - }*/ - }; -}); - From 5a19f7cc5d55a1ee27e5d2f1c530ad08f26d99a5 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 3 May 2019 15:07:04 +0200 Subject: [PATCH 02/25] Recent pads improvements --- www/common/outer/userObject.js | 6 ++++- www/common/proxy-manager.js | 15 ++++++++++- www/common/userObject.js | 2 ++ www/drive/app-drive.less | 18 +++++++++++++ www/drive/inner.js | 47 ++++++++++++++++++++++++++-------- www/drive/tests.js | 18 ++++++++++++- 6 files changed, 93 insertions(+), 13 deletions(-) diff --git a/www/common/outer/userObject.js b/www/common/outer/userObject.js index 46ae72b3b..10e30ba95 100644 --- a/www/common/outer/userObject.js +++ b/www/common/outer/userObject.js @@ -636,7 +636,7 @@ define([ } // If we have an edit link, check the view link - if (el.href && parsed.hashData.type === "pad") { + if (el.href && parsed.hashData.type === "pad" && parsed.hashData.version) { if (parsed.hashData.mode === "view") { el.roHref = el.href; delete el.href; @@ -651,6 +651,10 @@ define([ } } } + // v0 hashes don't support read-only + if (parsed.hashData.version === 0) { + delete el.roHref; + } // Fix href if (el.href && /^https*:\/\//.test(el.href)) { el.href = Hash.getRelativeHref(el.href); } diff --git a/www/common/proxy-manager.js b/www/common/proxy-manager.js index d23ab3ebc..a933da776 100644 --- a/www/common/proxy-manager.js +++ b/www/common/proxy-manager.js @@ -961,7 +961,20 @@ define([ }; var getRecentPads = function (Env) { - return Env.user.userObject.getRecentPads(); + var files = []; + var userObjects = _getUserObjects(Env); + userObjects.forEach(function (uo) { + var data = uo.getFiles([UserObject.FILES_DATA]).map(function (id) { + return [Number(id), uo.getFileData(id)]; + }); + Array.prototype.push.apply(files, data); + }); + var sorted = files.filter(function (a) { return a[1].atime; }) + .sort(function (a,b) { + return b[1].atime - a[1].atime; + }); + return sorted; + //return Env.user.userObject.getRecentPads(); }; var getOwnedPads = function (Env) { return Env.user.userObject.getOwnedPads(Env.edPublic); diff --git a/www/common/userObject.js b/www/common/userObject.js index ce6a3168d..1a2229d40 100644 --- a/www/common/userObject.js +++ b/www/common/userObject.js @@ -95,6 +95,8 @@ define([ exp.isReadOnlyFile = function (element) { if (!isFile(element)) { return false; } var data = exp.getFileData(element); + // undefined means this pad doesn't support read-only + if (!data.roHref) { return; } return Boolean(data.roHref && !data.href); }; diff --git a/www/drive/app-drive.less b/www/drive/app-drive.less index 5bf6a7ea8..7a993a5e5 100644 --- a/www/drive/app-drive.less +++ b/www/drive/app-drive.less @@ -509,6 +509,10 @@ } } } + &.cp-app-drive-element-separator { + text-align: left; + font-weight: bold; + } } } .cp-app-drive-element { @@ -521,6 +525,12 @@ &.cp-app-drive-element { position: relative; } + &.cp-app-drive-element-separator { + display: block; + height: auto; + width: auto; + border: none !important; + } input { width: 100%; margin: 0; @@ -600,6 +610,14 @@ height: @variables_bar-height; line-height: @variables_bar-height; } + &.cp-app-drive-element-separator { + position: relative; + height: 1.5 * @variables_bar-height; + line-height: 1.5 * @variables_bar-height; + span { + position: absolute; + } + } &.cp-app-drive-element-header { cursor: default; color: @drive_table-header-fg; diff --git a/www/drive/inner.js b/www/drive/inner.js index 850db5450..a58cee94f 100644 --- a/www/drive/inner.js +++ b/www/drive/inner.js @@ -2454,24 +2454,51 @@ define([ var displayRecent = function ($list) { var filesList = manager.getRecentPads(); var limit = 20; + + var now = new Date(); + var last1 = new Date(now); + last1.setDate(last1.getDate()-1); + var last7 = new Date(now); + last7.setDate(last7.getDate()-7); + var last28 = new Date(now); + last28.setDate(last28.getDate()-28); + + var header7, header28, headerOld; var i = 0; - filesList.forEach(function (id) { - if (i >= limit) { return; } - // Check path (pad exists and not in trash) + $list.append(h('li.cp-app-drive-element-separator', h('span', Messages.drive_active1Day))); + filesList.some(function (arr) { + if (i >= limit) { return true; } + var id = arr[0]; + var file = arr[1]; + if (!file || !file.atime) { return; } + + if (file.atime <= last28 && i >= limit) { + return true; + } + var paths = manager.findFile(id); if (!paths.length) { return; } var path = paths[0]; if (manager.isPathIn(path, [TRASH])) { return; } - // Display the pad - var file = manager.getFileData(id); - if (!file) { - //debug("Unsorted or template returns an element not present in filesData: ", href); - file = { title: Messages.fm_noname }; - //return; + + + if (!header7 && file.atime < last1) { + $list.append(h('li.cp-app-drive-element-separator', h('span', Messages.drive_active7Days))); + header7 = true; } + if (!header28 && file.atime < last7) { + $list.append(h('li.cp-app-drive-element-separator', h('span', Messages.drive_active28Days))); + header28 = true; + } + if (!headerOld && file.atime < last28) { + $list.append(h('li.cp-app-drive-element-separator', h('span', Messages.drive_activeOld))); + headerOld = true; + } + + // Display the pad var $icon = getFileIcon(id); var ro = manager.isReadOnlyFile(id); - // ro undefined mens it's an old hash which doesn't support read-only + // ro undefined means it's an old hash which doesn't support read-only var roClass = typeof(ro) === 'undefined' ? ' cp-app-drive-element-noreadonly' : ro ? ' cp-app-drive-element-readonly' : ''; var $element = $('
  • ', { diff --git a/www/drive/tests.js b/www/drive/tests.js index 015178208..1633740bc 100644 --- a/www/drive/tests.js +++ b/www/drive/tests.js @@ -268,9 +268,21 @@ define([ assert(function (cb) { console.log('START DRIVE utils'); var files = JSON.parse(JSON.stringify(example)); + + var href6 = "/pad/#67a9385b07352be53e40746d2be6ccd7XAYSuJYYqa9NfmInyGbj7LNy/"; + var id6 = 1000000000006; + var data = { + href: href6, + title: 'Title6', + atime: +new Date(), + ctime: +new Date() + }; + files.filesData[id6] = data; + var fo = FO.init(files, config); fo.fixFiles(); + if (fo.isFile({}) || fo.isFile(href1) || !fo.isFile(href1, true) || !fo.isFile(id1)) { console.log("DRIVE utils: isFile returns an incorrect value"); return cb(); @@ -283,6 +295,10 @@ define([ console.log("DRIVE utils: isReadOnlyFile returns false for a 'view' file"); return cb(); } + if (typeof fo.isReadOnlyFile(id6) !== "undefined") { + console.log("DRIVE utils: isReadOnlyFile should return undefined for a v0 hash"); + return cb(); + } if (!fo.hasSubfolder(files.root.Folder) || fo.hasSubfolder(files.root.Folder2)) { console.log("DRIVE utils: hasSubfolder returns an incorrect value"); return cb(); @@ -303,7 +319,7 @@ define([ console.log("DRIVE utils: 'find' returns an incorrect value"); return cb(); } - if (fo.getFiles().length !== 4 || fo.getFiles(['trash']).length !== 2) { + if (fo.getFiles().length !== 5 || fo.getFiles(['trash']).length !== 2) { console.log("DRIVE utils: getFiles returns an incorrect value"); return cb(); } From 275d0390c93f3a7b7dd573cae68f3734ed7ae94f Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 3 May 2019 13:08:18 +0000 Subject: [PATCH 03/25] Translated using Weblate (English) Currently translated at 100.0% (956 of 956 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ Translated using Weblate (English) Currently translated at 100.0% (955 of 955 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ Translated using Weblate (English) Currently translated at 100.0% (954 of 954 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ --- www/common/translations/messages.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/www/common/translations/messages.json b/www/common/translations/messages.json index 375f24dd7..8273513ab 100644 --- a/www/common/translations/messages.json +++ b/www/common/translations/messages.json @@ -1047,5 +1047,8 @@ "admin_diskUsageHint": "Amount of storage space consumed by various CryptPad resources", "admin_diskUsageButton": "Generate report", "settings_codeSpellcheckTitle": "Spellcheck", - "settings_codeSpellcheckLabel": "Enable spellcheck in the code editor" + "settings_codeSpellcheckLabel": "Enable spellcheck in the code editor", + "drive_active1Day": "Last 24 hours", + "drive_active7Days": "Last 7 days", + "drive_active28Days": "Last 4 weeks" } From f5f2b16d1004284c9f9ea16946952ca6a61f1bc6 Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 3 May 2019 13:08:18 +0000 Subject: [PATCH 04/25] Translated using Weblate (French) Currently translated at 100.0% (956 of 956 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/fr/ --- www/common/translations/messages.fr.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/www/common/translations/messages.fr.json b/www/common/translations/messages.fr.json index 2d69fc534..5852f0d41 100644 --- a/www/common/translations/messages.fr.json +++ b/www/common/translations/messages.fr.json @@ -1047,5 +1047,8 @@ "admin_diskUsageHint": "Quantité d'espace de stockage utilisé par la base de données de CryptPad", "admin_diskUsageButton": "Générer le rapport", "settings_codeSpellcheckTitle": "Vérification orthographique", - "settings_codeSpellcheckLabel": "Activer la vérification orthographique" + "settings_codeSpellcheckLabel": "Activer la vérification orthographique", + "drive_active1Day": "Dernières 24 heures", + "drive_active7Days": "7 derniers jours", + "drive_active28Days": "4 dernières semaines" } From f04f9955de74edc1790cc65c5f2f33166f147e03 Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 3 May 2019 13:08:18 +0000 Subject: [PATCH 05/25] Translated using Weblate (German) Currently translated at 100.0% (956 of 956 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/de/ --- www/common/translations/messages.de.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/www/common/translations/messages.de.json b/www/common/translations/messages.de.json index 0abb1f49e..5bb1c0937 100644 --- a/www/common/translations/messages.de.json +++ b/www/common/translations/messages.de.json @@ -1041,5 +1041,14 @@ "contact_devHint": "Für Verbesserungsvorschläge oder zum Danke-Sagen.", "contact_bug": "Fehlerbericht", "contact_chat": "Chat", - "contact_email": "E-Mail" + "contact_email": "E-Mail", + "timeoutError": "Ein Fehler hat deine Verbindung zum Server unterbrochen.
    Drücke Esc, um die Seite neu zu laden.", + "admin_diskUsageTitle": "Speicherplatzbelegung", + "admin_diskUsageHint": "Speicherplatz, der von verschiedenen CryptPad-Ressourcen verwendet wird", + "admin_diskUsageButton": "Bericht generieren", + "settings_codeSpellcheckTitle": "Rechtschreibprüfung", + "settings_codeSpellcheckLabel": "Rechtschreibprüfung im Code-Editor aktivieren", + "drive_active1Day": "Letzte 24 Stunden", + "drive_active7Days": "Letzte 7 Tage", + "drive_active28Days": "Letzte 4 Wochen" } From 8d3ba0fd7513acd6fca2145355e6a3ecdf9bf7ad Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 3 May 2019 15:18:23 +0200 Subject: [PATCH 06/25] Fix reset tips in settings --- www/settings/inner.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/settings/inner.js b/www/settings/inner.js index e74495c82..85934c765 100644 --- a/www/settings/inner.js +++ b/www/settings/inner.js @@ -832,9 +832,9 @@ define([ var localStore = window.cryptpadStore; $button.click(function () { - Object.keys(localStore).forEach(function (k) { + Object.keys(localStore.store).forEach(function (k) { if(k.slice(0, 9) === "hide-info") { - localStore.put(k, undefined); + localStore.put(k, null); } }); UI.alert(Messages.settings_resetTipsDone); From 64667d6d0d81a3eabbe7e4a315c17052546b1d40 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 13 May 2019 15:23:46 +0200 Subject: [PATCH 07/25] Recent pads UI fix --- www/drive/app-drive.less | 1 + 1 file changed, 1 insertion(+) diff --git a/www/drive/app-drive.less b/www/drive/app-drive.less index 7a993a5e5..3554306e8 100644 --- a/www/drive/app-drive.less +++ b/www/drive/app-drive.less @@ -512,6 +512,7 @@ &.cp-app-drive-element-separator { text-align: left; font-weight: bold; + margin-top: 0; } } } From a148434244606128fc208ce409d22a1537199f16 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 13 May 2019 15:26:20 +0200 Subject: [PATCH 08/25] Fix share dialog pre-selecting the edit link in a read-only pad #365 --- www/common/common-ui-elements.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 79863a527..9418c2e79 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -452,7 +452,7 @@ define([ } common.getAttribute(['general', 'share'], function (err, val) { val = val || {}; - if (val.edit === false) { + if (val.edit === false || !hashes.editHash) { $(link).find('#cp-share-editable-false').prop('checked', true); $(link).find('#cp-share-editable-true').prop('checked', false); } else { From ce8cbaf136879e1eeb7643d4b7e7011c1082434d Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 14 May 2019 09:15:05 +0000 Subject: [PATCH 09/25] Translated using Weblate (English) Currently translated at 100.0% (957 of 957 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ --- www/common/translations/messages.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/www/common/translations/messages.json b/www/common/translations/messages.json index 8273513ab..9b7fc7281 100644 --- a/www/common/translations/messages.json +++ b/www/common/translations/messages.json @@ -1050,5 +1050,6 @@ "settings_codeSpellcheckLabel": "Enable spellcheck in the code editor", "drive_active1Day": "Last 24 hours", "drive_active7Days": "Last 7 days", - "drive_active28Days": "Last 4 weeks" + "drive_active28Days": "Last 4 weeks", + "drive_activeOld": "Less recent pads" } From e0592bddd486dce8eda29fbc9c6aac98ee4c4955 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 14 May 2019 09:15:06 +0000 Subject: [PATCH 10/25] Translated using Weblate (French) Currently translated at 100.0% (957 of 957 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/fr/ --- www/common/translations/messages.fr.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/www/common/translations/messages.fr.json b/www/common/translations/messages.fr.json index 5852f0d41..1393dd470 100644 --- a/www/common/translations/messages.fr.json +++ b/www/common/translations/messages.fr.json @@ -1050,5 +1050,6 @@ "settings_codeSpellcheckLabel": "Activer la vérification orthographique", "drive_active1Day": "Dernières 24 heures", "drive_active7Days": "7 derniers jours", - "drive_active28Days": "4 dernières semaines" + "drive_active28Days": "4 dernières semaines", + "drive_activeOld": "Pads moins récents" } From 0722f302a5482af5ee132711554a45d0cdbd7bcf Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 14 May 2019 09:15:06 +0000 Subject: [PATCH 11/25] Translated using Weblate (Italian) Currently translated at 43.5% (416 of 956 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/it/ --- www/common/translations/messages.it.json | 71 +++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/www/common/translations/messages.it.json b/www/common/translations/messages.it.json index 5a37bd222..6b4463892 100644 --- a/www/common/translations/messages.it.json +++ b/www/common/translations/messages.it.json @@ -358,5 +358,74 @@ "fm_info_template": "Contiene tutti i pads salvati come modelli e che puoi riutilizzare per creare nuovi pad.", "fm_info_recent": "Lista dei pads recentemente aperti o modificati.", "fm_info_trash": "Svuota il tuo cestino per liberare spazio nel tuo CryptDrive.", - "fm_info_allFiles": "Contiene tutti i files da \"Documenti\", \"Non catalogati\", \"Cestino\". Non puoi muovere o cancellare files da qui." + "fm_info_allFiles": "Contiene tutti i files da \"Documenti\", \"Non catalogati\", \"Cestino\". Non puoi muovere o cancellare files da qui.", + "fm_info_anonymous": "Non sei loggato, quindi i tuoi pads scadranno tra tre mesi (find out more). Sono salvati nel tuo browser, quindi cancellando la cronologia potresti farli scomparire.
    Registrati o Effettua il login per salvarti permanentemente.
    ", + "fm_info_sharedFolder": "Questa è una cartella condivisa. Non sei loggato, quindi puoi accederla solo in modalità solo lettura.
    Registrati o Effettua il login per poterla importare nel tuo CryptDrive e per modificarla.", + "fm_info_owned": "Sei il proprietario dei pads mostrati qui. Questo significa che puoi rimuoverli permanentemente dal server, quando lo desideri. Se lo fai, gli altri utenti non potranno mai più accedervi.", + "fm_alert_backupUrl": "Link di backup per questo drive.
    Èestremamente raccomandato che tu lo tenga segreto.
    Puoi usarlo per recuperare tutti i tuoi files nel caso in cui la memoria del tuo browser venga cancellata.
    Chiunque in possesso di questo link può modificare o rimuovere tutti i files nel tuo file manager.
    ", + "fm_backup_title": "Link di backup", + "fm_nameFile": "Come vuoi chiamare questo file?", + "fm_error_cantPin": "Errore interno del server. Per favore, ricarica la pagina e prova di nuovo.", + "fm_viewListButton": "Visualizzazione lista", + "fm_viewGridButton": "Visualizzazione griglia", + "fm_renamedPad": "Hai impostato un nome personalizzato per questo pad. Il suo titolo condiviso è:
    {0}", + "fm_canBeShared": "Questa cartella può essere condivisa", + "fm_prop_tagsList": "Tags", + "fm_burnThisDriveButton": "Cancella tutte le informazioni salvate da CryptPad nel tuo browser", + "fm_burnThisDrive": "Sei sicuro di voler rimuovere tutti i dati salvati da CryptPad nel tuo browser?
    Questo rimuoverà il tuo CryptDrive e la sua cronologia dal tuo browser, ma i tuoi pad continueranno a esistere (criptati) nel nostro server.", + "fm_padIsOwned": "Sei il proprietario di questo pad", + "fm_padIsOwnedOther": "Il proprietario di questo pad è un altro user", + "fm_deletedPads": "Questi pads non esistono più sul server, sono stati rimossi dal tuo CryptDrive: {0}", + "fm_tags_name": "Nome del tag", + "fm_tags_used": "Numero di utilizzi", + "fm_restoreDrive": "Ripristina il tuo drive ad uno stato precedente. Per i migliori risultati, evita di fare cambiamenti al tuo drive sinchè questo processo non sarà completato.", + "fm_moveNestedSF": "Non puoi spostare una cartella condivisa all'interno di un'altra. La cartella {0} non è stata spostata.", + "fm_passwordProtected": "Questo documento è protetto da una password", + "fc_newfolder": "Nuova cartella", + "fc_newsharedfolder": "Nuova cartella condivisa", + "fc_rename": "Rinomina", + "fc_open": "Apri", + "fc_open_ro": "Apri (solo lettura)", + "fc_delete": "Muovi nel cestino", + "fc_delete_owned": "Cancella dal server", + "fc_restore": "Ripristina", + "fc_remove": "Rimuovi dal tuo CryptDrive", + "fc_remove_sharedfolder": "Rimuovi", + "fc_empty": "Svuota il cestino", + "fc_prop": "Proprietà", + "fc_hashtag": "Tags", + "fc_sizeInKilobytes": "Dimensione in Kilobytes", + "fo_moveUnsortedError": "Non puoi muovere una cartella nella lista dei modelli", + "fo_existingNameError": "Il nome è già utilizzato in questa cartella. Per favore, scegline un altro.", + "fo_moveFolderToChildError": "Non puoi muovere una cartella in una contenuta in essa", + "fo_unableToRestore": "Impossibile ripristinare questo file nella sua location originaria. Puoi provare a muoverlo in una nuova posizione.", + "fo_unavailableName": "Un file o una cartella con lo stesso nome esiste già nella nuova posizione. Rinomina l'elemento e prova di nuovo.", + "fs_migration": "Il tuo CryptDrive sta per essere aggiornato a una nuova versione. La pagina corrente sarà ricaricata.
    Per favore, ricarica la pagina per continuare a usarla.", + "login_login": "Login", + "login_makeAPad": "Crea un pad in maniera anonima", + "login_nologin": "Sfoglia i pads locali", + "login_register": "Registrati", + "logoutButton": "Logout", + "settingsButton": "Impostazioni", + "login_username": "Nome utente", + "login_password": "Password", + "login_confirm": "Conferma la tua password", + "login_remember": "Ricorda l'accesso", + "login_hashing": "Effettuo l'hash della tua password, questo può richiedere del tempo.", + "login_hello": "Buongiorno {0},", + "login_helloNoName": "Ciao,", + "login_accessDrive": "Accedi al tuo drive", + "login_orNoLogin": "o", + "login_noSuchUser": "Nome utente o password non validi. Prova di nuovi, oppure registrati", + "login_invalUser": "Nome utente richiesto", + "login_invalPass": "Password richiesta", + "login_unhandledError": "Si è verificato un errore inaspettato :(", + "register_importRecent": "Importa i pads dalla tua sessione anonima", + "register_acceptTerms": "Accetto i termini del servizio", + "register_passwordsDontMatch": "Le passwords non corrispondono!", + "register_passwordTooShort": "Le passwords devono essere lunghe almeno {0} caratteri.", + "register_mustAcceptTerms": "Devi accettare i termini del servizio.", + "register_mustRememberPass": "Non possiamo ripristinare la tua password se la dimentichi. È estremamente importante che tu la ricordi! Per favore, spunta la checkbox per confermare.", + "register_whyRegister": "Perché registrarsi?", + "register_header": "Benvenuto su CryptPad" } From 3b420bc71b5add18d3337baa80323e2b20bb3be1 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 14 May 2019 09:15:06 +0000 Subject: [PATCH 12/25] Translated using Weblate (Romanian) Currently translated at 57.6% (551 of 956 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ro/ --- www/common/translations/messages.ro.json | 42 +++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/www/common/translations/messages.ro.json b/www/common/translations/messages.ro.json index 5e66d7287..376fb3636 100644 --- a/www/common/translations/messages.ro.json +++ b/www/common/translations/messages.ro.json @@ -514,5 +514,45 @@ "fm_padIsOwnedOther": "Acest pad îi aparține altui utilizator", "fm_deletedPads": "Aceste pad-uri nu mai există pe server, au fost șterse din CryptDrive: {0}", "fm_tags_name": "Numele etichetei", - "fm_tags_used": "Numărul de utilizări" + "fm_tags_used": "Numărul de utilizări", + "fm_restoreDrive": "Drive-ul tău va fi setat la o versiune aneterioară. Pentru a obține cele mai bune rezultate, te rugăm să eviți să aduci modificări în drive-ul tău până când procesul va fi terminat.", + "fm_moveNestedSF": "Nu poti plasa un folder partajat în interiorul altuia. Folderul {0} nu a fost mutat.", + "fm_passwordProtected": "Acest document este protejat cu o parolă", + "fc_newsharedfolder": "Folder partajat nou", + "fc_delete_owned": "Șterge de pe server", + "fc_remove_sharedfolder": "Șterge", + "fc_hashtag": "Etichete", + "fs_migration": "CrytpDrive-ul tău este updatat la o versiune nouă. În consecință, pagina curentă trebuie reîncarcată. Te rugăm să reîncarci această pagina pentru a continua să o utilizezi.", + "register_passwordTooShort": "Parolele trebuie să aibă o lungime de cel putin {0} caractere.", + "register_whyRegister": "De ce să te înscrii?", + "settings_cat_account": "Cont", + "settings_cat_drive": "CrytpDrive", + "settings_cat_cursor": "Cursor", + "settings_cat_code": "Cod", + "settings_cat_pad": "Rich text", + "settings_cat_creation": "Pad nou", + "settings_cat_subscription": "Abonare", + "settings_backupCategory": "Backup", + "settings_backupHint": "Fă backup sau restaurează tot conținutul CryptDrive-ului tău. Aceasta nu va însemna conținutul pad-urilor tale, ci doar modalitatea de a le accesa", + "settings_backupHint2": "Descarcă conținutul actual al pad-urilor tale. Ele vor fi descărcate într-un format care poate fi citit, dacă un astfel de format este disponibil.", + "settings_backup2": "Descarcă-mi CryptDrive-ul", + "settings_backup2Confirm": "Această operatiune va descărca toate pad-urile și fișierele din CryptDrive-ul tău. Dacă vrei să continui, alege un nume și apasă OK", + "settings_exportTitle": "Exportă-ți CryptDrive-ul", + "settings_exportDescription": "Te rugăm să aștepți descărcarea și decriptarea documentelor tale. Această operațiune poate dura câteva minute. Închiderea ferestrei va întrerupe acest proces.", + "settings_exportFailed": "Dacă descărcarea unui pad durează mai mult de 1 minut, acesta nu va fi inclus în export. Exportul va conține link-uri către toate pad-urile care nu au fost descărcate.", + "settings_exportWarning": "Notă: acest program este în versiune beta și ar putea avea probleme de scalabilitate. Pentru o performanță mai bună, îți recomandam să rămâi pe acest tab", + "settings_exportCancel": "Ești sigur că vrei să anulezi exportul? Va trebui să-l rulezi de la început data viitoare.", + "settings_export_reading": "Citire CryptDrive...", + "settings_export_download": "Descărcarea și decriptarea documentelor tale este în curs...", + "settings_export_compressing": "Comprimăm datele...", + "settings_export_done": "Descărcarea este gata!", + "settings_exportError": "Vizualizează erorile", + "settings_exportErrorDescription": "Următoarele documente nu au putut fi adăugate în export:", + "settings_exportErrorEmpty": "Acest document nu poate fi exportat (conținut gol sau invalid)", + "settings_exportErrorMissing": "Acest document lipsește de pe serverele noastre (este expirat sau a fost șters de către proprietarul său)", + "settings_exportErrorOther": "A apărut o eroare in timpul exportului acestui document: {0}", + "settings_resetNewTitle": "Curățare CryptDrive", + "settings_resetButton": "Șterge", + "settings_resetTipsAction": "Resetează", + "settings_thumbnails": "Miniaturi" } From bc413d7514fc137c0274e5c0160a77f06151fabd Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 14 May 2019 09:15:06 +0000 Subject: [PATCH 13/25] Translated using Weblate (Russian) Currently translated at 36.7% (351 of 956 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/ru/ --- www/common/translations/messages.ru.json | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/www/common/translations/messages.ru.json b/www/common/translations/messages.ru.json index 3c43c4a8e..3e473505b 100644 --- a/www/common/translations/messages.ru.json +++ b/www/common/translations/messages.ru.json @@ -335,5 +335,22 @@ "contacts_info4": "Любой участник может полностью очистить историю чата", "contacts_confirmRemoveHistory": "Вы уверены, что хотите навсегда удалить свою историю чата? Данные не могут быть восстановлены", "contacts_removeHistoryServerError": "При удалении истории чата произошла ошибка. Попробуйте позже еще раз", - "contacts_online": "Другой пользователь из этой комнаты находится онлайн" + "contacts_online": "Другой пользователь из этой комнаты находится онлайн", + "fm_newButtonTitle": "Создайте новый пэд или папку, импортируйте файл в текущую папку", + "fm_lastAccess": "Последний доступ", + "fm_creation": "Создание", + "fm_forbidden": "Запрещенное действие", + "fm_removePermanentlyDialog": "Вы уверены, что хотите навсегда удалить этот элемент из вашего хранилища?", + "fm_removeSeveralDialog": "Вы уверены, что хотите перенести эти {0} элементы в корзину?", + "fm_removeDialog": "Вы уверены, что хотите переместить {0} в корзину?", + "fm_deleteOwnedPad": "Вы уверены, что хотите навсегда удалить этот пэд с сервера?", + "fm_deleteOwnedPads": "Вы уверены, что хотите навсегда удалить эти пэды с сервера?", + "fm_restoreDialog": "Вы уверены, что хотите восстановить {0} в прежнее местоположение?", + "fm_unknownFolderError": "Выбранный или последний раз посещенный каталог больше не существует. Открывается изначальная папка...", + "fm_contextMenuError": "Невозможно открыть контекстное меню для данного элемента. Если проблема остается, попробуйте перезагрузить страницу.", + "fm_selectError": "Невозможно выбрать выбранный элемент. Если проблема сохраняется, попробуйте перезагрузить страницу.", + "fm_info_root": "Создавайте здесь неограниченное количество вложенных папок, чтобы сортировать ваши файлы.", + "fm_info_template": "Содержит все пэды, сохраненные в виде шаблонов, которые можно использовать повторно при создании нового пэда.", + "fm_info_recent": "Показать недавно измененные или открытые пэды.", + "fm_info_trash": "Опустошите корзину, чтобы освободить место в хранилище." } From c7b165590720ceec2873ca3bb3ef9de150a81326 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 14 May 2019 09:15:06 +0000 Subject: [PATCH 14/25] Translated using Weblate (Spanish) Currently translated at 45.2% (433 of 957 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/es/ --- www/common/translations/messages.es.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/www/common/translations/messages.es.json b/www/common/translations/messages.es.json index 4bb98225c..6766907f1 100644 --- a/www/common/translations/messages.es.json +++ b/www/common/translations/messages.es.json @@ -10,7 +10,8 @@ "kanban": "Kanban", "drive": "CryptDrive", "todo": "Lista de tareas", - "file": "Archivo" + "file": "Archivo", + "media": "" }, "disconnected": "Desconectado", "synchronizing": "Sincronización", From c61617411a19502650d47179df2587db6534d713 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 15 May 2019 14:49:35 +0200 Subject: [PATCH 15/25] Add mailbox module --- www/common/outer/async-store.js | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index efa05d85d..72166095c 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -12,6 +12,7 @@ define([ '/common/common-messenger.js', '/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', @@ -22,7 +23,7 @@ define([ '/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, + Cursor, OnlyOffice, Mailbox, CpNfWorker, NetConfig, AppConfig, Crypto, ChainPad, Listmap, nThen, Saferphore) { var create = function () { @@ -939,7 +940,6 @@ define([ }; // Cursor - Store.cursor = { execCommand: function (clientId, data, cb) { if (!store.cursor) { return void cb ({error: 'Cursor channel is disabled'}); } @@ -947,6 +947,14 @@ define([ } }; + // Mailbox + Store.mailbox = { + execCommand: function (clientId, data, cb) { + if (!store.mailbox) { return void cb ({error: 'Mailbox is disabled'}); } + store.mailbox.execCommand(clientId, data, cb); + } + }; + // Admin Store.adminRpc = function (clientId, data, cb) { store.rpc.adminRpc(data, function (err, res) { @@ -1291,6 +1299,7 @@ define([ if (messengerIdx !== -1) { messengerEventClients.splice(messengerIdx, 1); } + // TODO mailbox events try { store.cursor.removeClient(clientId); } catch (e) { console.error(e); } @@ -1392,6 +1401,17 @@ define([ }); }; + var loadMailbox = function (waitFor) { + store.mailbox = Mailbox.init(store, waitFor, function (ev, data, clients) { + clients.forEach(function (cId) { + postMessage(cId, 'MAILBOX_EVENT', { + ev: ev, + data: data + }); + }); + }); + }; + ////////////////////////////////////////////////////////////////// /////////////////////// Init ///////////////////////////////////// ////////////////////////////////////////////////////////////////// @@ -1486,6 +1506,7 @@ define([ loadMessenger(); loadCursor(); loadOnlyOffice(); + loadMailbox(waitFor); }).nThen(function () { var requestLogin = function () { broadcast([], "REQUEST_LOGIN"); From 3feb310fc45a10403e6b41b0ed1a0701036ee2a5 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 15 May 2019 14:52:58 +0200 Subject: [PATCH 16/25] Add mailbox inner channel --- www/common/cryptpad-common.js | 8 ++++++++ www/common/outer/mailbox.js | 35 +++++++++++++++++++++++++++++++++++ www/common/outer/store-rpc.js | 2 ++ 3 files changed, 45 insertions(+) create mode 100644 www/common/outer/mailbox.js diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 9f1d3f544..027b61929 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -656,6 +656,12 @@ define([ }; cursor.onEvent = Util.mkEvent(); + // Mailbox + var mailbox = common.mailbox = {}; + mailbox.execCommand = function (data, cb) { + postMessage("MAILBOX_COMMAND", data, cb); + }; + mailbox.onEvent = Util.mkEvent(); // Pad RPC var pad = common.padRpc = {}; @@ -1096,6 +1102,8 @@ define([ CHAT_EVENT: common.messenger.onEvent.fire, // Cursor CURSOR_EVENT: common.cursor.onEvent.fire, + // Mailbox + MAILBOX_EVENT: common.mailbox.onEvent.fire, // Pad PAD_READY: common.padRpc.onReadyEvent.fire, PAD_MESSAGE: common.padRpc.onMessageEvent.fire, diff --git a/www/common/outer/mailbox.js b/www/common/outer/mailbox.js new file mode 100644 index 000000000..ab9d24d58 --- /dev/null +++ b/www/common/outer/mailbox.js @@ -0,0 +1,35 @@ +define([ + '/common/common-util.js', + '/common/common-constants.js', + '/customize/messages.js', + '/bower_components/chainpad-netflux/chainpad-netflux.js', + '/bower_components/chainpad-crypto/crypto.js', +], function (Util, Constants, Messages, CpNetflux, Crypto) { + var Mailbox = {}; + + Mailbox.init = function (store, waitFor, emit) { + var mailbox = {}; + var ctx = { + store: store, + emit: emit, + }; + + mailbox.removeClient = function (clientId) { + // TODO + //removeClient(ctx, clientId); + }; + mailbox.leavePad = function (padChan) { + // TODO + //leaveChannel(ctx, padChan); + }; + mailbox.execCommand = function (clientId, obj, cb) { + var cmd = obj.cmd; + var data = obj.data; + }; + + return mailbox; + }; + + return Mailbox; +}); + diff --git a/www/common/outer/store-rpc.js b/www/common/outer/store-rpc.js index 49bb7c960..aed0d5ab4 100644 --- a/www/common/outer/store-rpc.js +++ b/www/common/outer/store-rpc.js @@ -66,6 +66,8 @@ define([ OO_COMMAND: Store.onlyoffice.execCommand, // Cursor CURSOR_COMMAND: Store.cursor.execCommand, + // Mailbox + MAILBOX_COMMAND: Store.mailbox.execCommand, // Pad SEND_PAD_MSG: Store.sendPadMsg, JOIN_PAD: Store.joinPad, From 827a47d9b77273eb24fdc48c8f4577ab4c13e5ff Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 16 May 2019 14:11:31 +0200 Subject: [PATCH 17/25] Fix issue when reconnecting to a pad --- www/common/outer/async-store.js | 1 + 1 file changed, 1 insertion(+) diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index f9bca1e35..8a786aeec 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -1084,6 +1084,7 @@ define([ channel.queue.forEach(function (data) { channel.sendMessage(data.message, clientId); }); + channel.queue = []; channel.bcast("PAD_CONNECT", { myID: wc.myID, id: wc.id, From 909e70905c0ee345a5f0a1efc5759b4549a36d25 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 16 May 2019 15:20:50 +0200 Subject: [PATCH 18/25] Add comment --- www/common/outer/async-store.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 8a786aeec..2b6663ef2 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -1055,6 +1055,8 @@ define([ }, onConnectionChange: function () {}, crypto: { + // The encryption and decryption is done in the outer window. + // This async-store only deals with already encrypted messages. encrypt: function (m) { return m; }, decrypt: function (m) { return m; } }, From c8b9830298e094b8ec6d15d5f1e7a89a9f8ef93c Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 16 May 2019 16:10:13 +0200 Subject: [PATCH 19/25] Fix duplicate entries in the recent pads --- www/drive/inner.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/www/drive/inner.js b/www/drive/inner.js index a58cee94f..f6146fb4e 100644 --- a/www/drive/inner.js +++ b/www/drive/inner.js @@ -2465,6 +2465,8 @@ define([ var header7, header28, headerOld; var i = 0; + var channels = []; + $list.append(h('li.cp-app-drive-element-separator', h('span', Messages.drive_active1Day))); filesList.some(function (arr) { if (i >= limit) { return true; } @@ -2481,6 +2483,8 @@ define([ var path = paths[0]; if (manager.isPathIn(path, [TRASH])) { return; } + if (channels.indexOf(file.channel) !== -1) { return; } + channels.push(file.channel); if (!header7 && file.atime < last1) { $list.append(h('li.cp-app-drive-element-separator', h('span', Messages.drive_active7Days))); From de3bb5cdcf511b9839350a849eeb5e9bd16d6e40 Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 16 May 2019 16:14:25 +0200 Subject: [PATCH 20/25] Ignore jshint on mailbox placeholder --- www/common/outer/mailbox.js | 1 + 1 file changed, 1 insertion(+) diff --git a/www/common/outer/mailbox.js b/www/common/outer/mailbox.js index ab9d24d58..313690a29 100644 --- a/www/common/outer/mailbox.js +++ b/www/common/outer/mailbox.js @@ -1,3 +1,4 @@ +// jshint ignore: start define([ '/common/common-util.js', '/common/common-constants.js', From 3be85b155d9e448b8df5b10cb55913ebc3a08851 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 20 May 2019 17:18:02 +0200 Subject: [PATCH 21/25] Fix issues with templates in polls #375 --- www/common/common-ui-elements.js | 3 ++- www/common/cryptget.js | 9 +++++---- www/common/cryptpad-common.js | 4 ++++ www/common/outer/async-store.js | 5 +++-- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 9418c2e79..9c1d2690c 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -719,7 +719,8 @@ define([ } } sframeChan.query('Q_SAVE_AS_TEMPLATE', { - toSave: toSave + toSave: toSave, + title: title }, function () { UI.alert(Messages.templateSaved); Feedback.send('TEMPLATE_CREATED'); diff --git a/www/common/cryptget.js b/www/common/cryptget.js index 5279a17c9..d08b4b297 100644 --- a/www/common/cryptget.js +++ b/www/common/cryptget.js @@ -28,9 +28,9 @@ define([ } }; - var makeConfig = function (hash, password) { + var makeConfig = function (hash, opt) { // We can't use cryptget with a file or a user so we can use 'pad' as hash type - var secret = Hash.getSecrets('pad', hash, password); + var secret = Hash.getSecrets('pad', hash, opt.password); if (!secret.keys) { secret.keys = secret.key; } // support old hashses var config = { websocketURL: NetConfig.getWebsocketURL(), @@ -38,6 +38,7 @@ define([ validateKey: secret.keys.validateKey || undefined, crypto: Crypto.createEncryptor(secret.keys), logLevel: 0, + initialState: opt.initialState }; return config; }; @@ -57,7 +58,7 @@ define([ } opt = opt || {}; - var config = makeConfig(hash, opt.password); + var config = makeConfig(hash, opt); var Session = { cb: cb, hasNetwork: Boolean(opt.network) }; config.onReady = function (info) { @@ -82,7 +83,7 @@ define([ } opt = opt || {}; - var config = makeConfig(hash, opt.password); + var config = makeConfig(hash, opt); var Session = { cb: cb, }; config.onReady = function (info) { diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 027b61929..7b9e939b1 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -512,6 +512,10 @@ define([ optsPut = optsPut || {}; var optsGet = {}; + + if (parsed.type === 'poll') { optsGet.initialState = '{}'; } + if (parsed2.type === 'poll') { optsPut.initialState = '{}'; } + Nthen(function (waitFor) { if (parsed.hashData && parsed.hashData.password) { common.getPadAttribute('password', waitFor(function (err, password) { diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index be0bcb9b8..e174ecad3 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -479,10 +479,11 @@ define([ Store.addPad = function (clientId, data, cb) { if (!data.href && !data.roHref) { return void cb({error:'NO_HREF'}); } + var secret; if (!data.roHref) { var parsed = Hash.parsePadUrl(data.href); if (parsed.hashData.type === "pad") { - var secret = Hash.getSecrets(parsed.type, parsed.hash, data.password); + secret = Hash.getSecrets(parsed.type, parsed.hash, data.password); data.roHref = '/' + parsed.type + '/#' + Hash.getViewHashFromKeys(secret); } } @@ -490,7 +491,7 @@ define([ if (data.owners) { pad.owners = data.owners; } if (data.expire) { pad.expire = data.expire; } if (data.password) { pad.password = data.password; } - if (data.channel) { pad.channel = data.channel; } + if (data.channel || secret) { pad.channel = data.channel || secret.channel; } store.manager.addPad(data.path, pad, function (e) { if (e) { return void cb({error: e}); } sendDriveEvent('DRIVE_CHANGE', { From 6691d93a4cc2cf2851494bc895f1c6b19a9344de Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 20 May 2019 15:32:36 +0000 Subject: [PATCH 22/25] Translated using Weblate (German) Currently translated at 100.0% (957 of 957 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/de/ --- www/common/translations/messages.de.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/www/common/translations/messages.de.json b/www/common/translations/messages.de.json index 5bb1c0937..603ad53b0 100644 --- a/www/common/translations/messages.de.json +++ b/www/common/translations/messages.de.json @@ -1050,5 +1050,6 @@ "settings_codeSpellcheckLabel": "Rechtschreibprüfung im Code-Editor aktivieren", "drive_active1Day": "Letzte 24 Stunden", "drive_active7Days": "Letzte 7 Tage", - "drive_active28Days": "Letzte 4 Wochen" + "drive_active28Days": "Letzte 4 Wochen", + "drive_activeOld": "Ältere Pads" } From ce0709a31c3a554a43130b47f51d0176edf26d72 Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 20 May 2019 15:32:36 +0000 Subject: [PATCH 23/25] Translated using Weblate (Spanish) Currently translated at 58.4% (559 of 957 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/es/ Translated using Weblate (Spanish) Currently translated at 58.4% (559 of 957 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/es/ Translated using Weblate (Spanish) Currently translated at 58.3% (558 of 957 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/es/ Translated using Weblate (Spanish) Currently translated at 51.7% (495 of 957 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/es/ --- www/common/translations/messages.es.json | 137 ++++++++++++++++++++++- 1 file changed, 131 insertions(+), 6 deletions(-) diff --git a/www/common/translations/messages.es.json b/www/common/translations/messages.es.json index 6766907f1..5225f4ce8 100644 --- a/www/common/translations/messages.es.json +++ b/www/common/translations/messages.es.json @@ -11,10 +11,11 @@ "drive": "CryptDrive", "todo": "Lista de tareas", "file": "Archivo", - "media": "" + "media": "Media", + "sheet": "Hoja (Beta)" }, "disconnected": "Desconectado", - "synchronizing": "Sincronización", + "synchronizing": "Sincronizando", "reconnecting": "Reconectando...", "lag": "Retraso", "readonly": "Sólo lectura", @@ -374,16 +375,16 @@ "profile_urlPlaceholder": "URL", "profile_namePlaceholder": "Nombre mostrado en su perfil", "profile_avatar": "Imagen", - "profile_upload": "Subir una imagen", + "profile_upload": "Subir una imagen de perfil", "profile_error": "Error al crear tu perfil: {0}", - "profile_register": "Tienes que registrarte para crear un perfil", + "profile_register": "Tienes que ingresar para crear un perfil!", "profile_create": "Crear perfil", "profile_description": "Descripción", "profile_fieldSaved": "Guardado: {0}", "download_mt_button": "Descargar", "updated_0_header_logoTitle": "Volver a tu CryptDrive", "realtime_unrecoverableError": "El motor de tiempo real ha encontrado un error. Haga clic en OK para recargar la página.", - "typing": "Escribiendo", + "typing": "Editando", "profile_inviteButton": "Conectar", "profile_inviteButtonTitle": "Crear un enlace de invitación para este usuario.", "profile_inviteExplanation": "Hacer clic en OK creará un enlace de mensaje seguro que sólo {0} podrá ver.

    El enlace será copiado a tu portapapeles y puede ser compartido públicamente.", @@ -436,5 +437,129 @@ "settings_codeUseTabs": "Utilizar tabulaciones en vez de espacios", "pad_showToolbar": "Mostrar la barra de herramientas", "pad_hideToolbar": "Esconder la barra de herramientas", - "main_catch_phrase": "El Cloud Zero Knowledge" + "main_catch_phrase": "El Cloud Zero Knowledge", + "button_newkanban": "Nuevo Kanban", + "button_newsheet": "Nueva Hoja", + "padNotPinned": "Esta nota expirará luego de 3 meses de inactividad, {0}ingresar{1} o {2}registrarse{3}para conservar", + "anonymousStoreDisabled": "El webmaster de esta instancia de CryptPad a deshabilitado al almacenamiento para usuarios anónimos. Debes ingresar para poder usar CrytDrive.", + "expiredError": "Este pad ha expirado y ya no está disponible", + "deletedError": "Esta nota ha sido borrada por su dueño y ya no está disponible.", + "inactiveError": "Esta nota ha sido eliminada por inactividad. Presione Esc para crear una nueva nota.", + "chainpadError": "Ha ocurrido un error crítico al actualizar su contenido. Esta página esta en modo de sólo lectura, para asegurarse que no perderá su trabajo.
    HitEscpara continuar y ver esta nota, o recargar para editar nuevamente.", + "invalidHashError": "El documento que has solicitado tiene una URL invalida.", + "errorCopy": " Aún puedes copiar el contenido a otra ubicación apretando Esc.
    Una vez que dejes esta página desaparecerá para siempre!", + "errorRedirectToHome": "PresionaEscpara ser redirigido a tu Cryptdrive.", + "newVersionError": "Una nueva versión de CryptPad está disponible.
    Recargar para usar la nueva versión, o presiona escape para acceder a tu contenido en modo offline.", + "deletedFromServer": "Nota borrada desde el servidor", + "mustLogin": "Debes haber ingresado a tu cuenta para acceder a esta página", + "disabledApp": "Esta nota ha sido eliminada por inactividad. Presione Esc para crear una nueva nota.", + "initializing": "Iniciando...", + "forgotten": "Movido a la basura", + "errorState": "Error crítico: {0}", + "userlist_offline": "Actualmente estás desconectado, la lista del usuario ya no está disponible.", + "chatButton": "Chat", + "useTemplate": "Comenzar con una plantilla?", + "useTemplateOK": "Elija una plantilla (Enter)", + "template_import": "Importar una plantilla", + "template_empty": "No hay plantillas disponibles", + "propertiesButton": "Propiedades", + "propertiesButtonTitle": "Obtener las propiedades de esta nota", + "printButtonTitle2": "Imprimir el documento o exportar como archivo PDF", + "printBackground": "Usar una imagen de fondo", + "printBackgroundButton": "Elija una imagen", + "printBackgroundValue": "Fondo de pantalla actual{0}", + "printBackgroundRemove": "Eliminar este fondo de pantalla", + "tags_title": "Etiquetas (sólo para tí)", + "tags_add": "Actualizar las etiquetas de esta página", + "tags_searchHint": "Comenzar una búsqueda con # en tú CryptDrive para encontrar las notas etiquetadas", + "tags_notShared": "Tus etiquetas no están compartidas con otros usuarios", + "tags_duplicate": "Duplicar etiquetas:{0}", + "tags_noentry": "No puedes etiquetar una nota eliminada!", + "slide_invalidLess": "Estilo personalizado no válido", + "fileShare": "Copiar link", + "ok": "OK", + "doNotAskAgain": "No preguntar nuevamente (Esc)", + "show_help_button": "Mostrar ayuda", + "hide_help_button": "Esconder ayuda", + "help_button": "Ayuda", + "history_loadMore": "Cargar más historial", + "pad_mediatagWidth": "Ancho (px)", + "pad_mediatagHeight": "Altura (px)", + "pad_mediatagRatio": "Mantener proporción", + "pad_mediatagBorder": "Ancho del borde (px)", + "pad_mediatagPreview": "Previsualizar", + "pad_mediatagImport": "Grabar en su CryptDrive", + "pad_mediatagOptions": "Propiedades de la Imagen", + "kanban_newBoard": "Nueva Pizarra", + "kanban_item": "Item {0}", + "kanban_todo": "Por hacer", + "kanban_done": "Hecho", + "kanban_working": "En progreso", + "kanban_deleteBoard": "Estás seguro que quieres eliminar esta pizarra?", + "kanban_addBoard": "Agregar una pizarra", + "kanban_removeItem": "Remover este item", + "kanban_removeItemConfirm": "Estás seguro que quieres eliminar este ítem?", + "printBackgroundNoValue": "No se muestra fondo de pantalla", + "getEmbedCode": "Obtener el código insertado", + "viewEmbedTitle": "Insertar la nota en una página externa", + "viewEmbedTag": "Para insertar esta nota, incluya este iframe en su página donde usted quiera. Puede darle estilo usando CSS o atributos HTML.", + "fileEmbedTitle": "Insertar el archivo en una pagina externa", + "fileEmbedScript": "Para insertar este archivo, incluya este código una vez en su página para cargar el Etiqueta de Media:", + "fileEmbedTag": "Luego ponga esta Etiqueta de Media donde quiera que sea incorporada en su página: ", + "pad_mediatagTitle": "Opciones de Etiquetas de Media", + "poll_bookmark_col": "Agregue esta columna a sus marcadores así estará siempre desbloqueada y se le mostrará al comienzo", + "poll_bookmarked_col": "Esta es su columna de bookmarks. Siempre será desbloqueada y mostrada al comienzo para usted.", + "poll_total": "TOTAL", + "poll_comment_list": "Comentarios", + "poll_comment_add": "Agregue un comentario", + "poll_comment_submit": "Enviar", + "poll_comment_remove": "Elimine este comentario", + "poll_comment_placeholder": "Su comentario", + "poll_comment_disabled": "Publique esta encuesta usando el botón ✓ para habilitar los comentarios.", + "oo_reconnect": "La conexión con el servidor se ha restablecido. Haga clic en OK para recargar y continúe con la edición.", + "oo_cantUpload": "Subir no está permitido mientras usuarios están presentes.", + "oo_uploaded": "La subida de archivos se ha completado. Clic en OK para recargar la página o cancelar para continuar en modo de solo lectura.", + "canvas_imageEmbed": "Añada una imagen desde su computador", + "profile_uploadSizeError": "Error: su imagen de perfil debe ser menor que {0}", + "profile_uploadTypeError": "Error: su imagen de perfil no es permitida. Los tipos permitidos son: {0}", + "contacts_warning": "Todo lo que escribas acá es persistente y estará disponible para todo los usuarios de esta nota. Sea precavido con la información sensible e importante!", + "contacts_padTitle": "Chat", + "contacts_fetchHistory": "Recuperar la historial antigua", + "contacts_friends": "Amigos", + "contacts_rooms": "Sala de chat", + "contacts_leaveRoom": "Deja esta sala", + "contacts_online": "Otro usuario de esta sala está online", + "debug_getGraph": "Obtenga el código para generar un grafico de este documento", + "debug_getGraphWait": "Generando el gráfico... Por favor espere.", + "debug_getGraphText": "Este es el código DOT para generar un gráfico del historial de este documento:", + "fm_recentPadsName": "Notas recientes", + "fm_ownedPadsName": "Dueño", + "fm_tagsName": "Etiquetas", + "fm_sharedFolderName": "Carpeta compartida", + "fm_sharedFolder": "Carpeta compartida", + "fm_removePermanentlyNote": "Sus notas serán removidas del servidor si continua.", + "fm_deleteOwnedPad": "Está seguro que quiere remover esta nota del servidor de manera permanente?", + "fm_deleteOwnedPads": "Está seguro que quiere remover estas notas del servidor de manera permanente?", + "fm_info_recent": "Lista de notas recientemente abiertas o modificadas.", + "fm_info_sharedFolder": "Esta es una carpeta compartida. Usted no ha ingresado a su cuenta por lo que solo tiene acceso en modo solo lectura.
    ingresar o ingresar para poder importarla a su Cryptdrive y modificarla.", + "fm_info_owned": "Usted es el dueño de las notas que se presentan. Esto significa que puede removerlas de manera permanente del servidor cuando lo desee. Si lo hace, los otros usuarios no podrán acceder a ellas nunca más.", + "fm_renamedPad": "Ha definido un nombre personalizado para esta nota. El título que se comparte es: br>{0}", + "fm_canBeShared": "Esta carpeta puede ser compartida", + "fm_prop_tagsList": "Etiquetas", + "fm_burnThisDriveButton": "Borre toda la información que ha sido almacenada por CryptPad en su navegador", + "fm_burnThisDrive": "Está seguro que quiere remover todo lo que ha sido almacenado por CryptPad en su navegador?
    Esto removerá su CryptDrive y su historial de su navegador, pero sus notas aun existirán (encriptadas) en nuestro servidor.", + "fm_padIsOwned": "Usted es el dueño de esta nota", + "fm_padIsOwnedOther": "El dueño de esta nota es otro usuario", + "fm_deletedPads": "Estas notas ya no existen en este servidor, han sido removidas desde su CryptDrive: {0}", + "fm_tags_name": "Nombre de la Etiqueta", + "fm_tags_used": "Número de usos", + "fm_restoreDrive": "Su drive se está reseteando a un estado anterior. Para mejores resultados evite hacer cambios a su drive hasta que el proceso se haya completado.", + "fm_moveNestedSF": "No puedes poner una carpeta compartida dentro de otra. La carpeta {0} no se movió.", + "fm_passwordProtected": "Este documento está protegido por una contraseña", + "fc_newsharedfolder": "Nueva carpeta compartida", + "fc_delete_owned": "Eliminar desde el servidor", + "fc_remove_sharedfolder": "Eliminar", + "fc_hashtag": "Etiquetas", + "register_passwordTooShort": "La contraseña debe tener por los menos {0} caracteres de largo.", + "useTemplateCancel": "Recomenzar (Esc)" } From a67e5e0f696ac7148df38257a2175ec1a4a73921 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 20 May 2019 17:44:18 +0200 Subject: [PATCH 24/25] update package.json and footer --- customize.dist/pages.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/customize.dist/pages.js b/customize.dist/pages.js index bdae16b01..b5d277e81 100644 --- a/customize.dist/pages.js +++ b/customize.dist/pages.js @@ -103,7 +103,7 @@ define([ ])*/ ]) ]), - h('div.cp-version-footer', "CryptPad v2.21.0 (Vervet)") + h('div.cp-version-footer', "CryptPad v2.22.0 (Wolf)") ]); }; diff --git a/package.json b/package.json index 7a6dd8b18..bda497b7d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "cryptpad", "description": "realtime collaborative visual editor with zero knowlege server", - "version": "2.21.0", + "version": "2.22.0", "license": "AGPL-3.0+", "repository": { "type": "git", From 1802656d9c1595d2d8a458c52db9628ab61bd475 Mon Sep 17 00:00:00 2001 From: yflory Date: Tue, 21 May 2019 11:05:30 +0200 Subject: [PATCH 25/25] Fix templates in poll part 2 #375 --- www/common/cryptpad-common.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 7b9e939b1..324e6cab9 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -477,6 +477,9 @@ define([ // PPP: password for the new template? var hash = Hash.createRandomHash(p.type); var href = '/' + p.type + '/#' + hash; + + var optsPut = {}; + if (p.type === 'poll') { optsPut.initialState = '{}'; } // PPP: add password as cryptput option Cryptput(hash, data.toSave, function (e) { if (e) { throw new Error(e); } @@ -488,7 +491,7 @@ define([ if (obj && obj.error) { return void cb(obj.error); } cb(); }); - }); + }, optsPut); }; common.isTemplate = function (href, cb) {