From 00694e8ebdf840563517a8fb03d733edc7400f2c Mon Sep 17 00:00:00 2001 From: yflory Date: Thu, 29 Oct 2020 14:06:16 +0100 Subject: [PATCH] Stop using sessionStorage when creating/opening pads --- www/common/common-hash.js | 29 +++++++++++ www/common/cryptpad-common.js | 35 ++++++------- www/common/drive-ui.js | 87 +++++++++++++------------------ www/common/notifications.js | 24 ++++----- www/common/sframe-common-outer.js | 81 +++++++++++++++------------- 5 files changed, 137 insertions(+), 119 deletions(-) diff --git a/www/common/common-hash.js b/www/common/common-hash.js index 0b584d4c3..ff8764da4 100644 --- a/www/common/common-hash.js +++ b/www/common/common-hash.js @@ -169,6 +169,17 @@ Version 1 /code/#/1/edit/3Ujt4F2Sjnjbis6CoYWpoQ/usn4+9CqVja8Q7RZOGTfRgqI */ + var getNewPadOpts = function (hashArr) { + var k; + // Check if we have a ownerKey for this pad + hashArr.some(function (data) { + if (/^newpad=/.test(data)) { + k = data.slice(7); + return true; + } + }); + return k || ''; + }; var getVersionHash = function (hashArr) { var k; // Check if we have a ownerKey for this pad @@ -202,6 +213,7 @@ Version 1 parsed.present = options.indexOf('present') !== -1; parsed.embed = options.indexOf('embed') !== -1; parsed.versionHash = getVersionHash(options); + parsed.newPadOpts = getNewPadOpts(options); parsed.ownerKey = getOwnerKey(options); }; @@ -217,6 +229,13 @@ Version 1 password: parsed.password }; }; + + if (/^\/newpad=/.test(hash)) { + return { + newPadOpts: hash.slice(8, -1) + }; + } + if (hash.slice(0,1) !== '/' && hash.length >= 56) { // Version 0 // Old hash parsed.channel = hash.slice(0, 32); @@ -237,6 +256,9 @@ Version 1 if (versionHash) { hash += 'hash=' + Crypto.b64RemoveSlashes(versionHash) + '/'; } + if (opts.newPadOpts) { + hash += 'newpad=' + opts.newPadOpts + '/'; + } return hash; }; @@ -372,6 +394,10 @@ Version 1 var url = '/'; if (!ret.type) { return url; } url += ret.type + '/'; + // New pad with options: append the options to the hash + if (!ret.hashData && options.newPadOpts) { + return url + '#/newpad=' + options.newPadOpts + '/'; + } if (!ret.hashData) { return url; } if (ret.hashData.type !== 'pad') { return url + '#' + ret.hash; } if (ret.hashData.version === 0) { return url + '#' + ret.hash; } @@ -575,6 +601,9 @@ Version 1 // Valid hash? if (parsed.hash) { if (!parsed.hashData) { return; } + // New pad: only newPadOpts allowed + if (Object.keys(parsed.hashData).length === 1 && + parsed.hashData.newPadOpts) { return true; } // Version should be a number if (typeof(parsed.hashData.version) === "undefined") { return; } // pads and files should have a base64 (or hex) key diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 4613e5756..70ebe5bcc 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -148,6 +148,21 @@ define([ send(); }; + common.setTabHref = function (href) { + var ohc = window.onhashchange; + window.onhashchange = function () {}; + window.location.href = href; + window.onhashchange = ohc; + ohc({reset: true}); + }; + common.setTabHash = function (hash) { + var ohc = window.onhashchange; + window.onhashchange = function () {}; + window.location.hash = hash; + window.onhashchange = ohc; + ohc({reset: true}); + }; + // RESTRICTED // Settings only common.resetDrive = function (cb) { @@ -2090,26 +2105,6 @@ define([ language: common.getLanguage(), driveEvents: true //rdyCfg.driveEvents // Boolean }; - // if a pad is created from a file - if (sessionStorage[Constants.newPadFileData]) { - common.fromFileData = JSON.parse(sessionStorage[Constants.newPadFileData]); - var _parsed1 = Hash.parsePadUrl(common.fromFileData.href); - var _parsed2 = Hash.parsePadUrl(window.location.href); - if (_parsed1.hashData.type === 'pad') { - if (_parsed1.type !== _parsed2.type) { delete common.fromFileData; } - } - delete sessionStorage[Constants.newPadFileData]; - } - - if (sessionStorage[Constants.newPadPathKey]) { - common.initialPath = sessionStorage[Constants.newPadPathKey]; - delete sessionStorage[Constants.newPadPathKey]; - } - - if (sessionStorage[Constants.newPadTeamKey]) { - common.initialTeam = sessionStorage[Constants.newPadTeamKey]; - delete sessionStorage[Constants.newPadTeamKey]; - } var channelIsReady = waitFor(); diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js index 5d6a71b9d..08a3f1279 100644 --- a/www/common/drive-ui.js +++ b/www/common/drive-ui.js @@ -1125,6 +1125,18 @@ define([ var hiddenHref = Hash.hashToHref(hash, parsed.type); window.open(APP.origin + hiddenHref); }; + var openIn = function (type, path, team, fData) { + var obj = JSON.stringify({ + p: path, + t: team, + d: fData + }); + var str = encodeURIComponent(obj); + var parsed = Hash.parsePadUrl(Hash.hashToHref('', type)); + var opts = parsed.getOptions(); + opts.newPadOpts = str; + common.openURL(parsed.getUrl(opts)); + }; var refresh = APP.refresh = function () { APP.displayDirectory(currentPath); @@ -2667,12 +2679,7 @@ define([ .click(function () { var type = $(this).attr('data-type') || 'pad'; var path = manager.isPathIn(currentPath, [TRASH]) ? '' : currentPath; - nThen(function (waitFor) { - common.sessionStorage.put(Constants.newPadPathKey, path, waitFor()); - common.sessionStorage.put(Constants.newPadTeamKey, APP.team, waitFor()); - }).nThen(function () { - common.openURL('/' + type + '/'); - }); + openIn(type, path, APP.team); }); }; var createNewButton = function (isInRoot, $container) { @@ -4227,31 +4234,19 @@ define([ else if ($this.hasClass('cp-app-drive-context-makeacopy')) { if (paths.length !== 1) { return; } el = manager.find(paths[0].path); - var _metadata = manager.getFileData(el); - var _simpleData = { - title: _metadata.filename || _metadata.title, - href: _metadata.href || _metadata.roHref, - password: _metadata.password, - channel: _metadata.channel, - }; - nThen(function (waitFor) { + (function () { var path = currentPath; if (path[0] !== ROOT) { path = [ROOT]; } - common.sessionStorage.put(Constants.newPadFileData, JSON.stringify(_simpleData), waitFor()); - common.sessionStorage.put(Constants.newPadPathKey, path, waitFor()); - common.sessionStorage.put(Constants.newPadTeamKey, APP.team, waitFor()); - }).nThen(function () { + var _metadata = manager.getFileData(el); + var _simpleData = { + title: _metadata.filename || _metadata.title, + href: _metadata.href || _metadata.roHref, + password: _metadata.password, + channel: _metadata.channel, + }; var parsed = Hash.parsePadUrl(_metadata.href || _metadata.roHref); - common.openURL(Hash.hashToHref('', parsed.type)); - // We need to restore sessionStorage for the next time we want to create a pad from this tab - // NOTE: the 100ms timeout is to fix a race condition in firefox where sessionStorage - // would be deleted before the new tab was created - setTimeout(function () { - common.sessionStorage.put(Constants.newPadFileData, '', function () {}); - common.sessionStorage.put(Constants.newPadPathKey, '', function () {}); - common.sessionStorage.put(Constants.newPadTeamKey, '', function () {}); - }, 100); - }); + openIn(parsed.type, path, APP.team, _simpleData); + })(); } else if ($this.hasClass('cp-app-drive-context-openincode')) { if (paths.length !== 1) { return; } @@ -4264,23 +4259,20 @@ define([ password: metadata.password, channel: metadata.channel, }; - nThen(function (waitFor) { - common.sessionStorage.put(Constants.newPadFileData, JSON.stringify(simpleData), waitFor()); - common.sessionStorage.put(Constants.newPadPathKey, currentPath, waitFor()); - common.sessionStorage.put(Constants.newPadTeamKey, APP.team, waitFor()); - }).nThen(function () { - common.openURL('/code/'); - // We need to restore sessionStorage for the next time we want to create a pad from this tab - // NOTE: the 100ms timeout is to fix a race condition in firefox where sessionStorage - // would be deleted before the new tab was created - setTimeout(function () { - common.sessionStorage.put(Constants.newPadFileData, '', function () {}); - common.sessionStorage.put(Constants.newPadPathKey, '', function () {}); - common.sessionStorage.put(Constants.newPadTeamKey, '', function () {}); - }, 100); - }); + (function () { + var path = currentPath; + if (path[0] !== ROOT) { path = [ROOT]; } + var _metadata = manager.getFileData(el); + var _simpleData = { + title: _metadata.filename || _metadata.title, + href: _metadata.href || _metadata.roHref, + password: _metadata.password, + channel: _metadata.channel, + }; + var parsed = Hash.parsePadUrl(_metadata.href || _metadata.roHref); + openIn('code', path, APP.team, _simpleData); + })(); } - else if ($this.hasClass('cp-app-drive-context-expandall') || $this.hasClass('cp-app-drive-context-collapseall')) { if (paths.length !== 1) { return; } @@ -4482,12 +4474,7 @@ define([ else if ($this.hasClass("cp-app-drive-context-newdoc")) { var ntype = $this.data('type') || 'pad'; var path2 = manager.isPathIn(currentPath, [TRASH]) ? '' : currentPath; - nThen(function (waitFor) { - common.sessionStorage.put(Constants.newPadPathKey, path2, waitFor()); - common.sessionStorage.put(Constants.newPadTeamKey, APP.team, waitFor()); - }).nThen(function () { - common.openURL('/' + ntype + '/'); - }); + openIn(ntype, path2, APP.team); } else if ($this.hasClass("cp-app-drive-context-properties")) { if (type === 'trash') { diff --git a/www/common/notifications.js b/www/common/notifications.js index 44125ed71..1686b87f9 100644 --- a/www/common/notifications.js +++ b/www/common/notifications.js @@ -108,21 +108,17 @@ define([ return Messages._getKey(key, [name, title, teamName]); }; content.handler = function() { - var todo = function() { - common.openURL(msg.content.href); - defaultDismiss(common, data)(); - }; - nThen(function(waitFor) { - if (msg.content.isTemplate) { - common.sessionStorage.put(Constants.newPadPathKey, ['template'], waitFor()); - } - if (teamNotification) { - common.sessionStorage.put(Constants.newPadTeamKey, teamNotification, waitFor()); - } - common.sessionStorage.put('newPadPassword', msg.content.password || '', waitFor()); - }).nThen(function() { - todo(); + var obj = JSON.stringify({ + p: msg.content.isTemplate ? ['template'] : undefined, + t: teamNotification || undefined, + pw: msg.content.password || '' }); + var str = encodeURIComponent(obj); + var parsed = Hash.parsePadUrl(msg.content.href); + var opts = parsed.getOptions(); + opts.newPadOpts = str; + common.openURL(parsed.getUrl(opts)); + defaultDismiss(common, data)(); }; if (!content.archived) { content.dismissHandler = defaultDismiss(common, data); diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index c837a9b72..1e149abeb 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -26,7 +26,7 @@ define([ }; var AppConfig; var Test; - var password; + var password, newPadPassword; var initialPathInDrive; var burnAfterReading; @@ -196,15 +196,47 @@ define([ } // Rendered (maybe hidden) hash var renderedParsed = Utils.Hash.parsePadUrl(window.location.href); - var ohc = window.onhashchange; - window.onhashchange = function () {}; - window.location.href = renderedParsed.getUrl(opts); - window.onhashchange = ohc; - ohc({reset: true}); + Cryptpad.setTabHref(renderedParsed.getUrl(opts)); } })); }; + // New pad options + if (parsed.hashData && parsed.hashData.newPadOpts) { + try { + var newPad = JSON.parse(decodeURIComponent(parsed.hashData.newPadOpts)); + Cryptpad.initialTeam = newPad.t; + Cryptpad.initialPath = newPad.p; + newPadPassword = newPad.pw; + if (newPad.d) { + Cryptpad.fromFileData = newPad.d; + var _parsed1 = Utils.Hash.parsePadUrl(Cryptpad.fromFileData.href); + if (_parsed1.hashData.type === 'pad' && _parsed1.type !== parsed.type) { + delete Cryptpad.fromFileData; + } + } + } catch (e) { + console.error(e, parsed.hashData.newPadOpts); + } + delete parsed.hashData.newPadOpts; + + // If it's a new pad, don't check password + if (!Object.keys(parsed.hashData).length) { + delete parsed.hashData; + parsed.hash = ''; + currentPad.hash = ''; + Cryptpad.setTabHash(''); + return void todo(); + } + // Otherwise, existing pad (new for us) + var opts = parsed.getOptions(); + delete opts.newPadOpts; + parsed = Utils.Hash.parsePadUrl(parsed.getUrl(opts)); + currentPad.hash = parsed.hash; + Cryptpad.setTabHash(parsed.hash); + } + + if (!parsed.hashData) { // No hash, no need to check for a password return void todo(); } @@ -334,9 +366,8 @@ define([ password = val; }), parsed.getUrl()); }).nThen(function (w) { - if (!password && !stored && sessionStorage.newPadPassword) { - passwordCfg.value = sessionStorage.newPadPassword; - delete sessionStorage.newPadPassword; + if (!password && !stored && newPadPassword) { + passwordCfg.value = newPadPassword; } if (parsed.type === "file") { @@ -356,7 +387,7 @@ define([ waitFor.abort(); return; } - if (!isNew) { return void todo(); } + if (!e && !isNew) { return void todo(); } if (parsed.hashData.mode === 'view' && (password || !parsed.hashData.password)) { // Error, wrong password stored, the view seed has changed with the password // password will never work @@ -507,18 +538,10 @@ define([ sframeChan.onReg('EV_METADATA_UPDATE', updateMeta); Utils.LocalStore.onLogin(function () { - var ohc = window.onhashchange; - window.onhashchange = function () {}; - window.location.hash = currentPad.hash; - window.onhashchange = ohc; - ohc({reset: true}); + Cryptpad.setTabHash(currentPad.hash); }); Utils.LocalStore.onLogout(function () { - var ohc = window.onhashchange; - window.onhashchange = function () {}; - window.location.hash = currentPad.hash; - window.onhashchange = ohc; - ohc({reset: true}); + Cryptpad.setTabHash(currentPad.hash); sframeChan.event('EV_LOGOUT'); }); @@ -1166,11 +1189,7 @@ define([ var hiddenParsed = Utils.Hash.parsePadUrl(window.location.href); // Update the hash in the address bar - var ohc = window.onhashchange; - window.onhashchange = function () {}; - window.location.href = hiddenParsed.getUrl(opts); - window.onhashchange = ohc; - ohc({reset: true}); + Cryptpad.setTabHref(hiddenParsed.getUrl(opts)); }); @@ -1521,11 +1540,7 @@ define([ // in the address bar Cryptpad.padRpc.onChannelDeleted.reg(function (channel) { if (channel !== secret.channel) { return; } - var ohc = window.onhashchange; - window.onhashchange = function () {}; - window.location.href = currentPad.href; - window.onhashchange = ohc; - ohc({reset: true}); + Cryptpad.setTabHref(currentPad.href); }); // Join the netflux channel @@ -1609,13 +1624,9 @@ define([ Utils.crypto = Utils.Crypto.createEncryptor(Utils.secret.keys); // Update the hash in the address bar - var ohc = window.onhashchange; - window.onhashchange = function () {}; - window.location.hash = newHash; currentPad.hash = newHash; currentPad.href = '/' + parsed.type + '/#' + newHash; - window.onhashchange = ohc; - ohc({reset: true}); + Cryptpad.setTabHash(newHash); // Update metadata values and send new metadata inside parsed = Utils.Hash.parsePadUrl(currentPad.href);