diff --git a/www/assert/main.js b/www/assert/main.js index eb470eb35..c50360e53 100644 --- a/www/assert/main.js +++ b/www/assert/main.js @@ -223,6 +223,30 @@ define([ hd.type === 'invite'); }, "test support for invite urls"); + // 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); + }, "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); + }, "test support for password in version 2 hash failed to parse"); + assert(function (cb) { var url = '/pad/?utm_campaign=new_comment&utm_medium=email&utm_source=thread_mailer#/1/edit/3Ujt4F2Sjnjbis6CoYWpoQ/usn4+9CqVja8Q7RZOGTfRgqI/'; var secret = Hash.parsePadUrl(url); diff --git a/www/common/common-hash.js b/www/common/common-hash.js index 870b19dfe..852260acc 100644 --- a/www/common/common-hash.js +++ b/www/common/common-hash.js @@ -19,7 +19,50 @@ define([ .decodeUTF8(JSON.stringify(list)))); }; - var getEditHashFromKeys = Hash.getEditHashFromKeys = function (chanKey, keys) { + var getEditHashFromKeys = Hash.getEditHashFromKeys = function (secret) { + var version = secret.version; + var data = secret.keys; + if (version === 0) { + return secret.channel + secret.key; + } + if (version === 1) { + if (!data.editKeyStr) { return; } + return '/1/edit/' + hexToBase64(secret.channel) + + '/' + Crypto.b64RemoveSlashes(data.editKeyStr) + '/'; + } + if (version === 2) { + if (!data.editKeyStr) { return; } + var pass = secret.password ? 'p/' : ''; + return '/2/' + secret.type + '/edit/' + Crypto.b64RemoveSlashes(data.editKeyStr) + '/' + pass; + } + }; + var getViewHashFromKeys = Hash.getViewHashFromKeys = function (secret) { + var version = secret.version; + var data = secret.keys; + if (version === 0) { return; } + if (version === 1) { + if (!data.viewKeyStr) { return; } + return '/1/view/' + hexToBase64(secret.channel) + + '/'+Crypto.b64RemoveSlashes(data.viewKeyStr)+'/'; + } + if (version === 2) { + if (!data.viewKeyStr) { return; } + var pass = secret.password ? 'p/' : ''; + return '/2/' + secret.type + '/view/' + Crypto.b64RemoveSlashes(data.viewKeyStr) + '/' + pass; + } + }; + var getFileHashFromKeys = Hash.getFileHashFromKeys = function (secret) { + var version = secret.version; + var data = secret.keys; + if (version === 0) { return; } + if (version === 1) { + return '/1/' + hexToBase64(secret.channel) + '/' + + Crypto.b64RemoveSlashes(data.fileKeyStr) + '/'; + } + }; + + // V1 + /*var getEditHashFromKeys = Hash.getEditHashFromKeys = function (chanKey, keys) { if (typeof keys === 'string') { return chanKey + keys; } @@ -34,7 +77,7 @@ define([ }; var getFileHashFromKeys = Hash.getFileHashFromKeys = function (fileKey, cryptKey) { return '/1/' + hexToBase64(fileKey) + '/' + Crypto.b64RemoveSlashes(cryptKey) + '/'; - }; + };*/ Hash.getUserHrefFromKeys = function (origin, username, pubkey) { return origin + '/user/#/1/' + username + '/' + pubkey.replace(/\//g, '-'); }; @@ -43,6 +86,24 @@ define([ return s.replace(/\/+/g, '/'); }; + Hash.createChannelId = function () { + var id = uint8ArrayToHex(Crypto.Nacl.randomBytes(16)); + if (id.length !== 32 || /[^a-f0-9]/.test(id)) { + throw new Error('channel ids must consist of 32 hex characters'); + } + return id; + }; + + Hash.createRandomHash = function (type, password) { + var cryptor = Crypto.createEditCryptor2(void 0, void 0, password); + return getEditHashFromKeys({ + password: Boolean(password), + version: 2, + type: type, + keys: { editKeyStr: cryptor.editKeyStr } + }); + }; + /* Version 0 /pad/#67b8385b07352be53e40746d2be6ccd7XAYSuJYYqa9NfmInyHci7LNy @@ -50,25 +111,49 @@ Version 1 /code/#/1/edit/3Ujt4F2Sjnjbis6CoYWpoQ/usn4+9CqVja8Q7RZOGTfRgqI */ - var parseTypeHash = Hash.parseTypeHash = function (type, hash) { + var parseTypeHash = Hash.parseTypeHash = function (type, hash, password) { if (!hash) { return; } var parsed = {}; var hashArr = fixDuplicateSlashes(hash).split('/'); if (['media', 'file', 'user', 'invite'].indexOf(type) === -1) { parsed.type = 'pad'; - if (hash.slice(0,1) !== '/' && hash.length >= 56) { + if (hash.slice(0,1) !== '/' && hash.length >= 56) { // Version 0 // Old hash parsed.channel = hash.slice(0, 32); parsed.key = hash.slice(32, 56); parsed.version = 0; return parsed; } - if (hashArr[1] && hashArr[1] === '1') { + var options; + if (hashArr[1] && hashArr[1] === '1') { // Version 1 parsed.version = 1; parsed.mode = hashArr[2]; parsed.channel = hashArr[3]; - parsed.key = hashArr[4].replace(/-/g, '/'); - var options = hashArr.slice(5); + parsed.key = Crypto.b64AddSlashes(hashArr[4]); + + options = hashArr.slice(5); + parsed.present = options.indexOf('present') !== -1; + parsed.embed = options.indexOf('embed') !== -1; + return parsed; + } + if (hashArr[1] && hashArr[1] === '2') { // Version 2 + parsed.version = 2; + parsed.app = hashArr[2]; + 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; return parsed; @@ -107,7 +192,7 @@ Version 1 } return; }; - var parsePadUrl = Hash.parsePadUrl = function (href) { + var parsePadUrl = Hash.parsePadUrl = function (href, password) { var patt = /^https*:\/\/([^\/]*)\/(.*?)\//i; var ret = {}; @@ -125,17 +210,33 @@ Version 1 url += ret.type + '/'; if (!ret.hashData) { return url; } if (ret.hashData.type !== 'pad') { return url + '#' + ret.hash; } - if (ret.hashData.version !== 1) { return url + '#' + ret.hash; } - url += '#/' + ret.hashData.version + - '/' + ret.hashData.mode + - '/' + ret.hashData.channel.replace(/\//g, '-') + - '/' + ret.hashData.key.replace(/\//g, '-') +'/'; - if (options.embed) { - url += 'embed/'; - } - if (options.present) { - url += 'present/'; + if (ret.hashData.version === 0) { return url + '#' + ret.hash; } + var hash; + if (options.readOnly === true || + (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 + } + }); } + url += '#' + hash; + if (options.embed) { url += 'embed/'; } + if (options.present) { url += 'present/'; } return url; }; @@ -143,7 +244,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); + ret.hashData = parseTypeHash(ret.type, ret.hash, password); return ret; } @@ -154,7 +255,7 @@ Version 1 }); idx = href.indexOf('/#'); ret.hash = href.slice(idx + 2); - ret.hashData = parseTypeHash(ret.type, ret.hash); + ret.hashData = parseTypeHash(ret.type, ret.hash, password); return ret; }; @@ -170,11 +271,13 @@ Version 1 * - 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 (type, secretHash) { + Hash.getSecrets = function (type, secretHash, password) { var secret = {}; var generate = function () { - secret.keys = Crypto.createEditCryptor(); - secret.key = Crypto.createEditCryptor().editKeyStr; + secret.keys = Crypto.createEditCryptor2(void 0, void 0, password); + secret.channel = base64ToHex(secret.keys.chanId); + secret.version = 2; + secret.type = type; }; if (!secretHash && !window.location.hash) { //!/#/.test(window.location.href)) { generate(); @@ -203,9 +306,10 @@ Version 1 // Old hash secret.channel = parsed.channel; secret.key = parsed.key; - } - else if (parsed.version === 1) { + secret.version = 0; + } else if (parsed.version === 1) { // New hash + secret.version = 1; if (parsed.type === "pad") { secret.channel = base64ToHex(parsed.channel); if (parsed.mode === 'edit') { @@ -229,45 +333,60 @@ Version 1 // version 2 hashes are to be used for encrypted blobs throw new Error("User hashes can't be opened (yet)"); } + } else if (parsed.version === 2) { + // New hash + secret.version = 2; + secret.type = type; + secret.password = Boolean(password); + if (parsed.type === "pad") { + if (parsed.mode === 'edit') { + secret.keys = Crypto.createEditCryptor2(parsed.key); + secret.channel = base64ToHex(secret.keys.chanId); + secret.key = secret.keys.editKeyStr; + if (secret.channel.length !== 32 || secret.key.length !== 24) { + throw new Error("The channel key and/or the encryption key is invalid"); + } + } + else if (parsed.mode === 'view') { + secret.keys = Crypto.createViewCryptor2(parsed.key); + secret.channel = base64ToHex(secret.keys.chanId); + if (secret.channel.length !== 32) { + throw new Error("The channel key is invalid"); + } + } + } else if (parsed.type === "file") { + throw new Error("File hashes should be version 1"); + } else if (parsed.type === "user") { + throw new Error("User hashes can't be opened (yet)"); + } } } return secret; }; - Hash.getHashes = function (channel, secret) { + Hash.getHashes = function (secret) { var hashes = {}; - if (!secret.keys) { + secret = JSON.parse(JSON.stringify(secret)); + + if (!secret.keys && !secret.key) { console.error('e'); return hashes; + } else if (!secret.keys) { + secret.keys = {}; } - if (secret.keys.editKeyStr) { - hashes.editHash = getEditHashFromKeys(channel, secret.keys); + + if (secret.keys.editKeyStr || (secret.version === 0 && secret.key)) { + hashes.editHash = getEditHashFromKeys(secret); } if (secret.keys.viewKeyStr) { - hashes.viewHash = getViewHashFromKeys(channel, secret.keys); + hashes.viewHash = getViewHashFromKeys(secret); } if (secret.keys.fileKeyStr) { - hashes.fileHash = getFileHashFromKeys(channel, secret.keys.fileKeyStr); + hashes.fileHash = getFileHashFromKeys(secret); } return hashes; }; - var createChannelId = Hash.createChannelId = function () { - var id = uint8ArrayToHex(Crypto.Nacl.randomBytes(16)); - if (id.length !== 32 || /[^a-f0-9]/.test(id)) { - throw new Error('channel ids must consist of 32 hex characters'); - } - return id; - }; - - Hash.createRandomHash = function () { - // 16 byte channel Id - var channelId = Util.hexToBase64(createChannelId()); - // 18 byte encryption key - var key = Crypto.b64RemoveSlashes(Crypto.rand64(18)); - return '/1/edit/' + [channelId, key].join('/') + '/'; - }; - // STORAGE Hash.findWeaker = function (href, recents) { var rHref = href || getRelativeHref(window.location.href); @@ -336,7 +455,7 @@ Version 1 parsed = parsed.hashData; if (parsed.version === 0) { return parsed.channel; - } else if (parsed.version !== 1 && parsed.version !== 2) { + } else if (!parsed.version) { console.error("parsed href had no version"); console.error(parsed); return; diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js index 2b9487a73..2d09b2abe 100644 --- a/www/common/common-ui-elements.js +++ b/www/common/common-ui-elements.js @@ -60,6 +60,10 @@ define([ var getPropertiesData = function (common, cb) { var data = {}; NThen(function (waitFor) { + common.getPadAttribute('password', waitFor(function (err, val) { + data.password = val; + })); + }).nThen(function (waitFor) { common.getPadAttribute('href', waitFor(function (err, val) { var base = common.getMetadataMgr().getPrivateData().origin; @@ -75,9 +79,9 @@ define([ if (parsed.hashData.type !== "pad") { return; } var i = data.href.indexOf('#') + 1; var hBase = data.href.slice(0, i); - var hrefsecret = Hash.getSecrets(parsed.type, parsed.hash); + var hrefsecret = Hash.getSecrets(parsed.type, parsed.hash, data.password); if (!hrefsecret.keys) { return; } - var viewHash = Hash.getViewHashFromKeys(hrefsecret.channel, hrefsecret.keys); + var viewHash = Hash.getViewHashFromKeys(hrefsecret); data.roHref = hBase + viewHash; })); common.getPadAttribute('atime', waitFor(function (err, val) { diff --git a/www/common/cryptget.js b/www/common/cryptget.js index 686c69884..d5cb3edc1 100644 --- a/www/common/cryptget.js +++ b/www/common/cryptget.js @@ -20,9 +20,9 @@ define([ } }; - var makeConfig = function (hash) { + var makeConfig = function (hash, password) { // We can't use cryptget with a file or a user so we can use 'pad' as hash type - var secret = Hash.getSecrets('pad', hash); + var secret = Hash.getSecrets('pad', hash, password); if (!secret.keys) { secret.keys = secret.key; } // support old hashses var config = { websocketURL: NetConfig.getWebsocketURL(), @@ -43,12 +43,15 @@ define([ Object.keys(b).forEach(function (k) { a[k] = b[k]; }); }; + // XXX make sure we pass the password here in opt var get = function (hash, cb, opt) { if (typeof(cb) !== 'function') { throw new Error('Cryptget expects a callback'); } + opt = opt || {}; + + var config = makeConfig(hash, opt.password); var Session = { cb: cb, }; - var config = makeConfig(hash); config.onReady = function (info) { var rt = Session.session = info.realtime; @@ -60,13 +63,16 @@ define([ Session.realtime = CPNetflux.start(config); }; + // XXX make sure we pass the password here in opt var put = function (hash, doc, cb, opt) { if (typeof(cb) !== 'function') { throw new Error('Cryptput expects a callback'); } + opt = opt || {}; - var config = makeConfig(hash); + var config = makeConfig(hash, opt.password); var Session = { cb: cb, }; + config.onReady = function (info) { var realtime = Session.session = info.realtime; Session.network = info.network; diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index d4adb1ee0..e473b397c 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -260,8 +260,8 @@ define([ }); }; - common.isNewChannel = function (href, cb) { - postMessage('IS_NEW_CHANNEL', {href: href}, function (obj) { + common.isNewChannel = function (href, password, cb) { + postMessage('IS_NEW_CHANNEL', {href: href, password: password}, function (obj) { if (obj.error) { return void cb(obj.error); } if (!obj) { return void cb('INVALID_RESPONSE'); } cb(undefined, obj.isNew); @@ -395,7 +395,7 @@ define([ common.saveAsTemplate = function (Cryptput, data, cb) { var p = Hash.parsePadUrl(window.location.href); if (!p.type) { return; } - var hash = Hash.createRandomHash(); + var hash = Hash.createRandomHash(p.type); var href = '/' + p.type + '/#' + hash; Cryptput(hash, data.toSave, function (e) { if (e) { throw new Error(e); } @@ -556,13 +556,13 @@ define([ common.getShareHashes = function (secret, cb) { var hashes; if (!window.location.hash) { - hashes = Hash.getHashes(secret.channel, secret); + hashes = Hash.getHashes(secret); return void cb(null, hashes); } 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); } - hashes = Hash.getHashes(secret.channel, secret); + hashes = Hash.getHashes(secret); if (!hashes.editHash && !hashes.viewHash && parsed.hashData && !parsed.hashData.mode) { // It means we're using an old hash diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js index 0125e6018..676277475 100644 --- a/www/common/outer/async-store.js +++ b/www/common/outer/async-store.js @@ -316,7 +316,7 @@ define([ Store.isNewChannel = function (data, cb) { if (!store.anon_rpc) { return void cb({error: 'ANON_RPC_NOT_READY'}); } - var channelId = Hash.hrefToHexChannelId(data.href); + var channelId = Hash.hrefToHexChannelId(data.href, data.password); store.anon_rpc.send("IS_NEW_CHANNEL", channelId, function (e, response) { if (e) { return void cb({error: e}); } if (response && response.length && typeof(response[0]) === 'boolean') { @@ -524,7 +524,7 @@ define([ */ Store.createReadme = function (data, cb) { require(['/common/cryptget.js'], function (Crypt) { - var hash = Hash.createRandomHash(); + var hash = Hash.createRandomHash('pad'); Crypt.put(hash, data.driveReadme, function (e) { if (e) { return void cb({ error: "Error while creating the default pad:"+ e}); @@ -717,7 +717,7 @@ define([ // If the hash is different but represents the same channel, check if weaker or stronger if (!shouldUpdate && - h.version === 1 && h2.version === 1 && + h.version === h2.version && h.channel === h2.channel) { // We had view & now we have edit, update if (h2.mode === 'view' && h.mode === 'edit') { shouldUpdate = true; } @@ -1123,7 +1123,7 @@ define([ }; var connect = function (data, cb) { - var hash = data.userHash || data.anonHash || Hash.createRandomHash(); + var hash = data.userHash || data.anonHash || Hash.createRandomHash('drive'); storeHash = hash; if (!hash) { throw new Error('[Store.init] Unable to find or create a drive hash. Aborting...'); @@ -1150,7 +1150,7 @@ define([ store.realtime = info.realtime; store.network = info.network; if (!data.userHash) { - returned.anonHash = Hash.getEditHashFromKeys(info.channel, secret.keys); + returned.anonHash = Hash.getEditHashFromKeys(secret); } }).on('ready', function () { if (store.userObject) { return; } // the store is already ready, it is a reconnection diff --git a/www/common/outer/local-store.js b/www/common/outer/local-store.js index 7e93d34e7..a40a3e6f5 100644 --- a/www/common/outer/local-store.js +++ b/www/common/outer/local-store.js @@ -108,7 +108,7 @@ define([ // Make sure we have an FS_hash in localStorage before reloading all the tabs // so that we don't end up with tabs using different anon hashes if (!LocalStore.getFSHash()) { - LocalStore.setFSHash(Hash.createRandomHash()); + LocalStore.setFSHash(Hash.createRandomHash('drive')); } eraseTempSessionValues(); diff --git a/www/common/outer/upload.js b/www/common/outer/upload.js index cce3e6b3c..ee9f4d77c 100644 --- a/www/common/outer/upload.js +++ b/www/common/outer/upload.js @@ -51,7 +51,14 @@ define([ var b64Key = Nacl.util.encodeBase64(key); - var hash = Hash.getFileHashFromKeys(id, b64Key); + var secret = { + version: 1, + channel: id, + keys: { + fileKeyStr: b64Key + } + }; + var hash = Hash.getFileHashFromKeys(secret); var href = '/file/#' + hash; var title = metadata.name; diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js index 014914b50..e6543bb30 100644 --- a/www/common/sframe-common-outer.js +++ b/www/common/sframe-common-outer.js @@ -121,11 +121,17 @@ define([ }); })); } else { - secret = Utils.Hash.getSecrets(); - if (!secret.channel) { + var parsedType = Utils.Hash.parsePadUrl(window.location.href).type; + // XXX prompt the password here if we have a hash containing /p/ + // OR get it from the pad attributes + secret = Utils.Hash.getSecrets(parsedType); + + // TODO: New hashes V2 already contain a channel ID so we can probably remove the following lines + //if (!secret.channel) { // New pad: create a new random channel id - secret.channel = Utils.Hash.createChannelId(); - } + //secret.channel = Utils.Hash.createChannelId(); + //} + Cryptpad.getShareHashes(secret, waitFor(function (err, h) { hashes = h; })); } }).nThen(function (waitFor) { @@ -133,7 +139,9 @@ define([ if (!window.location.hash) { isNewFile = true; return; } if (realtime) { - Cryptpad.isNewChannel(window.location.href, waitFor(function (e, isNew) { + // XXX get password + var password; + Cryptpad.isNewChannel(window.location.href, password, waitFor(function (e, isNew) { if (e) { return console.error(e); } isNewFile = Boolean(isNew); })); @@ -635,7 +643,7 @@ define([ isNewHash: isNewHash, readOnly: readOnly, crypto: Crypto.createEncryptor(secret.keys), - onConnect: function (wc) { + onConnect: function () { if (window.location.hash && window.location.hash !== '#') { window.location = parsed.getUrl({ present: parsed.hashData.present, @@ -644,7 +652,7 @@ define([ return; } if (readOnly || cfg.noHash) { return; } - replaceHash(Utils.Hash.getEditHashFromKeys(wc, secret.keys)); + replaceHash(Utils.Hash.getEditHashFromKeys(secret)); } }; @@ -671,8 +679,10 @@ define([ sframeChan.on('Q_CREATE_PAD', function (data, cb) { if (!isNewFile || rtStarted) { return; } // Create a new hash - var newHash = Utils.Hash.createRandomHash(); - secret = Utils.Hash.getSecrets(parsed.type, newHash); + // XXX add password here + var password = data.password; + var newHash = Utils.Hash.createRandomHash(parsed.type, password); + secret = Utils.Hash.getSecrets(parsed.type, newHash, password); // Update the hash in the address bar var ohc = window.onhashchange; @@ -684,7 +694,7 @@ define([ // Update metadata values and send new metadata inside parsed = Utils.Hash.parsePadUrl(window.location.href); defaultTitle = Utils.Hash.getDefaultName(parsed); - hashes = Utils.Hash.getHashes(secret.channel, secret); + hashes = Utils.Hash.getHashes(secret); readOnly = false; updateMeta(); diff --git a/www/common/sframe-common.js b/www/common/sframe-common.js index ab3c2389d..a56afa382 100644 --- a/www/common/sframe-common.js +++ b/www/common/sframe-common.js @@ -114,6 +114,7 @@ define([ }; funcs.getMediatagFromHref = function (href) { var parsed = Hash.parsePadUrl(href); + // FILE_HASHES2 var secret = Hash.getSecrets('file', parsed.hash); var data = ctx.metadataMgr.getPrivateData(); if (secret.keys && secret.channel) { diff --git a/www/drive/inner.js b/www/drive/inner.js index df9708d97..08c067183 100644 --- a/www/drive/inner.js +++ b/www/drive/inner.js @@ -2653,9 +2653,9 @@ define([ if (parsed.hashData.type !== "pad") { return; } var i = data.href.indexOf('#') + 1; var base = data.href.slice(0, i); - var hrefsecret = Hash.getSecrets(parsed.type, parsed.hash); + var hrefsecret = Hash.getSecrets(parsed.type, parsed.hash, data.password); if (!hrefsecret.keys) { return; } - var viewHash = Hash.getViewHashFromKeys(hrefsecret.channel, hrefsecret.keys); + var viewHash = Hash.getViewHashFromKeys(hrefsecret); return base + viewHash; }; @@ -2720,24 +2720,6 @@ define([ $(window).focus(); if (!res) { return; } filesOp.delete(pathsList, refresh); - /* - // Try to delete each selected pad from server, and delete from drive if no error - var n = nThen(function () {}); - pathsList.forEach(function (p) { - var el = filesOp.find(p); - var data = filesOp.getFileData(el); - var parsed = Hash.parsePadUrl(data.href); - var channel = Util.base64ToHex(parsed.hashData.channel); - n = n.nThen(function (waitFor) { - sframeChan.query('Q_REMOVE_OWNED_CHANNEL', channel, - waitFor(function (e) { - if (e) { return void console.error(e); } - filesOp.delete([p], function () {}, false, true); - })); - }); - }); - n.nThen(function () { refresh(); }); - */ }); }; $contextMenu.on("click", "a", function(e) { diff --git a/www/file/inner.js b/www/file/inner.js index 8ad9532ad..98a77f647 100644 --- a/www/file/inner.js +++ b/www/file/inner.js @@ -61,6 +61,7 @@ define([ if (!priv.filehash) { uploadMode = true; } else { + // FILE_HASHES2 secret = Hash.getSecrets('file', priv.filehash); if (!secret.keys) { throw new Error("You need a hash"); } hexFileName = Util.base64ToHex(secret.channel); diff --git a/www/profile/main.js b/www/profile/main.js index c4b3847a4..90557d793 100644 --- a/www/profile/main.js +++ b/www/profile/main.js @@ -58,7 +58,7 @@ define([ window.location.href = '/drive'; return void cb(); } - var hash = Hash.createRandomHash(); + var hash = Hash.createRandomHash('profile'); var secret = Hash.getSecrets('profile', hash); Cryptpad.pinPads([secret.channel], function (e) { if (e) { @@ -69,8 +69,8 @@ define([ //return void UI.log(Messages._getKey('profile_error', [e])) // TODO } var profile = {}; - profile.edit = Utils.Hash.getEditHashFromKeys(secret.channel, secret.keys); - profile.view = Utils.Hash.getViewHashFromKeys(secret.channel, secret.keys); + profile.edit = Utils.Hash.getEditHashFromKeys(secret); + profile.view = Utils.Hash.getViewHashFromKeys(secret); Cryptpad.setNewProfile(profile); }); cb(null, secret); diff --git a/www/todo/main.js b/www/todo/main.js index b86546bf6..3b1db1ef2 100644 --- a/www/todo/main.js +++ b/www/todo/main.js @@ -38,7 +38,7 @@ define([ }).nThen(function (/*waitFor*/) { var getSecrets = function (Cryptpad, Utils, cb) { Cryptpad.getTodoHash(function (hash) { - var nHash = hash || Utils.Hash.createRandomHash(); + var nHash = hash || Utils.Hash.createRandomHash('todo'); if (!hash) { Cryptpad.setTodoHash(nHash); } cb(null, Utils.Hash.getSecrets('todo', nHash)); });