diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js index d8e6f73d2..e2bbdd082 100644 --- a/customize.dist/translations/messages.fr.js +++ b/customize.dist/translations/messages.fr.js @@ -32,6 +32,7 @@ define(function () { out.error = "Erreur"; out.saved = "Enregistré"; out.synced = "Tout est enregistré"; + out.deleted = "Pad supprimé de votre CryptDrive"; out.disconnected = 'Déconnecté'; out.synchronizing = 'Synchronisation'; diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index afdbdc6b2..15f5dfc2b 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -34,6 +34,7 @@ define(function () { out.error = "Error"; out.saved = "Saved"; out.synced = "Everything is saved"; + out.deleted = "Pad deleted from your CryptDrive"; out.disconnected = 'Disconnected'; out.synchronizing = 'Synchronizing'; diff --git a/www/common/common-codemirror.js b/www/common/common-codemirror.js index d9dfddaf6..bec2b98e4 100644 --- a/www/common/common-codemirror.js +++ b/www/common/common-codemirror.js @@ -149,9 +149,7 @@ define([ left: true, // Open to the left of the button isSelect: true, }; - console.log('here'); var $block = exp.$language = Cryptpad.createDropdown(dropdownConfig); - console.log(exp); $block.find('a').click(function () { setMode($(this).attr('data-value'), $block); onLocal(); diff --git a/www/common/common-hash.js b/www/common/common-hash.js index a2e96e2fc..401291d6c 100644 --- a/www/common/common-hash.js +++ b/www/common/common-hash.js @@ -32,9 +32,65 @@ define([ return '/1/view/' + hexToBase64(chanKey) + '/'+Crypto.b64RemoveSlashes(keys.viewKeyStr)+'/'; }; var getFileHashFromKeys = Hash.getFileHashFromKeys = function (fileKey, cryptKey) { - return '/2/' + hexToBase64(fileKey) + '/' + Crypto.b64RemoveSlashes(cryptKey) + '/'; + return '/1/' + hexToBase64(fileKey) + '/' + Crypto.b64RemoveSlashes(cryptKey) + '/'; }; + var fixDuplicateSlashes = function (s) { + return s.replace(/\/+/g, '/'); + }; + +/* +Version 0 + /pad/#67b8385b07352be53e40746d2be6ccd7XAYSuJYYqa9NfmInyHci7LNy +Version 1 + /code/#/1/edit/3Ujt4F2Sjnjbis6CoYWpoQ/usn4+9CqVja8Q7RZOGTfRgqI +*/ + + var parseTypeHash = Hash.parseTypeHash = function (type, hash) { + if (!hash) { return; } + var parsed = {}; + var hashArr = fixDuplicateSlashes(hash).split('/'); + if (['media', 'file', 'user'].indexOf(type) === -1) { + parsed.type = 'pad'; + if (hash.slice(0,1) !== '/' && hash.length >= 56) { + // Old hash + parsed.channel = hash.slice(0, 32); + parsed.key = hash.slice(32); + parsed.version = 0; + return parsed; + } + if (hashArr[1] && hashArr[1] === '1') { + parsed.version = 1; + parsed.mode = hashArr[2]; + parsed.channel = hashArr[3]; + parsed.key = hashArr[4].replace(/-/g, '/'); + parsed.present = typeof(hashArr[5]) === "string" && hashArr[5] === 'present'; + return parsed; + } + return parsed; + } + if (['media', 'file'].indexOf(type) !== -1) { + parsed.type = 'file'; + if (hashArr[1] && hashArr[1] === '1') { + parsed.version = 1; + parsed.channel = hashArr[2].replace(/-/g, '/'); + parsed.key = hashArr[3].replace(/-/g, '/'); + return parsed; + } + return parsed; + } + if (['user'].indexOf(type) !== -1) { + parsed.type = 'user'; + if (hashArr[1] && hashArr[1] === '1') { + parsed.version = 1; + parsed.user = hashArr[2]; + parsed.pubkey = hashArr[3].replace(/-/g, '/'); + return parsed; + } + return parsed; + } + return; + }; var parsePadUrl = Hash.parsePadUrl = function (href) { var patt = /^https*:\/\/([^\/]*)\/(.*?)\//i; @@ -43,10 +99,13 @@ define([ if (!href) { return ret; } if (href.slice(-1) !== '/') { href += '/'; } + + if (!/^https*:\/\//.test(href)) { var idx = href.indexOf('/#'); ret.type = href.slice(1, idx); ret.hash = href.slice(idx + 2); + ret.hashData = parseTypeHash(ret.type, ret.hash); return ret; } @@ -56,6 +115,7 @@ define([ return ''; }); ret.hash = hash.replace(/#/g, ''); + ret.hashData = parseTypeHash(ret.type, ret.hash); return ret; }; @@ -66,16 +126,12 @@ define([ return '/' + parsed.type + '/#' + parsed.hash; }; - var fixDuplicateSlashes = function (s) { - return s.replace(/\/+/g, '/'); - }; - /* * Returns all needed keys for a realtime channel * - no argument: use the URL hash or create one if it doesn't exist * - secretHash provided: use secretHash to find the keys */ - Hash.getSecrets = function (secretHash) { + Hash.getSecrets = function (type, secretHash) { var secret = {}; var generate = function () { secret.keys = Crypto.createEditCryptor(); @@ -85,50 +141,53 @@ define([ generate(); return secret; } else { - var hash = secretHash || window.location.hash.slice(1); + var parsed; + var hash; + if (secretHash) { + if (!type) { throw new Error("getSecrets with a hash requires a type parameter"); } + parsed = parseTypeHash(type, secretHash); + hash = secretHash; + } else { + var pHref = parsePadUrl(window.location.href); + parsed = pHref.hashData; + hash = pHref.hash; + } + //var parsed = parsePadUrl(window.location.href); + //var hash = secretHash || window.location.hash.slice(1); if (hash.length === 0) { generate(); return secret; } // old hash system : #{hexChanKey}{cryptKey} // new hash system : #/{hashVersion}/{b64ChanKey}/{cryptKey} - if (hash.slice(0,1) !== '/' && hash.length >= 56) { + if (parsed.version === 0) { // Old hash secret.channel = hash.slice(0, 32); secret.key = hash.slice(32); } - else { + else if (parsed.version === 1) { // New hash - var hashArray = fixDuplicateSlashes(hash).split('/'); - if (hashArray.length < 4) { - Hash.alert("Unable to parse the key"); - throw new Error("Unable to parse the key"); - } - var version = hashArray[1]; - if (version === "1") { - var mode = hashArray[2]; - if (mode === 'edit') { - secret.channel = base64ToHex(hashArray[3]); - var keys = Crypto.createEditCryptor(hashArray[4].replace(/-/g, '/')); - secret.keys = keys; - secret.key = keys.editKeyStr; + if (parsed.type === "pad") { + secret.channel = base64ToHex(parsed.channel); + if (parsed.mode === 'edit') { + secret.keys = Crypto.createEditCryptor(parsed.key); + secret.key = secret.keys.editKeyStr; if (secret.channel.length !== 32 || secret.key.length !== 24) { Hash.alert("The channel key and/or the encryption key is invalid"); throw new Error("The channel key and/or the encryption key is invalid"); } } - else if (mode === 'view') { - secret.channel = base64ToHex(hashArray[3]); - secret.keys = Crypto.createViewCryptor(hashArray[4].replace(/-/g, '/')); + else if (parsed.mode === 'view') { + secret.keys = Crypto.createViewCryptor(parsed.key); if (secret.channel.length !== 32) { Hash.alert("The channel key is invalid"); throw new Error("The channel key is invalid"); } } - } else if (version === "2") { + } else if (parsed.type === "file") { // version 2 hashes are to be used for encrypted blobs - secret.channel = hashArray[2].replace(/-/g, '/'); - secret.keys = { fileKeyStr: hashArray[3].replace(/-/g, '/') }; + secret.channel = parsed.channel; + secret.keys = { fileKeyStr: parsed.key }; } } } @@ -165,42 +224,6 @@ define([ return '/1/edit/' + [channelId, key].join('/') + '/'; }; -/* -Version 0 - /pad/#67b8385b07352be53e40746d2be6ccd7XAYSuJYYqa9NfmInyHci7LNy -Version 1 - /code/#/1/edit/3Ujt4F2Sjnjbis6CoYWpoQ/usn4+9CqVja8Q7RZOGTfRgqI -Version 2 - /file/#/2/// - /file/#/2/K6xWU-LT9BJHCQcDCT-DcQ/ajExFODrFH4lVBwxxsrOKw/image-png -*/ - var parseHash = Hash.parseHash = function (hash) { - var parsed = {}; - if (hash.slice(0,1) !== '/' && hash.length >= 56) { - // Old hash - parsed.channel = hash.slice(0, 32); - parsed.key = hash.slice(32); - parsed.version = 0; - return parsed; - } - var hashArr = fixDuplicateSlashes(hash).split('/'); - if (hashArr[1] && hashArr[1] === '1') { - parsed.version = 1; - parsed.mode = hashArr[2]; - parsed.channel = hashArr[3]; - parsed.key = hashArr[4]; - parsed.present = typeof(hashArr[5]) === "string" && hashArr[5] === 'present'; - return parsed; - } - if (hashArr[1] && hashArr[1] === '2') { - parsed.version = 2; - parsed.channel = hashArr[2].replace(/-/g, '/'); - parsed.key = hashArr[3].replace(/-/g, '/'); - return parsed; - } - return; - }; - // STORAGE Hash.findWeaker = function (href, recents) { var rHref = href || getRelativeHref(window.location.href); @@ -211,9 +234,13 @@ Version 2 var p = parsePadUrl(pad.href); if (p.type !== parsed.type) { return; } // Not the same type if (p.hash === parsed.hash) { return; } // Same hash, not stronger - var pHash = parseHash(p.hash); - var parsedHash = parseHash(parsed.hash); + var pHash = p.hashData; + var parsedHash = parsed.hashData; if (!parsedHash || !pHash) { return; } + + // We don't have stronger/weaker versions of files or users + if (pHash.type !== 'pad' && parsedHash.type !== 'pad') { return; } + if (pHash.version !== parsedHash.version) { return; } if (pHash.channel !== parsedHash.channel) { return; } if (pHash.mode === 'view' && parsedHash.mode === 'edit') { @@ -233,9 +260,13 @@ Version 2 var p = parsePadUrl(pad.href); if (p.type !== parsed.type) { return; } // Not the same type if (p.hash === parsed.hash) { return; } // Same hash, not stronger - var pHash = parseHash(p.hash); - var parsedHash = parseHash(parsed.hash); + var pHash = p.hashData; + var parsedHash = parsed.hashData; if (!parsedHash || !pHash) { return; } + + // We don't have stronger/weaker versions of files or users + if (pHash.type !== 'pad' && parsedHash.type !== 'pad') { return; } + if (pHash.version !== parsedHash.version) { return; } if (pHash.channel !== parsedHash.channel) { return; } if (pHash.mode === 'edit' && parsedHash.mode === 'view') { @@ -254,8 +285,7 @@ Version 2 var parsed = Hash.parsePadUrl(href); if (!parsed || !parsed.hash) { return; } - parsed = Hash.parseHash(parsed.hash); - + parsed = parsed.hashData; if (parsed.version === 0) { return parsed.channel; } else if (parsed.version !== 1 && parsed.version !== 2) { diff --git a/www/common/common-history.js b/www/common/common-history.js index 8597598c1..48b210eb3 100644 --- a/www/common/common-history.js +++ b/www/common/common-history.js @@ -35,8 +35,8 @@ define([ }; var realtime = createRealtime(); - var hash = config.href ? common.parsePadUrl(config.href).hash : undefined; - var secret = common.getSecrets(hash); + var parsed = config.href ? common.parsePadUrl(config.href) : {}; + var secret = common.getSecrets(parsed.type, parsed.hash); var crypto = Crypto.createEncryptor(secret.keys); var to = window.setTimeout(function () { diff --git a/www/common/cryptget.js b/www/common/cryptget.js index 382ab023c..cde78d298 100644 --- a/www/common/cryptget.js +++ b/www/common/cryptget.js @@ -22,7 +22,8 @@ define([ }; var makeConfig = function (hash) { - var secret = Cryptpad.getSecrets(hash); + // We can't use cryptget with a file or a user so we can use 'pad' as hash type + var secret = Cryptpad.getSecrets('pad', hash); if (!secret.keys) { secret.keys = secret.key; } // support old hashses var config = { websocketURL: Cryptpad.getWebsocketURL(), diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index e63399ec1..f91069286 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -75,10 +75,10 @@ define([ // import hash utilities for export var createRandomHash = common.createRandomHash = Hash.createRandomHash; + common.parseTypeHash = Hash.parseTypeHash; var parsePadUrl = common.parsePadUrl = Hash.parsePadUrl; var isNotStrongestStored = common.isNotStrongestStored = Hash.isNotStrongestStored; var hrefToHexChannelId = common.hrefToHexChannelId = Hash.hrefToHexChannelId; - var parseHash = common.parseHash = Hash.parseHash; var getRelativeHref = common.getRelativeHref = Hash.getRelativeHref; common.getBlobPathFromHex = Hash.getBlobPathFromHex; @@ -286,27 +286,22 @@ define([ if (!pad.title) { pad.title = common.getDefaultname(parsed); } - return parsed.hash; + return parsed.hashData; }; // Migrate from legacy store (localStorage) var migrateRecentPads = common.migrateRecentPads = function (pads) { return pads.map(function (pad) { - var hash; + var parsedHash; if (Array.isArray(pad)) { // TODO DEPRECATE_F - var href = pad[0]; - href.replace(/\#(.*)$/, function (a, h) { - hash = h; - }); - return { href: pad[0], atime: pad[1], - title: pad[2] || hash && hash.slice(0,8), + title: pad[2] || '', ctime: pad[1], }; } else if (pad && typeof(pad) === 'object') { - hash = checkObjectData(pad); - if (!hash || !common.parseHash(hash)) { return; } + parsedHash = checkObjectData(pad); + if (!parsedHash || !parsedHash.type) { return; } return pad; } else { console.error("[Cryptpad.migrateRecentPads] pad had unexpected value"); @@ -319,8 +314,8 @@ define([ var checkRecentPads = common.checkRecentPads = function (pads) { pads.forEach(function (pad, i) { if (pad && typeof(pad) === 'object') { - var hash = checkObjectData(pad); - if (!hash || !common.parseHash(hash)) { + var parsedHash = checkObjectData(pad); + if (!parsedHash || !parsedHash.type) { console.error("[Cryptpad.checkRecentPads] pad had unexpected value", pad); getStore().removeData(i); return; @@ -538,6 +533,7 @@ define([ common.setPadTitle = function (name, cb) { var href = window.location.href; var parsed = parsePadUrl(href); + if (!parsed.hash) { return; } href = getRelativeHref(href); // getRecentPads return the array from the drive, not a copy // We don't have to call "set..." at the end, everything is stored with listmap @@ -558,8 +554,8 @@ define([ // Version 1 : we have up to 4 differents hash for 1 pad, keep the strongest : // Edit > Edit (present) > View > View (present) - var pHash = parseHash(p.hash); - var parsedHash = parseHash(parsed.hash); + var pHash = p.hashData; + var parsedHash = parsed.hashData; if (!pHash) { return; } // We may have a corrupted pad in our storage, abort here in that case @@ -661,7 +657,8 @@ define([ var userHash = localStorage && localStorage.User_hash; if (!userHash) { return null; } - var userChannel = common.parseHash(userHash).channel; + var userParsedHash = common.parseTypeHash('drive', userHash); + var userChannel = userParsedHash && userParsedHash.channel; if (!userChannel) { return null; } var list = fo.getFiles([fo.FILES_DATA]).map(hrefToHexChannelId) @@ -746,13 +743,13 @@ define([ common.updatePinLimit = function (cb) { if (!pinsReady()) { return void cb('[RPC_NOT_READY]'); } - rpc.getFileListSize(cb); + rpc.updatePinLimits(cb); }; common.getPinLimit = function (cb) { if (!pinsReady()) { return void cb('[RPC_NOT_READY]'); } - rpc.getFileListSize(cb); - //cb(void 0, typeof(AppConfig.pinLimit) === 'number'? AppConfig.pinLimit: 1000); + cb(void 0, typeof(AppConfig.pinLimit) === 'number'? AppConfig.pinLimit: 1000); + //rpc.getLimit(cb); TODO }; common.isOverPinLimit = function (cb) { @@ -861,7 +858,8 @@ define([ if (callback) { button.click(function() { var href = window.location.href; - common.confirm(Messages.forgetPrompt, function (yes) { + var msg = isLoggedIn() ? Messages.forgetPrompt : Messages.fm_removePermanentlyDialog; + common.confirm(msg, function (yes) { if (!yes) { return; } common.forgetPad(href, function (err) { if (err) { @@ -880,7 +878,8 @@ define([ } else { callback(); } - common.alert(Messages.movedToTrash, undefined, true); + var cMsg = isLoggedIn() ? Messages.movedToTrash : Messages.deleted; + common.alert(cMsg, undefined, true); return; }); }); @@ -1280,20 +1279,21 @@ define([ UI.Alertify.reset(); // Load the new pad when the hash has changed - var oldHash = document.location.hash.slice(1); + var oldHref = document.location.href; window.onhashchange = function () { - var newHash = document.location.hash.slice(1); - var parsedOld = parseHash(oldHash); - var parsedNew = parseHash(newHash); + var newHref = document.location.href; + var parsedOld = parsePadUrl(oldHref).hashData; + var parsedNew = parsePadUrl(newHref).hashData; if (parsedOld && parsedNew && ( - parsedOld.channel !== parsedNew.channel + parsedOld.type !== parsedNew.type + || parsedOld.channel !== parsedNew.channel || parsedOld.mode !== parsedNew.mode || parsedOld.key !== parsedNew.key)) { document.location.reload(); return; } if (parsedNew) { - oldHash = newHash; + oldHref = newHref; } }; diff --git a/www/common/fsStore.js b/www/common/fsStore.js index 1be9e797f..b20c38c48 100644 --- a/www/common/fsStore.js +++ b/www/common/fsStore.js @@ -222,7 +222,7 @@ define([ if (!hash) { throw new Error('[Store.init] Unable to find or create a drive hash. Aborting...'); } - var secret = Cryptpad.getSecrets(hash); + var secret = Cryptpad.getSecrets('drive', hash); var listmapConfig = { data: {}, websocketURL: Cryptpad.getWebsocketURL(), diff --git a/www/common/userObject.js b/www/common/userObject.js index 0972b6943..51840dca5 100644 --- a/www/common/userObject.js +++ b/www/common/userObject.js @@ -61,9 +61,7 @@ define([ if (!isFile(element)) { return false; } var parsed = Cryptpad.parsePadUrl(element); if (!parsed) { return false; } - var hash = parsed.hash; - var pHash = Cryptpad.parseHash(hash); - if (pHash && !pHash.mode) { return; } + var pHash = parsed.hashData; return pHash && pHash.mode === 'view'; }; @@ -541,6 +539,7 @@ define([ // ADD var add = exp.add = function (data, path) { + if (!Cryptpad.isLoggedIn()) { return; } if (!data || typeof(data) !== "object") { return; } var href = data.href; var name = data.title; @@ -598,6 +597,18 @@ define([ // FORGET (move with href not path) exp.forget = function (href) { + if (!Cryptpad.isLoggedIn()) { + // delete permanently + var data = getFileData(href); + if (data) { + var i = find([FILES_DATA]).indexOf(data); + if (i !== -1) { + exp.removePadAttribute(href); + spliceFileData(i); + } + } + return; + } var paths = findFile(href); move(paths, [TRASH]); }; @@ -605,7 +616,7 @@ define([ // DELETE // Permanently delete multiple files at once using a list of paths // NOTE: We have to be careful when removing elements from arrays (trash root, unsorted or template) - var removePadAttribute = function (f) { + var removePadAttribute = exp.removePadAttribute = function (f) { if (typeof(f) !== 'string') { console.error("Can't find pad attribute for an undefined pad"); return; @@ -621,7 +632,7 @@ define([ }; var checkDeletedFiles = function () { // Nothing in FILES_DATA for workgroups - if (workgroup) { return; } + if (workgroup || !Cryptpad.isLoggedIn()) { return; } var filesList = getFiles([ROOT, 'hrefArray', TRASH]); var toRemove = []; @@ -656,6 +667,23 @@ define([ var hrefPaths = paths.filter(function(x) { return isPathIn(x, ['hrefArray']); }); var rootPaths = paths.filter(function(x) { return isPathIn(x, [ROOT]); }); var trashPaths = paths.filter(function(x) { return isPathIn(x, [TRASH]); }); + var allFilesPaths = paths.filter(function(x) { return isPathIn(x, [FILES_DATA]); }); + + if (!Cryptpad.isLoggedIn()) { + var toSplice = []; + allFilesPaths.forEach(function (path) { + var el = find(path); + toSplice.push(el); + }); + toSplice.forEach(function (el) { + var i = find([FILES_DATA]).indexOf(el); + if (i === -1) { return; } + removePadAttribute(el.href); + console.log(el.href); + spliceFileData(i); + }); + return; + } var hrefs = []; hrefPaths.forEach(function (path) { @@ -884,7 +912,7 @@ define([ toClean.push(el); return; } - if (rootFiles.indexOf(el.href) === -1) { + if (Cryptpad.isLoggedIn() && rootFiles.indexOf(el.href) === -1) { debug("An element in filesData was not in ROOT, TEMPLATE or TRASH.", el); var name = el.title || NEW_FILE_NAME; var newName = getAvailableName(root, name); diff --git a/www/drive/file.css b/www/drive/file.css index fed050db1..2f353a371 100644 --- a/www/drive/file.css +++ b/www/drive/file.css @@ -154,6 +154,9 @@ span.fa-folder-open { min-width: 30px; cursor: pointer; } +#tree #allfilesTree { + margin-top: 0; +} #tree #searchContainer { text-align: center; padding: 5px 0; diff --git a/www/drive/file.less b/www/drive/file.less index fe506ae35..13a8adc6b 100644 --- a/www/drive/file.less +++ b/www/drive/file.less @@ -194,6 +194,9 @@ span { } } } + #allfilesTree { + margin-top: 0; + } #searchContainer { text-align: center; padding: 5px 0; diff --git a/www/drive/main.js b/www/drive/main.js index 47868bde4..27671f54e 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -205,7 +205,6 @@ define([ var $trashTreeContextMenu = $iframe.find("#trashTreeContextMenu"); var $trashContextMenu = $iframe.find("#trashContextMenu"); - // TOOLBAR /* add a "change username" button */ @@ -227,10 +226,14 @@ define([ if (AppConfig.enableTemplates) { displayedCategories.push(TEMPLATE); } if (isWorkgroup()) { displayedCategories = [ROOT, TRASH, SEARCH]; } + if (!Cryptpad.isLoggedIn()) { + displayedCategories = [FILES_DATA]; + currentPath = [FILES_DATA]; + } + if (!APP.readOnly) { setEditable(true); } - var appStatus = { isReady: true, _onReady: [], @@ -1103,7 +1106,7 @@ define([ var type = Messages.type[hrefData.type] || hrefData.type; var $title = $('', {'class': 'title listElement', title: data.title}).text(data.title); var $type = $('', {'class': 'type listElement', title: type}).text(type); - if (hrefData.hash && Cryptpad.parseHash(hrefData.hash) && Cryptpad.parseHash(hrefData.hash).mode === 'view') { + if (hrefData.hashData && hrefData.hashData.mode === 'view') { $type.append(' (' + Messages.readonly+ ')'); } var $adate = $('', {'class': 'atime listElement', title: getDate(data.atime)}).text(getDate(data.atime)); @@ -1811,14 +1814,16 @@ define([ module.resetTree(); - // in history mode we want to focus the version number input - if (!history.isHistoryMode && !APP.mobile()) { - var st = $tree.scrollTop() || 0; - $tree.find('#searchInput').focus(); - $tree.scrollTop(st); + if (displayedCategories.indexOf(SEARCH) !== -1) { + // in history mode we want to focus the version number input + if (!history.isHistoryMode && !APP.mobile()) { + var st = $tree.scrollTop() || 0; + $tree.find('#searchInput').focus(); + $tree.scrollTop(st); + } + $tree.find('#searchInput')[0].selectionStart = getSearchCursor(); + $tree.find('#searchInput')[0].selectionEnd = getSearchCursor(); } - $tree.find('#searchInput')[0].selectionStart = getSearchCursor(); - $tree.find('#searchInput')[0].selectionEnd = getSearchCursor(); if (!isWorkgroup()) { setLastOpenedFolder(path); @@ -2155,9 +2160,9 @@ define([ var getReadOnlyUrl = APP.getRO = function (href) { if (!filesOp.isFile(href)) { return; } var i = href.indexOf('#') + 1; - var hash = href.slice(i); + var parsed = Cryptpad.parsePadUrl(href); var base = href.slice(0, i); - var hrefsecret = Cryptpad.getSecrets(hash); + var hrefsecret = Cryptpad.getSecrets(parsed.type, parsed.hash); if (!hrefsecret.keys) { return; } var viewHash = Cryptpad.getViewHashFromKeys(hrefsecret.channel, hrefsecret.keys); return base + viewHash; @@ -2310,6 +2315,19 @@ define([ else if ($(this).hasClass('delete')) { var pathsList = []; paths.forEach(function (p) { pathsList.push(p.path); }); + if (!Cryptpad.isLoggedIn()) { + console.log(paths); + var msg = Messages._getKey("fm_removeSeveralPermanentlyDialog", [paths.length]); + if (paths.length === 1) { + msg = Messages.fm_removePermanentlyDialog; + } + Cryptpad.confirm(msg, function(res) { + $(ifrw).focus(); + if (!res) { return; } + filesOp.delete(pathsList, refresh); + }); + return; + } moveElements(pathsList, [TRASH], false, refresh); } else if ($(this).hasClass("properties")) { @@ -2432,7 +2450,9 @@ define([ $appContainer.on('keydown', function (e) { // "Del" if (e.which === 46) { - if (filesOp.isPathIn(currentPath, [FILES_DATA])) { return; } // We can't remove elements directly from filesData + if (filesOp.isPathIn(currentPath, [FILES_DATA]) && Cryptpad.isLoggedIn()) { + return; // We can't remove elements directly from filesData + } var $selected = $iframe.find('.selected'); if (!$selected.length) { return; } var paths = []; @@ -2442,7 +2462,7 @@ define([ paths.push($(elmt).data('path')); }); // If we are in the trash or anon pad or if we are holding the "shift" key, delete permanently, - if (isTrash || e.shiftKey) { + if (!Cryptpad.isLoggedIn() || isTrash || e.shiftKey) { var msg = Messages._getKey("fm_removeSeveralPermanentlyDialog", [paths.length]); if (paths.length === 1) { msg = Messages.fm_removePermanentlyDialog; @@ -2608,7 +2628,7 @@ define([ } var hash = window.location.hash.slice(1) || Cryptpad.getUserHash() || localStorage.FS_hash; - var secret = Cryptpad.getSecrets(hash); + var secret = Cryptpad.getSecrets('drive', hash); var readOnly = APP.readOnly = secret.keys && !secret.keys.editKeyStr; var listmapConfig = module.config = {