From 46117845ef47ff0cd5aaab69188cbe0cde5cb903 Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 22 Mar 2021 17:47:47 +0100 Subject: [PATCH 01/10] Translated using Weblate (French) Currently translated at 100.0% (1189 of 1189 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/fr/ --- www/common/translations/messages.fr.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/www/common/translations/messages.fr.json b/www/common/translations/messages.fr.json index 322c7cf7b..f3eff56bc 100644 --- a/www/common/translations/messages.fr.json +++ b/www/common/translations/messages.fr.json @@ -27,11 +27,11 @@ "padNotPinned": "Ce pad va expirer après 3 mois d'inactivité, {0}connectez-vous{1} ou {2}enregistrez-vous{3} pour le préserver.", "anonymousStoreDisabled": "L'administrateur de cette instance de CryptPad a désactivé le drive pour les utilisateurs non enregistrés. Vous devez vous connecter pour pouvoir utiliser CryptDrive.", "expiredError": "Ce pad a atteint sa date d'expiration est n'est donc plus disponible.", - "deletedError": "Ce pad a été supprimé par son propriétaire et n'est donc plus disponible.", + "deletedError": "Ce document a été supprimé et n'est plus disponible.", "inactiveError": "Ce pad a été supprimé en raison de son inactivité. Appuyez sur Échap pour créer un nouveau pad.", "chainpadError": "Une erreur critique est survenue lors de la mise à jour du contenu. Le pad est désormais en mode lecture seule afin de s'assurer que vous ne perdiez pas davantage de données.
Appuyez sur Échap pour voir le pad ou rechargez la page pour pouvoir le modifier à nouveau.", "invalidHashError": "L'URL du document demandé n'est pas valide.", - "errorCopy": " Vous pouvez accéder au contenu en appuyant sur Échap.
Quand vous fermerez cette page, il sera définitivement supprimé.", + "errorCopy": " Vous pouvez toujours utiliser la version actuelle en mode lecture seule en appuyant sur Échap.", "errorRedirectToHome": "Appuyez sur Échap pour retourner vers votre CryptDrive.", "newVersionError": "Une nouvelle version de CryptPad est disponible.
Rechargez la page pour utiliser la nouvelle version, ou appuyez sur Échap pour accéder au contenu actuel en mode hors-ligne.", "loading": "Chargement...", @@ -604,8 +604,8 @@ "creation_expiration": "Date d'expiration", "creation_passwordValue": "Mot de passe", "creation_newPadModalDescription": "Cliquer sur le type de document à créer. Vous pouvez aussi utiliser les touches Tab pour sélectionner un type et Entrée pour valider.", - "password_info": "Le pad auquel vous essayez d'accéder n'existe plus ou est protégé par un mot de passe. Entrez le bon mot de passe pour accéder à son contenu.", - "password_error": "Pad introuvable !
Cette erreur peut provenir de deux facteurs. Soit le mot de passe est faux, soit le pad a été supprimé du serveur.", + "password_info": "Le document auquel vous essayez d'accéder n'existe plus ou est protégé par un nouveau mot de passe. Entrez le bon mot de passe pour accéder au contenu.", + "password_error": "Document introuvable
Cette erreur peut provenir de deux facteurs : soit le mot de passe est faux, soit le document a été détruit.", "password_placeholder": "Tapez le mot de passe ici...", "password_submit": "Valider", "properties_addPassword": "Ajouter un mot de passe", From bf4cff95161e47366183b219c76c9525a8ed2906 Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 22 Mar 2021 17:47:47 +0100 Subject: [PATCH 02/10] Translated using Weblate (English) Currently translated at 100.0% (1189 of 1189 strings) Translation: CryptPad/App Translate-URL: http://weblate.cryptpad.fr/projects/cryptpad/app/en/ --- www/common/translations/messages.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/www/common/translations/messages.json b/www/common/translations/messages.json index d0e4d20cb..51877b35f 100644 --- a/www/common/translations/messages.json +++ b/www/common/translations/messages.json @@ -29,11 +29,11 @@ "padNotPinnedVariable": "This pad will expire after {4} days of inactivity, {0}login{1} or {2}register{3} to preserve it.", "anonymousStoreDisabled": "The webmaster of this CryptPad instance has disabled the store for anonymous users. You have to log in to be able to use CryptDrive.", "expiredError": "This pad has reached its expiration time and is no longer available.", - "deletedError": "This pad has been deleted by its owner and is no longer available.", + "deletedError": "This document has been deleted and is no longer available.", "inactiveError": "This pad has been deleted due to inactivity. Press Esc to create a new pad.", "chainpadError": "A critical error occurred when updating your content. This page is in read-only mode to make sure you won't lose your work.
Hit Esc to continue to view this pad, or reload to try editing again.", "invalidHashError": "The document you've requested has an invalid URL.", - "errorCopy": " You can still access the content by pressing Esc.
Once you close this window you will not be able to access it again.", + "errorCopy": " You can still use the current version in read-only mode by pressing Esc.", "errorRedirectToHome": "Press Esc to be redirected to your CryptDrive.", "newVersionError": "A new version of CryptPad is available.
Reload to use the new version, or press escape to access your content in offline mode.", "loading": "Loading...", @@ -619,8 +619,8 @@ "creation_expiration": "Expiration date", "creation_passwordValue": "Password", "creation_newPadModalDescription": "Click on a document type to create it. You can also press Tab to select the type and press Enter to confirm.", - "password_info": "The pad you're trying to open no longer exist or is protected with a password. Enter the correct password to access its content.", - "password_error": "Pad not found!
This error can be caused by two factors: either the password in invalid, or the pad has been deleted from the server.", + "password_info": "The document you are trying to open no longer exist or is protected with a new password. Enter the correct password to access the content.", + "password_error": "Document not found
This error can be caused by two factors: either the password is invalid, or the document has been destroyed.", "password_placeholder": "Type the password here...", "password_submit": "Submit", "properties_addPassword": "Add a password", From 550c5175aa104fa93aaaa2d1b650cc5b713b2f11 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 22 Mar 2021 17:49:33 +0100 Subject: [PATCH 03/10] Fix password change issues with cache --- www/common/common-ui-elements.js | 42 ++++++++++++++++-- www/common/cryptpad-common.js | 13 +++++- www/common/outer/async-store.js | 6 +++ www/common/sframe-common-outer.js | 71 ++++++++++++++++++++++++++----- 4 files changed, 117 insertions(+), 15 deletions(-) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 08c84d1e6..4f6c6c8b9 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -2540,6 +2540,7 @@ define([ UIElements.onServerError = function (common, err, toolbar, cb) { //if (["EDELETED", "EEXPIRED", "ERESTRICTED"].indexOf(err.type) === -1) { return; } var priv = common.getMetadataMgr().getPrivateData(); + var sframeChan = common.getSframeChannel(); var msg = err.type; if (err.type === 'EEXPIRED') { msg = Messages.expiredError; @@ -2549,10 +2550,25 @@ define([ if (toolbar && typeof toolbar.deleted === "function") { toolbar.deleted(); } } else if (err.type === 'EDELETED') { if (priv.burnAfterReading) { return void cb(); } + + // View users have the wrong seed, thay can't retireve access directly + // Version 1 hashes don't support passwords + if (!priv.readOnly && !priv.oldVersionHash) { + sframeChan.event('EV_SHARE_OPEN', {hidden: true}); // Close share modal + UIElements.displayPasswordPrompt(common, { + fromServerError: true, + loaded: err.loaded, + }); + if (toolbar && typeof toolbar.deleted === "function") { toolbar.deleted(); } + (cb || function () {})(); + return; + } + msg = Messages.deletedError; if (err.loaded) { msg += Messages.errorCopy; } + if (toolbar && typeof toolbar.deleted === "function") { toolbar.deleted(); } } else if (err.type === 'ERESTRICTED') { msg = Messages.restrictedError; @@ -2561,7 +2577,6 @@ define([ msg = Messages.oo_deletedVersion; if (toolbar && typeof toolbar.failed === "function") { toolbar.failed(true); } } - var sframeChan = common.getSframeChannel(); sframeChan.event('EV_SHARE_OPEN', {hidden: true}); UI.errorLoadingScreen(msg, Boolean(err.loaded), Boolean(err.loaded)); (cb || function () {})(); @@ -2570,7 +2585,10 @@ define([ UIElements.displayPasswordPrompt = function (common, cfg, isError) { var error; if (isError) { error = setHTML(h('p.cp-password-error'), Messages.password_error); } + var info = h('p.cp-password-info', Messages.password_info); + var info_loaded = h('p.cp-password-info', Messages.password_info_loaded); + var password = UI.passwordInput({placeholder: Messages.password_placeholder}); var $password = $(password); var button = h('button.btn.btn-primary', Messages.password_submit); @@ -2582,6 +2600,21 @@ define([ var submit = function () { var value = $password.find('.cp-password-input').val(); + + // Password-prompt called from UIElements.onServerError + if (cfg.fromServerError) { + common.getSframeChannel().query('Q_PASSWORD_CHECK', value, function (err, obj) { + if (obj && obj.error) { + console.error(obj.error); + return void UI.warn(Messages.error); + } + // On success, outer will reload the page: this is a wrong password + UIElements.displayPasswordPrompt(common, cfg, true); + }); + return; + } + + // Initial load UI.addLoadingScreen({newProgress: true}); if (window.CryptPad_updateLoadingProgress) { window.CryptPad_updateLoadingProgress({ @@ -2595,6 +2628,8 @@ define([ } }); }; + + $password.find('.cp-password-input').on('keydown', function (e) { if (e.which === 13) { submit(); } }); $(button).on('click', function () { submit(); }); @@ -2602,12 +2637,13 @@ define([ var block = h('div#cp-loading-password-prompt', [ error, info, + cfg.loaded ? info_loaded : undefined, h('p.cp-password-form', [ password, button - ]) + ]), ]); - UI.errorLoadingScreen(block); + UI.errorLoadingScreen(block, Boolean(cfg.loaded), Boolean(cfg.loaded)); $password.find('.cp-password-input').focus(); }; diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 8bf01c965..1d19089e3 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -481,10 +481,20 @@ define([ }); }; + common.isNewChannel = function (href, password, _cb) { + var cb = Util.once(Util.mkAsync(_cb)); + var channel = Hash.hrefToHexChannelId(href, password); + postMessage('IS_NEW_CHANNEL', {channel: channel}, function (obj) { + var error = obj && obj.error; + if (error) { return void cb(error); } + if (!obj) { return void cb('ERROR'); } + cb (null, obj.isNew); + }, {timeout: -1}); + }; // This function is used when we want to open a pad. We first need // to check if it exists. With the cached drive, we need to wait for // the network to be available before we can continue. - common.isNewChannel = function (href, password, _cb) { + common.hasChannelHistory = function (href, password, _cb) { var cb = Util.once(Util.mkAsync(_cb)); var channel = Hash.hrefToHexChannelId(href, password); var error; @@ -2506,6 +2516,7 @@ define([ } if (parsedNew.hashData) { oldHref = newHref; } }; + // XXX if you're in noDrive mode, check if an FS_hash is added and reload if that's the case // Listen for login/logout in other tabs window.addEventListener('storage', function (e) { if (e.key !== Constants.userHashKey) { return; } diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 8ac1a77c3..088c5fe29 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -1710,6 +1710,10 @@ define([ var onError = function (err) { channel.bcast("PAD_ERROR", err); + if (err && err.type === "EDELETED" && Cache && Cache.clearChannel) { + Cache.clearChannel(data.channel); + } + // If this is a DELETED, EXPIRED or RESTRICTED pad, leave the channel if (["EDELETED", "EEXPIRED", "ERESTRICTED"].indexOf(err.type) === -1) { return; } Store.leavePad(null, data, function () {}); @@ -1720,11 +1724,13 @@ define([ postMessage(clientId, "PAD_CACHE"); }, onCacheReady: function () { + channel.hasCache = true; postMessage(clientId, "PAD_CACHE_READY"); }, onReady: function (pad) { var padData = pad.metadata || {}; channel.data = padData; + channel.ready = true; if (padData && padData.validateKey && store.messenger) { store.messenger.storeValidateKey(data.channel, padData.validateKey); } diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index 8d791c8cd..0af8eb9e2 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -78,7 +78,7 @@ define([ }; var AppConfig; var Test; - var password, newPadPassword; + var password, newPadPassword, newPadPasswordForce; var initialPathInDrive; var burnAfterReading; @@ -312,6 +312,7 @@ define([ newPadPassword = Crypto.decrypt(newPad.pw, uKey); } catch (e) { console.error(e); } } + if (newPad.f) { newPadPasswordForce = 1; } if (newPad.d) { Cryptpad.fromFileData = newPad.d; var _parsed1 = Utils.Hash.parsePadUrl(Cryptpad.fromFileData.href); @@ -319,6 +320,7 @@ define([ delete Cryptpad.fromFileData; } } + } catch (e) { console.error(e, parsed.hashData.newPadOpts); } @@ -349,7 +351,7 @@ define([ } // We now need to check if there is a password and if we know the correct password. - // We'll use getFileSize and isNewChannel to detect incorrect passwords. + // We'll use getFileSize and hasChannelHistory to detect incorrect passwords. // First we'll get the password value from our drive (getPadAttribute), and we'll check // if the channel is valid. If the pad is not stored in our drive, we'll test with an @@ -397,15 +399,15 @@ define([ } }; if (parsed.type === "file") { - // `isNewChannel` doesn't work for files (not a channel) + // `hasChannelHistory` doesn't work for files (not a channel) // `getFileSize` is not adapted to channels because of metadata Cryptpad.getFileSize(currentPad.href, password, function (e, size) { next(e, size === 0); }); return; } - // Not a file, so we can use `isNewChannel` - Cryptpad.isNewChannel(currentPad.href, password, next); + // Not a file, so we can use `hasChannelHistory` + Cryptpad.hasChannelHistory(currentPad.href, password, next); }); sframeChan.event("EV_PAD_PASSWORD", cfg); }; @@ -474,17 +476,25 @@ define([ password = val; }), parsed.getUrl()); }).nThen(function (w) { + // If we've already tested this password and this is a redirect, force + if (typeof(newPadPassword) !== "undefined" && newPadPasswordForce) { + password = newPadPassword; + return void todo(); + } + + // If the pad is not stored and we have a newPadPassword, it probably + // comes from a notification: password prompt pre-filled if (!password && !stored && newPadPassword) { passwordCfg.value = newPadPassword; } // Pad not stored && password required: always ask for the password - if (!stored && parsed.hashData.password) { + if (!stored && parsed.hashData.password && !newPadPasswordForce) { return void askPassword(true, passwordCfg); } if (parsed.type === "file") { - // `isNewChannel` doesn't work for files (not a channel) + // `hasChannelHistory` doesn't work for files (not a channel) // `getFileSize` is not adapted to channels because of metadata Cryptpad.getFileSize(currentPad.href, password, w(function (e, size) { if (size !== 0) { return void todo(); } @@ -493,8 +503,8 @@ define([ })); return; } - // Not a file, so we can use `isNewChannel` - Cryptpad.isNewChannel(currentPad.href, password, w(function(e, isNew) { + // Not a file, so we can use `hasChannelHistory` + Cryptpad.hasChannelHistory(currentPad.href, password, w(function(e, isNew) { if (isNew && expire && expire < (+new Date())) { sframeChan.event("EV_EXPIRED_ERROR"); waitFor.abort(); @@ -541,8 +551,7 @@ define([ if (realtime) { // TODO we probably don't need to check again for password-protected pads - // (we use isNewChannel to test the password...) - Cryptpad.isNewChannel(currentPad.href, password, waitFor(function (e, isNew) { + Cryptpad.hasChannelHistory(currentPad.href, password, waitFor(function (e, isNew) { if (e) { return console.error(e); } isNewFile = Boolean(isNew); })); @@ -608,6 +617,7 @@ define([ feedbackAllowed: Utils.Feedback.state, isPresent: parsed.hashData && parsed.hashData.present, isEmbed: parsed.hashData && parsed.hashData.embed, + oldVersionHash: parsed.hashData && parsed.hashData.version < 2, // password isHistoryVersion: parsed.hashData && parsed.hashData.versionHash, notifications: notifs, accounts: { @@ -1674,6 +1684,45 @@ define([ }); }); + sframeChan.on('Q_PASSWORD_CHECK', function (pw, cb) { + Cryptpad.isNewChannel(currentPad.href, pw, function (e, isNew) { + if (isNew === false) { + var channel = Hash.hrefToHexChannelId(currentPad.href, pw); + + nThen(function (w) { + // If the pad is stored, update its data + var _secret = Utils.Hash.getSecrets(parsed.type, parsed.hash, pw); + var chan = _secret.channel; + var editH = Utils.Hash.getEditHashFromKeys(_secret); + var viewH = Utils.Hash.getViewHashFromKeys(_secret); + var href = Utils.Hash.hashToHref(editH, parsed.type); + var roHref = Utils.Hash.hashToHref(viewH, parsed.type); + Cryptpad.setPadAttribute('password', password, w(), parsed.getUrl()); + Cryptpad.setPadAttribute('channel', chan, w(), parsed.getUrl()); + Cryptpad.setPadAttribute('href', href, w(), parsed.getUrl()); + Cryptpad.setPadAttribute('roHref', roHref, w(), parsed.getUrl()); + }).nThen(function () { + // Get redirect URL + var uHash = Utils.LocalStore.getUserHash(); + var uSecret = Utils.Hash.getSecrets('drive', uHash); + var uKey = uSecret.keys.cryptKey; + var url = Utils.Hash.getNewPadURL(currentPad.href, { + pw: Crypto.encrypt(pw, uKey), + f: 1 + }); + // redirect + window.location.href = url; + document.location.reload(); + }); + + return; + } + cb({ + error: e + }); + }); + }); + if (cfg.messaging) { sframeChan.on('Q_CHAT_OPENPADCHAT', function (data, cb) { Cryptpad.universal.execCommand({ From 815bd5961eea1bf0afa488e5325d59a2817e563f Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 22 Mar 2021 18:00:56 +0100 Subject: [PATCH 04/10] Fix translation key --- 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 4f6c6c8b9..791116247 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -2587,7 +2587,7 @@ define([ if (isError) { error = setHTML(h('p.cp-password-error'), Messages.password_error); } var info = h('p.cp-password-info', Messages.password_info); - var info_loaded = h('p.cp-password-info', Messages.password_info_loaded); + var info_loaded = h('p.cp-password-info', Messages.errorCopy); var password = UI.passwordInput({placeholder: Messages.password_placeholder}); var $password = $(password); From a0155ad689ba53ddcab8eea9d7beb83c397b665a Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 22 Mar 2021 18:03:41 +0100 Subject: [PATCH 05/10] Fix referenceError introduced in latest commit --- www/common/sframe-common-outer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index 0af8eb9e2..131958d83 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -1687,7 +1687,7 @@ define([ sframeChan.on('Q_PASSWORD_CHECK', function (pw, cb) { Cryptpad.isNewChannel(currentPad.href, pw, function (e, isNew) { if (isNew === false) { - var channel = Hash.hrefToHexChannelId(currentPad.href, pw); + var channel = Utils.Hash.hrefToHexChannelId(currentPad.href, pw); nThen(function (w) { // If the pad is stored, update its data From 8dfebbb38424f9c6b853520ee4e19949d731e99a Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 22 Mar 2021 18:07:58 +0100 Subject: [PATCH 06/10] Fix HTML in translation key --- 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 791116247..b61cc5f9e 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -2587,7 +2587,7 @@ define([ if (isError) { error = setHTML(h('p.cp-password-error'), Messages.password_error); } var info = h('p.cp-password-info', Messages.password_info); - var info_loaded = h('p.cp-password-info', Messages.errorCopy); + var info_loaded = setHTML(h('p.cp-password-info'), Messages.errorCopy); var password = UI.passwordInput({placeholder: Messages.password_placeholder}); var $password = $(password); From ba4bef2beb72980c26b74acd15ebf4110ce641f8 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 22 Mar 2021 18:26:04 +0100 Subject: [PATCH 07/10] Reload when a drive is created in a different worker (driveless mode) --- www/common/cryptpad-common.js | 17 +++++++++++++++++ www/common/outer/async-store.js | 7 +++++++ www/common/outer/store-rpc.js | 1 + 3 files changed, 25 insertions(+) diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 1d19089e3..7cc19a78c 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -2518,6 +2518,23 @@ define([ }; // XXX if you're in noDrive mode, check if an FS_hash is added and reload if that's the case // Listen for login/logout in other tabs + if (rdyCfg.noDrive && !localStorage[Constants.fileHashKey]) { + window.addEventListener('storage', function (e) { + if (e.key !== Constants.fileHashKey) { return; } + // New entry added to FS_hash: drive created in another tab, reload + var o = e.oldValue; + var n = e.newValue; + if (!o && n) { + postMessage('HAS_DRIVE', null, function(obj) { + // If we're still in noDrive mode, reload + if (!obj.state) { + LocalStore.loginReload(); + } + // Otherwise this worker is connected, nothing to do + }); + } + }); + } window.addEventListener('storage', function (e) { if (e.key !== Constants.userHashKey) { return; } var o = e.oldValue; diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 088c5fe29..83735de7e 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -2947,6 +2947,13 @@ define([ */ var initialized = false; + // Are we still in noDrive mode? + Store.hasDrive = function (clientId, data, cb) { + cb({ + state: Boolean(store.proxy) + }); + }; + // If we load CryptPad for the first time from an existing pad, don't create a // drive automatically. var onNoDrive = function (clientId, cb) { diff --git a/www/common/outer/store-rpc.js b/www/common/outer/store-rpc.js index e444f47f5..c4d1d1301 100644 --- a/www/common/outer/store-rpc.js +++ b/www/common/outer/store-rpc.js @@ -15,6 +15,7 @@ define([ MIGRATE_ANON_DRIVE: Store.migrateAnonDrive, PING: function (cId, data, cb) { cb(); }, CACHE_DISABLE: Store.disableCache, + HAS_DRIVE: Store.hasDrive, // RPC UPDATE_PIN_LIMIT: Store.updatePinLimit, GET_PIN_LIMIT: Store.getPinLimit, From fdfd7db3628de5885c9b77cf2fad29f50778d319 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 22 Mar 2021 18:29:57 +0100 Subject: [PATCH 08/10] Remove autostore modal when the pad has been deleted by another user --- www/common/common-ui-elements.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index b61cc5f9e..a02accadf 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -2551,6 +2551,10 @@ define([ } else if (err.type === 'EDELETED') { if (priv.burnAfterReading) { return void cb(); } + if (autoStoreModal[priv.channel]) { + autoStoreModal[priv.channel].delete(); + delete autoStoreModal[priv.channel]; + } // View users have the wrong seed, thay can't retireve access directly // Version 1 hashes don't support passwords if (!priv.readOnly && !priv.oldVersionHash) { From 9c8924ee27bdb4fb09343aa5631e478f097f7123 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 22 Mar 2021 18:45:03 +0100 Subject: [PATCH 09/10] Fix change password to a previously used value --- www/common/cryptpad-common.js | 3 ++- www/common/outer/async-store.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 7cc19a78c..d653bd72e 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -1192,7 +1192,6 @@ define([ } else if (mailbox && typeof(mailbox) === "object") { m = {}; Object.keys(mailbox).forEach(function (ed) { - console.log(mailbox[ed]); try { m[ed] = newCrypto.encrypt(oldCrypto.decrypt(mailbox[ed], true, true)); } catch (e) { @@ -1227,6 +1226,7 @@ define([ cryptgetVal = JSON.stringify(parsed); } }), optsGet); + Cache.clearChannel(newSecret.channel, waitFor()); }).nThen(function (waitFor) { optsPut.metadata.restricted = oldMetadata.restricted; optsPut.metadata.allowed = oldMetadata.allowed; @@ -1608,6 +1608,7 @@ define([ } })); })); + Cache.clearChannel(newSecret.channel, waitFor()); }).nThen(function (waitFor) { // The new rt channel is ready // The blob uses its own encryption and doesn't need to be reencrypted diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 83735de7e..f20a545ec 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -452,7 +452,7 @@ define([ account.note = obj.note; cb(obj); }); - }); + }, Cache); }; ////////////////////////////////////////////////////////////////// From d7b4fca703c4393dea3cfa61f38a2e51c06b7e49 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 22 Mar 2021 19:00:40 +0100 Subject: [PATCH 10/10] Fix allow list and transfer ownership when owned pad not stored --- www/common/inner/access.js | 23 ++++++++++++++++------- www/common/toolbar.js | 7 ++++++- www/secureiframe/inner.js | 3 ++- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/www/common/inner/access.js b/www/common/inner/access.js index 47b04a5c4..cb3fc57c9 100644 --- a/www/common/inner/access.js +++ b/www/common/inner/access.js @@ -25,10 +25,12 @@ define([ var sframeChan = common.getSframeChannel(); var metadataMgr = common.getMetadataMgr(); - var channel = data.channel; + var priv = metadataMgr.getPrivateData(); + var channel = data.channel || priv.channel; var owners = data.owners || []; var pending_owners = data.pending_owners || []; var teamOwner = data.teamId; + var title = opts.title; opts = opts || {}; var redrawAll = function () {}; @@ -115,7 +117,7 @@ define([ if (!friend) { return; } common.mailbox.sendTo("RM_OWNER", { channel: channel, - title: data.title, + title: data.title || title, pending: pending }, { channel: friend.notifications, @@ -271,7 +273,7 @@ define([ href: data.href || data.rohref, password: data.password, path: isTemplate ? ['template'] : undefined, - title: data.title || '', + title: data.title || title || "", teamId: obj.id }, waitFor(function (err) { if (err) { return void console.error(err); } @@ -320,6 +322,12 @@ define([ })); } }).nThen(function (waitFor) { + var href = data.href; + var hashes = priv.hashes || {}; + var bestHash = hashes.editHash || hashes.viewHash || hashes.fileHash; + if (data.fakeHref) { + href = Hash.hashToHref(bestHash, priv.app); + } sel.forEach(function (el) { var curve = $(el).attr('data-curve'); if (curve === user.curvePublic) { return; } @@ -327,9 +335,9 @@ define([ if (!friend) { return; } common.mailbox.sendTo("ADD_OWNER", { channel: channel, - href: data.href, - password: data.password, - title: data.title + href: href, + password: data.password || priv.password, + title: data.title || title }, { channel: friend.notifications, curvePublic: friend.curvePublic @@ -398,7 +406,8 @@ define([ var sframeChan = common.getSframeChannel(); var metadataMgr = common.getMetadataMgr(); - var channel = data.channel; + var priv = metadataMgr.getPrivateData(); + var channel = data.channel || priv.channel; var owners = data.owners || []; var restricted = data.restricted || false; var allowed = data.allowed || []; diff --git a/www/common/toolbar.js b/www/common/toolbar.js index aafc356a5..2c208c1c9 100644 --- a/www/common/toolbar.js +++ b/www/common/toolbar.js @@ -565,7 +565,12 @@ MessengerUI, Messages) { h('span.cp-button-name', Messages.accessButton) ])); $accessBlock.click(function () { - Common.getSframeChannel().event('EV_ACCESS_OPEN'); + var title = (config.title && config.title.getTitle && config.title.getTitle()) + || (config.title && config.title.defaultName) + || ""; + Common.getSframeChannel().event('EV_ACCESS_OPEN', { + title: title + }); }); toolbar.$bottomM.append($accessBlock); diff --git a/www/secureiframe/inner.js b/www/secureiframe/inner.js index 01635cbaa..1c5af4a57 100644 --- a/www/secureiframe/inner.js +++ b/www/secureiframe/inner.js @@ -89,9 +89,10 @@ define([ }; // Access modal - create['access'] = function () { + create['access'] = function (data) { require(['/common/inner/access.js'], function (Access) { Access.getAccessModal(common, { + title: data.title, onClose: function () { hideIframe(); }