diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js index e43cad6a1..5147baaa8 100644 --- a/customize.dist/translations/messages.fr.js +++ b/customize.dist/translations/messages.fr.js @@ -1081,6 +1081,7 @@ define(function () { out.creation_expireMonths = "Mois"; out.creation_expire1 = "Un pad illimité ne sera pas supprimé du serveur à moins que son propriétaire ne le décide."; out.creation_expire2 = "Un pad à durée de vie sera supprimé automatiquement du serveur et du CryptDrive des utilisateurs lorsque cette durée sera dépassée."; + out.creation_password = "Ajouter un mot de passe"; out.creation_noTemplate = "Pas de modèle"; out.creation_newTemplate = "Nouveau modèle"; out.creation_create = "Créer"; diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index 4c3720151..f51e552dc 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -1127,6 +1127,7 @@ define(function () { out.creation_expireMonths = "Month(s)"; out.creation_expire1 = "An unlimited pad will not be removed from the server until its owner deletes it."; out.creation_expire2 = "An expiring pad has a set lifetime, after which it will be automatically removed from the server and other users' CryptDrives."; + out.creation_password = "Add a password"; out.creation_noTemplate = "No template"; out.creation_newTemplate = "New template"; out.creation_create = "Create"; diff --git a/www/assert/main.js b/www/assert/main.js index c50360e53..f8177a03f 100644 --- a/www/assert/main.js +++ b/www/assert/main.js @@ -225,26 +225,29 @@ define([ // test support for V2 assert(function (cb) { - var secret = Hash.parsePadUrl('/pad/#/2/pad/edit/oRE0oLCtEXusRDyin7GyLGcS/'); - return cb(secret.hashData.version === 2 && - secret.hashData.mode === "edit" && - secret.hashData.type === "pad" && - secret.hashData.channel === "2NUbSuqGPz8FD0f4rSYXUw" && - secret.hashData.key === "oRE0oLCtEXusRDyin7GyLGcS" && - window.nacl.util.encodeBase64(secret.hashData.cryptKey) === "0Ts1M6VVEozErV2Nx/LTv6Im5SCD7io2LlhasyyBPQo=" && - secret.hashData.validateKey === "f5A1FM9Gp55tnOcM75RyHD1oxBG9ZPh9WDA7qe2Fvps=" && - !secret.hashData.present); + var parsed = Hash.parsePadUrl('/pad/#/2/pad/edit/oRE0oLCtEXusRDyin7GyLGcS/'); + var secret = Hash.getSecrets('pad', '/2/pad/edit/oRE0oLCtEXusRDyin7GyLGcS/'); + return cb(parsed.hashData.version === 2 && + parsed.hashData.mode === "edit" && + parsed.hashData.type === "pad" && + parsed.hashData.key === "oRE0oLCtEXusRDyin7GyLGcS" && + secret.channel === "d8d51b4aea863f3f050f47f8ad261753" && + window.nacl.util.encodeBase64(secret.keys.cryptKey) === "0Ts1M6VVEozErV2Nx/LTv6Im5SCD7io2LlhasyyBPQo=" && + secret.keys.validateKey === "f5A1FM9Gp55tnOcM75RyHD1oxBG9ZPh9WDA7qe2Fvps=" && + !parsed.hashData.present); }, "test support for version 2 hash failed to parse"); assert(function (cb) { - var secret = Hash.parsePadUrl('/pad/#/2/pad/edit/HGu0tK2od-2BBnwAz2ZNS-t4/p/embed', 'pewpew'); - return cb(secret.hashData.version === 2 && - secret.hashData.mode === "edit" && - secret.hashData.type === "pad" && - secret.hashData.channel === "P7bck4B9kDr-OQtfeYySyQ" && - secret.hashData.key === "HGu0tK2od-2BBnwAz2ZNS-t4" && - window.nacl.util.encodeBase64(secret.hashData.cryptKey) === "EeCkGJra8eJgVu7v4Yl2Hc3yUjrgpKpxr0Lcc3bSWVs=" && - secret.hashData.validateKey === "WGkBczJf2V6vQZfAScz8V1KY6jKdoxUCckrD+E75gGE=" && - secret.hashData.embed); + var parsed = Hash.parsePadUrl('/pad/#/2/pad/edit/HGu0tK2od-2BBnwAz2ZNS-t4/p/embed'); + var secret = Hash.getSecrets('pad', '/2/pad/edit/HGu0tK2od-2BBnwAz2ZNS-t4/p/embed', 'pewpew'); + return cb(parsed.hashData.version === 2 && + parsed.hashData.mode === "edit" && + parsed.hashData.type === "pad" && + parsed.hashData.key === "HGu0tK2od-2BBnwAz2ZNS-t4" && + secret.channel === "3fb6dc93807d903aff390b5f798c92c9" && + window.nacl.util.encodeBase64(secret.keys.cryptKey) === "EeCkGJra8eJgVu7v4Yl2Hc3yUjrgpKpxr0Lcc3bSWVs=" && + secret.keys.validateKey === "WGkBczJf2V6vQZfAScz8V1KY6jKdoxUCckrD+E75gGE=" && + parsed.hashData.embed && + parsed.hashData.password); }, "test support for password in version 2 hash failed to parse"); assert(function (cb) { diff --git a/www/common/common-hash.js b/www/common/common-hash.js index 2f7171fbf..95b80e989 100644 --- a/www/common/common-hash.js +++ b/www/common/common-hash.js @@ -96,7 +96,6 @@ define([ Hash.createRandomHash = function (type, password) { var cryptor = Crypto.createEditCryptor2(void 0, void 0, password); - console.log(cryptor); return getEditHashFromKeys({ password: Boolean(password), version: 2, @@ -112,7 +111,7 @@ Version 1 /code/#/1/edit/3Ujt4F2Sjnjbis6CoYWpoQ/usn4+9CqVja8Q7RZOGTfRgqI */ - var parseTypeHash = Hash.parseTypeHash = function (type, hash, password) { + var parseTypeHash = Hash.parseTypeHash = function (type, hash) { if (!hash) { return; } var parsed = {}; var hashArr = fixDuplicateSlashes(hash).split('/'); @@ -123,6 +122,7 @@ Version 1 parsed.channel = hash.slice(0, 32); parsed.key = hash.slice(32, 56); parsed.version = 0; + parsed.getHash = function () { return hash; }; return parsed; } var options; @@ -135,6 +135,13 @@ Version 1 options = hashArr.slice(5); parsed.present = options.indexOf('present') !== -1; parsed.embed = options.indexOf('embed') !== -1; + + parsed.getHash = function (opts) { + var hash = hashArr.slice(0, 5).join('/') + '/'; + if (opts.embed) { hash += 'embed/'; } + if (opts.present) { hash += 'present/'; } + return hash; + }; return parsed; } if (hashArr[1] && hashArr[1] === '2') { // Version 2 @@ -143,24 +150,23 @@ Version 1 parsed.mode = hashArr[3]; parsed.key = hashArr[4]; - var cryptor; - if (parsed.mode === "edit") { - cryptor = Crypto.createEditCryptor2(parsed.key, void 0, password); - } else if (parsed.mode === "view") { - cryptor = Crypto.createViewCryptor2(parsed.key, password); - } - parsed.channel = cryptor.chanId; - parsed.cryptKey = cryptor.cryptKey; - parsed.validateKey = cryptor.validateKey; - options = hashArr.slice(5); parsed.password = options.indexOf('p') !== -1; parsed.present = options.indexOf('present') !== -1; parsed.embed = options.indexOf('embed') !== -1; + + parsed.getHash = function (opts) { + var hash = hashArr.slice(0, 5).join('/') + '/'; + if (parsed.password) { hash += 'p/'; } + if (opts.embed) { hash += 'embed/'; } + if (opts.present) { hash += 'present/'; } + return hash; + }; return parsed; } return parsed; } + parsed.getHash = function () { return hashArr.join('/'); }; if (['media', 'file'].indexOf(type) !== -1) { parsed.type = 'file'; if (hashArr[1] && hashArr[1] === '1') { @@ -193,7 +199,7 @@ Version 1 } return; }; - var parsePadUrl = Hash.parsePadUrl = function (href, password) { + var parsePadUrl = Hash.parsePadUrl = function (href) { var patt = /^https*:\/\/([^\/]*)\/(.*?)\//i; var ret = {}; @@ -212,31 +218,8 @@ Version 1 if (!ret.hashData) { return url; } if (ret.hashData.type !== 'pad') { return url + '#' + ret.hash; } if (ret.hashData.version === 0) { return url + '#' + ret.hash; } - var hash; - if (typeof (options.readOnly === "undefined") && ret.hashData.mode === "view") { - hash = getViewHashFromKeys({ - version: ret.hashData.version, - type: ret.hashData.app, - channel: base64ToHex(ret.hashData.channel || ''), - password: ret.hashData.password, - keys: { - viewKeyStr: ret.hashData.key - } - }); - } else { - hash = getEditHashFromKeys({ - version: ret.hashData.version, - type: ret.hashData.app, - channel: base64ToHex(ret.hashData.channel || ''), - password: ret.hashData.password, - keys: { - editKeyStr: ret.hashData.key - } - }); - } + var hash = ret.hashData.getHash(options); url += '#' + hash; - if (options.embed) { url += 'embed/'; } - if (options.present) { url += 'present/'; } return url; }; @@ -244,7 +227,7 @@ Version 1 idx = href.indexOf('/#'); ret.type = href.slice(1, idx); ret.hash = href.slice(idx + 2); - ret.hashData = parseTypeHash(ret.type, ret.hash, password); + ret.hashData = parseTypeHash(ret.type, ret.hash); return ret; } @@ -254,15 +237,15 @@ Version 1 return ''; }); idx = href.indexOf('/#'); + if (idx === -1) { return ret; } ret.hash = href.slice(idx + 2); - ret.hashData = parseTypeHash(ret.type, ret.hash, password); + ret.hashData = parseTypeHash(ret.type, ret.hash); return ret; }; var getRelativeHref = Hash.getRelativeHref = function (href) { if (!href) { return; } if (href.indexOf('#') === -1) { return; } - // Password not needed to get the type or the hash var parsed = parsePadUrl(href); return '/' + parsed.type + '/#' + parsed.hash; }; @@ -288,11 +271,9 @@ Version 1 var hash; if (secretHash) { if (!type) { throw new Error("getSecrets with a hash requires a type parameter"); } - // Password not needed here, we only use the hash key parsed = parseTypeHash(type, secretHash); hash = secretHash; } else { - // Password not needed here, we only use the hash key var pHref = parsePadUrl(window.location.href); parsed = pHref.hashData; hash = pHref.hash; @@ -390,16 +371,17 @@ Version 1 }; // STORAGE - Hash.findWeaker = function (href, recents, password) { - var rHref = href || getRelativeHref(window.location.href); - var parsed = parsePadUrl(rHref, password); + Hash.findWeaker = function (href, channel, recents) { + var parsed = parsePadUrl(href); if (!parsed.hash) { return false; } var weaker; Object.keys(recents).some(function (id) { var pad = recents[id]; - var p = parsePadUrl(pad.href, pad.password); + 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 + if (channel !== pad.channel) { return; } // Not the same channel + var pHash = p.hashData; var parsedHash = parsed.hashData; if (!parsedHash || !pHash) { return; } @@ -408,7 +390,6 @@ Version 1 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') { weaker = pad; return true; @@ -417,18 +398,19 @@ Version 1 }); return weaker; }; - Hash.findStronger = function (href, recents, password) { - var rHref = href || getRelativeHref(window.location.href); - var parsed = parsePadUrl(rHref, password); + Hash.findStronger = function (href, channel, recents) { + var parsed = parsePadUrl(href); if (!parsed.hash) { return false; } // We can't have a stronger hash if we're already in edit mode if (parsed.hashData && parsed.hashData.mode === 'edit') { return; } var stronger; Object.keys(recents).some(function (id) { var pad = recents[id]; - var p = parsePadUrl(pad.href, pad.password); + 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 + if (channel !== pad.channel) { return; } // Not the same channel + var pHash = p.hashData; var parsedHash = parsed.hashData; if (!parsedHash || !pHash) { return; } @@ -437,7 +419,6 @@ Version 1 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') { stronger = pad; return true; @@ -448,23 +429,10 @@ Version 1 }; Hash.hrefToHexChannelId = function (href, password) { - var parsed = Hash.parsePadUrl(href, password); + var parsed = Hash.parsePadUrl(href); if (!parsed || !parsed.hash) { return; } - - parsed = parsed.hashData; - if (parsed.version === 0) { - return parsed.channel; - } else if (!parsed.version) { - console.error("parsed href had no version"); - console.error(parsed); - return; - } - - var channel = parsed.channel; - if (!channel) { return; } - - var hex = base64ToHex(channel); - return hex; + var secret = Hash.getSecrets(parsed.type, parsed.hash, password); + return secret.channel; }; Hash.getBlobPathFromHex = function (id) { diff --git a/www/common/common-interface.js b/www/common/common-interface.js index 6f4850010..0e4124430 100644 --- a/www/common/common-interface.js +++ b/www/common/common-interface.js @@ -629,7 +629,6 @@ define([ var type = data.type; if (!href && !type) { return $icon; } - // Password not needed to get the type if (!type) { type = Hash.parsePadUrl(href).type; } $icon = UI.getIcon(type); diff --git a/www/common/common-messaging.js b/www/common/common-messaging.js index 13d132219..e98cfb84f 100644 --- a/www/common/common-messaging.js +++ b/www/common/common-messaging.js @@ -99,7 +99,7 @@ define([ try { var parsed = Hash.parsePadUrl(window.location.href); if (!parsed.hashData) { return; } - var chan = parsed.hashData.channel; + var chan = Hash.hrefToHexChannelId(data.href); // Decrypt var keyStr = parsed.hashData.key; var cryptor = Crypto.createEditCryptor(keyStr); @@ -113,7 +113,7 @@ define([ if (!decryptMsg) { return; } // Parse msg = JSON.parse(decryptMsg); - if (msg[1] !== parsed.hashData.channel) { return; } + if (msg[1] !== chan) { return; } var msgData = msg[2]; var msgStr; if (msg[0] === "FRIEND_REQ") { @@ -199,7 +199,7 @@ define([ var parsed = Hash.parsePadUrl(data.href); if (!parsed.hashData) { return; } // Message - var chan = parsed.hashData.channel; + var chan = Hash.hrefToHexChannelId(data.href); var myData = createData(cfg.proxy); var msg = ["FRIEND_REQ", chan, myData]; // Encryption diff --git a/www/common/common-thumbnail.js b/www/common/common-thumbnail.js index 455b095c9..2495b2aac 100644 --- a/www/common/common-thumbnail.js +++ b/www/common/common-thumbnail.js @@ -205,7 +205,7 @@ define([ if (content === oldThumbnailState) { return; } oldThumbnailState = content; Thumb.fromDOM(opts, function (err, b64) { - Thumb.setPadThumbnail(common, opts.href, b64); + Thumb.setPadThumbnail(common, opts.href, null, b64); }); }; var nafa = Util.notAgainForAnother(mkThumbnail, Thumb.UPDATE_INTERVAL); @@ -240,20 +240,22 @@ define([ Thumb.addThumbnail = function(thumb, $span, cb) { return addThumbnail(null, thumb, $span, cb); }; - var getKey = function (href) { - var parsed = Hash.parsePadUrl(href); - return 'thumbnail-' + parsed.type + '-' + parsed.hashData.channel; + var getKey = function (type, channel) { + return 'thumbnail-' + type + '-' + channel; }; - Thumb.setPadThumbnail = function (common, href, b64, cb) { + Thumb.setPadThumbnail = function (common, href, channel, b64, cb) { cb = cb || function () {}; - var k = getKey(href); + var parsed = Hash.parsePadUrl(href); + var channel = channel || common.getMetadataMgr().getPrivateData().channel; + var k = getKey(parsed.type, channel); common.setThumbnail(k, b64, cb); }; - Thumb.displayThumbnail = function (common, href, $container, cb) { + Thumb.displayThumbnail = function (common, href, channel, $container, cb) { cb = cb || function () {}; var parsed = Hash.parsePadUrl(href); - var k = getKey(href); + var k = getKey(parsed.type, channel); var whenNewThumb = function () { + // PASSWORD_FILES var secret = Hash.getSecrets('file', parsed.hash); var hexFileName = Util.base64ToHex(secret.channel); var src = Hash.getBlobPathFromHex(hexFileName); @@ -270,7 +272,7 @@ define([ if (!v) { v = 'EMPTY'; } - Thumb.setPadThumbnail(common, href, v, function (err) { + Thumb.setPadThumbnail(common, href, hexFileName, v, function (err) { if (!metadata.thumbnail) { return; } addThumbnail(err, metadata.thumbnail, $container, cb); }); diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 3cf902a1a..ce4504c2d 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -67,7 +67,7 @@ define([ common.getPadAttribute('href', waitFor(function (err, val) { var base = common.getMetadataMgr().getPrivateData().origin; - var parsed = Hash.parsePadUrl(val, data.password); + var parsed = Hash.parsePadUrl(val); if (parsed.hashData.mode === "view") { data.roHref = base + val; return; @@ -75,6 +75,7 @@ define([ // We're not in a read-only pad data.href = base + val; + // Get Read-only href if (parsed.hashData.type !== "pad") { return; } var i = data.href.indexOf('#') + 1; @@ -84,6 +85,9 @@ define([ var viewHash = Hash.getViewHashFromKeys(hrefsecret); data.roHref = hBase + viewHash; })); + common.getPadAttribute('channel', waitFor(function (err, val) { + data.channel = val; + })); common.getPadAttribute('atime', waitFor(function (err, val) { data.atime = val; })); @@ -180,7 +184,7 @@ define([ if (common.isLoggedIn() && AppConfig.enablePinning) { // check the size of this file... - common.getFileSize(data.href, data.password, function (e, bytes) { + common.getFileSize(data.channel, function (e, bytes) { if (e) { // there was a problem with the RPC console.error(e); @@ -285,7 +289,6 @@ define([ var hash = (edit && hashes.editHash) ? hashes.editHash : hashes.viewHash; var href = origin + pathname + '#' + hash; - // Password not needed here since we don't access hashData var parsed = Hash.parsePadUrl(href); return origin + parsed.getUrl({embed: embed, present: present}); }; @@ -323,7 +326,6 @@ define([ var getEmbedValue = function () { var hash = hashes.viewHash || hashes.editHash; var href = origin + pathname + '#' + hash; - // Password not needed here since we don't access hashData var parsed = Hash.parsePadUrl(href); var url = origin + parsed.getUrl({embed: true, present: true}); return ''; @@ -1141,13 +1143,13 @@ define([ }; return; } + // No password for avatars var secret = Hash.getSecrets('file', parsed.hash); if (secret.keys && secret.channel) { var cryptKey = secret.keys && secret.keys.fileKeyStr; var hexFileName = Util.base64ToHex(secret.channel); var src = Hash.getBlobPathFromHex(hexFileName); - // No password for avatars - Common.getFileSize(href, null, function (e, data) { + Common.getFileSize(hexFileName, function (e, data) { if (e) { displayDefault(); return void console.error(e); @@ -1916,13 +1918,13 @@ define([ // Password var password = h('div.cp-creation-password', [ - UI.createCheckbox('cp-creation-password', 'TODO Add a password', false), //XXX + UI.createCheckbox('cp-creation-password', Messages.creation_password, false), h('span.cp-creation-password-picker.cp-creation-slider', [ h('input#cp-creation-password-val', { type: "text" // TODO type password with click to show }), ]), - createHelper('#', "TODO: password protection adds another layer of security ........") // TODO + //createHelper('#', "TODO: password protection adds another layer of security ........") // TODO ]); var right = h('span.fa.fa-chevron-right.cp-creation-template-more'); diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index d6bae315a..daf033274 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -385,7 +385,6 @@ define([ if (!type) { return void cb(null, obj); } var templates = obj.filter(function (f) { - // Password not needed here since we don't access hashData var parsed = Hash.parsePadUrl(f.href); return parsed.type === type; }); @@ -394,13 +393,12 @@ define([ }; common.saveAsTemplate = function (Cryptput, data, cb) { - // Password not needed here since we don't access hashData var p = Hash.parsePadUrl(window.location.href); if (!p.type) { return; } - // XXX PPP + // PPP: password for the new template? var hash = Hash.createRandomHash(p.type); var href = '/' + p.type + '/#' + hash; - // XXX PPP + // PPP: add password as cryptput option Cryptput(hash, data.toSave, function (e) { if (e) { throw new Error(e); } postMessage("ADD_PAD", { @@ -427,8 +425,6 @@ define([ // opts is used to overrides options for chainpad-netflux in cryptput // it allows us to add owners and expiration time if it is a new file - // Password not needed here, we only need the hash and to know if - // we need to get the password var parsed = Hash.parsePadUrl(href); var parsed2 = Hash.parsePadUrl(window.location.href); if(!parsed) { throw new Error("Cannot get template hash"); } @@ -576,7 +572,6 @@ define([ hashes = Hash.getHashes(secret); return void cb(null, hashes); } - // Password not needed here since only want the type var parsed = Hash.parsePadUrl(window.location.href); if (!parsed.type || !parsed.hashData) { return void cb('E_INVALID_HREF'); } if (parsed.type === 'file') { secret.channel = Util.base64ToHex(secret.channel); } @@ -832,17 +827,14 @@ define([ window.onhashchange = function (ev) { if (ev && ev.reset) { oldHref = document.location.href; return; } var newHref = document.location.href; - // Password not needed here since we don't access hashData + + // Compare the URLs without /embed and /present var parsedOld = Hash.parsePadUrl(oldHref); var parsedNew = Hash.parsePadUrl(newHref); if (parsedOld.hashData && parsedNew.hashData && parsedOld.getUrl() !== parsedNew.getUrl()) { - /*parseOld && parsedNew && ( - parsedOld.type !== parsedNew.type - || parsedOld.channel !== parsedNew.channel - || parsedOld.mode !== parsedNew.mode - || parsedOld.key !== parsedNew.key)) {*/ - if (!parsedOld.hashData.channel) { oldHref = newHref; return; } + if (!parsedOld.hashData.key) { oldHref = newHref; return; } + // If different, reload document.location.reload(); return; } diff --git a/www/common/mergeDrive.js b/www/common/mergeDrive.js index a20cd798b..f491643f9 100644 --- a/www/common/mergeDrive.js +++ b/www/common/mergeDrive.js @@ -122,10 +122,10 @@ define([ // Do not migrate a pad if we already have it, it would create a duplicate in the drive if (newHrefs.indexOf(href) !== -1) { return; } // If we have a stronger version, do not add the current href - if (Hash.findStronger(href, newRecentPads, oldRecentPads[id].password)) { return; } + if (Hash.findStronger(href, oldRecentPads[id].channel, newRecentPads)) { return; } // If we have a weaker version, replace the href by the new one // NOTE: if that weaker version is in the trash, the strong one will be put in unsorted - var weaker = Hash.findWeaker(href, newRecentPads, oldRecentPads[id].password); + var weaker = Hash.findWeaker(href, oldRecentPads[id].channel, newRecentPads); if (weaker) { // Update RECENTPADS weaker.href = href; diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 776843812..fb520918d 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -68,8 +68,9 @@ define([ var userHash = storeHash; if (!userHash) { return null; } - var userParsedHash = Hash.parseTypeHash('drive', userHash); - var userChannel = userParsedHash && userParsedHash.channel; + // No password for drive + var secret = Hash.getSecrets('drive', userHash); + var userChannel = secret.channel; if (!userChannel) { return null; } // Get the list of pads' channel ID in your drive @@ -81,14 +82,13 @@ define([ var d = store.userObject.getFileData(id); if (d.owners && d.owners.length && edPublic && d.owners.indexOf(edPublic) === -1) { return; } - return Hash.hrefToHexChannelId(d.href, d.password); + return d.channel; }) .filter(function (x) { return x; }); // Get the avatar var profile = store.proxy.profile; if (profile) { - // No password for profile or avatar var profileChan = profile.edit ? Hash.hrefToHexChannelId('/profile/#' + profile.edit, null) : null; if (profileChan) { list.push(profileChan); } var avatarChan = profile.avatar ? Hash.hrefToHexChannelId(profile.avatar, null) : null; @@ -100,7 +100,7 @@ define([ list = list.concat(fList); } - list.push(Util.base64ToHex(userChannel)); + list.push(userChannel); list.sort(); return list; @@ -116,7 +116,7 @@ define([ // because of the expiration time if ((data.owners && data.owners.length && data.owners.indexOf(edPublic) === -1) || (data.expire && data.expire < (+new Date()))) { - list.push(Hash.hrefToHexChannelId(data.href, data.password)); + list.push(data.channel); } }); return list; @@ -404,7 +404,6 @@ define([ var makePad = function (href, title) { var now = +new Date(); - // Password not needed here since we only need the type return { href: href, atime: now, @@ -419,6 +418,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; } store.userObject.pushData(pad, function (e, id) { if (e) { return void cb({error: "Error while adding a template:"+ e}); } var path = data.path || ['root']; @@ -436,7 +436,7 @@ define([ // Push channels owned by someone else or channel that should have expired // because of the expiration time if (data.owners && data.owners.length === 1 && data.owners.indexOf(edPublic) !== -1) { - list.push(Hash.hrefToHexChannelId(data.href, data.password)); + list.push(data.channel); } }); if (store.proxy.todo) { @@ -444,7 +444,7 @@ define([ list.push(Hash.hrefToHexChannelId('/todo/#' + store.proxy.todo, null)); } if (store.proxy.profile && store.proxy.profile.edit) { - // No password for todo + // No password for profile list.push(Hash.hrefToHexChannelId('/profile/#' + store.proxy.profile.edit, null)); } return list; @@ -466,6 +466,7 @@ define([ Store.deleteAccount = function (data, cb) { var edPublic = store.proxy.edPublic; + // No password for drive var secret = Hash.getSecrets('drive', storeHash); Store.anonRpcMsg({ msg: 'GET_METADATA', @@ -535,19 +536,13 @@ define([ return void cb({ error: "Error while creating the default pad:"+ e}); } var href = '/pad/#' + hash; + var channel = Hash.hrefToHexChannelId(href, null); var fileData = { href: href, + channel: channel, title: data.driveReadmeTitle, - atime: +new Date(), - ctime: +new Date() }; - store.userObject.pushData(fileData, function (e, id) { - if (e) { - return void cb({ error: "Error while creating the default pad:"+ e}); - } - store.userObject.add(id); - onSync(cb); - }); + addPad(fileData, cb); }); }); }; @@ -619,7 +614,6 @@ define([ }); }; Store.getPadAttribute = function (data, cb) { - console.log(data.href, data.attr); store.userObject.getPadAttribute(data.href, data.attr, function (err, val) { if (err) { return void cb({error: err}); } cb(val); @@ -689,18 +683,18 @@ define([ var p = Hash.parsePadUrl(href); var h = p.hashData; - console.log(channel, data); if (AppConfig.disableAnonymousStore && !store.loggedIn) { return void cb(); } var owners; - if (Store.channel && Store.channel.wc && Util.base64ToHex(h.channel) === Store.channel.wc.id) { + if (Store.channel && Store.channel.wc && channel === Store.channel.wc.id) { owners = Store.channel.data.owners || undefined; } var expire; - if (Store.channel && Store.channel.wc && Util.base64ToHex(h.channel) === Store.channel.wc.id) { + if (Store.channel && Store.channel.wc && channel === Store.channel.wc.id) { expire = +Store.channel.data.expire || undefined; } + console.log(owners, expire); var allPads = Util.find(store.proxy, ['drive', 'filesData']) || {}; var isStronger; @@ -795,7 +789,7 @@ define([ }; store.userObject.getFiles(where).forEach(function (id) { var data = store.userObject.getFileData(id); - var parsed = Hash.parsePadUrl(data.href, data.password); + var parsed = Hash.parsePadUrl(data.href); if ((!types || types.length === 0 || types.indexOf(parsed.type) !== -1) && hashes.indexOf(parsed.hash) === -1 && !isFiltered(parsed.type, data)) { @@ -840,9 +834,9 @@ define([ var allPads = Util.find(store.proxy, ['drive', 'filesData']) || {}; // If we have a stronger version in drive, add it and add a redirect button - var stronger = Hash.findStronger(data.href, allPads, data.password); + var stronger = Hash.findStronger(data.href, data.channel, allPads); if (stronger) { - var parsed2 = Hash.parsePadUrl(stronger.href, stronger.password); + var parsed2 = Hash.parsePadUrl(stronger.href); return void cb(parsed2.hash); } cb(); @@ -1135,6 +1129,7 @@ define([ if (!hash) { throw new Error('[Store.init] Unable to find or create a drive hash. Aborting...'); } + // No password for drive var secret = Hash.getSecrets('drive', hash); var listmapConfig = { data: {}, diff --git a/www/common/outer/userObject.js b/www/common/outer/userObject.js index 06b62d696..be718562c 100644 --- a/www/common/outer/userObject.js +++ b/www/common/outer/userObject.js @@ -75,7 +75,7 @@ define([ return void todo(); } if (!pinPads) { return; } - pinPads([Hash.hrefToHexChannelId(data.href, data.password)], function (obj) { + pinPads([data.channel], function (obj) { if (obj && obj.error) { return void cb(obj.error); } todo(); }); @@ -98,7 +98,7 @@ define([ exp.getFiles([FILES_DATA]).forEach(function (id) { if (filesList.indexOf(id) === -1) { var fd = exp.getFileData(id); - var channelId = fd && fd.href && Hash.hrefToHexChannelId(fd.href, fd.password); + var channelId = fd.channel; // If trying to remove an owned pad, remove it from server also if (!isOwnPadRemoved && fd.owners && fd.owners.indexOf(edPublic) !== -1 && channelId) { diff --git a/www/common/sframe-app-framework.js b/www/common/sframe-app-framework.js index 274069507..40c3d1d7e 100644 --- a/www/common/sframe-app-framework.js +++ b/www/common/sframe-app-framework.js @@ -315,8 +315,7 @@ define([ privateDat.availableHashes.viewHash; var href = privateDat.pathname + '#' + hash; if (AppConfig.textAnalyzer && textContentGetter) { - var channelId = Hash.hrefToHexChannelId(href, privateDat.password); - AppConfig.textAnalyzer(textContentGetter, channelId); + AppConfig.textAnalyzer(textContentGetter, privateDat.channel); } if (options.thumbnail && privateDat.thumbnails) { diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index f1cc789fb..bc9d50d00 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -115,6 +115,7 @@ define([ if (cfg.getSecrets) { var w = waitFor(); + // No password for drive, profile and todo cfg.getSecrets(Cryptpad, Utils, waitFor(function (err, s) { secret = s; Cryptpad.getShareHashes(secret, function (err, h) { @@ -123,7 +124,6 @@ define([ }); })); } else { - // Password not needed here since we only want to know if we need a password var parsed = Utils.Hash.parsePadUrl(window.location.href); var todo = function () { secret = Utils.Hash.getSecrets(parsed.type, void 0, password); @@ -135,7 +135,6 @@ define([ var needPassword = parsed.hashData && parsed.hashData.password; if (needPassword) { Cryptpad.getPadAttribute('password', waitFor(function (err, val) { - console.log(val); if (val) { // We already know the password, use it! password = val; @@ -185,7 +184,7 @@ define([ secret.keys = secret.key; readOnly = false; } - var parsed = Utils.Hash.parsePadUrl(window.location.href, password); + var parsed = Utils.Hash.parsePadUrl(window.location.href); if (!parsed.type) { throw new Error(); } var defaultTitle = Utils.Hash.getDefaultName(parsed); var edPublic; @@ -228,7 +227,8 @@ define([ isNewFile: isNewFile, isDeleted: isNewFile && window.location.hash.length > 0, forceCreationScreen: forceCreationScreen, - password: password + password: password, + channel: secret.channel }; for (var k in additionalPriv) { metaObj.priv[k] = additionalPriv[k]; } @@ -424,12 +424,10 @@ define([ // Present mode URL sframeChan.on('Q_PRESENT_URL_GET_VALUE', function (data, cb) { - // Password not needed here since we only need something directly in the hash var parsed = Utils.Hash.parsePadUrl(window.location.href); cb(parsed.hashData && parsed.hashData.present); }); sframeChan.on('EV_PRESENT_URL_SET_VALUE', function (data) { - // Password not needed here var parsed = Utils.Hash.parsePadUrl(window.location.href); window.location.href = parsed.getUrl({ embed: parsed.hashData.embed, @@ -521,10 +519,9 @@ define([ cb(templates.length > 0); }); }); - var getKey = function (href) { - // Password not needed here. We use the fake channel id for thumbnails at the moment + var getKey = function (href, channel) { var parsed = Utils.Hash.parsePadUrl(href); - return 'thumbnail-' + parsed.type + '-' + parsed.hashData.channel; + return 'thumbnail-' + parsed.type + '-' + channel; }; sframeChan.on('Q_CREATE_TEMPLATES', function (type, cb) { Cryptpad.getSecureFilesList({ @@ -537,7 +534,7 @@ define([ var res = []; nThen(function (waitFor) { Object.keys(data).map(function (el) { - var k = getKey(data[el].href); + var k = getKey(data[el].href, data[el].channel); Utils.LocalStore.getThumbnail(k, waitFor(function (e, thumb) { res.push({ id: el, @@ -732,7 +729,7 @@ define([ ohc({reset: true}); // Update metadata values and send new metadata inside - parsed = Utils.Hash.parsePadUrl(window.location.href, password); + parsed = Utils.Hash.parsePadUrl(window.location.href); defaultTitle = Utils.Hash.getDefaultName(parsed); hashes = Utils.Hash.getHashes(secret); readOnly = false; diff --git a/www/common/sframe-common.js b/www/common/sframe-common.js index 77308aacd..a1b9a4221 100644 --- a/www/common/sframe-common.js +++ b/www/common/sframe-common.js @@ -127,8 +127,7 @@ define([ } return; }; - funcs.getFileSize = function (href, password, cb) { - var channelId = Hash.hrefToHexChannelId(href, password); + funcs.getFileSize = function (channelId, cb) { funcs.sendAnonRpcMsg("GET_FILE_SIZE", channelId, function (data) { if (!data) { return void cb("No response"); } if (data.error) { return void cb(data.error); } diff --git a/www/common/toolbar3.js b/www/common/toolbar3.js index 54cc6df6c..1cecffe0c 100644 --- a/www/common/toolbar3.js +++ b/www/common/toolbar3.js @@ -578,7 +578,7 @@ define([ var o = pd.origin; var hashes = pd.availableHashes; var url = pd.origin + pd.pathname + '#' + (hashes.editHash || hashes.viewHash); - var cid = Hash.hrefToHexChannelId(url, pd.password); + var cid = pd.channel; Common.sendAnonRpcMsg('IS_CHANNEL_PINNED', cid, function (x) { if (x.error || !Array.isArray(x.response)) { return void console.log(x); } if (x.response[0] === true) { diff --git a/www/common/userObject.js b/www/common/userObject.js index f38c7d219..6192c4236 100644 --- a/www/common/userObject.js +++ b/www/common/userObject.js @@ -78,7 +78,6 @@ define([ exp.isReadOnlyFile = function (element) { if (!isFile(element)) { return false; } var data = exp.getFileData(element); - // Password not needed var parsed = Hash.parsePadUrl(data.href); if (!parsed) { return false; } var pHash = parsed.hashData; @@ -385,11 +384,9 @@ define([ // Get drive ids of files from their channel ids exp.findChannels = function (channels) { var allFilesList = files[FILES_DATA]; - var channels64 = channels.slice().map(Util.hexToBase64); return getFiles([FILES_DATA]).filter(function (k) { var data = allFilesList[k]; - var parsed = Hash.parsePadUrl(data.href, data.password); - return parsed.hashData && channels64.indexOf(parsed.hashData.channel) !== -1; + return channels.indexOf(data.channel) !== -1; }); }; diff --git a/www/drive/inner.js b/www/drive/inner.js index 5ec1cf901..5975d1e26 100644 --- a/www/drive/inner.js +++ b/www/drive/inner.js @@ -1264,7 +1264,6 @@ define([ var data = filesOp.getFileData(element); if (!data) { return void logError("No data for the file", element); } - // Password not needed var hrefData = Hash.parsePadUrl(data.href); if (hrefData.type) { $span.addClass('cp-border-color-'+hrefData.type); @@ -1297,7 +1296,7 @@ define([ $span.attr('title', name); var type = Messages.type[hrefData.type] || hrefData.type; - common.displayThumbnail(data.href, $span, function ($thumb) { + common.displayThumbnail(data.href, data.channel, $span, function ($thumb) { // Called only if the thumbnail exists // Remove the .hide() added by displayThumnail() because it hides the icon in // list mode too @@ -1836,7 +1835,6 @@ define([ var data = filesOp.getFileData(id); if (!data) { return ''; } if (prop === 'type') { - // Password not needed var hrefData = Hash.parsePadUrl(data.href); return hrefData.type; } @@ -1872,7 +1870,6 @@ define([ }; } if (prop === 'type') { - // Password not needed var hrefData = Hash.parsePadUrl(e.href); return hrefData.type; } @@ -2096,7 +2093,6 @@ define([ filesList.forEach(function (r) { r.paths.forEach(function (path) { var href = r.data.href; - // Password not needed var parsed = Hash.parsePadUrl(href); var $table = $('
', {'rowspan': '3', 'class': 'cp-app-drive-search-icon'}) @@ -2653,7 +2649,6 @@ define([ if (!filesOp.isFile(id)) { return; } var data = filesOp.getFileData(id); if (!data) { return; } - // Password not needed var parsed = Hash.parsePadUrl(data.href); if (parsed.hashData.type !== "pad") { return; } var i = data.href.indexOf('#') + 1; diff --git a/www/drive/main.js b/www/drive/main.js index 61afafb2f..79347695c 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -39,6 +39,7 @@ define([ var getSecrets = function (Cryptpad, Utils, cb) { var hash = window.location.hash.slice(1) || Utils.LocalStore.getUserHash() || Utils.LocalStore.getFSHash(); + // No password for drive cb(null, Utils.Hash.getSecrets('drive', hash)); }; var addRpc = function (sframeChan, Cryptpad, Utils) { diff --git a/www/file/inner.js b/www/file/inner.js index e7cedab71..44a51d5ba 100644 --- a/www/file/inner.js +++ b/www/file/inner.js @@ -61,7 +61,7 @@ define([ if (!priv.filehash) { uploadMode = true; } else { - // FILE_HASHES2 + // PASSWORD_FILES secret = Hash.getSecrets('file', priv.filehash); if (!secret.keys) { throw new Error("You need a hash"); } hexFileName = Util.base64ToHex(secret.channel); @@ -232,8 +232,7 @@ define([ $dlform.find('#cp-app-file-dlfile, #cp-app-file-dlprogress').click(onClick); }; var href = priv.origin + priv.pathname + priv.filehash; - // PASSWORD_FILES - common.getFileSize(href, null, function (e, data) { + common.getFileSize(hexFileName, function (e, data) { if (e) { return void UI.errorLoadingScreen(e); } diff --git a/www/filepicker/inner.js b/www/filepicker/inner.js index 194b56bd0..9dd05076a 100644 --- a/www/filepicker/inner.js +++ b/www/filepicker/inner.js @@ -139,7 +139,7 @@ define([ }); // Add thumbnail if it exists - common.displayThumbnail(data.href, $span); + common.displayThumbnail(data.href, data.channel, $span); }); $input.focus(); }; diff --git a/www/profile/main.js b/www/profile/main.js index 1d6e2974d..1bc34e902 100644 --- a/www/profile/main.js +++ b/www/profile/main.js @@ -40,6 +40,7 @@ define([ var Hash = Utils.Hash; // 1st case: visiting someone else's profile with hash in the URL if (window.location.hash) { + // No password for profiles return void cb(null, Hash.getSecrets('profile', window.location.hash.slice(1))); } var editHash; @@ -50,6 +51,7 @@ define([ })); }).nThen(function () { if (editHash) { + // No password for profile return void cb(null, Hash.getSecrets('profile', editHash)); } // 3rd case: profile creation (create a new random hash, store it later if needed) @@ -58,6 +60,7 @@ define([ window.location.href = '/drive'; return void cb(); } + // No password for profile var hash = Hash.createRandomHash('profile'); var secret = Hash.getSecrets('profile', hash); Cryptpad.pinPads([secret.channel], function (e) { diff --git a/www/todo/main.js b/www/todo/main.js index 3b1db1ef2..7cd69223e 100644 --- a/www/todo/main.js +++ b/www/todo/main.js @@ -38,6 +38,7 @@ define([ }).nThen(function (/*waitFor*/) { var getSecrets = function (Cryptpad, Utils, cb) { Cryptpad.getTodoHash(function (hash) { + // No password for todo var nHash = hash || Utils.Hash.createRandomHash('todo'); if (!hash) { Cryptpad.setTodoHash(nHash); } cb(null, Utils.Hash.getSecrets('todo', nHash)); diff --git a/www/whiteboard/inner.js b/www/whiteboard/inner.js index 9082836b1..4949343ba 100644 --- a/www/whiteboard/inner.js +++ b/www/whiteboard/inner.js @@ -389,7 +389,7 @@ define([ var D = Thumb.getResizedDimensions($canvas[0], 'pad'); Thumb.fromCanvas($canvas[0], D, function (err, b64) { oldThumbnailState = content; - Thumb.setPadThumbnail(common, href, b64); + Thumb.setPadThumbnail(common, href, privateDat.channel, b64); }); }; window.setInterval(mkThumbnail, Thumb.UPDATE_INTERVAL); |