Add support for version 2 hashes needed for password-protected pads
parent
fd89811479
commit
811463b870
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue