From 17bc1ee70377d9b9e11516ab90d72ed65e63a5d4 Mon Sep 17 00:00:00 2001 From: yflory Date: Fri, 28 Sep 2018 15:06:24 +0200 Subject: [PATCH 1/4] Load shared folder when not logged in --- www/common/cryptpad-common.js | 6 ++++++ www/common/outer/async-store.js | 3 +++ www/common/outer/store-rpc.js | 1 + www/drive/main.js | 12 +++++++++++- 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 150d2a469..2d77fbe6b 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -89,6 +89,12 @@ define([ cb(obj); }); }; + common.loadSharedFolder = function (id, data, cb) { + postMessage("LOAD_SHARED_FOLDER", { + id: id, + data: data + }, cb); + }; // Settings and ready common.mergeAnonDrive = function (cb) { var data = { diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index da5edd951..536d6b71a 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -1239,6 +1239,9 @@ define([ } return rt; }; + Store.loadSharedFolderAnon = function (clientId, data, cb) { + loadSharedFolder(data.id, data.data, cb); + }; Store.addSharedFolder = function (clientId, data, cb) { Store.userObjectCommand(clientId, { cmd: 'addSharedFolder', diff --git a/www/common/outer/store-rpc.js b/www/common/outer/store-rpc.js index a724fbd06..1c37be12c 100644 --- a/www/common/outer/store-rpc.js +++ b/www/common/outer/store-rpc.js @@ -56,6 +56,7 @@ define([ INCREMENT_TEMPLATE_USE: Store.incrementTemplateUse, GET_SHARED_FOLDER: Store.getSharedFolder, ADD_SHARED_FOLDER: Store.addSharedFolder, + LOAD_SHARED_FOLDER: Store.loadSharedFolderAnon, // Messaging INVITE_FROM_USERLIST: Store.inviteFromUserlist, ADD_DIRECT_MESSAGE_HANDLERS: Store.addDirectMessageHandlers, diff --git a/www/drive/main.js b/www/drive/main.js index 2ace94441..668f77f38 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -39,7 +39,7 @@ define([ var getSecrets = function (Cryptpad, Utils, cb) { var hash = window.location.hash.slice(1); var secret = Utils.Hash.getSecrets('drive', hash); - if (hash) { + if (hash && Utils.LocalStore.isLoggedIn()) { // Add a shared folder! // TODO password? Cryptpad.addSharedFolder(secret, function (id) { @@ -53,6 +53,16 @@ define([ cb(null, secret); }); return; + } else if (hash) { + var id = Utils.Util.createRandomInteger(); + window.CryptPad_newSharedFolder = id; + var data = { + href: Utils.Hash.getRelativeHref(window.location.href), + }; + Cryptpad.loadSharedFolder(id, data, function () { + cb(null, secret); + }); + return; } // No password for drive cb(null, secret); From 0a83840c9c65b304cf811efca5d3d7f018dea610 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 1 Oct 2018 15:17:27 +0200 Subject: [PATCH 2/4] View a shared folder with an unregistered user --- customize.dist/translations/messages.fr.js | 3 + customize.dist/translations/messages.js | 3 + www/common/outer/async-store.js | 4 +- www/common/proxy-manager.js | 3 +- www/common/sframe-common-title.js | 1 - www/drive/inner.js | 121 +++++++++++++++++---- www/drive/main.js | 1 + 7 files changed, 114 insertions(+), 22 deletions(-) diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js index 4b5b9f825..d8757cc46 100644 --- a/customize.dist/translations/messages.fr.js +++ b/customize.dist/translations/messages.fr.js @@ -395,6 +395,7 @@ define(function () { out.fm_recentPadsName = "Pads récents"; out.fm_ownedPadsName = "Pads en votre possession"; out.fm_tagsName = "Mots-clés"; + out.fm_sharedFolderName = "Dossier partagé"; out.fm_searchPlaceholder = "Rechercher..."; out.fm_newButton = "Nouveau"; out.fm_newButtonTitle = "Créer un nouveau pad ou un dossier, importer un fichier dans le dossier courant"; @@ -437,6 +438,8 @@ define(function () { out.fm_info_anonymous = 'Vous n\'êtes pas connecté, ces pads seront donc supprimés après 3 mois d\'inactivité (découvrez pourquoi). ' + 'Ils sont stockés dans votre navigateur donc nettoyer votre historique peut les faire disparaître.
' + 'Inscrivez-vous ou connectez-vous pour les maintenir en vie.'; + out.fm_info_sharedFolder = "Voici le contenu d'un dossier partagé. Il n'est accessible qu'en lecture seule car vous n'êtes pas connecté.
" + + 'Inscrivez-vous ou connectez-vous pour pouvoir l\'importer dans votre CryptDrive et le modifier.'; out.fm_info_owned = "Vous êtes propriétaire des pads affichés dans cette catégorie. Cela signifie que vous pouvez choisir de les supprimer définitivement du serveur à n'importe quel moment. Ils seront alors inaccessibles pour tous les autres utilisateurs."; out.fm_alert_backupUrl = "Lien de secours pour ce CryptDrive.
" + "Il est fortement recommandé de garder ce lien pour vous-même.
" + diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index 5f57a8905..d52e4f4c5 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -397,6 +397,7 @@ define(function () { out.fm_recentPadsName = "Recent pads"; out.fm_ownedPadsName = "Owned"; out.fm_tagsName = "Tags"; + out.fm_sharedFolderName = "Shared folder"; out.fm_searchPlaceholder = "Search..."; out.fm_newButton = "New"; out.fm_newButtonTitle = "Create a new pad or folder, import a file in the current folder"; @@ -439,6 +440,8 @@ define(function () { out.fm_info_anonymous = 'You are not logged in so your pads will expire after 3 months (find out more). ' + 'They are stored in your browser so clearing history may make them disappear.
' + 'Sign up or Log in to keep them alive.
'; + out.fm_info_sharedFolder = "This is a shared folder. You're not logged in so you can only access it in read-only mode.
" + + 'Sign up or Log in to be able to import it in your CryptDrive and to modify it.
'; out.fm_info_owned = "You are the owner of the pads displayed here. This means you can remove them permanently from the server whenever you want. If you do so, other users won't be able to access them anymore."; out.fm_alert_backupUrl = "Backup link for this drive.
" + "It is highly recommended that you keep it secret.
" + diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 536d6b71a..ca42a7645 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -1240,7 +1240,9 @@ define([ return rt; }; Store.loadSharedFolderAnon = function (clientId, data, cb) { - loadSharedFolder(data.id, data.data, cb); + loadSharedFolder(data.id, data.data, function () { + cb(); + }); }; Store.addSharedFolder = function (clientId, data, cb) { Store.userObjectCommand(clientId, { diff --git a/www/common/proxy-manager.js b/www/common/proxy-manager.js index 3a6028ab1..b35e6c742 100644 --- a/www/common/proxy-manager.js +++ b/www/common/proxy-manager.js @@ -838,7 +838,8 @@ define([ var getFileData = _getFileData; var getUserObjectPath = _getUserObjectPath; - var find = function (Env, path) { + var find = function (Env, path, fId) { + if (fId) { return Env.folders[fId].userObject.find(path); } var resolved = _resolvePath(Env, path); return resolved.userObject.find(resolved.path); }; diff --git a/www/common/sframe-common-title.js b/www/common/sframe-common-title.js index dcbf6288a..b406a5dd0 100644 --- a/www/common/sframe-common-title.js +++ b/www/common/sframe-common-title.js @@ -23,7 +23,6 @@ define([ var $title; exp.setToolbar = function (toolbar) { $title = toolbar && (toolbar.title || toolbar.pageTitle); - console.log('SET TOOLBAR'); }; exp.getTitle = function () { return exp.title; }; diff --git a/www/drive/inner.js b/www/drive/inner.js index fa43a550d..8b8055778 100644 --- a/www/drive/inner.js +++ b/www/drive/inner.js @@ -67,6 +67,8 @@ define([ var OWNED_NAME = Messages.fm_ownedPadsName; var TAGS = "tags"; var TAGS_NAME = Messages.fm_tagsName; + var SHARED_FOLDER = 'sf'; + var SHARED_FOLDER_NAME = Messages.fm_sharedFolderName; // Icons var faFolder = 'fa-folder'; @@ -123,7 +125,7 @@ define([ var FOLDER_CONTENT_ID = "cp-app-drive-content-folder"; var config = {}; - var DEBUG = config.DEBUG = true; + var DEBUG = config.DEBUG = false; var debug = config.debug = DEBUG ? function () { console.log.apply(console, arguments); } : function () { return; }; @@ -239,6 +241,10 @@ define([ var updateObject = function (sframeChan, obj, cb) { sframeChan.query('Q_DRIVE_GETOBJECT', null, function (err, newObj) { copyObjectValue(obj, newObj); + if (!APP.loggedIn && APP.newSharedFolder) { + obj.drive.sharedFolders = obj.drive.sharedFolders || {}; + obj.drive.sharedFolders[APP.newSharedFolder] = {}; + } cb(); }); }; @@ -410,16 +416,22 @@ define([ // Tags used: display Tags category if (Object.keys(manager.getTagsList()).length) { displayedCategories.push(TAGS); } - var virtualCategories = [SEARCH, RECENT, OWNED, TAGS]; + var virtualCategories = [SEARCH, RECENT, OWNED, TAGS, SHARED_FOLDER]; if (!APP.loggedIn) { - displayedCategories = [FILES_DATA]; - currentPath = [FILES_DATA]; $tree.hide(); - if (Object.keys(files.root).length && !proxy.anonymousAlert) { - var msg = common.fixLinks($('
').html(Messages.fm_alert_anonymous)); - UI.alert(msg); - proxy.anonymousAlert = true; + if (APP.newSharedFolder) { + // ANON_SHARED_FOLDER + displayedCategories = [SHARED_FOLDER]; + currentPath = [SHARED_FOLDER, ROOT]; + } else { + displayedCategories = [FILES_DATA]; + currentPath = [FILES_DATA]; + if (Object.keys(files.root).length && !proxy.anonymousAlert) { + var msg = common.fixLinks($('
').html(Messages.fm_alert_anonymous)); + UI.alert(msg); + proxy.anonymousAlert = true; + } } } @@ -1485,15 +1497,17 @@ define([ var isTrash = path[0] === TRASH; var newPath = path.slice(); var key; + var element; if (isTrash && Array.isArray(elPath)) { key = elPath[0]; elPath.forEach(function (k) { newPath.push(k); }); + element = manager.find(newPath); } else { key = elPath; newPath.push(key); + element = root[key]; } - var element = manager.find(newPath); var isSharedFolder = manager.isSharedFolder(element); var $icon = !isFolder ? getFileIcon(element) : undefined; @@ -1586,6 +1600,7 @@ define([ case RECENT: pName = RECENT_NAME; break; case OWNED: pName = OWNED_NAME; break; case TAGS: pName = TAGS_NAME; break; + case SHARED_FOLDER: pName = SHARED_FOLDER_NAME; break; default: pName = name; } return pName; @@ -1610,8 +1625,8 @@ define([ var name = p; var currentEl = isVirtual ? undefined : manager.find(path.slice(0, idx+1)); - if (currentEl && manager.isSharedFolder(currentEl)) { - name = manager.getSharedFolderData(currentEl).title; + if (p === SHARED_FOLDER || (currentEl && manager.isSharedFolder(currentEl))) { + name = manager.getSharedFolderData(currentEl || APP.newSharedFolder).title; skipNext = true; } @@ -1629,7 +1644,7 @@ define([ name = getElementName(path); } - if (idx === 0) { name = getPrettyName(p); } + if (idx === 0) { name = p === SHARED_FOLDER ? name : getPrettyName(p); } else { var $span2 = $('', { 'class': 'cp-app-drive-path-element cp-app-drive-path-separator' @@ -1669,7 +1684,7 @@ define([ msg = undefined; } if (!APP.loggedIn) { - msg = Messages.fm_info_anonymous; + msg = APP.newSharedFolder ? Messages.fm_info_sharedFolder : Messages.fm_info_anonymous; return $(common.fixLinks($box.html(msg))); } if (!msg || APP.store['hide-info-' + path[0]] === '1') { @@ -2066,6 +2081,10 @@ define([ var sortElements = function (folder, path, oldkeys, prop, asc, useId) { var root = path && manager.find(path); + if (path[0] === SHARED_FOLDER) { + path = path.slice(1); + root = Util.find(folders[APP.newSharedFolder], path); + } var test = folder ? manager.isFolder : manager.isFile; var keys = oldkeys.filter(function (e) { return useId ? test(e) : (path && test(root[e])); @@ -2212,8 +2231,11 @@ define([ $('
', {'class': 'cp-app-drive-toolbar-filler'}).appendTo($toolbar); var $rightside = $('
', {'class': 'cp-app-drive-toolbar-rightside'}) .appendTo($toolbar); - var $hist = common.createButton('history', true, {histConfig: APP.histConfig}); - $rightside.append($hist); + if (APP.loggedIn || !APP.newSharedFolder) { + // ANON_SHARED_FOLDER + var $hist = common.createButton('history', true, {histConfig: APP.histConfig}); + $rightside.append($hist); + } if (APP.$burnThisDrive) { $rightside.append(APP.$burnThisDrive); } @@ -2520,6 +2542,39 @@ define([ $(h('li.cp-app-drive-tags-list', h('table', lines))).appendTo($container); }; + // ANON_SHARED_FOLDER + // Display a shared folder for anon users (read-only) + var displaySharedFolder = function ($list) { + if (currentPath.length === 1) { + currentPath.push(ROOT); + } + var fId = APP.newSharedFolder; + var data = folders[fId]; + var $folderHeader = getFolderListHeader(); + var $fileHeader = getFileListHeader(true); + var path = currentPath.slice(1); + var root = Util.find(data, path); + + if (manager.hasSubfolder(root)) { $list.append($folderHeader); } + // display sub directories + var keys = Object.keys(root); + var sortedFolders = sortElements(true, currentPath, keys, null, !getSortFolderDesc()); + var sortedFiles = sortElements(false, currentPath, keys, APP.store[SORT_FILE_BY], !getSortFileDesc()); + sortedFolders.forEach(function (key) { + if (manager.isFile(root[key])) { return; } + var $element = createElement(currentPath, key, root, true); + $element.appendTo($list); + }); + if (manager.hasFile(root)) { $list.append($fileHeader); } + // display files + sortedFiles.forEach(function (key) { + if (manager.isFolder(root[key])) { return; } + var $element = createElement(currentPath, key, root, false); + if (!$element) { return; } + $element.appendTo($list); + }); + }; + // Display the selected directory into the content part (rightside) // NOTE: Elements in the trash are not using the same storage structure as the others var _displayDirectory = function (path, force) { @@ -2551,9 +2606,12 @@ define([ var isVirtual = virtualCategories.indexOf(path[0]) !== -1; var isSearch = path[0] === SEARCH; var isTags = path[0] === TAGS; + // ANON_SHARED_FOLDER + var isSharedFolder = path[0] === SHARED_FOLDER && APP.newSharedFolder; var root = isVirtual ? undefined : manager.find(path); if (manager.isSharedFolder(root)) { + // ANON_SHARED_FOLDER path.push(manager.user.userObject.ROOT); root = manager.find(path); if (!root) { return; } @@ -2664,6 +2722,9 @@ define([ displayOwned($list); } else if (isTags) { displayTags($list); + } else if (isSharedFolder) { + // ANON_SHARED_FOLDER + displaySharedFolder($list); } else { $dirContent.contextmenu(openContextMenu('content')); if (manager.hasSubfolder(root)) { $list.append($folderHeader); } @@ -3071,6 +3132,10 @@ define([ else if ($(this).hasClass('cp-app-drive-context-openro')) { paths.forEach(function (p) { var el = manager.find(p.path); + if (paths[0].path[0] === SHARED_FOLDER && APP.newSharedFolder) { + // ANON_SHARED_FOLDER + el = manager.find(paths[0].path.slice(1), APP.newSharedFolder); + } var href; if (manager.isPathIn(p.path, [FILES_DATA])) { href = el.roHref; @@ -3159,6 +3224,10 @@ define([ } if (paths.length !== 1) { return; } el = manager.find(paths[0].path); + if (paths[0].path[0] === SHARED_FOLDER && APP.newSharedFolder) { + // ANON_SHARED_FOLDER + el = manager.find(paths[0].path.slice(1), APP.newSharedFolder); + } getProperties(el, function (e, $prop) { if (e) { return void logError(e); } UI.alert($prop[0], undefined, true); @@ -3447,6 +3516,11 @@ define([ common: common, logging: false };*/ + var metadataMgr = common.getMetadataMgr(); + var privateData = metadataMgr.getPrivateData(); + if (privateData.newSharedFolder) { + APP.newSharedFolder = privateData.newSharedFolder; + } var sframeChan = common.getSframeChannel(); updateObject(sframeChan, proxy, waitFor(function () { @@ -3457,14 +3531,23 @@ define([ var metadataMgr = common.getMetadataMgr(); var privateData = metadataMgr.getPrivateData(); - if (privateData.newSharedFolder) { - APP.newSharedFolder = privateData.newSharedFolder; - } APP.disableSF = !privateData.enableSF && AppConfig.disableSharedFolders; + if (APP.newSharedFolder && !APP.loggedIn) { + readOnly = APP.readOnly = true; + var data = folders[APP.newSharedFolder]; + if (data) { + sframeChan.query('Q_SET_PAD_TITLE_IN_DRIVE', { + title: data.metadata && data.metadata.title, + }, function () {}); + } + } + + // ANON_SHARED_FOLDER + var pageTitle = (!APP.loggedIn && APP.newSharedFolder) ? SHARED_FOLDER_NAME : Messages.type.drive; var configTb = { displayed: ['useradmin', 'pageTitle', 'newpad', 'limit'], - pageTitle: Messages.type.drive, + pageTitle: pageTitle, metadataMgr: metadataMgr, readOnly: readOnly, sfCommon: common, diff --git a/www/drive/main.js b/www/drive/main.js index 668f77f38..aff51b5ec 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -99,6 +99,7 @@ define([ }); sframeChan.on('EV_DRIVE_SET_HASH', function (hash) { // Update the hash in the address bar + if (!Utils.LocalStore.isLoggedIn()) { return; } var ohc = window.onhashchange; window.onhashchange = function () {}; window.location.hash = hash || ''; From dcabfb464d0a8a2278ec8a7d6fe4d4f52e5e72d7 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 1 Oct 2018 15:42:29 +0200 Subject: [PATCH 3/4] Refresh shared folder on change for anon users --- www/drive/inner.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/www/drive/inner.js b/www/drive/inner.js index 8b8055778..80634bd67 100644 --- a/www/drive/inner.js +++ b/www/drive/inner.js @@ -3378,6 +3378,11 @@ define([ var path = data.path.slice(); var originalPath = data.path.slice(); + if (!APP.loggedIn && APP.newSharedFolder && data.id === APP.newSharedFolder) { + // ANON_SHARED_FOLDER + return void onRefresh.refresh(); + } + // Fix the path if this is about a shared folder if (data.id && manager.folders[data.id]) { var uoPath = manager.getUserObjectPath(manager.folders[data.id].userObject); @@ -3408,6 +3413,11 @@ define([ var path = data.path.slice(); + if (!APP.loggedIn && APP.newSharedFolder && data.id === APP.newSharedFolder) { + // ANON_SHARED_FOLDER + return void onRefresh.refresh(); + } + // Fix the path if this is about a shared folder if (data.id && manager.folders[data.id]) { var uoPath = manager.getUserObjectPath(manager.folders[data.id].userObject); From 62880e8cd918f927932e020fbc241cb078168063 Mon Sep 17 00:00:00 2001 From: yflory Date: Mon, 1 Oct 2018 16:21:11 +0200 Subject: [PATCH 4/4] Fix typo --- customize.dist/translations/messages.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index d52e4f4c5..8914e3f76 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -441,7 +441,7 @@ define(function () { 'They are stored in your browser so clearing history may make them disappear.
' + 'Sign up or Log in to keep them alive.
'; out.fm_info_sharedFolder = "This is a shared folder. You're not logged in so you can only access it in read-only mode.
" + - 'Sign up or Log in to be able to import it in your CryptDrive and to modify it.
'; + 'Sign up or Log in to be able to import it to your CryptDrive and to modify it.'; out.fm_info_owned = "You are the owner of the pads displayed here. This means you can remove them permanently from the server whenever you want. If you do so, other users won't be able to access them anymore."; out.fm_alert_backupUrl = "Backup link for this drive.
" + "It is highly recommended that you keep it secret.
" +