Merge branch 'communities-hash' into staging
This commit is contained in:
commit
f253e19575
@ -60,6 +60,21 @@ var factory = function (Util, Crypto, Nacl) {
|
|||||||
return '/2/' + secret.type + '/view/' + Crypto.b64RemoveSlashes(data.viewKeyStr) + '/' + pass;
|
return '/2/' + secret.type + '/view/' + Crypto.b64RemoveSlashes(data.viewKeyStr) + '/' + pass;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Hash.getHiddenHashFromKeys = function (type, secret, opts) {
|
||||||
|
var mode = ((secret.keys && secret.keys.editKeyStr) || secret.key) ? 'edit/' : 'view/';
|
||||||
|
var pass = secret.password ? 'p/' : '';
|
||||||
|
|
||||||
|
if (secret.keys && secret.keys.fileKeyStr) { mode = ''; }
|
||||||
|
|
||||||
|
var hash = '/3/' + type + '/' + mode + secret.channel + '/' + pass;
|
||||||
|
var hashData = Hash.parseTypeHash(type, hash);
|
||||||
|
if (hashData && hashData.getHash) {
|
||||||
|
return hashData.getHash(opts || {});
|
||||||
|
}
|
||||||
|
return hash;
|
||||||
|
};
|
||||||
|
|
||||||
var getFileHashFromKeys = Hash.getFileHashFromKeys = function (secret) {
|
var getFileHashFromKeys = Hash.getFileHashFromKeys = function (secret) {
|
||||||
var version = secret.version;
|
var version = secret.version;
|
||||||
var data = secret.keys;
|
var data = secret.keys;
|
||||||
@ -160,12 +175,28 @@ Version 1
|
|||||||
};
|
};
|
||||||
var parseTypeHash = Hash.parseTypeHash = function (type, hash) {
|
var parseTypeHash = Hash.parseTypeHash = function (type, hash) {
|
||||||
if (!hash) { return; }
|
if (!hash) { return; }
|
||||||
var options;
|
var options = [];
|
||||||
var parsed = {};
|
var parsed = {};
|
||||||
var hashArr = fixDuplicateSlashes(hash).split('/');
|
var hashArr = fixDuplicateSlashes(hash).split('/');
|
||||||
|
|
||||||
|
var addOptions = function () {
|
||||||
|
parsed.password = options.indexOf('p') !== -1;
|
||||||
|
parsed.present = options.indexOf('present') !== -1;
|
||||||
|
parsed.embed = options.indexOf('embed') !== -1;
|
||||||
|
parsed.ownerKey = getOwnerKey(options);
|
||||||
|
};
|
||||||
|
|
||||||
if (['media', 'file', 'user', 'invite'].indexOf(type) === -1) {
|
if (['media', 'file', 'user', 'invite'].indexOf(type) === -1) {
|
||||||
parsed.type = 'pad';
|
parsed.type = 'pad';
|
||||||
parsed.getHash = function () { return hash; };
|
parsed.getHash = function () { return hash; };
|
||||||
|
parsed.getOptions = function () {
|
||||||
|
return {
|
||||||
|
embed: parsed.embed,
|
||||||
|
present: parsed.present,
|
||||||
|
ownerKey: parsed.ownerKey,
|
||||||
|
password: parsed.password
|
||||||
|
};
|
||||||
|
};
|
||||||
if (hash.slice(0,1) !== '/' && hash.length >= 56) { // Version 0
|
if (hash.slice(0,1) !== '/' && hash.length >= 56) { // Version 0
|
||||||
// Old hash
|
// Old hash
|
||||||
parsed.channel = hash.slice(0, 32);
|
parsed.channel = hash.slice(0, 32);
|
||||||
@ -173,6 +204,18 @@ Version 1
|
|||||||
parsed.version = 0;
|
parsed.version = 0;
|
||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Version >= 1: more hash options
|
||||||
|
parsed.getHash = function (opts) {
|
||||||
|
var hash = hashArr.slice(0, 5).join('/') + '/';
|
||||||
|
var owner = typeof(opts.ownerKey) !== "undefined" ? opts.ownerKey : parsed.ownerKey;
|
||||||
|
if (owner) { hash += owner + '/'; }
|
||||||
|
if (parsed.password || opts.password) { hash += 'p/'; }
|
||||||
|
if (opts.embed) { hash += 'embed/'; }
|
||||||
|
if (opts.present) { hash += 'present/'; }
|
||||||
|
return hash;
|
||||||
|
};
|
||||||
|
|
||||||
if (hashArr[1] && hashArr[1] === '1') { // Version 1
|
if (hashArr[1] && hashArr[1] === '1') { // Version 1
|
||||||
parsed.version = 1;
|
parsed.version = 1;
|
||||||
parsed.mode = hashArr[2];
|
parsed.mode = hashArr[2];
|
||||||
@ -180,18 +223,8 @@ Version 1
|
|||||||
parsed.key = Crypto.b64AddSlashes(hashArr[4]);
|
parsed.key = Crypto.b64AddSlashes(hashArr[4]);
|
||||||
|
|
||||||
options = hashArr.slice(5);
|
options = hashArr.slice(5);
|
||||||
parsed.present = options.indexOf('present') !== -1;
|
addOptions();
|
||||||
parsed.embed = options.indexOf('embed') !== -1;
|
|
||||||
parsed.ownerKey = getOwnerKey(options);
|
|
||||||
|
|
||||||
parsed.getHash = function (opts) {
|
|
||||||
var hash = hashArr.slice(0, 5).join('/') + '/';
|
|
||||||
var owner = typeof(opts.ownerKey) !== "undefined" ? opts.ownerKey : parsed.ownerKey;
|
|
||||||
if (owner) { hash += owner + '/'; }
|
|
||||||
if (opts.embed) { hash += 'embed/'; }
|
|
||||||
if (opts.present) { hash += 'present/'; }
|
|
||||||
return hash;
|
|
||||||
};
|
|
||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
if (hashArr[1] && hashArr[1] === '2') { // Version 2
|
if (hashArr[1] && hashArr[1] === '2') { // Version 2
|
||||||
@ -201,20 +234,19 @@ Version 1
|
|||||||
parsed.key = hashArr[4];
|
parsed.key = hashArr[4];
|
||||||
|
|
||||||
options = hashArr.slice(5);
|
options = hashArr.slice(5);
|
||||||
parsed.password = options.indexOf('p') !== -1;
|
addOptions();
|
||||||
parsed.present = options.indexOf('present') !== -1;
|
|
||||||
parsed.embed = options.indexOf('embed') !== -1;
|
return parsed;
|
||||||
parsed.ownerKey = getOwnerKey(options);
|
}
|
||||||
|
if (hashArr[1] && hashArr[1] === '3') { // Version 3: hidden hash
|
||||||
|
parsed.version = 3;
|
||||||
|
parsed.app = hashArr[2];
|
||||||
|
parsed.mode = hashArr[3];
|
||||||
|
parsed.channel = hashArr[4];
|
||||||
|
|
||||||
|
options = hashArr.slice(5);
|
||||||
|
addOptions();
|
||||||
|
|
||||||
parsed.getHash = function (opts) {
|
|
||||||
var hash = hashArr.slice(0, 5).join('/') + '/';
|
|
||||||
var owner = typeof(opts.ownerKey) !== "undefined" ? opts.ownerKey : parsed.ownerKey;
|
|
||||||
if (owner) { hash += owner + '/'; }
|
|
||||||
if (parsed.password) { hash += 'p/'; }
|
|
||||||
if (opts.embed) { hash += 'embed/'; }
|
|
||||||
if (opts.present) { hash += 'present/'; }
|
|
||||||
return hash;
|
|
||||||
};
|
|
||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
return parsed;
|
return parsed;
|
||||||
@ -222,34 +254,54 @@ Version 1
|
|||||||
parsed.getHash = function () { return hashArr.join('/'); };
|
parsed.getHash = function () { return hashArr.join('/'); };
|
||||||
if (['media', 'file'].indexOf(type) !== -1) {
|
if (['media', 'file'].indexOf(type) !== -1) {
|
||||||
parsed.type = 'file';
|
parsed.type = 'file';
|
||||||
|
|
||||||
|
parsed.getOptions = function () {
|
||||||
|
return {
|
||||||
|
embed: parsed.embed,
|
||||||
|
present: parsed.present,
|
||||||
|
ownerKey: parsed.ownerKey,
|
||||||
|
password: parsed.password
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
parsed.getHash = function (opts) {
|
||||||
|
var hash = hashArr.slice(0, 4).join('/') + '/';
|
||||||
|
var owner = typeof(opts.ownerKey) !== "undefined" ? opts.ownerKey : parsed.ownerKey;
|
||||||
|
if (owner) { hash += owner + '/'; }
|
||||||
|
if (parsed.password || opts.password) { hash += 'p/'; }
|
||||||
|
if (opts.embed) { hash += 'embed/'; }
|
||||||
|
if (opts.present) { hash += 'present/'; }
|
||||||
|
return hash;
|
||||||
|
};
|
||||||
|
|
||||||
if (hashArr[1] && hashArr[1] === '1') {
|
if (hashArr[1] && hashArr[1] === '1') {
|
||||||
parsed.version = 1;
|
parsed.version = 1;
|
||||||
parsed.channel = hashArr[2].replace(/-/g, '/');
|
parsed.channel = hashArr[2].replace(/-/g, '/');
|
||||||
parsed.key = hashArr[3].replace(/-/g, '/');
|
parsed.key = hashArr[3].replace(/-/g, '/');
|
||||||
options = hashArr.slice(4);
|
options = hashArr.slice(4);
|
||||||
parsed.ownerKey = getOwnerKey(options);
|
addOptions();
|
||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hashArr[1] && hashArr[1] === '2') { // Version 2
|
if (hashArr[1] && hashArr[1] === '2') { // Version 2
|
||||||
parsed.version = 2;
|
parsed.version = 2;
|
||||||
parsed.app = hashArr[2];
|
parsed.app = hashArr[2];
|
||||||
parsed.key = hashArr[3];
|
parsed.key = hashArr[3];
|
||||||
|
|
||||||
options = hashArr.slice(4);
|
options = hashArr.slice(4);
|
||||||
parsed.password = options.indexOf('p') !== -1;
|
addOptions();
|
||||||
parsed.present = options.indexOf('present') !== -1;
|
|
||||||
parsed.embed = options.indexOf('embed') !== -1;
|
return parsed;
|
||||||
parsed.ownerKey = getOwnerKey(options);
|
}
|
||||||
|
|
||||||
|
if (hashArr[1] && hashArr[1] === '3') { // Version 3: hidden hash
|
||||||
|
parsed.version = 3;
|
||||||
|
parsed.app = hashArr[2];
|
||||||
|
parsed.channel = hashArr[3];
|
||||||
|
|
||||||
|
options = hashArr.slice(4);
|
||||||
|
addOptions();
|
||||||
|
|
||||||
parsed.getHash = function (opts) {
|
|
||||||
var hash = hashArr.slice(0, 4).join('/') + '/';
|
|
||||||
var owner = typeof(opts.ownerKey) !== "undefined" ? opts.ownerKey : parsed.ownerKey;
|
|
||||||
if (owner) { hash += owner + '/'; }
|
|
||||||
if (parsed.password) { hash += 'p/'; }
|
|
||||||
if (opts.embed) { hash += 'embed/'; }
|
|
||||||
if (opts.present) { hash += 'present/'; }
|
|
||||||
return hash;
|
|
||||||
};
|
|
||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
return parsed;
|
return parsed;
|
||||||
@ -303,6 +355,10 @@ Version 1
|
|||||||
url += '#' + hash;
|
url += '#' + hash;
|
||||||
return url;
|
return url;
|
||||||
};
|
};
|
||||||
|
ret.getOptions = function () {
|
||||||
|
if (!ret.hashData || !ret.hashData.getOptions) { return {}; }
|
||||||
|
return ret.hashData.getOptions();
|
||||||
|
};
|
||||||
|
|
||||||
if (!/^https*:\/\//.test(href)) {
|
if (!/^https*:\/\//.test(href)) {
|
||||||
idx = href.indexOf('/#');
|
idx = href.indexOf('/#');
|
||||||
@ -325,6 +381,14 @@ Version 1
|
|||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Hash.hashToHref = function (hash, type) {
|
||||||
|
return '/' + type + '/#' + hash;
|
||||||
|
};
|
||||||
|
Hash.hrefToHash = function (href) {
|
||||||
|
var parsed = Hash.parsePadUrl(href);
|
||||||
|
return parsed.hash;
|
||||||
|
};
|
||||||
|
|
||||||
Hash.getRelativeHref = function (href) {
|
Hash.getRelativeHref = function (href) {
|
||||||
if (!href) { return; }
|
if (!href) { return; }
|
||||||
if (href.indexOf('#') === -1) { return; }
|
if (href.indexOf('#') === -1) { return; }
|
||||||
@ -345,7 +409,7 @@ Version 1
|
|||||||
secret.version = 2;
|
secret.version = 2;
|
||||||
secret.type = type;
|
secret.type = type;
|
||||||
};
|
};
|
||||||
if (!secretHash && !window.location.hash) { //!/#/.test(window.location.href)) {
|
if (!secretHash) {
|
||||||
generate();
|
generate();
|
||||||
return secret;
|
return secret;
|
||||||
} else {
|
} else {
|
||||||
@ -355,12 +419,7 @@ Version 1
|
|||||||
if (!type) { throw new Error("getSecrets with a hash requires a type parameter"); }
|
if (!type) { throw new Error("getSecrets with a hash requires a type parameter"); }
|
||||||
parsed = parseTypeHash(type, secretHash);
|
parsed = parseTypeHash(type, secretHash);
|
||||||
hash = secretHash;
|
hash = secretHash;
|
||||||
} else {
|
|
||||||
var pHref = parsePadUrl(window.location.href);
|
|
||||||
parsed = pHref.hashData;
|
|
||||||
hash = pHref.hash;
|
|
||||||
}
|
}
|
||||||
//var hash = secretHash || window.location.hash.slice(1);
|
|
||||||
if (hash.length === 0) {
|
if (hash.length === 0) {
|
||||||
generate();
|
generate();
|
||||||
return secret;
|
return secret;
|
||||||
@ -496,8 +555,8 @@ Version 1
|
|||||||
if (typeof(parsed.hashData.version) === "undefined") { return; }
|
if (typeof(parsed.hashData.version) === "undefined") { return; }
|
||||||
// pads and files should have a base64 (or hex) key
|
// pads and files should have a base64 (or hex) key
|
||||||
if (parsed.hashData.type === 'pad' || parsed.hashData.type === 'file') {
|
if (parsed.hashData.type === 'pad' || parsed.hashData.type === 'file') {
|
||||||
if (!parsed.hashData.key) { return; }
|
if (!parsed.hashData.key && !parsed.hashData.channel) { return; }
|
||||||
if (!/^[a-zA-Z0-9+-/=]+$/.test(parsed.hashData.key)) { return; }
|
if (parsed.hashData.key && !/^[a-zA-Z0-9+-/=]+$/.test(parsed.hashData.key)) { return; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -1104,5 +1104,36 @@ define([
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
UI.makeSpinner = function ($container) {
|
||||||
|
var $ok = $('<span>', {'class': 'fa fa-check', title: Messages.saved}).hide();
|
||||||
|
var $spinner = $('<span>', {'class': 'fa fa-spinner fa-pulse'}).hide();
|
||||||
|
|
||||||
|
var spin = function () {
|
||||||
|
$ok.hide();
|
||||||
|
$spinner.show();
|
||||||
|
};
|
||||||
|
var hide = function () {
|
||||||
|
$ok.hide();
|
||||||
|
$spinner.hide();
|
||||||
|
};
|
||||||
|
var done = function () {
|
||||||
|
$ok.show();
|
||||||
|
$spinner.hide();
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($container && $container.append) {
|
||||||
|
$container.append($ok);
|
||||||
|
$container.append($spinner);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
ok: $ok[0],
|
||||||
|
spinner: $spinner[0],
|
||||||
|
spin: spin,
|
||||||
|
hide: hide,
|
||||||
|
done: done
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return UI;
|
return UI;
|
||||||
});
|
});
|
||||||
|
|||||||
@ -49,6 +49,12 @@ define([
|
|||||||
account: {},
|
account: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Store the href in memory
|
||||||
|
// This is a placeholder value overriden in common.ready from sframe-common-outer
|
||||||
|
var currentPad = common.currentPad = {
|
||||||
|
href: window.location.href
|
||||||
|
};
|
||||||
|
|
||||||
// COMMON
|
// COMMON
|
||||||
common.getLanguage = function () {
|
common.getLanguage = function () {
|
||||||
return Messages._languageUsed;
|
return Messages._languageUsed;
|
||||||
@ -374,7 +380,7 @@ define([
|
|||||||
|
|
||||||
|
|
||||||
common.getMetadata = function (cb) {
|
common.getMetadata = function (cb) {
|
||||||
var parsed = Hash.parsePadUrl(window.location.href);
|
var parsed = Hash.parsePadUrl(currentPad.href);
|
||||||
postMessage("GET_METADATA", parsed && parsed.type, function (obj) {
|
postMessage("GET_METADATA", parsed && parsed.type, function (obj) {
|
||||||
if (obj && obj.error) { return void cb(obj.error); }
|
if (obj && obj.error) { return void cb(obj.error); }
|
||||||
cb(null, obj);
|
cb(null, obj);
|
||||||
@ -394,7 +400,7 @@ define([
|
|||||||
|
|
||||||
common.setPadAttribute = function (attr, value, cb, href) {
|
common.setPadAttribute = function (attr, value, cb, href) {
|
||||||
cb = cb || function () {};
|
cb = cb || function () {};
|
||||||
href = Hash.getRelativeHref(href || window.location.href);
|
href = Hash.getRelativeHref(href || currentPad.href);
|
||||||
postMessage("SET_PAD_ATTRIBUTE", {
|
postMessage("SET_PAD_ATTRIBUTE", {
|
||||||
href: href,
|
href: href,
|
||||||
attr: attr,
|
attr: attr,
|
||||||
@ -405,7 +411,7 @@ define([
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
common.getPadAttribute = function (attr, cb, href) {
|
common.getPadAttribute = function (attr, cb, href) {
|
||||||
href = Hash.getRelativeHref(href || window.location.href);
|
href = Hash.getRelativeHref(href || currentPad.href);
|
||||||
if (!href) {
|
if (!href) {
|
||||||
return void cb('E404');
|
return void cb('E404');
|
||||||
}
|
}
|
||||||
@ -505,7 +511,7 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
common.saveAsTemplate = function (Cryptput, data, cb) {
|
common.saveAsTemplate = function (Cryptput, data, cb) {
|
||||||
var p = Hash.parsePadUrl(window.location.href);
|
var p = Hash.parsePadUrl(currentPad.href);
|
||||||
if (!p.type) { return; }
|
if (!p.type) { return; }
|
||||||
// PPP: password for the new template?
|
// PPP: password for the new template?
|
||||||
var hash = Hash.createRandomHash(p.type);
|
var hash = Hash.createRandomHash(p.type);
|
||||||
@ -543,7 +549,7 @@ define([
|
|||||||
var href = data.href;
|
var href = data.href;
|
||||||
|
|
||||||
var parsed = Hash.parsePadUrl(href);
|
var parsed = Hash.parsePadUrl(href);
|
||||||
var parsed2 = Hash.parsePadUrl(window.location.href);
|
var parsed2 = Hash.parsePadUrl(currentPad.href);
|
||||||
if(!parsed) { throw new Error("Cannot get template hash"); }
|
if(!parsed) { throw new Error("Cannot get template hash"); }
|
||||||
postMessage("INCREMENT_TEMPLATE_USE", href);
|
postMessage("INCREMENT_TEMPLATE_USE", href);
|
||||||
|
|
||||||
@ -601,7 +607,7 @@ define([
|
|||||||
var fileHost = Config.fileHost || window.location.origin;
|
var fileHost = Config.fileHost || window.location.origin;
|
||||||
var data = common.fromFileData;
|
var data = common.fromFileData;
|
||||||
var parsed = Hash.parsePadUrl(data.href);
|
var parsed = Hash.parsePadUrl(data.href);
|
||||||
var parsed2 = Hash.parsePadUrl(window.location.href);
|
var parsed2 = Hash.parsePadUrl(currentPad.href);
|
||||||
var hash = parsed.hash;
|
var hash = parsed.hash;
|
||||||
var name = data.title;
|
var name = data.title;
|
||||||
var secret = Hash.getSecrets('file', hash, data.password);
|
var secret = Hash.getSecrets('file', hash, data.password);
|
||||||
@ -660,7 +666,7 @@ define([
|
|||||||
|
|
||||||
// Forget button
|
// Forget button
|
||||||
common.moveToTrash = function (cb, href) {
|
common.moveToTrash = function (cb, href) {
|
||||||
href = href || window.location.href;
|
href = href || currentPad.href;
|
||||||
postMessage("MOVE_TO_TRASH", { href: href }, cb);
|
postMessage("MOVE_TO_TRASH", { href: href }, cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -668,7 +674,7 @@ define([
|
|||||||
common.setPadTitle = function (data, cb) {
|
common.setPadTitle = function (data, cb) {
|
||||||
if (!data || typeof (data) !== "object") { return cb ('Data is not an object'); }
|
if (!data || typeof (data) !== "object") { return cb ('Data is not an object'); }
|
||||||
|
|
||||||
var href = data.href || window.location.href;
|
var href = data.href || currentPad.href;
|
||||||
var parsed = Hash.parsePadUrl(href);
|
var parsed = Hash.parsePadUrl(href);
|
||||||
if (!parsed.hash) { return cb ('Invalid hash'); }
|
if (!parsed.hash) { return cb ('Invalid hash'); }
|
||||||
data.href = parsed.getUrl({present: parsed.present});
|
data.href = parsed.getUrl({present: parsed.present});
|
||||||
@ -698,7 +704,7 @@ define([
|
|||||||
if (obj.error !== "EAUTH") { console.log("unable to set pad title"); }
|
if (obj.error !== "EAUTH") { console.log("unable to set pad title"); }
|
||||||
return void cb(obj.error);
|
return void cb(obj.error);
|
||||||
}
|
}
|
||||||
cb();
|
cb(null, obj);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -755,6 +761,13 @@ define([
|
|||||||
cb(void 0, data);
|
cb(void 0, data);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
// Get data about a given channel: use with hidden hashes
|
||||||
|
common.getPadDataFromChannel = function (obj, cb) {
|
||||||
|
if (!obj || !obj.channel) { return void cb('EINVAL'); }
|
||||||
|
postMessage("GET_PAD_DATA_FROM_CHANNEL", obj, function (data) {
|
||||||
|
cb(void 0, data);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Admin
|
// Admin
|
||||||
@ -832,6 +845,7 @@ define([
|
|||||||
pad.onConnectEvent = Util.mkEvent();
|
pad.onConnectEvent = Util.mkEvent();
|
||||||
pad.onErrorEvent = Util.mkEvent();
|
pad.onErrorEvent = Util.mkEvent();
|
||||||
pad.onMetadataEvent = Util.mkEvent();
|
pad.onMetadataEvent = Util.mkEvent();
|
||||||
|
pad.onChannelDeleted = Util.mkEvent();
|
||||||
|
|
||||||
pad.requestAccess = function (data, cb) {
|
pad.requestAccess = function (data, cb) {
|
||||||
postMessage("REQUEST_PAD_ACCESS", data, cb);
|
postMessage("REQUEST_PAD_ACCESS", data, cb);
|
||||||
@ -1608,7 +1622,7 @@ define([
|
|||||||
hashes = Hash.getHashes(secret);
|
hashes = Hash.getHashes(secret);
|
||||||
return void cb(null, hashes);
|
return void cb(null, hashes);
|
||||||
}
|
}
|
||||||
var parsed = Hash.parsePadUrl(window.location.href);
|
var parsed = Hash.parsePadUrl(currentPad.href);
|
||||||
if (!parsed.type || !parsed.hashData) { return void cb('E_INVALID_HREF'); }
|
if (!parsed.type || !parsed.hashData) { return void cb('E_INVALID_HREF'); }
|
||||||
hashes = Hash.getHashes(secret);
|
hashes = Hash.getHashes(secret);
|
||||||
|
|
||||||
@ -1679,7 +1693,7 @@ define([
|
|||||||
LocalStore.logout();
|
LocalStore.logout();
|
||||||
|
|
||||||
// redirect them to log in, and come back when they're done.
|
// redirect them to log in, and come back when they're done.
|
||||||
sessionStorage.redirectTo = window.location.href;
|
sessionStorage.redirectTo = currentPad.href;
|
||||||
window.location.href = '/login/';
|
window.location.href = '/login/';
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1740,6 +1754,7 @@ define([
|
|||||||
PAD_CONNECT: common.padRpc.onConnectEvent.fire,
|
PAD_CONNECT: common.padRpc.onConnectEvent.fire,
|
||||||
PAD_ERROR: common.padRpc.onErrorEvent.fire,
|
PAD_ERROR: common.padRpc.onErrorEvent.fire,
|
||||||
PAD_METADATA: common.padRpc.onMetadataEvent.fire,
|
PAD_METADATA: common.padRpc.onMetadataEvent.fire,
|
||||||
|
CHANNEL_DELETED: common.padRpc.onChannelDeleted.fire,
|
||||||
// Drive
|
// Drive
|
||||||
DRIVE_LOG: common.drive.onLog.fire,
|
DRIVE_LOG: common.drive.onLog.fire,
|
||||||
DRIVE_CHANGE: common.drive.onChange.fire,
|
DRIVE_CHANGE: common.drive.onChange.fire,
|
||||||
@ -1780,6 +1795,11 @@ define([
|
|||||||
|
|
||||||
return function (f, rdyCfg) {
|
return function (f, rdyCfg) {
|
||||||
rdyCfg = rdyCfg || {};
|
rdyCfg = rdyCfg || {};
|
||||||
|
|
||||||
|
if (rdyCfg.currentPad) {
|
||||||
|
currentPad = common.currentPad = rdyCfg.currentPad;
|
||||||
|
}
|
||||||
|
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
return void setTimeout(function () { f(void 0, env); });
|
return void setTimeout(function () { f(void 0, env); });
|
||||||
}
|
}
|
||||||
@ -1878,7 +1898,7 @@ define([
|
|||||||
anonHash: LocalStore.getFSHash(),
|
anonHash: LocalStore.getFSHash(),
|
||||||
localToken: tryParsing(localStorage.getItem(Constants.tokenKey)), // TODO move this to LocalStore ?
|
localToken: tryParsing(localStorage.getItem(Constants.tokenKey)), // TODO move this to LocalStore ?
|
||||||
language: common.getLanguage(),
|
language: common.getLanguage(),
|
||||||
driveEvents: rdyCfg.driveEvents // Boolean
|
driveEvents: true //rdyCfg.driveEvents // Boolean
|
||||||
};
|
};
|
||||||
// if a pad is created from a file
|
// if a pad is created from a file
|
||||||
if (sessionStorage[Constants.newPadFileData]) {
|
if (sessionStorage[Constants.newPadFileData]) {
|
||||||
|
|||||||
@ -1029,15 +1029,28 @@ define([
|
|||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
var openFile = function (el, href) {
|
var openFile = function (el, isRo) {
|
||||||
if (!href) {
|
|
||||||
var data = manager.getFileData(el);
|
var data = manager.getFileData(el);
|
||||||
if (!data || (!data.href && !data.roHref)) {
|
if (!data || (!data.href && !data.roHref)) {
|
||||||
return void logError("Missing data for the file", el, data);
|
return void logError("Missing data for the file", el, data);
|
||||||
}
|
}
|
||||||
href = data.href || data.roHref;
|
var href = isRo ? data.roHref : (data.href || data.roHref);
|
||||||
|
var priv = metadataMgr.getPrivateData();
|
||||||
|
var useUnsafe = Util.find(priv, ['settings', 'security', 'unsafeLinks']);
|
||||||
|
if (useUnsafe) {
|
||||||
|
return void window.open(APP.origin + href);
|
||||||
}
|
}
|
||||||
window.open(APP.origin + href);
|
|
||||||
|
// Get hidden hash
|
||||||
|
var parsed = Hash.parsePadUrl(href);
|
||||||
|
var secret = Hash.getSecrets(parsed.type, parsed.hash, data.password);
|
||||||
|
if (isRo && secret.keys && secret.keys.editKeyStr) {
|
||||||
|
delete secret.keys.editKeyStr;
|
||||||
|
delete secret.key;
|
||||||
|
}
|
||||||
|
var hash = Hash.getHiddenHashFromKeys(parsed.type, secret);
|
||||||
|
var hiddenHref = Hash.hashToHref(hash, parsed.type);
|
||||||
|
window.open(APP.origin + hiddenHref);
|
||||||
};
|
};
|
||||||
|
|
||||||
var refresh = APP.refresh = function () {
|
var refresh = APP.refresh = function () {
|
||||||
@ -3034,7 +3047,7 @@ define([
|
|||||||
$icon.append(getFileIcon(r.id));
|
$icon.append(getFileIcon(r.id));
|
||||||
$type.text(Messages.type[parsed.type] || parsed.type);
|
$type.text(Messages.type[parsed.type] || parsed.type);
|
||||||
$title.click(function () {
|
$title.click(function () {
|
||||||
openFile(null, r.data.href);
|
openFile(r.id);
|
||||||
});
|
});
|
||||||
$atimeName.text(Messages.fm_lastAccess);
|
$atimeName.text(Messages.fm_lastAccess);
|
||||||
$atime.text(new Date(r.data.atime).toLocaleString());
|
$atime.text(new Date(r.data.atime).toLocaleString());
|
||||||
@ -3944,15 +3957,12 @@ define([
|
|||||||
// ANON_SHARED_FOLDER
|
// ANON_SHARED_FOLDER
|
||||||
el = manager.find(paths[0].path.slice(1), APP.newSharedFolder);
|
el = manager.find(paths[0].path.slice(1), APP.newSharedFolder);
|
||||||
}
|
}
|
||||||
var href;
|
|
||||||
if (manager.isPathIn(p.path, [FILES_DATA])) {
|
if (manager.isPathIn(p.path, [FILES_DATA])) {
|
||||||
href = el.roHref;
|
el = p.path[1];
|
||||||
} else {
|
} else {
|
||||||
if (!el || manager.isFolder(el)) { return; }
|
if (!el || manager.isFolder(el)) { return; }
|
||||||
var data = manager.getFileData(el);
|
|
||||||
href = data.roHref;
|
|
||||||
}
|
}
|
||||||
openFile(null, href);
|
openFile(el, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if ($this.hasClass('cp-app-drive-context-openincode')) {
|
else if ($this.hasClass('cp-app-drive-context-openincode')) {
|
||||||
|
|||||||
@ -9,6 +9,7 @@ define([
|
|||||||
var requireConfig = RequireConfig();
|
var requireConfig = RequireConfig();
|
||||||
|
|
||||||
// Loaded in load #2
|
// Loaded in load #2
|
||||||
|
var hash, href;
|
||||||
nThen(function (waitFor) {
|
nThen(function (waitFor) {
|
||||||
DomReady.onReady(waitFor());
|
DomReady.onReady(waitFor());
|
||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
@ -19,6 +20,13 @@ define([
|
|||||||
};
|
};
|
||||||
window.rc = requireConfig;
|
window.rc = requireConfig;
|
||||||
window.apiconf = ApiConfig;
|
window.apiconf = ApiConfig;
|
||||||
|
|
||||||
|
// Hidden hash
|
||||||
|
hash = window.location.hash;
|
||||||
|
href = window.location.href;
|
||||||
|
if (window.history && window.history.replaceState && hash) {
|
||||||
|
window.history.replaceState({}, window.document.title, '#');
|
||||||
|
}
|
||||||
document.getElementById('sbox-iframe').setAttribute('src',
|
document.getElementById('sbox-iframe').setAttribute('src',
|
||||||
ApiConfig.httpSafeOrigin + window.location.pathname + 'inner.html?' +
|
ApiConfig.httpSafeOrigin + window.location.pathname + 'inner.html?' +
|
||||||
requireConfig.urlArgs + '#' + encodeURIComponent(JSON.stringify(req)));
|
requireConfig.urlArgs + '#' + encodeURIComponent(JSON.stringify(req)));
|
||||||
@ -144,6 +152,8 @@ define([
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
SFCommonO.start({
|
SFCommonO.start({
|
||||||
|
hash: hash,
|
||||||
|
href: href,
|
||||||
type: 'oo',
|
type: 'oo',
|
||||||
useCreationScreen: true,
|
useCreationScreen: true,
|
||||||
addData: addData,
|
addData: addData,
|
||||||
|
|||||||
@ -1016,8 +1016,12 @@ define([
|
|||||||
|
|
||||||
if (title.trim() === "") { title = UserObject.getDefaultName(p); }
|
if (title.trim() === "") { title = UserObject.getDefaultName(p); }
|
||||||
|
|
||||||
if (AppConfig.disableAnonymousStore && !store.loggedIn) { return void cb(); }
|
if (AppConfig.disableAnonymousStore && !store.loggedIn) {
|
||||||
if (p.type === "debug") { return void cb(); }
|
return void cb({ notStored: true });
|
||||||
|
}
|
||||||
|
if (p.type === "debug") {
|
||||||
|
return void cb({ notStored: true });
|
||||||
|
}
|
||||||
|
|
||||||
var channelData = Store.channels && Store.channels[channel];
|
var channelData = Store.channels && Store.channels[channel];
|
||||||
|
|
||||||
@ -1108,7 +1112,7 @@ define([
|
|||||||
postMessage(clientId, "AUTOSTORE_DISPLAY_POPUP", {
|
postMessage(clientId, "AUTOSTORE_DISPLAY_POPUP", {
|
||||||
autoStore: autoStore
|
autoStore: autoStore
|
||||||
});
|
});
|
||||||
return void cb();
|
return void cb({ notStored: true });
|
||||||
} else {
|
} else {
|
||||||
var roHref;
|
var roHref;
|
||||||
if (h.mode === "view") {
|
if (h.mode === "view") {
|
||||||
@ -1187,7 +1191,9 @@ define([
|
|||||||
});
|
});
|
||||||
cb(list);
|
cb(list);
|
||||||
};
|
};
|
||||||
// Get the first pad we can find in any of our managers and return its file data
|
|
||||||
|
// Get the first pad we can find in any of our drives and return its file data
|
||||||
|
// NOTE: This is currently only used for template: this won't search inside shared folders
|
||||||
Store.getPadData = function (clientId, id, cb) {
|
Store.getPadData = function (clientId, id, cb) {
|
||||||
var res = {};
|
var res = {};
|
||||||
getAllStores().some(function (s) {
|
getAllStores().some(function (s) {
|
||||||
@ -1199,6 +1205,49 @@ define([
|
|||||||
cb(res);
|
cb(res);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Store.getPadDataFromChannel = function (clientId, obj, cb) {
|
||||||
|
var channel = obj.channel;
|
||||||
|
var edit = obj.edit;
|
||||||
|
var isFile = obj.file;
|
||||||
|
var res;
|
||||||
|
var viewRes;
|
||||||
|
getAllStores().some(function (s) {
|
||||||
|
var chans = s.manager.findChannel(channel);
|
||||||
|
if (!Array.isArray(chans)) { return; }
|
||||||
|
return chans.some(function (pad) {
|
||||||
|
if (!pad || !pad.data) { return; }
|
||||||
|
var data = pad.data;
|
||||||
|
// We've found a match: return the value and stop the loops
|
||||||
|
if ((edit && data.href) || (!edit && data.roHref) || isFile) {
|
||||||
|
res = data;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// We've found a weaker match: store it for now
|
||||||
|
if (edit && !viewRes && data.roHref) {
|
||||||
|
viewRes = data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// Call back with the best value we can get
|
||||||
|
cb(res || viewRes || {});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Hidden hash: if a pad is deleted, we may have to switch back to full hash
|
||||||
|
// in some tabs
|
||||||
|
Store.checkDeletedPad = function (channel) {
|
||||||
|
if (!channel) { return; }
|
||||||
|
|
||||||
|
// Check if the pad is still stored in one of our drives
|
||||||
|
Store.getPadDataFromChannel(null, {
|
||||||
|
channel: channel,
|
||||||
|
isFile: true // we don't care if it's view or edit
|
||||||
|
}, function (res) {
|
||||||
|
// If it is stored, abort
|
||||||
|
if (Object.keys(res).length) { return; }
|
||||||
|
// Otherwise, tell all the tabs that this channel was deleted and give them the hrefs
|
||||||
|
broadcast([], "CHANNEL_DELETED", channel);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Messaging (manage friends from the userlist)
|
// Messaging (manage friends from the userlist)
|
||||||
Store.answerFriendRequest = function (clientId, obj, cb) {
|
Store.answerFriendRequest = function (clientId, obj, cb) {
|
||||||
@ -2095,6 +2144,12 @@ define([
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (o && !n && Array.isArray(p) && (p[0] === UserObject.FILES_DATA ||
|
||||||
|
(p[0] === 'drive' && p[1] === UserObject.FILES_DATA))) {
|
||||||
|
setTimeout(function () {
|
||||||
|
Store.checkDeletedPad(o && o.channel);
|
||||||
|
});
|
||||||
|
}
|
||||||
sendDriveEvent('DRIVE_CHANGE', {
|
sendDriveEvent('DRIVE_CHANGE', {
|
||||||
id: fId,
|
id: fId,
|
||||||
old: o,
|
old: o,
|
||||||
|
|||||||
@ -50,6 +50,7 @@ define([
|
|||||||
GET_TEMPLATES: Store.getTemplates,
|
GET_TEMPLATES: Store.getTemplates,
|
||||||
GET_SECURE_FILES_LIST: Store.getSecureFilesList,
|
GET_SECURE_FILES_LIST: Store.getSecureFilesList,
|
||||||
GET_PAD_DATA: Store.getPadData,
|
GET_PAD_DATA: Store.getPadData,
|
||||||
|
GET_PAD_DATA_FROM_CHANNEL: Store.getPadDataFromChannel,
|
||||||
GET_STRONGER_HASH: Store.getStrongerHash,
|
GET_STRONGER_HASH: Store.getStrongerHash,
|
||||||
INCREMENT_TEMPLATE_USE: Store.incrementTemplateUse,
|
INCREMENT_TEMPLATE_USE: Store.incrementTemplateUse,
|
||||||
GET_SHARED_FOLDER: Store.getSharedFolder,
|
GET_SHARED_FOLDER: Store.getSharedFolder,
|
||||||
|
|||||||
@ -93,6 +93,12 @@ define([
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (o && !n && Array.isArray(p) && (p[0] === UserObject.FILES_DATA ||
|
||||||
|
(p[0] === 'drive' && p[1] === UserObject.FILES_DATA))) {
|
||||||
|
setTimeout(function () {
|
||||||
|
ctx.Store.checkDeletedPad(o && o.channel);
|
||||||
|
});
|
||||||
|
}
|
||||||
team.sendEvent('DRIVE_CHANGE', {
|
team.sendEvent('DRIVE_CHANGE', {
|
||||||
id: fId,
|
id: fId,
|
||||||
old: o,
|
old: o,
|
||||||
|
|||||||
@ -771,6 +771,9 @@ define([
|
|||||||
toUnpin.forEach(function (chan) {
|
toUnpin.forEach(function (chan) {
|
||||||
if (toKeep.indexOf(chan) === -1) {
|
if (toKeep.indexOf(chan) === -1) {
|
||||||
unpinList.push(chan);
|
unpinList.push(chan);
|
||||||
|
|
||||||
|
// Check if need need to restore a full hash (hidden hash deleted from drive)
|
||||||
|
Env.Store.checkDeletedPad(chan);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -783,7 +786,16 @@ define([
|
|||||||
};
|
};
|
||||||
// Empty the trash (main drive only)
|
// Empty the trash (main drive only)
|
||||||
var _emptyTrash = function (Env, data, cb) {
|
var _emptyTrash = function (Env, data, cb) {
|
||||||
Env.user.userObject.emptyTrash(cb);
|
Env.user.userObject.emptyTrash(function (err, toClean) {
|
||||||
|
cb();
|
||||||
|
|
||||||
|
// Check if need need to restore a full hash (hidden hash deleted from drive)
|
||||||
|
if (!Array.isArray(toClean)) { return; }
|
||||||
|
var toCheck = Util.deduplicateString(toClean);
|
||||||
|
toCheck.forEach(function (chan) {
|
||||||
|
Env.Store.checkDeletedPad(chan);
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
// Rename files or folders
|
// Rename files or folders
|
||||||
var _rename = function (Env, data, cb) {
|
var _rename = function (Env, data, cb) {
|
||||||
|
|||||||
@ -8,6 +8,7 @@ define([
|
|||||||
], function (nThen, ApiConfig, DomReady, RequireConfig, SFCommonO) {
|
], function (nThen, ApiConfig, DomReady, RequireConfig, SFCommonO) {
|
||||||
var requireConfig = RequireConfig();
|
var requireConfig = RequireConfig();
|
||||||
|
|
||||||
|
var hash, href;
|
||||||
nThen(function (waitFor) {
|
nThen(function (waitFor) {
|
||||||
DomReady.onReady(waitFor());
|
DomReady.onReady(waitFor());
|
||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
@ -18,6 +19,14 @@ define([
|
|||||||
};
|
};
|
||||||
window.rc = requireConfig;
|
window.rc = requireConfig;
|
||||||
window.apiconf = ApiConfig;
|
window.apiconf = ApiConfig;
|
||||||
|
|
||||||
|
// Hidden hash
|
||||||
|
hash = window.location.hash;
|
||||||
|
href = window.location.href;
|
||||||
|
if (window.history && window.history.replaceState && hash) {
|
||||||
|
window.history.replaceState({}, window.document.title, '#');
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById('sbox-iframe').setAttribute('src',
|
document.getElementById('sbox-iframe').setAttribute('src',
|
||||||
ApiConfig.httpSafeOrigin + window.location.pathname + 'inner.html?' +
|
ApiConfig.httpSafeOrigin + window.location.pathname + 'inner.html?' +
|
||||||
requireConfig.urlArgs + '#' + encodeURIComponent(JSON.stringify(req)));
|
requireConfig.urlArgs + '#' + encodeURIComponent(JSON.stringify(req)));
|
||||||
@ -36,6 +45,8 @@ define([
|
|||||||
window.addEventListener('message', onMsg);
|
window.addEventListener('message', onMsg);
|
||||||
}).nThen(function (/*waitFor*/) {
|
}).nThen(function (/*waitFor*/) {
|
||||||
SFCommonO.start({
|
SFCommonO.start({
|
||||||
|
hash: hash,
|
||||||
|
href: href,
|
||||||
useCreationScreen: true,
|
useCreationScreen: true,
|
||||||
messaging: true
|
messaging: true
|
||||||
});
|
});
|
||||||
|
|||||||
@ -30,6 +30,11 @@ define([
|
|||||||
var password;
|
var password;
|
||||||
var initialPathInDrive;
|
var initialPathInDrive;
|
||||||
|
|
||||||
|
var currentPad = window.CryptPad_location = {
|
||||||
|
href: cfg.href || window.location.href,
|
||||||
|
hash: cfg.hash || window.location.hash
|
||||||
|
};
|
||||||
|
|
||||||
nThen(function (waitFor) {
|
nThen(function (waitFor) {
|
||||||
// Load #2, the loading screen is up so grab whatever you need...
|
// Load #2, the loading screen is up so grab whatever you need...
|
||||||
require([
|
require([
|
||||||
@ -134,8 +139,15 @@ define([
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}), {
|
}), {
|
||||||
driveEvents: cfg.driveEvents
|
driveEvents: cfg.driveEvents,
|
||||||
|
currentPad: currentPad
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (window.history && window.history.replaceState && currentPad.hash) {
|
||||||
|
var nHash = currentPad.hash;
|
||||||
|
if (!/^#/.test(nHash)) { nHash = '#' + nHash; }
|
||||||
|
window.history.replaceState({}, window.document.title, nHash);
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
if (!Utils.Hash.isValidHref(window.location.href)) {
|
if (!Utils.Hash.isValidHref(window.location.href)) {
|
||||||
@ -171,15 +183,26 @@ define([
|
|||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
var parsed = Utils.Hash.parsePadUrl(window.location.href);
|
var parsed = Utils.Hash.parsePadUrl(currentPad.href);
|
||||||
var todo = function () {
|
var todo = function () {
|
||||||
secret = Utils.secret = Utils.Hash.getSecrets(parsed.type, void 0, password);
|
secret = Utils.secret = Utils.Hash.getSecrets(parsed.type, parsed.hash, password);
|
||||||
Cryptpad.getShareHashes(secret, waitFor(function (err, h) {
|
Cryptpad.getShareHashes(secret, waitFor(function (err, h) {
|
||||||
hashes = h;
|
hashes = h;
|
||||||
|
// Update the rendered hash and the full hash with the "password" settings
|
||||||
if (password && !parsed.hashData.password) {
|
if (password && !parsed.hashData.password) {
|
||||||
|
var opts = parsed.getOptions();
|
||||||
|
opts.password = true;
|
||||||
|
|
||||||
|
// Full hash
|
||||||
|
currentPad.href = parsed.getUrl(opts);
|
||||||
|
if (parsed.hashData) {
|
||||||
|
currentPad.hash = parsed.hashData.getHash(opts);
|
||||||
|
}
|
||||||
|
// Rendered (maybe hidden) hash
|
||||||
|
var renderedParsed = Utils.Hash.parsePadUrl(window.location.href);
|
||||||
var ohc = window.onhashchange;
|
var ohc = window.onhashchange;
|
||||||
window.onhashchange = function () {};
|
window.onhashchange = function () {};
|
||||||
window.location.hash = h.fileHash || h.editHash || h.viewHash || window.location.hash;
|
window.location.href = renderedParsed.getUrl(opts);
|
||||||
window.onhashchange = ohc;
|
window.onhashchange = ohc;
|
||||||
ohc({reset: true});
|
ohc({reset: true});
|
||||||
}
|
}
|
||||||
@ -241,13 +264,13 @@ define([
|
|||||||
if (parsed.type === "file") {
|
if (parsed.type === "file") {
|
||||||
// `isNewChannel` doesn't work for files (not a channel)
|
// `isNewChannel` doesn't work for files (not a channel)
|
||||||
// `getFileSize` is not adapted to channels because of metadata
|
// `getFileSize` is not adapted to channels because of metadata
|
||||||
Cryptpad.getFileSize(window.location.href, password, function (e, size) {
|
Cryptpad.getFileSize(currentPad.href, password, function (e, size) {
|
||||||
next(e, size === 0);
|
next(e, size === 0);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Not a file, so we can use `isNewChannel`
|
// Not a file, so we can use `isNewChannel`
|
||||||
Cryptpad.isNewChannel(window.location.href, password, next);
|
Cryptpad.isNewChannel(currentPad.href, password, next);
|
||||||
});
|
});
|
||||||
sframeChan.event("EV_PAD_PASSWORD", cfg);
|
sframeChan.event("EV_PAD_PASSWORD", cfg);
|
||||||
};
|
};
|
||||||
@ -257,7 +280,48 @@ define([
|
|||||||
var passwordCfg = {
|
var passwordCfg = {
|
||||||
value: ''
|
value: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Hidden hash: can't find the channel in our drives: abort
|
||||||
|
var noPadData = function (err) {
|
||||||
|
sframeChan.event("EV_PAD_NODATA", err);
|
||||||
|
};
|
||||||
|
|
||||||
|
var newHref;
|
||||||
nThen(function (w) {
|
nThen(function (w) {
|
||||||
|
if (!parsed.hashData.key && parsed.hashData.channel) {
|
||||||
|
var edit = parsed.hashData.mode === 'edit';
|
||||||
|
Cryptpad.getPadDataFromChannel({
|
||||||
|
channel: parsed.hashData.channel,
|
||||||
|
edit: edit,
|
||||||
|
file: parsed.hashData.type === 'file'
|
||||||
|
}, w(function (err, res) {
|
||||||
|
// Error while getting data? abort
|
||||||
|
if (err || !res || res.error) {
|
||||||
|
w.abort();
|
||||||
|
return void noPadData(err || (!res ? 'EINVAL' : res.error));
|
||||||
|
}
|
||||||
|
// No data found? abort
|
||||||
|
if (!Object.keys(res).length) {
|
||||||
|
w.abort();
|
||||||
|
return void noPadData('NO_RESULT');
|
||||||
|
}
|
||||||
|
// Data found but weaker? warn
|
||||||
|
if (edit && !res.href) {
|
||||||
|
newHref = res.roHref;
|
||||||
|
}
|
||||||
|
// We have good data, keep the hash in memory
|
||||||
|
newHref = edit ? res.href : (res.roHref || res.href);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}).nThen(function (w) {
|
||||||
|
if (newHref) {
|
||||||
|
// Get the options (embed, present, etc.) of the hidden hash
|
||||||
|
// Use the same options in the full hash
|
||||||
|
var opts = parsed.getOptions();
|
||||||
|
parsed = Utils.Hash.parsePadUrl(newHref);
|
||||||
|
currentPad.href = parsed.getUrl(opts);
|
||||||
|
currentPad.hash = parsed.hashData && parsed.hashData.getHash(opts);
|
||||||
|
}
|
||||||
Cryptpad.getPadAttribute('title', w(function (err, data) {
|
Cryptpad.getPadAttribute('title', w(function (err, data) {
|
||||||
stored = (!err && typeof (data) === "string");
|
stored = (!err && typeof (data) === "string");
|
||||||
}));
|
}));
|
||||||
@ -273,7 +337,7 @@ define([
|
|||||||
if (parsed.type === "file") {
|
if (parsed.type === "file") {
|
||||||
// `isNewChannel` doesn't work for files (not a channel)
|
// `isNewChannel` doesn't work for files (not a channel)
|
||||||
// `getFileSize` is not adapted to channels because of metadata
|
// `getFileSize` is not adapted to channels because of metadata
|
||||||
Cryptpad.getFileSize(window.location.href, password, w(function (e, size) {
|
Cryptpad.getFileSize(currentPad.href, password, w(function (e, size) {
|
||||||
if (size !== 0) { return void todo(); }
|
if (size !== 0) { return void todo(); }
|
||||||
// Wrong password or deleted file?
|
// Wrong password or deleted file?
|
||||||
askPassword(true, passwordCfg);
|
askPassword(true, passwordCfg);
|
||||||
@ -281,7 +345,7 @@ define([
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Not a file, so we can use `isNewChannel`
|
// Not a file, so we can use `isNewChannel`
|
||||||
Cryptpad.isNewChannel(window.location.href, password, w(function(e, isNew) {
|
Cryptpad.isNewChannel(currentPad.href, password, w(function(e, isNew) {
|
||||||
if (!isNew) { return void todo(); }
|
if (!isNew) { return void todo(); }
|
||||||
if (parsed.hashData.mode === 'view' && (password || !parsed.hashData.password)) {
|
if (parsed.hashData.mode === 'view' && (password || !parsed.hashData.password)) {
|
||||||
// Error, wrong password stored, the view seed has changed with the password
|
// Error, wrong password stored, the view seed has changed with the password
|
||||||
@ -305,10 +369,12 @@ define([
|
|||||||
}
|
}
|
||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
// Check if the pad exists on server
|
// Check if the pad exists on server
|
||||||
if (!window.location.hash) { isNewFile = true; return; }
|
if (!currentPad.hash) { isNewFile = true; return; }
|
||||||
|
|
||||||
if (realtime) {
|
if (realtime) {
|
||||||
Cryptpad.isNewChannel(window.location.href, password, waitFor(function (e, isNew) {
|
// TODO we probably don't need to check again for password-protected pads
|
||||||
|
// (we use isNewChannel to test the password...)
|
||||||
|
Cryptpad.isNewChannel(currentPad.href, password, waitFor(function (e, isNew) {
|
||||||
if (e) { return console.error(e); }
|
if (e) { return console.error(e); }
|
||||||
isNewFile = Boolean(isNew);
|
isNewFile = Boolean(isNew);
|
||||||
}));
|
}));
|
||||||
@ -322,11 +388,12 @@ define([
|
|||||||
readOnly = false;
|
readOnly = false;
|
||||||
}
|
}
|
||||||
Utils.crypto = Utils.Crypto.createEncryptor(Utils.secret.keys);
|
Utils.crypto = Utils.Crypto.createEncryptor(Utils.secret.keys);
|
||||||
var parsed = Utils.Hash.parsePadUrl(window.location.href);
|
var parsed = Utils.Hash.parsePadUrl(currentPad.href);
|
||||||
var burnAfterReading = parsed && parsed.hashData && parsed.hashData.ownerKey;
|
var burnAfterReading = parsed && parsed.hashData && parsed.hashData.ownerKey;
|
||||||
if (!parsed.type) { throw new Error(); }
|
if (!parsed.type) { throw new Error(); }
|
||||||
var defaultTitle = Utils.UserObject.getDefaultName(parsed);
|
var defaultTitle = Utils.UserObject.getDefaultName(parsed);
|
||||||
var edPublic, curvePublic, notifications, isTemplate;
|
var edPublic, curvePublic, notifications, isTemplate;
|
||||||
|
var settings = {};
|
||||||
var forceCreationScreen = cfg.useCreationScreen &&
|
var forceCreationScreen = cfg.useCreationScreen &&
|
||||||
sessionStorage[Utils.Constants.displayPadCreationScreen];
|
sessionStorage[Utils.Constants.displayPadCreationScreen];
|
||||||
delete sessionStorage[Utils.Constants.displayPadCreationScreen];
|
delete sessionStorage[Utils.Constants.displayPadCreationScreen];
|
||||||
@ -340,9 +407,10 @@ define([
|
|||||||
edPublic = metaObj.priv.edPublic; // needed to create an owned pad
|
edPublic = metaObj.priv.edPublic; // needed to create an owned pad
|
||||||
curvePublic = metaObj.user.curvePublic;
|
curvePublic = metaObj.user.curvePublic;
|
||||||
notifications = metaObj.user.notifications;
|
notifications = metaObj.user.notifications;
|
||||||
|
settings = metaObj.priv.settings;
|
||||||
}));
|
}));
|
||||||
if (typeof(isTemplate) === "undefined") {
|
if (typeof(isTemplate) === "undefined") {
|
||||||
Cryptpad.isTemplate(window.location.href, waitFor(function (err, t) {
|
Cryptpad.isTemplate(currentPad.href, waitFor(function (err, t) {
|
||||||
if (err) { console.log(err); }
|
if (err) { console.log(err); }
|
||||||
isTemplate = t;
|
isTemplate = t;
|
||||||
}));
|
}));
|
||||||
@ -368,7 +436,7 @@ define([
|
|||||||
upgradeURL: Cryptpad.upgradeURL
|
upgradeURL: Cryptpad.upgradeURL
|
||||||
},
|
},
|
||||||
isNewFile: isNewFile,
|
isNewFile: isNewFile,
|
||||||
isDeleted: isNewFile && window.location.hash.length > 0,
|
isDeleted: isNewFile && currentPad.hash.length > 0,
|
||||||
forceCreationScreen: forceCreationScreen,
|
forceCreationScreen: forceCreationScreen,
|
||||||
password: password,
|
password: password,
|
||||||
channel: secret.channel,
|
channel: secret.channel,
|
||||||
@ -487,7 +555,7 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
sframeChan.on('Q_SET_LOGIN_REDIRECT', function (data, cb) {
|
sframeChan.on('Q_SET_LOGIN_REDIRECT', function (data, cb) {
|
||||||
sessionStorage.redirectTo = window.location.href;
|
sessionStorage.redirectTo = currentPad.href;
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -570,7 +638,18 @@ define([
|
|||||||
channel: secret.channel,
|
channel: secret.channel,
|
||||||
path: initialPathInDrive // Where to store the pad if we don't have it in our drive
|
path: initialPathInDrive // Where to store the pad if we don't have it in our drive
|
||||||
};
|
};
|
||||||
Cryptpad.setPadTitle(data, function (err) {
|
Cryptpad.setPadTitle(data, function (err, obj) {
|
||||||
|
if (!err && !(obj && obj.notStored)) {
|
||||||
|
// No error and the pad was correctly stored
|
||||||
|
// hide the hash
|
||||||
|
var opts = parsed.getOptions();
|
||||||
|
var hash = Utils.Hash.getHiddenHashFromKeys(parsed.type, secret, opts);
|
||||||
|
var useUnsafe = Utils.Util.find(settings, ['security', 'unsafeLinks']);
|
||||||
|
if (!useUnsafe && window.history && window.history.replaceState) {
|
||||||
|
if (!/^#/.test(hash)) { hash = '#' + hash; }
|
||||||
|
window.history.replaceState({}, window.document.title, hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
cb({error: err});
|
cb({error: err});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -580,6 +659,9 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
sframeChan.on('EV_SET_HASH', function (hash) {
|
sframeChan.on('EV_SET_HASH', function (hash) {
|
||||||
|
// In this case, we want to set the hash for the next page reload
|
||||||
|
// This hash is a category for the sidebar layout apps
|
||||||
|
// No need to store it in memory
|
||||||
window.location.hash = hash;
|
window.location.hash = hash;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -595,6 +677,17 @@ define([
|
|||||||
forceSave: true
|
forceSave: true
|
||||||
};
|
};
|
||||||
Cryptpad.setPadTitle(data, function (err) {
|
Cryptpad.setPadTitle(data, function (err) {
|
||||||
|
if (!err && !(obj && obj.notStored)) {
|
||||||
|
// No error and the pad was correctly stored
|
||||||
|
// hide the hash
|
||||||
|
var opts = parsed.getOptions();
|
||||||
|
var hash = Utils.Hash.getHiddenHashFromKeys(parsed.type, secret, opts);
|
||||||
|
var useUnsafe = Utils.Util.find(settings, ['security', 'unsafeLinks']);
|
||||||
|
if (!useUnsafe && window.history && window.history.replaceState) {
|
||||||
|
if (!/^#/.test(hash)) { hash = '#' + hash; }
|
||||||
|
window.history.replaceState({}, window.document.title, hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
cb({error: err});
|
cb({error: err});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -801,15 +894,19 @@ define([
|
|||||||
|
|
||||||
// Present mode URL
|
// Present mode URL
|
||||||
sframeChan.on('Q_PRESENT_URL_GET_VALUE', function (data, cb) {
|
sframeChan.on('Q_PRESENT_URL_GET_VALUE', function (data, cb) {
|
||||||
var parsed = Utils.Hash.parsePadUrl(window.location.href);
|
var parsed = Utils.Hash.parsePadUrl(currentPad.href);
|
||||||
cb(parsed.hashData && parsed.hashData.present);
|
cb(parsed.hashData && parsed.hashData.present);
|
||||||
});
|
});
|
||||||
sframeChan.on('EV_PRESENT_URL_SET_VALUE', function (data) {
|
sframeChan.on('EV_PRESENT_URL_SET_VALUE', function (data) {
|
||||||
var parsed = Utils.Hash.parsePadUrl(window.location.href);
|
// Update the rendered hash and the full hash with the "present" settings
|
||||||
window.location.href = parsed.getUrl({
|
var opts = parsed.getOptions();
|
||||||
embed: parsed.hashData.embed,
|
opts.present = data;
|
||||||
present: data
|
// Full hash
|
||||||
});
|
currentPad.href = parsed.getUrl(opts);
|
||||||
|
if (parsed.hashData) { currentPad.hash = parsed.hashData.getHash(opts); }
|
||||||
|
// Rendered (maybe hidden) hash
|
||||||
|
var hiddenParsed = Utils.Hash.parsePadUrl(window.location.href);
|
||||||
|
window.location.href = hiddenParsed.getUrl(opts);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -1011,7 +1108,7 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
sframeChan.on('Q_BLOB_PASSWORD_CHANGE', function (data, cb) {
|
sframeChan.on('Q_BLOB_PASSWORD_CHANGE', function (data, cb) {
|
||||||
data.href = data.href || window.location.href;
|
data.href = data.href || currentPad.href;
|
||||||
var onPending = function (cb) {
|
var onPending = function (cb) {
|
||||||
sframeChan.query('Q_BLOB_PASSWORD_CHANGE_PENDING', null, function (err, obj) {
|
sframeChan.query('Q_BLOB_PASSWORD_CHANGE_PENDING', null, function (err, obj) {
|
||||||
if (obj && obj.cancel) { cb(); }
|
if (obj && obj.cancel) { cb(); }
|
||||||
@ -1027,12 +1124,12 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
sframeChan.on('Q_OO_PASSWORD_CHANGE', function (data, cb) {
|
sframeChan.on('Q_OO_PASSWORD_CHANGE', function (data, cb) {
|
||||||
data.href = data.href || window.location.href;
|
data.href = data.href || currentPad.href;
|
||||||
Cryptpad.changeOOPassword(data, cb);
|
Cryptpad.changeOOPassword(data, cb);
|
||||||
});
|
});
|
||||||
|
|
||||||
sframeChan.on('Q_PAD_PASSWORD_CHANGE', function (data, cb) {
|
sframeChan.on('Q_PAD_PASSWORD_CHANGE', function (data, cb) {
|
||||||
data.href = data.href || window.location.href;
|
data.href = data.href || currentPad.href;
|
||||||
Cryptpad.changePadPassword(Cryptget, Crypto, data, cb);
|
Cryptpad.changePadPassword(Cryptget, Crypto, data, cb);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1227,14 +1324,26 @@ define([
|
|||||||
}
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
|
// If our channel was deleted from all of our drives, sitch back to full hash
|
||||||
|
// in the address bar
|
||||||
|
Cryptpad.padRpc.onChannelDeleted.reg(function (channel) {
|
||||||
|
if (channel !== secret.channel) { return; }
|
||||||
|
var ohc = window.onhashchange;
|
||||||
|
window.onhashchange = function () {};
|
||||||
|
window.location.href = currentPad.href;
|
||||||
|
window.onhashchange = ohc;
|
||||||
|
ohc({reset: true});
|
||||||
|
});
|
||||||
|
|
||||||
// Join the netflux channel
|
// Join the netflux channel
|
||||||
var rtStarted = false;
|
var rtStarted = false;
|
||||||
var startRealtime = function (rtConfig) {
|
var startRealtime = function (rtConfig) {
|
||||||
rtConfig = rtConfig || {};
|
rtConfig = rtConfig || {};
|
||||||
rtStarted = true;
|
rtStarted = true;
|
||||||
|
|
||||||
var replaceHash = function (hash) {
|
var replaceHash = function (hash) {
|
||||||
|
// The pad has just been created but is not stored yet. We'll switch
|
||||||
|
// to hidden hash once the pad is stored
|
||||||
if (window.history && window.history.replaceState) {
|
if (window.history && window.history.replaceState) {
|
||||||
if (!/^#/.test(hash)) { hash = '#' + hash; }
|
if (!/^#/.test(hash)) { hash = '#' + hash; }
|
||||||
window.history.replaceState({}, window.document.title, hash);
|
window.history.replaceState({}, window.document.title, hash);
|
||||||
@ -1250,7 +1359,7 @@ define([
|
|||||||
Cryptpad.padRpc.onReadyEvent.reg(function () {
|
Cryptpad.padRpc.onReadyEvent.reg(function () {
|
||||||
Cryptpad.burnPad({
|
Cryptpad.burnPad({
|
||||||
password: password,
|
password: password,
|
||||||
href: window.location.href,
|
href: currentPad.href,
|
||||||
channel: secret.channel,
|
channel: secret.channel,
|
||||||
ownerKey: burnAfterReading
|
ownerKey: burnAfterReading
|
||||||
});
|
});
|
||||||
@ -1265,7 +1374,7 @@ define([
|
|||||||
readOnly: readOnly,
|
readOnly: readOnly,
|
||||||
crypto: Crypto.createEncryptor(secret.keys),
|
crypto: Crypto.createEncryptor(secret.keys),
|
||||||
onConnect: function () {
|
onConnect: function () {
|
||||||
if (window.location.hash && window.location.hash !== '#') {
|
if (currentPad.hash && currentPad.hash !== '#') {
|
||||||
/*window.location = parsed.getUrl({
|
/*window.location = parsed.getUrl({
|
||||||
present: parsed.hashData.present,
|
present: parsed.hashData.present,
|
||||||
embed: parsed.hashData.embed
|
embed: parsed.hashData.embed
|
||||||
@ -1278,11 +1387,11 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
nThen(function (waitFor) {
|
nThen(function (waitFor) {
|
||||||
if (isNewFile && cfg.owned && !window.location.hash) {
|
if (isNewFile && cfg.owned && !currentPad.hash) {
|
||||||
Cryptpad.getMetadata(waitFor(function (err, m) {
|
Cryptpad.getMetadata(waitFor(function (err, m) {
|
||||||
cpNfCfg.owners = [m.priv.edPublic];
|
cpNfCfg.owners = [m.priv.edPublic];
|
||||||
}));
|
}));
|
||||||
} else if (isNewFile && !cfg.useCreationScreen && window.location.hash) {
|
} else if (isNewFile && !cfg.useCreationScreen && currentPad.hash) {
|
||||||
console.log("new file with hash in the address bar in an app without pcs and which requires owners");
|
console.log("new file with hash in the address bar in an app without pcs and which requires owners");
|
||||||
sframeChan.onReady(function () {
|
sframeChan.onReady(function () {
|
||||||
sframeChan.query("EV_LOADING_ERROR", "DELETED");
|
sframeChan.query("EV_LOADING_ERROR", "DELETED");
|
||||||
@ -1309,11 +1418,13 @@ define([
|
|||||||
var ohc = window.onhashchange;
|
var ohc = window.onhashchange;
|
||||||
window.onhashchange = function () {};
|
window.onhashchange = function () {};
|
||||||
window.location.hash = newHash;
|
window.location.hash = newHash;
|
||||||
|
currentPad.hash = newHash;
|
||||||
|
currentPad.href = '/' + parsed.type + '/#' + newHash;
|
||||||
window.onhashchange = ohc;
|
window.onhashchange = ohc;
|
||||||
ohc({reset: true});
|
ohc({reset: true});
|
||||||
|
|
||||||
// Update metadata values and send new metadata inside
|
// Update metadata values and send new metadata inside
|
||||||
parsed = Utils.Hash.parsePadUrl(window.location.href);
|
parsed = Utils.Hash.parsePadUrl(currentPad.href);
|
||||||
defaultTitle = Utils.UserObject.getDefaultName(parsed);
|
defaultTitle = Utils.UserObject.getDefaultName(parsed);
|
||||||
hashes = Utils.Hash.getHashes(secret);
|
hashes = Utils.Hash.getHashes(secret);
|
||||||
readOnly = false;
|
readOnly = false;
|
||||||
|
|||||||
@ -603,6 +603,10 @@ define([
|
|||||||
|
|
||||||
UI.addTooltips();
|
UI.addTooltips();
|
||||||
|
|
||||||
|
ctx.sframeChan.on("EV_PAD_NODATA", function (err) {
|
||||||
|
UI.errorLoadingScreen(Messages.safeLinks_error);
|
||||||
|
});
|
||||||
|
|
||||||
ctx.sframeChan.on("EV_PAD_PASSWORD", function (cfg) {
|
ctx.sframeChan.on("EV_PAD_PASSWORD", function (cfg) {
|
||||||
UIElements.displayPasswordPrompt(funcs, cfg);
|
UIElements.displayPasswordPrompt(funcs, cfg);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -9,6 +9,7 @@ define([
|
|||||||
var requireConfig = RequireConfig();
|
var requireConfig = RequireConfig();
|
||||||
|
|
||||||
// Loaded in load #2
|
// Loaded in load #2
|
||||||
|
var hash, href;
|
||||||
nThen(function (waitFor) {
|
nThen(function (waitFor) {
|
||||||
DomReady.onReady(waitFor());
|
DomReady.onReady(waitFor());
|
||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
@ -19,6 +20,14 @@ define([
|
|||||||
};
|
};
|
||||||
window.rc = requireConfig;
|
window.rc = requireConfig;
|
||||||
window.apiconf = ApiConfig;
|
window.apiconf = ApiConfig;
|
||||||
|
|
||||||
|
// Hidden hash
|
||||||
|
hash = window.location.hash;
|
||||||
|
href = window.location.href;
|
||||||
|
if (window.history && window.history.replaceState && hash) {
|
||||||
|
window.history.replaceState({}, window.document.title, '#');
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById('sbox-iframe').setAttribute('src',
|
document.getElementById('sbox-iframe').setAttribute('src',
|
||||||
ApiConfig.httpSafeOrigin + '/drive/inner.html?' + requireConfig.urlArgs +
|
ApiConfig.httpSafeOrigin + '/drive/inner.html?' + requireConfig.urlArgs +
|
||||||
'#' + encodeURIComponent(JSON.stringify(req)));
|
'#' + encodeURIComponent(JSON.stringify(req)));
|
||||||
@ -37,19 +46,25 @@ define([
|
|||||||
window.addEventListener('message', onMsg);
|
window.addEventListener('message', onMsg);
|
||||||
}).nThen(function (/*waitFor*/) {
|
}).nThen(function (/*waitFor*/) {
|
||||||
var afterSecrets = function (Cryptpad, Utils, secret, cb) {
|
var afterSecrets = function (Cryptpad, Utils, secret, cb) {
|
||||||
var hash = window.location.hash.slice(1);
|
var _hash = hash.slice(1);
|
||||||
if (hash && Utils.LocalStore.isLoggedIn()) {
|
if (_hash && Utils.LocalStore.isLoggedIn()) {
|
||||||
// Add a shared folder!
|
// Add a shared folder!
|
||||||
Cryptpad.addSharedFolder(null, secret, function (id) {
|
Cryptpad.addSharedFolder(null, secret, function (id) {
|
||||||
window.CryptPad_newSharedFolder = id;
|
window.CryptPad_newSharedFolder = id;
|
||||||
|
|
||||||
|
// Clear the hash now that the secrets have been generated
|
||||||
|
if (window.history && window.history.replaceState && hash) {
|
||||||
|
window.history.replaceState({}, window.document.title, '#');
|
||||||
|
}
|
||||||
|
|
||||||
cb();
|
cb();
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
} else if (hash) {
|
} else if (_hash) {
|
||||||
var id = Utils.Util.createRandomInteger();
|
var id = Utils.Util.createRandomInteger();
|
||||||
window.CryptPad_newSharedFolder = id;
|
window.CryptPad_newSharedFolder = id;
|
||||||
var data = {
|
var data = {
|
||||||
href: Utils.Hash.getRelativeHref(window.location.href),
|
href: Utils.Hash.getRelativeHref(Cryptpad.currentPad.href),
|
||||||
password: secret.password
|
password: secret.password
|
||||||
};
|
};
|
||||||
return void Cryptpad.loadSharedFolder(id, data, cb);
|
return void Cryptpad.loadSharedFolder(id, data, cb);
|
||||||
@ -82,14 +97,17 @@ define([
|
|||||||
cb(obj);
|
cb(obj);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
sframeChan.on('EV_DRIVE_SET_HASH', function (hash) {
|
sframeChan.on('EV_DRIVE_SET_HASH', function (/*hash*/) {
|
||||||
// Update the hash in the address bar
|
// Update the hash in the address bar
|
||||||
|
// XXX Hidden hash: don't put the shared folder href in the address bar
|
||||||
|
/*
|
||||||
if (!Utils.LocalStore.isLoggedIn()) { return; }
|
if (!Utils.LocalStore.isLoggedIn()) { return; }
|
||||||
var ohc = window.onhashchange;
|
var ohc = window.onhashchange;
|
||||||
window.onhashchange = function () {};
|
window.onhashchange = function () {};
|
||||||
window.location.hash = hash || '';
|
window.location.hash = hash || '';
|
||||||
window.onhashchange = ohc;
|
window.onhashchange = ohc;
|
||||||
ohc({reset:true});
|
ohc({reset:true});
|
||||||
|
*/
|
||||||
});
|
});
|
||||||
Cryptpad.onNetworkDisconnect.reg(function () {
|
Cryptpad.onNetworkDisconnect.reg(function () {
|
||||||
sframeChan.event('EV_NETWORK_DISCONNECT');
|
sframeChan.event('EV_NETWORK_DISCONNECT');
|
||||||
@ -107,11 +125,13 @@ define([
|
|||||||
sframeChan.event('EV_DRIVE_REMOVE', data);
|
sframeChan.event('EV_DRIVE_REMOVE', data);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
var addData = function (meta) {
|
var addData = function (meta, Cryptpad) {
|
||||||
if (!window.CryptPad_newSharedFolder) { return; }
|
if (!window.CryptPad_newSharedFolder) { return; }
|
||||||
meta.anonSFHref = window.location.href;
|
meta.anonSFHref = Cryptpad.currentPad.href;
|
||||||
};
|
};
|
||||||
SFCommonO.start({
|
SFCommonO.start({
|
||||||
|
hash: hash,
|
||||||
|
href: href,
|
||||||
afterSecrets: afterSecrets,
|
afterSecrets: afterSecrets,
|
||||||
noHash: true,
|
noHash: true,
|
||||||
noRealtime: true,
|
noRealtime: true,
|
||||||
|
|||||||
@ -9,6 +9,7 @@ define([
|
|||||||
var requireConfig = RequireConfig();
|
var requireConfig = RequireConfig();
|
||||||
|
|
||||||
// Loaded in load #2
|
// Loaded in load #2
|
||||||
|
var hash, href;
|
||||||
nThen(function (waitFor) {
|
nThen(function (waitFor) {
|
||||||
DomReady.onReady(waitFor());
|
DomReady.onReady(waitFor());
|
||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
@ -19,6 +20,14 @@ define([
|
|||||||
};
|
};
|
||||||
window.rc = requireConfig;
|
window.rc = requireConfig;
|
||||||
window.apiconf = ApiConfig;
|
window.apiconf = ApiConfig;
|
||||||
|
|
||||||
|
// Hidden hash
|
||||||
|
hash = window.location.hash;
|
||||||
|
href = window.location.href;
|
||||||
|
if (window.history && window.history.replaceState && hash) {
|
||||||
|
window.history.replaceState({}, window.document.title, '#');
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById('sbox-iframe').setAttribute('src',
|
document.getElementById('sbox-iframe').setAttribute('src',
|
||||||
ApiConfig.httpSafeOrigin + '/file/inner.html?' + requireConfig.urlArgs +
|
ApiConfig.httpSafeOrigin + '/file/inner.html?' + requireConfig.urlArgs +
|
||||||
'#' + encodeURIComponent(JSON.stringify(req)));
|
'#' + encodeURIComponent(JSON.stringify(req)));
|
||||||
@ -36,10 +45,12 @@ define([
|
|||||||
};
|
};
|
||||||
window.addEventListener('message', onMsg);
|
window.addEventListener('message', onMsg);
|
||||||
}).nThen(function (/*waitFor*/) {
|
}).nThen(function (/*waitFor*/) {
|
||||||
var addData = function (meta) {
|
var addData = function (meta, Cryptpad) {
|
||||||
meta.filehash = window.location.hash;
|
meta.filehash = Cryptpad.currentPad.hash;
|
||||||
};
|
};
|
||||||
SFCommonO.start({
|
SFCommonO.start({
|
||||||
|
hash: hash,
|
||||||
|
href: href,
|
||||||
noRealtime: true,
|
noRealtime: true,
|
||||||
addData: addData
|
addData: addData
|
||||||
});
|
});
|
||||||
|
|||||||
@ -9,6 +9,7 @@ define([
|
|||||||
var requireConfig = RequireConfig();
|
var requireConfig = RequireConfig();
|
||||||
|
|
||||||
// Loaded in load #2
|
// Loaded in load #2
|
||||||
|
var hash, href;
|
||||||
nThen(function (waitFor) {
|
nThen(function (waitFor) {
|
||||||
DomReady.onReady(waitFor());
|
DomReady.onReady(waitFor());
|
||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
@ -19,6 +20,14 @@ define([
|
|||||||
};
|
};
|
||||||
window.rc = requireConfig;
|
window.rc = requireConfig;
|
||||||
window.apiconf = ApiConfig;
|
window.apiconf = ApiConfig;
|
||||||
|
|
||||||
|
// Hidden hash
|
||||||
|
hash = window.location.hash;
|
||||||
|
href = window.location.href;
|
||||||
|
if (window.history && window.history.replaceState && hash) {
|
||||||
|
window.history.replaceState({}, window.document.title, '#');
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById('sbox-iframe').setAttribute('src',
|
document.getElementById('sbox-iframe').setAttribute('src',
|
||||||
ApiConfig.httpSafeOrigin + '/poll/inner.html?' + requireConfig.urlArgs +
|
ApiConfig.httpSafeOrigin + '/poll/inner.html?' + requireConfig.urlArgs +
|
||||||
'#' + encodeURIComponent(JSON.stringify(req)));
|
'#' + encodeURIComponent(JSON.stringify(req)));
|
||||||
@ -37,6 +46,8 @@ define([
|
|||||||
window.addEventListener('message', onMsg);
|
window.addEventListener('message', onMsg);
|
||||||
}).nThen(function (/*waitFor*/) {
|
}).nThen(function (/*waitFor*/) {
|
||||||
SFCommonO.start({
|
SFCommonO.start({
|
||||||
|
hash: hash,
|
||||||
|
href: href,
|
||||||
useCreationScreen: true,
|
useCreationScreen: true,
|
||||||
messaging: true
|
messaging: true
|
||||||
});
|
});
|
||||||
|
|||||||
@ -52,14 +52,16 @@ define([
|
|||||||
'cp-settings-displayname',
|
'cp-settings-displayname',
|
||||||
'cp-settings-language-selector',
|
'cp-settings-language-selector',
|
||||||
'cp-settings-resettips',
|
'cp-settings-resettips',
|
||||||
'cp-settings-logout-everywhere',
|
|
||||||
'cp-settings-autostore',
|
|
||||||
'cp-settings-userfeedback',
|
|
||||||
'cp-settings-change-password',
|
'cp-settings-change-password',
|
||||||
'cp-settings-migrate',
|
'cp-settings-migrate',
|
||||||
'cp-settings-backup',
|
|
||||||
'cp-settings-delete'
|
'cp-settings-delete'
|
||||||
],
|
],
|
||||||
|
'security': [ // XXX
|
||||||
|
'cp-settings-logout-everywhere',
|
||||||
|
'cp-settings-autostore',
|
||||||
|
'cp-settings-safe-links',
|
||||||
|
'cp-settings-userfeedback',
|
||||||
|
],
|
||||||
'creation': [
|
'creation': [
|
||||||
'cp-settings-creation-owned',
|
'cp-settings-creation-owned',
|
||||||
'cp-settings-creation-expire',
|
'cp-settings-creation-expire',
|
||||||
@ -115,6 +117,24 @@ define([
|
|||||||
|
|
||||||
var create = {};
|
var create = {};
|
||||||
|
|
||||||
|
var makeBlock = function (key, getter, full) {
|
||||||
|
var safeKey = key.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });
|
||||||
|
|
||||||
|
create[key] = function () {
|
||||||
|
var $div = $('<div>', {'class': 'cp-settings-' + key + ' cp-sidebarlayout-element'});
|
||||||
|
if (full) {
|
||||||
|
$('<label>').text(Messages['settings_'+safeKey+'Title'] || key).appendTo($div);
|
||||||
|
$('<span>', {'class': 'cp-sidebarlayout-description'})
|
||||||
|
.text(Messages['settings_'+safeKey+'Hint'] || 'Coming soon...').appendTo($div);
|
||||||
|
}
|
||||||
|
getter(function (content) {
|
||||||
|
$div.append(content);
|
||||||
|
}, $div);
|
||||||
|
return $div;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Account settings
|
// Account settings
|
||||||
|
|
||||||
create['info-block'] = function () {
|
create['info-block'] = function () {
|
||||||
@ -547,6 +567,35 @@ define([
|
|||||||
return $div;
|
return $div;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Security
|
||||||
|
|
||||||
|
makeBlock('safe-links', function (cb) {
|
||||||
|
// XXX settings_safeLinksTitle, settings_safeLinksHint, settings_safeLinksCheckbox
|
||||||
|
|
||||||
|
var $cbox = $(UI.createCheckbox('cp-settings-safe-links',
|
||||||
|
Messages.settings_safeLinksCheckbox,
|
||||||
|
true, { label: {class: 'noTitle'} }));
|
||||||
|
|
||||||
|
var spinner = UI.makeSpinner($cbox);
|
||||||
|
|
||||||
|
var $checkbox = $cbox.find('input').on('change', function () {
|
||||||
|
spinner.spin();
|
||||||
|
var val = !$checkbox.is(':checked');
|
||||||
|
common.setAttribute(['security', 'unsafeLinks'], val, function () {
|
||||||
|
spinner.done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
common.getAttribute(['security', 'unsafeLinks'], function (e, val) {
|
||||||
|
if (e) { return void console.error(e); }
|
||||||
|
if (!val) {
|
||||||
|
$checkbox.attr('checked', 'checked');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cb($cbox);
|
||||||
|
}, true);
|
||||||
|
|
||||||
// Pad Creation settings
|
// Pad Creation settings
|
||||||
|
|
||||||
var setHTML = function (e, html) {
|
var setHTML = function (e, html) {
|
||||||
@ -1578,6 +1627,7 @@ define([
|
|||||||
if (key === 'code') { $category.append($('<span>', {'class': 'fa fa-file-code-o' })); }
|
if (key === 'code') { $category.append($('<span>', {'class': 'fa fa-file-code-o' })); }
|
||||||
if (key === 'pad') { $category.append($('<span>', {'class': 'fa fa-file-word-o' })); }
|
if (key === 'pad') { $category.append($('<span>', {'class': 'fa fa-file-word-o' })); }
|
||||||
if (key === 'creation') { $category.append($('<span>', {'class': 'fa fa-plus-circle' })); }
|
if (key === 'creation') { $category.append($('<span>', {'class': 'fa fa-plus-circle' })); }
|
||||||
|
if (key === 'security') { $category.append($('<span>', {'class': 'fa fa-lock' })); }
|
||||||
if (key === 'subscription') { $category.append($('<span>', {'class': 'fa fa-star-o' })); }
|
if (key === 'subscription') { $category.append($('<span>', {'class': 'fa fa-star-o' })); }
|
||||||
|
|
||||||
if (key === active) {
|
if (key === active) {
|
||||||
@ -1596,9 +1646,10 @@ define([
|
|||||||
showCategories(categories[key]);
|
showCategories(categories[key]);
|
||||||
});
|
});
|
||||||
|
|
||||||
$category.append(Messages['settings_cat_'+key]);
|
$category.append(Messages['settings_cat_'+key] || key);
|
||||||
});
|
});
|
||||||
showCategories(categories[active]);
|
showCategories(categories[active]);
|
||||||
|
common.setHash(active);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ define([
|
|||||||
var requireConfig = RequireConfig();
|
var requireConfig = RequireConfig();
|
||||||
|
|
||||||
// Loaded in load #2
|
// Loaded in load #2
|
||||||
|
var hash, href;
|
||||||
nThen(function (waitFor) {
|
nThen(function (waitFor) {
|
||||||
DomReady.onReady(waitFor());
|
DomReady.onReady(waitFor());
|
||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
@ -19,6 +20,14 @@ define([
|
|||||||
};
|
};
|
||||||
window.rc = requireConfig;
|
window.rc = requireConfig;
|
||||||
window.apiconf = ApiConfig;
|
window.apiconf = ApiConfig;
|
||||||
|
|
||||||
|
// Hidden hash
|
||||||
|
hash = window.location.hash;
|
||||||
|
href = window.location.href;
|
||||||
|
if (window.history && window.history.replaceState && hash) {
|
||||||
|
window.history.replaceState({}, window.document.title, '#');
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById('sbox-iframe').setAttribute('src',
|
document.getElementById('sbox-iframe').setAttribute('src',
|
||||||
ApiConfig.httpSafeOrigin + '/teams/inner.html?' + requireConfig.urlArgs +
|
ApiConfig.httpSafeOrigin + '/teams/inner.html?' + requireConfig.urlArgs +
|
||||||
'#' + encodeURIComponent(JSON.stringify(req)));
|
'#' + encodeURIComponent(JSON.stringify(req)));
|
||||||
@ -37,7 +46,6 @@ define([
|
|||||||
window.addEventListener('message', onMsg);
|
window.addEventListener('message', onMsg);
|
||||||
}).nThen(function (/*waitFor*/) {
|
}).nThen(function (/*waitFor*/) {
|
||||||
var teamId;
|
var teamId;
|
||||||
var hash = window.location.hash.slice(1);
|
|
||||||
var addRpc = function (sframeChan, Cryptpad) {
|
var addRpc = function (sframeChan, Cryptpad) {
|
||||||
sframeChan.on('Q_SET_TEAM', function (data, cb) {
|
sframeChan.on('Q_SET_TEAM', function (data, cb) {
|
||||||
teamId = data;
|
teamId = data;
|
||||||
@ -95,7 +103,7 @@ define([
|
|||||||
};
|
};
|
||||||
var addData = function (meta) {
|
var addData = function (meta) {
|
||||||
if (!hash) { return; }
|
if (!hash) { return; }
|
||||||
meta.teamInviteHash = hash;
|
meta.teamInviteHash = hash.slice(1);
|
||||||
};
|
};
|
||||||
SFCommonO.start({
|
SFCommonO.start({
|
||||||
getSecrets: getSecrets,
|
getSecrets: getSecrets,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user