diff --git a/customize.dist/loading.js b/customize.dist/loading.js
index 3af6aad8a..1db0b64ed 100644
--- a/customize.dist/loading.js
+++ b/customize.dist/loading.js
@@ -290,14 +290,7 @@ button.primary:hover{
].join('');
var built = false;
- // XXX
var types = ['less', 'drive', 'migrate', 'sf', 'team', 'pad', 'end'];
- Messages.loading_state_0 = "Less";
- Messages.loading_state_1 = "Drive";
- Messages.loading_state_2 = "Migrate";
- Messages.loading_state_3 = "SF";
- Messages.loading_state_4 = "Team";
- Messages.loading_state_5 = "Pad";
var current;
var makeList = function (data) {
var c = types.indexOf(data.type);
diff --git a/customize.dist/login.js b/customize.dist/login.js
index 35121f113..d07d4c4c3 100644
--- a/customize.dist/login.js
+++ b/customize.dist/login.js
@@ -28,6 +28,19 @@ define([
};
var Nacl = window.nacl;
+
+ var redirectTo = '/drive/';
+ var setRedirectTo = function () {
+ var parsed = Hash.parsePadUrl(window.location.href);
+ if (parsed.hashData && parsed.hashData.newPadOpts) {
+ var newPad = Hash.decodeDataOptions(parsed.hashData.newPadOpts);
+ redirectTo = newPad.href;
+ }
+ };
+ if (window.location.hash) {
+ setRedirectTo();
+ }
+
var allocateBytes = Exports.allocateBytes = function (bytes) {
var dispense = Cred.dispenser(bytes);
@@ -118,11 +131,11 @@ define([
};
var setMergeAnonDrive = function () {
- sessionStorage.migrateAnonDrive = 1;
+ Exports.mergeAnonDrive = 1;
};
var setCreateReadme = function () {
- sessionStorage.createReadme = 1;
+ Exports.createReadme = 1;
};
Exports.loginOrRegister = function (uname, passwd, isRegister, shouldImport, cb) {
@@ -416,12 +429,20 @@ define([
});
};
Exports.redirect = function () {
- if (sessionStorage.redirectTo) {
- var h = sessionStorage.redirectTo;
+ if (redirectTo) {
+ var h = redirectTo;
+ var loginOpts = {};
+ if (Exports.mergeAnonDrive) {
+ loginOpts.mergeAnonDrive = 1;
+ }
+ if (Exports.createReadme) {
+ loginOpts.createReadme = 1;
+ }
+ h = Hash.getLoginURL(h, loginOpts);
+
var parser = document.createElement('a');
parser.href = h;
if (parser.origin === window.location.origin) {
- delete sessionStorage.redirectTo;
window.location.href = h;
return;
}
diff --git a/customize.dist/pages/features.js b/customize.dist/pages/features.js
index 26303f9ba..da4a44c55 100644
--- a/customize.dist/pages/features.js
+++ b/customize.dist/pages/features.js
@@ -68,14 +68,6 @@ define([
target: '_blank',
rel: 'noopener noreferrer'
}, h('button.cp-features-register-button', Msg.features_f_subscribe));
- /*$(premiumButton).click(function (e) {
- if (LocalStore.isLoggedIn()) { return; }
- // Not logged in: go to /login with a redirect to this page
- e.preventDefault();
- e.stopPropagation();
- sessionStorage.redirectTo = '/features.html';
- window.location.href = '/login/';
- });*/
var anonymousFeatures =
h('div.col-12.col-sm-4.cp-anon-user',[
diff --git a/customize.dist/pages/index.js b/customize.dist/pages/index.js
index 5a4ec72eb..cd81d1b7c 100644
--- a/customize.dist/pages/index.js
+++ b/customize.dist/pages/index.js
@@ -4,12 +4,13 @@ define([
'/common/hyperscript.js',
'/common/common-feedback.js',
'/common/common-interface.js',
+ '/common/common-hash.js',
'/common/textFit.min.js',
'/customize/messages.js',
'/customize/application_config.js',
'/common/outer/local-store.js',
'/customize/pages.js'
-], function ($, Config, h, Feedback, UI, TextFit, Msg, AppConfig, LocalStore, Pages) {
+], function ($, Config, h, Feedback, UI, Hash, TextFit, Msg, AppConfig, LocalStore, Pages) {
var urlArgs = Config.requireConf.urlArgs;
var isAvailableType = function (x) {
@@ -46,8 +47,9 @@ define([
var href = '/'+ x[0] +'/';
var attr = isEnabled ? { href: href } : {
onclick: function () {
- sessionStorage.redirectTo = href;
- window.location.href = '/login/';
+ var href = Hash.hashToHref('', 'login');
+ var url = Hash.getNewPadURL(href, { href: href });
+ window.location.href = url;
}
};
if (!isEnabled) {
diff --git a/customize.dist/src/less2/include/app-print.less b/customize.dist/src/less2/include/app-print.less
index e4c344b20..7f42f100b 100644
--- a/customize.dist/src/less2/include/app-print.less
+++ b/customize.dist/src/less2/include/app-print.less
@@ -9,10 +9,6 @@
max-height: none;
overflow: visible;
display: block;
- @page {
- margin: 0;
- size: landscape;
- }
// Slide app
body.cp-app-slide {
display: block;
@@ -48,11 +44,15 @@
// Code app
body.cp-app-code {
display: block;
+ height: auto;
* {
visibility: hidden;
height: auto;
max-height: none;
}
+ .cp-toolbar-userlist-drawer {
+ display: none;
+ }
#cme_toolbox {
display: none;
}
@@ -64,6 +64,7 @@
#cp-app-code-preview {
display: block;
#cp-app-code-print {
+ font-size: 20px;
display: block;
overflow: visible !important;
width: 100%;
diff --git a/customize.dist/src/print-landscape.css b/customize.dist/src/print-landscape.css
new file mode 100644
index 000000000..26a9d495e
--- /dev/null
+++ b/customize.dist/src/print-landscape.css
@@ -0,0 +1,5 @@
+@page {
+ margin: 0;
+ size: A4 landscape;
+}
+
diff --git a/customize.dist/src/print.css b/customize.dist/src/print.css
new file mode 100644
index 000000000..1baf803d4
--- /dev/null
+++ b/customize.dist/src/print.css
@@ -0,0 +1,4 @@
+@page {
+ margin: 3cm;
+ size: A4 portrait;
+}
diff --git a/www/auth/index.html b/www/auth/index.html
deleted file mode 100644
index 685ca37c4..000000000
--- a/www/auth/index.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/www/auth/main.js b/www/auth/main.js
deleted file mode 100644
index fcbeaf3af..000000000
--- a/www/auth/main.js
+++ /dev/null
@@ -1,193 +0,0 @@
-define([
- 'jquery',
- '/api/config',
- '/common/cryptget.js',
- '/common/pinpad.js',
- '/common/common-constants.js',
- '/common/common-hash.js',
- '/common/outer/local-store.js',
- '/common/outer/login-block.js',
- '/common/outer/network-config.js',
- '/customize/login.js',
- '/common/test.js',
- '/bower_components/nthen/index.js',
- '/bower_components/netflux-websocket/netflux-client.js',
- '/bower_components/tweetnacl/nacl-fast.min.js'
-], function ($, ApiConfig, Crypt, Pinpad, Constants, Hash, LocalStore, Block, NetConfig, Login, Test, nThen, Netflux) {
- var Nacl = window.nacl;
-
- var signMsg = function (msg, privKey) {
- var signKey = Nacl.util.decodeBase64(privKey);
- var buffer = Nacl.util.decodeUTF8(msg);
- return Nacl.util.encodeBase64(Nacl.sign(buffer, signKey));
- };
-
- // TODO: Allow authing for any domain as long as the user clicks an "accept" button
- // inside of the iframe.
- var AUTHORIZED_DOMAINS = [
- /\.cryptpad\.fr$/,
- /^http(s)?:\/\/localhost\:/
- ];
-
- // Safari is weird about localStorage in iframes but seems to let sessionStorage slide.
- localStorage[Constants.userHashKey] = localStorage[Constants.userHashKey] ||
- sessionStorage[Constants.userHashKey];
-
- var proxy;
- var rpc;
- var network;
- var rpcError;
- var contacts = {};
-
- var loadProxy = function (hash) {
- nThen(function (waitFor) {
- var wsUrl = NetConfig.getWebsocketURL();
- var w = waitFor();
- Netflux.connect(wsUrl).then(function (_network) {
- network = _network;
- w();
- }, function (err) {
- rpcError = err;
- console.error(err);
- });
- }).nThen(function (waitFor) {
- Crypt.get(hash, waitFor(function (err, val) {
- if (err) {
- waitFor.abort();
- console.error(err);
- return;
- }
- try {
- var parsed = JSON.parse(val);
- proxy = parsed;
- } catch (e) {
- console.log("Can't parse user drive", e);
- }
- }), {
- network: network
- });
- }).nThen(function () {
- var origin = ApiConfig.fileHost || window.location.origin;
- // Get contacts and extract their avatar channel and key
- var getData = function (obj, href) {
- var parsed = Hash.parsePadUrl(href);
- if (!parsed || parsed.type !== "file") { return; }
- var secret = Hash.getSecrets('file', parsed.hash);
- if (!secret.keys || !secret.channel) { return; }
- obj.avatarKey = Hash.encodeBase64(secret.keys && secret.keys.cryptKey);
- obj.avatarSrc = origin + Hash.getBlobPathFromHex(secret.channel);
- };
- contacts.teams = proxy.teams || {};
- contacts.friends = proxy.friends || {};
- Object.keys(contacts.friends).map(function (key) {
- var friend = contacts.friends[key];
- if (!friend) { return; }
- var ret = {
- edPublic: friend.edPublic,
- name: friend.displayName,
- };
- getData(ret, friend.avatar);
- contacts.friends[key] = ret;
- });
- Object.keys(contacts.teams).map(function (key) {
- var team = contacts.teams[key];
- if (!team) { return; }
- var avatar = team.metadata && team.metadata.avatar;
- var ret = {
- edPublic: team.keys && team.keys.drive && team.keys.drive.edPublic,
- name: team.metadata && team.metadata.name
- };
- getData(ret, avatar);
- contacts.teams[key] = ret;
- });
- contacts.origin = window.location.origin;
- }).nThen(function (waitFor) {
- if (!network) { return void waitFor.abort(); }
- Pinpad.create(network, proxy, waitFor(function (e, call) {
- if (e) {
- rpcError = e;
- return void waitFor.abort();
- }
- rpc = call;
- }));
- }).nThen(function () {
- Test(function () {
- // This is only here to maybe trigger an error.
- window.drive = proxy['drive'];
- Test.passed();
- });
- });
- };
-
- var whenReady = function (cb) {
- if (proxy && (rpc || rpcError)) { return void cb(); }
- console.log('CryptPad not ready...');
- setTimeout(function () {
- whenReady(cb);
- }, 100);
- };
-
- $(window).on("message", function (jqe) {
- var evt = jqe.originalEvent;
- var data = JSON.parse(evt.data);
- var domain = evt.origin;
- var srcWindow = evt.source;
- var ret = { txid: data.txid };
- console.log('CP receiving', data);
- if (data.cmd === 'PING') {
- ret.res = 'PONG';
- } else if (data.cmd === 'LOGIN') {
- Login.loginOrRegister(data.data.name, data.data.password, false, false, function (err) {
- if (err) {
- ret.error = 'LOGIN_ERROR';
- srcWindow.postMessage(JSON.stringify(ret), domain);
- return;
- }
- loadProxy(LocalStore.getUserHash());
- srcWindow.postMessage(JSON.stringify(ret), domain);
- });
- return;
- } else if (data.cmd === 'SIGN') {
- if (!AUTHORIZED_DOMAINS.filter(function (x) { return x.test(domain); }).length) {
- ret.error = "UNAUTH_DOMAIN";
- } else if (!LocalStore.isLoggedIn()) {
- ret.error = "NOT_LOGGED_IN";
- } else {
- return void whenReady(function () {
- var sig = signMsg(data.data, proxy.edPrivate);
- ret.res = {
- uname: proxy.login_name,
- edPublic: proxy.edPublic,
- sig: sig
- };
- ret.contacts = contacts;
- srcWindow.postMessage(JSON.stringify(ret), domain);
- });
- }
- } else if (data.cmd === 'UPDATE_LIMIT') {
- return void whenReady(function () {
- if (rpcError) {
- // Tell the user on accounts that there was an issue and they need to wait maximum 24h or contact an admin
- ret.warning = true;
- srcWindow.postMessage(JSON.stringify(ret), domain);
- return;
- }
- rpc.updatePinLimits(function (e, limit, plan, note) {
- if (e) {
- ret.warning = true;
- }
- ret.res = [limit, plan, note];
- srcWindow.postMessage(JSON.stringify(ret), domain);
- });
- });
- } else {
- ret.error = "UNKNOWN_CMD";
- }
- srcWindow.postMessage(JSON.stringify(ret), domain);
- });
-
- var userHash = LocalStore.getUserHash();
- if (userHash) {
- loadProxy(userHash);
- }
-});
diff --git a/www/code/app-code.less b/www/code/app-code.less
index 0ca86fd8b..6557d39f6 100644
--- a/www/code/app-code.less
+++ b/www/code/app-code.less
@@ -136,7 +136,6 @@
#cp-app-code-print {
position: relative;
display: none;
- margin: 50px;
.markdown_preformatted-code;
.markdown_gfm-table(black);
}
diff --git a/www/code/inner.js b/www/code/inner.js
index 7dff21c82..31d12eff4 100644
--- a/www/code/inner.js
+++ b/www/code/inner.js
@@ -42,6 +42,7 @@ define([
'cm/addon/fold/comment-fold',
'cm/addon/display/placeholder',
+ 'css!/customize/src/print.css',
'less!/code/app-code.less'
], function (
diff --git a/www/common/boot2.js b/www/common/boot2.js
index fc3968fb3..30f776a25 100644
--- a/www/common/boot2.js
+++ b/www/common/boot2.js
@@ -43,6 +43,9 @@ define([
console.error("Require.js threw a Script Error. This probably means you're missing a dependency for CryptPad.\nIt is recommended that the admin of this server runs `bower install && bower update` to get the latest code, then modify their cache version.\nBest of luck,\nThe CryptPad Developers");
return void console.log();
}
+ if (window.CryptPad_loadingError) {
+ window.CryptPad_loadingError(e);
+ }
throw e;
};
diff --git a/www/common/common-constants.js b/www/common/common-constants.js
index 553665574..17db2302c 100644
--- a/www/common/common-constants.js
+++ b/www/common/common-constants.js
@@ -5,10 +5,6 @@ define(['/customize/application_config.js'], function (AppConfig) {
userNameKey: 'User_name',
blockHashKey: 'Block_hash',
fileHashKey: 'FS_hash',
- // sessionStorage
- newPadPathKey: "newPadPath",
- newPadTeamKey: "newPadTeam",
- newPadFileData: "newPadFileData",
// Store
displayNameKey: 'cryptpad.username',
oldStorageKey: 'CryptPad_RECENTPADS',
diff --git a/www/common/common-hash.js b/www/common/common-hash.js
index 0b584d4c3..06a1d7fef 100644
--- a/www/common/common-hash.js
+++ b/www/common/common-hash.js
@@ -169,6 +169,28 @@ Version 1
/code/#/1/edit/3Ujt4F2Sjnjbis6CoYWpoQ/usn4+9CqVja8Q7RZOGTfRgqI
*/
+ var getLoginOpts = function (hashArr) {
+ var k;
+ // Check if we have a ownerKey for this pad
+ hashArr.some(function (data) {
+ if (/^login=/.test(data)) {
+ k = data.slice(6);
+ return true;
+ }
+ });
+ return k || '';
+ };
+ var getNewPadOpts = function (hashArr) {
+ var k;
+ // Check if we have a ownerKey for this pad
+ hashArr.some(function (data) {
+ if (/^newpad=/.test(data)) {
+ k = data.slice(7);
+ return true;
+ }
+ });
+ return k || '';
+ };
var getVersionHash = function (hashArr) {
var k;
// Check if we have a ownerKey for this pad
@@ -202,21 +224,52 @@ Version 1
parsed.present = options.indexOf('present') !== -1;
parsed.embed = options.indexOf('embed') !== -1;
parsed.versionHash = getVersionHash(options);
+ parsed.newPadOpts = getNewPadOpts(options);
+ parsed.loginOpts = getLoginOpts(options);
parsed.ownerKey = getOwnerKey(options);
};
+ // Version 4: only login or newpad options, smae for all the apps
+ if (hashArr[1] && hashArr[1] === '4') {
+ parsed.getHash = function (opts) {
+ if (!opts || !Object.keys(opts).length) { return ''; }
+ var hash = '/4/';
+ if (opts.newPadOpts) { hash += 'newpad=' + opts.newPadOpts + '/'; }
+ if (opts.loginOpts) { hash += 'login=' + opts.loginOpts + '/'; }
+ return hash;
+ };
+ parsed.getOptions = function () {
+ var options = {};
+ if (parsed.newPadOpts) { options.newPadOpts = parsed.newPadOpts; }
+ if (parsed.loginOpts) { options.loginOpts = parsed.loginOpts; }
+ return options;
+ };
+
+ parsed.version = 4;
+ options = hashArr.slice(2);
+ addOptions();
+
+ return parsed;
+ }
+
+ // The other versions depends on the type
if (['media', 'file', 'user', 'invite'].indexOf(type) === -1) {
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,
versionHash: parsed.versionHash,
+ newPadOpts: parsed.newPadOpts,
+ loginOpts: parsed.loginOpts,
password: parsed.password
};
};
+
if (hash.slice(0,1) !== '/' && hash.length >= 56) { // Version 0
// Old hash
parsed.channel = hash.slice(0, 32);
@@ -237,6 +290,8 @@ Version 1
if (versionHash) {
hash += 'hash=' + Crypto.b64RemoveSlashes(versionHash) + '/';
}
+ if (opts.newPadOpts) { hash += 'newpad=' + opts.newPadOpts + '/'; }
+ if (opts.loginOpts) { hash += 'login=' + opts.loginOpts + '/'; }
return hash;
};
@@ -284,6 +339,8 @@ Version 1
embed: parsed.embed,
present: parsed.present,
ownerKey: parsed.ownerKey,
+ newPadOpts: parsed.newPadOpts,
+ loginOpts: parsed.loginOpts,
password: parsed.password
};
};
@@ -295,6 +352,8 @@ Version 1
if (parsed.password || opts.password) { hash += 'p/'; }
if (opts.embed) { hash += 'embed/'; }
if (opts.present) { hash += 'present/'; }
+ if (opts.newPadOpts) { hash += 'newpad=' + opts.newPadOpts + '/'; }
+ if (opts.loginOpts) { hash += 'login=' + opts.loginOpts + '/'; }
return hash;
};
@@ -367,14 +426,26 @@ Version 1
var idx;
+ // When we start without a hash, use version 4 links to add login or newpad options
+ var getHash = function (opts) {
+ if (!opts || !Object.keys(opts).length) { return ''; }
+ var hash = '/4/';
+ if (opts.newPadOpts) { hash += 'newpad=' + opts.newPadOpts + '/'; }
+ if (opts.loginOpts) { hash += 'login=' + opts.loginOpts + '/'; }
+ return hash;
+ };
ret.getUrl = function (options) {
options = options || {};
var url = '/';
if (!ret.type) { return url; }
url += ret.type + '/';
+ // New pad with options: append the options to the hash
+ if (!ret.hashData && options && Object.keys(options).length) {
+ return url + '#' + getHash(options);
+ }
if (!ret.hashData) { return url; }
- if (ret.hashData.type !== 'pad') { return url + '#' + ret.hash; }
- if (ret.hashData.version === 0) { return url + '#' + ret.hash; }
+ //if (ret.hashData.version === 0) { return url + '#' + ret.hash; }
+ //if (ret.hashData.type !== 'pad') { return url + '#' + ret.hash; }
var hash = ret.hashData.getHash(options);
url += '#' + hash;
return url;
@@ -523,7 +594,6 @@ Version 1
secret = JSON.parse(JSON.stringify(secret));
if (!secret.keys && !secret.key) {
- console.error('e');
return hashes;
} else if (!secret.keys) {
secret.keys = {};
@@ -575,6 +645,9 @@ Version 1
// Valid hash?
if (parsed.hash) {
if (!parsed.hashData) { return; }
+ // New pad: only newPadOpts allowed
+ if (Object.keys(parsed.hashData).length === 1 &&
+ parsed.hashData.newPadOpts) { return true; }
// Version should be a number
if (typeof(parsed.hashData.version) === "undefined") { return; }
// pads and files should have a base64 (or hex) key
@@ -586,6 +659,29 @@ Version 1
return true;
};
+ Hash.decodeDataOptions = function (opts) {
+ var b64 = decodeURIComponent(opts);
+ var str = Nacl.util.encodeUTF8(Nacl.util.decodeBase64(b64));
+ return JSON.parse(str);
+ };
+ Hash.encodeDataOptions = function (opts) {
+ var str = JSON.stringify(opts);
+ var b64 = Nacl.util.encodeBase64(Nacl.util.decodeUTF8(str));
+ return encodeURIComponent(b64);
+ };
+ Hash.getNewPadURL = function (href, opts) {
+ var parsed = Hash.parsePadUrl(href);
+ var options = parsed.getOptions();
+ options.newPadOpts = Hash.encodeDataOptions(opts);
+ return parsed.getUrl(options);
+ };
+ Hash.getLoginURL = function (href, opts) {
+ var parsed = Hash.parsePadUrl(href);
+ var options = parsed.getOptions();
+ options.loginOpts = Hash.encodeDataOptions(opts);
+ return parsed.getUrl(options);
+ };
+
return Hash;
};
diff --git a/www/common/common-interface.js b/www/common/common-interface.js
index 46faa7f53..83a5e80be 100644
--- a/www/common/common-interface.js
+++ b/www/common/common-interface.js
@@ -281,12 +281,10 @@ define([
var $root = $t.parent();
- Messages.add = "Add"; // XXX
- Messages.edit = "Edit"; // XXX
var $input = $root.find('.token-input');
var $button = $(h('button.btn.btn-primary', [
h('i.fa.fa-plus'),
- h('span', Messages.add)
+ h('span', Messages.tag_add)
]));
@@ -311,7 +309,7 @@ define([
}
$form.append($input);
$form.append($button);
- if (isEdit) { $button.find('span').text(Messages.edit); }
+ if (isEdit) { $button.find('span').text(Messages.tag_edit); }
else { $button.find('span').text(Messages.add); }
$container.append($form);
$input.focus();
@@ -942,8 +940,6 @@ define([
$loading.removeClass('cp-loading-hidden');
$loading.removeClass('cp-loading-transparent');
if (config.newProgress) {
- // XXX re-add progress bar for step 6 after password prompt for PPP
- // XXX also burn after reading
var progress = h('div.cp-loading-progress', [
h('p.cp-loading-progress-list'),
h('p.cp-loading-progress-container')
diff --git a/www/common/common-ui-elements.js b/www/common/common-ui-elements.js
index ad8e1ca6e..f9f76429f 100644
--- a/www/common/common-ui-elements.js
+++ b/www/common/common-ui-elements.js
@@ -248,20 +248,15 @@ define([
className: 'secondary',
name: Messages.login_register,
onClick: function () {
- common.setLoginRedirect(function () {
- common.gotoURL('/register/');
- });
+ common.setLoginRedirect('register');
}
}, {
className: 'secondary',
name: Messages.login_login,
onClick: function () {
- common.setLoginRedirect(function () {
- common.gotoURL('/login/');
- });
+ common.setLoginRedirect('login');
}
- }
- ]
+ }]
};
}
};
@@ -633,6 +628,7 @@ define([
button
.click(common.prepareFeedback(type))
.click(function () {
+ if (callback) { return void callback(); }
UIElements.openTemplatePicker(common, true);
});
break;
@@ -1802,9 +1798,7 @@ define([
attributes: {'class': 'cp-toolbar-menu-login fa fa-sign-in'},
content: h('span', Messages.login_login),
action: function () {
- Common.setLoginRedirect(function () {
- window.parent.location = origin+'/login/';
- });
+ Common.setLoginRedirect('login');
},
});
options.push({
@@ -1812,9 +1806,7 @@ define([
attributes: {'class': 'cp-toolbar-menu-register fa fa-user-plus'},
content: h('span', Messages.login_register),
action: function () {
- Common.setLoginRedirect(function () {
- window.parent.location = origin+'/register/';
- });
+ Common.setLoginRedirect('register');
},
});
}
@@ -1939,8 +1931,6 @@ define([
$modal.find('.cp-modal').append($title);
$modal.find('.cp-modal').append($description);
- var $advanced;
-
var $container = $('');
var i = 0;
var types = AppConfig.availablePadTypes.filter(function (p) {
@@ -1964,15 +1954,7 @@ define([
$element.attr('data-type', p);
$element.click(function () {
$modal.hide();
- if ($advanced && Util.isChecked($advanced)) {
- common.sessionStorage.put(Constants.displayPadCreationScreen, true, function (){
- common.openURL('/' + p + '/');
- });
- return;
- }
- common.sessionStorage.put(Constants.displayPadCreationScreen, "", function () {
- common.openURL('/' + p + '/');
- });
+ common.openURL('/' + p + '/');
});
});
@@ -1997,12 +1979,6 @@ define([
}
return;
}
- if (e.which === 32 && $advanced) {
- $advanced.prop('checked', !$advanced.prop('checked'));
- $modal.focus();
- e.stopPropagation();
- e.preventDefault();
- }
});
@@ -2109,7 +2085,7 @@ define([
var sframeChan = common.getSframeChannel();
var metadataMgr = common.getMetadataMgr();
var privateData = metadataMgr.getPrivateData();
- var type = metadataMgr.getMetadataLazy().type;
+ var type = metadataMgr.getMetadataLazy().type || privateData.app;
var fromFileData = privateData.fromFileData;
var $body = $('body');
@@ -2284,12 +2260,14 @@ define([
icon: h('span.cptools.cptools-new-template')
});
}
- allData.unshift({
- name: Messages.creation_noTemplate,
- id: 0,
- //icon: h('span.fa.fa-file')
- icon: UI.getFileIcon({type: type})
- });
+ if (!privateData.newTemplate) {
+ allData.unshift({
+ name: Messages.creation_noTemplate,
+ id: 0,
+ //icon: h('span.fa.fa-file')
+ icon: UI.getFileIcon({type: type})
+ });
+ }
var redraw = function (index) {
if (index < 0) { i = 0; }
else if (index > allData.length - 1) { return; }
@@ -2765,13 +2743,8 @@ define([
$(link).click(function (e) {
e.preventDefault();
e.stopPropagation();
- if (msg.content.password) {
- common.sessionStorage.put('newPadPassword', msg.content.password, function () {
- common.openURL(msg.content.href);
- });
- return;
- }
- common.openURL(msg.content.href);
+ var obj = { pw: msg.content.password || '' };
+ common.openURL(Hash.getNewPadURL(msg.content.href, obj));
});
var div = h('div', [
diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js
index a9b2923a9..36413d89d 100644
--- a/www/common/cryptpad-common.js
+++ b/www/common/cryptpad-common.js
@@ -148,6 +148,21 @@ define([
send();
};
+ common.setTabHref = function (href) {
+ var ohc = window.onhashchange;
+ window.onhashchange = function () {};
+ window.location.href = href;
+ window.onhashchange = ohc;
+ ohc({reset: true});
+ };
+ common.setTabHash = function (hash) {
+ var ohc = window.onhashchange;
+ window.onhashchange = function () {};
+ window.location.hash = hash;
+ window.onhashchange = ohc;
+ ohc({reset: true});
+ };
+
// RESTRICTED
// Settings only
common.resetDrive = function (cb) {
@@ -673,6 +688,7 @@ define([
if (!val) {
return void cb('ENOENT');
}
+ if (data.oo) { return void cb(val); } // OnlyOffice template: are handled in inner
try {
// Try to fix the title before importing the template
var parsed = JSON.parse(val);
@@ -1864,8 +1880,9 @@ define([
LocalStore.logout();
// redirect them to log in, and come back when they're done.
- sessionStorage.redirectTo = currentPad.href;
- window.location.href = '/login/';
+ var href = Hash.hashToHref('', 'login');
+ var url = Hash.getNewPadURL(href, { href: currentPad.href });
+ window.location.href = url;
};
common.startAccountDeletion = function (data, cb) {
@@ -2089,26 +2106,6 @@ define([
language: common.getLanguage(),
driveEvents: true //rdyCfg.driveEvents // Boolean
};
- // if a pad is created from a file
- if (sessionStorage[Constants.newPadFileData]) {
- common.fromFileData = JSON.parse(sessionStorage[Constants.newPadFileData]);
- var _parsed1 = Hash.parsePadUrl(common.fromFileData.href);
- var _parsed2 = Hash.parsePadUrl(window.location.href);
- if (_parsed1.hashData.type === 'pad') {
- if (_parsed1.type !== _parsed2.type) { delete common.fromFileData; }
- }
- delete sessionStorage[Constants.newPadFileData];
- }
-
- if (sessionStorage[Constants.newPadPathKey]) {
- common.initialPath = sessionStorage[Constants.newPadPathKey];
- delete sessionStorage[Constants.newPadPathKey];
- }
-
- if (sessionStorage[Constants.newPadTeamKey]) {
- common.initialTeam = sessionStorage[Constants.newPadTeamKey];
- delete sessionStorage[Constants.newPadTeamKey];
- }
var channelIsReady = waitFor();
@@ -2281,12 +2278,6 @@ define([
if (data.anonHash && !cfg.userHash) { LocalStore.setFSHash(data.anonHash); }
- /*if (cfg.userHash && sessionStorage) {
- // copy User_hash into sessionStorage because cross-domain iframes
- // on safari replaces localStorage with sessionStorage or something
- sessionStorage.setItem(Constants.userHashKey, cfg.userHash);
- }*/
-
if (cfg.userHash) {
var localToken = tryParsing(localStorage.getItem(Constants.tokenKey));
if (localToken === null) {
@@ -2341,21 +2332,18 @@ define([
postMessage("DISCONNECT");
});
}).nThen(function (waitFor) {
- if (sessionStorage.createReadme) {
+ if (common.createReadme) {
var data = {
driveReadme: Messages.driveReadme,
driveReadmeTitle: Messages.driveReadmeTitle,
};
postMessage("CREATE_README", data, waitFor(function (e) {
if (e && e.error) { return void console.error(e.error); }
- delete sessionStorage.createReadme;
}));
}
}).nThen(function (waitFor) {
- if (sessionStorage.migrateAnonDrive) {
- common.mergeAnonDrive(waitFor(function() {
- delete sessionStorage.migrateAnonDrive;
- }));
+ if (common.migrateAnonDrive) {
+ common.mergeAnonDrive(waitFor());
}
}).nThen(function (waitFor) {
if (AppConfig.afterLogin) {
diff --git a/www/common/drive-ui.js b/www/common/drive-ui.js
index c79e3d4e3..79ad9b83a 100644
--- a/www/common/drive-ui.js
+++ b/www/common/drive-ui.js
@@ -1125,6 +1125,15 @@ define([
var hiddenHref = Hash.hashToHref(hash, parsed.type);
window.open(APP.origin + hiddenHref);
};
+ var openIn = function (type, path, team, fData) {
+ var obj = {
+ p: path,
+ t: team,
+ d: fData
+ };
+ var href = Hash.hashToHref('', type);
+ common.openURL(Hash.getNewPadURL(href, obj));
+ };
var refresh = APP.refresh = function () {
APP.displayDirectory(currentPath);
@@ -2667,12 +2676,7 @@ define([
.click(function () {
var type = $(this).attr('data-type') || 'pad';
var path = manager.isPathIn(currentPath, [TRASH]) ? '' : currentPath;
- nThen(function (waitFor) {
- common.sessionStorage.put(Constants.newPadPathKey, path, waitFor());
- common.sessionStorage.put(Constants.newPadTeamKey, APP.team, waitFor());
- }).nThen(function () {
- common.openURL('/' + type + '/');
- });
+ openIn(type, path, APP.team);
});
};
var createNewButton = function (isInRoot, $container) {
@@ -4227,60 +4231,37 @@ define([
else if ($this.hasClass('cp-app-drive-context-makeacopy')) {
if (paths.length !== 1) { return; }
el = manager.find(paths[0].path);
- var _metadata = manager.getFileData(el);
- var _simpleData = {
- title: _metadata.filename || _metadata.title,
- href: _metadata.href || _metadata.roHref,
- password: _metadata.password,
- channel: _metadata.channel,
- };
- nThen(function (waitFor) {
+ (function () {
var path = currentPath;
if (path[0] !== ROOT) { path = [ROOT]; }
- common.sessionStorage.put(Constants.newPadFileData, JSON.stringify(_simpleData), waitFor());
- common.sessionStorage.put(Constants.newPadPathKey, path, waitFor());
- common.sessionStorage.put(Constants.newPadTeamKey, APP.team, waitFor());
- }).nThen(function () {
+ var _metadata = manager.getFileData(el);
+ var _simpleData = {
+ title: _metadata.filename || _metadata.title,
+ href: _metadata.href || _metadata.roHref,
+ password: _metadata.password,
+ channel: _metadata.channel,
+ };
var parsed = Hash.parsePadUrl(_metadata.href || _metadata.roHref);
- common.openURL(Hash.hashToHref('', parsed.type));
- // We need to restore sessionStorage for the next time we want to create a pad from this tab
- // NOTE: the 100ms timeout is to fix a race condition in firefox where sessionStorage
- // would be deleted before the new tab was created
- setTimeout(function () {
- common.sessionStorage.put(Constants.newPadFileData, '', function () {});
- common.sessionStorage.put(Constants.newPadPathKey, '', function () {});
- common.sessionStorage.put(Constants.newPadTeamKey, '', function () {});
- }, 100);
- });
+ openIn(parsed.type, path, APP.team, _simpleData);
+ })();
}
else if ($this.hasClass('cp-app-drive-context-openincode')) {
if (paths.length !== 1) { return; }
var p = paths[0];
el = manager.find(p.path);
- var metadata = manager.getFileData(el);
- var simpleData = {
- title: metadata.filename || metadata.title,
- href: metadata.href,
- password: metadata.password,
- channel: metadata.channel,
- };
- nThen(function (waitFor) {
- common.sessionStorage.put(Constants.newPadFileData, JSON.stringify(simpleData), waitFor());
- common.sessionStorage.put(Constants.newPadPathKey, currentPath, waitFor());
- common.sessionStorage.put(Constants.newPadTeamKey, APP.team, waitFor());
- }).nThen(function () {
- common.openURL('/code/');
- // We need to restore sessionStorage for the next time we want to create a pad from this tab
- // NOTE: the 100ms timeout is to fix a race condition in firefox where sessionStorage
- // would be deleted before the new tab was created
- setTimeout(function () {
- common.sessionStorage.put(Constants.newPadFileData, '', function () {});
- common.sessionStorage.put(Constants.newPadPathKey, '', function () {});
- common.sessionStorage.put(Constants.newPadTeamKey, '', function () {});
- }, 100);
- });
+ (function () {
+ var path = currentPath;
+ if (path[0] !== ROOT) { path = [ROOT]; }
+ var _metadata = manager.getFileData(el);
+ var _simpleData = {
+ title: _metadata.filename || _metadata.title,
+ href: _metadata.href || _metadata.roHref,
+ password: _metadata.password,
+ channel: _metadata.channel,
+ };
+ openIn('code', path, APP.team, _simpleData);
+ })();
}
-
else if ($this.hasClass('cp-app-drive-context-expandall') ||
$this.hasClass('cp-app-drive-context-collapseall')) {
if (paths.length !== 1) { return; }
@@ -4482,12 +4463,7 @@ define([
else if ($this.hasClass("cp-app-drive-context-newdoc")) {
var ntype = $this.data('type') || 'pad';
var path2 = manager.isPathIn(currentPath, [TRASH]) ? '' : currentPath;
- nThen(function (waitFor) {
- common.sessionStorage.put(Constants.newPadPathKey, path2, waitFor());
- common.sessionStorage.put(Constants.newPadTeamKey, APP.team, waitFor());
- }).nThen(function () {
- common.openURL('/' + ntype + '/');
- });
+ openIn(ntype, path2, APP.team);
}
else if ($this.hasClass("cp-app-drive-context-properties")) {
if (type === 'trash') {
diff --git a/www/common/notifications.js b/www/common/notifications.js
index 44125ed71..caf5bfe00 100644
--- a/www/common/notifications.js
+++ b/www/common/notifications.js
@@ -7,8 +7,7 @@ define([
'/common/common-util.js',
'/common/common-constants.js',
'/customize/messages.js',
- '/bower_components/nthen/index.js'
-], function($, h, Hash, UI, UIElements, Util, Constants, Messages, nThen) {
+], function($, h, Hash, UI, UIElements, Util, Constants, Messages) {
var handlers = {};
@@ -108,21 +107,13 @@ define([
return Messages._getKey(key, [name, title, teamName]);
};
content.handler = function() {
- var todo = function() {
- common.openURL(msg.content.href);
- defaultDismiss(common, data)();
+ var obj = {
+ p: msg.content.isTemplate ? ['template'] : undefined,
+ t: teamNotification || undefined,
+ pw: msg.content.password || ''
};
- nThen(function(waitFor) {
- if (msg.content.isTemplate) {
- common.sessionStorage.put(Constants.newPadPathKey, ['template'], waitFor());
- }
- if (teamNotification) {
- common.sessionStorage.put(Constants.newPadTeamKey, teamNotification, waitFor());
- }
- common.sessionStorage.put('newPadPassword', msg.content.password || '', waitFor());
- }).nThen(function() {
- todo();
- });
+ common.openURL(Hash.getNewPadURL(msg.content.href, obj));
+ defaultDismiss(common, data)();
};
if (!content.archived) {
content.dismissHandler = defaultDismiss(common, data);
diff --git a/www/common/onlyoffice/inner.js b/www/common/onlyoffice/inner.js
index 103381f62..ce0dbcc3f 100644
--- a/www/common/onlyoffice/inner.js
+++ b/www/common/onlyoffice/inner.js
@@ -114,6 +114,7 @@ define([
};
var getEditor = function () {
+ if (!window.frames || !window.frames[0]) { return; }
return window.frames[0].editor || window.frames[0].editorCell;
};
@@ -416,7 +417,7 @@ define([
clearTimeout(pendingChanges[key]);
delete pendingChanges[key];
});
- if (APP.stopHistory) { APP.history = false; }
+ if (APP.stopHistory || APP.template) { APP.history = false; }
startOO(blob, type, true);
};
@@ -426,14 +427,15 @@ define([
var file = getFileType();
blob.name = (metadataMgr.getMetadataLazy().title || file.doc) + '.' + file.type;
var data = {
- hash: APP.history ? ooChannel.historyLastHash : ooChannel.lastHash,
- index: APP.history ? ooChannel.currentIndex : ooChannel.cpIndex
+ hash: (APP.history || APP.template) ? ooChannel.historyLastHash : ooChannel.lastHash,
+ index: (APP.history || APP.template) ? ooChannel.currentIndex : ooChannel.cpIndex
};
fixSheets();
ooChannel.ready = false;
ooChannel.queue = [];
data.callback = function () {
+ if (APP.template) { APP.template = false; }
resetData(blob, file);
};
@@ -458,15 +460,11 @@ define([
var actions = h('div', [cancel, register, login]);
var modal = UI.cornerPopup(Messages.oo_login, actions, '', {alt: true});
$(register).click(function () {
- common.setLoginRedirect(function () {
- common.gotoURL('/register/');
- });
+ common.setLoginRedirect('register');
modal.delete();
});
$(login).click(function () {
- common.setLoginRedirect(function () {
- common.gotoURL('/login/');
- });
+ common.setLoginRedirect('login');
modal.delete();
});
$(cancel).click(function () {
@@ -1296,6 +1294,13 @@ define([
}
}
+ if (APP.template) {
+ getEditor().setViewModeDisconnect();
+ UI.removeLoadingScreen();
+ makeCheckpoint(true);
+ return;
+ }
+
if (APP.history) {
try {
getEditor().asc_setRestriction(true);
@@ -1829,6 +1834,108 @@ define([
pinImages();
};
+ var loadCp = function (cp, keepQueue) {
+ loadLastDocument(cp, function () {
+ var file = getFileType();
+ var type = common.getMetadataMgr().getPrivateData().ooType;
+ var blob = loadInitDocument(type, true);
+ if (!keepQueue) { ooChannel.queue = []; }
+ resetData(blob, file);
+ }, function (blob, file) {
+ if (!keepQueue) { ooChannel.queue = []; }
+ resetData(blob, file);
+ });
+ };
+
+ var loadTemplate = function (href, pw, parsed) {
+ APP.history = true;
+ APP.template = true;
+ var editor = getEditor();
+ if (editor) { editor.setViewModeDisconnect(); }
+ var content = parsed.content;
+
+ // Get checkpoint
+ var hashes = content.hashes || {};
+ var idx = sortCpIndex(hashes);
+ var lastIndex = idx[idx.length - 1];
+ var lastCp = hashes[lastIndex] || {};
+
+ // Current cp or initial hash (invalid hash ==> initial hash)
+ var toHash = lastCp.hash || 'NONE';
+ // Last hash
+ var fromHash = 'NONE';
+
+ sframeChan.query('Q_GET_HISTORY_RANGE', {
+ href: href,
+ password: pw,
+ channel: content.channel,
+ lastKnownHash: fromHash,
+ toHash: toHash,
+ }, function (err, data) {
+ if (err) { return void console.error(err); }
+ if (!Array.isArray(data.messages)) { return void console.error('Not an array!'); }
+
+ // The first "cp" in history is the empty doc. It doesn't include the first patch
+ // of the history
+ var initialCp = !lastCp.hash;
+
+ var messages = (data.messages || []).slice(initialCp ? 0 : 1);
+
+ ooChannel.queue = messages.map(function (obj) {
+ return {
+ hash: obj.serverHash,
+ msg: JSON.parse(obj.msg)
+ };
+ });
+ ooChannel.historyLastHash = ooChannel.lastHash;
+ ooChannel.currentIndex = ooChannel.cpIndex;
+ loadCp(lastCp, true);
+ });
+ };
+
+ var openTemplatePicker = function () {
+ var metadataMgr = common.getMetadataMgr();
+ var type = metadataMgr.getPrivateData().app;
+ var sframeChan = common.getSframeChannel();
+ var pickerCfgInit = {
+ types: [type],
+ where: ['template'],
+ hidden: true
+ };
+ var pickerCfg = {
+ types: [type],
+ where: ['template'],
+ };
+ var onConfirm = function () {
+ common.openFilePicker(pickerCfg, function (data) {
+ if (data.type !== type) { return; }
+ UI.addLoadingScreen({hideTips: true});
+ sframeChan.query('Q_OO_TEMPLATE_USE', {
+ href: data.href,
+ }, function (err, val) {
+ var parsed;
+ try {
+ parsed = JSON.parse(val);
+ } catch (e) {
+ console.error(e, val);
+ UI.removeLoadingScreen();
+ return void UI.warn(Messages.error);
+ }
+ console.error(data);
+ loadTemplate(data.href, data.password, parsed);
+ });
+ });
+ };
+ sframeChan.query("Q_TEMPLATE_EXIST", type, function (err, data) {
+ if (data) {
+ common.openFilePicker(pickerCfgInit);
+ onConfirm();
+ } else {
+ UI.alert(Messages.template_empty);
+ }
+ });
+ };
+
config.onInit = function (info) {
var privateData = metadataMgr.getPrivateData();
@@ -1850,6 +1957,7 @@ define([
Title.setToolbar(toolbar);
if (window.CP_DEV_MODE) {
+
var $save = common.createButton('save', true, {}, function () {
makeCheckpoint(true);
});
@@ -1866,18 +1974,6 @@ define([
APP.stopHistory = true;
makeCheckpoint(true);
};
- var loadCp = function (cp, keepQueue) {
- loadLastDocument(cp, function () {
- var file = getFileType();
- var type = common.getMetadataMgr().getPrivateData().ooType;
- var blob = loadInitDocument(type, true);
- if (!keepQueue) { ooChannel.queue = []; }
- resetData(blob, file);
- }, function (blob, file) {
- if (!keepQueue) { ooChannel.queue = []; }
- resetData(blob, file);
- });
- };
var onPatch = function (patch) {
// Patch on the current cp
ooChannel.send(JSON.parse(patch.msg));
@@ -1971,6 +2067,10 @@ define([
load: loadSnapshot
});
toolbar.$drawer.append($snapshot);
+
+ // Import template
+ var $template = common.createButton('importtemplate', true, {}, openTemplatePicker);
+ $template.appendTo(toolbar.$drawer);
})();
}
@@ -2129,11 +2229,18 @@ define([
openRtChannel(function () {
setMyId();
oldHashes = JSON.parse(JSON.stringify(content.hashes));
- loadDocument(newDoc, useNewDefault);
initializing = false;
+ common.openPadChat(APP.onLocal);
+
+ if (APP.startWithTemplate) {
+ var template = APP.startWithTemplate;
+ loadTemplate(template.href, template.password, template.content);
+ return;
+ }
+
+ loadDocument(newDoc, useNewDefault);
setEditable(!readOnly);
UI.removeLoadingScreen();
- common.openPadChat(APP.onLocal);
});
};
@@ -2257,8 +2364,11 @@ define([
}));
SFCommon.create(waitFor(function (c) { APP.common = common = c; }));
}).nThen(function (waitFor) {
+ common.getSframeChannel().on('EV_OO_TEMPLATE', function (data) {
+ APP.startWithTemplate = data;
+ });
common.handleNewFile(waitFor, {
- noTemplates: true
+ //noTemplates: true
});
}).nThen(function (/*waitFor*/) {
andThen(common);
diff --git a/www/common/onlyoffice/main.js b/www/common/onlyoffice/main.js
index 83d887548..0560b95bd 100644
--- a/www/common/onlyoffice/main.js
+++ b/www/common/onlyoffice/main.js
@@ -55,7 +55,7 @@ define([
var addData = function (obj) {
obj.ooType = window.location.pathname.replace(/^\//, '').replace(/\/$/, '');
obj.ooVersionHash = version;
- obj.ooForceVersion = localStorage.CryptPad_ooVersion || sessionStorage.CryptPad_ooVersion || "";
+ obj.ooForceVersion = localStorage.CryptPad_ooVersion || "";
};
var addRpc = function (sframeChan, Cryptpad, Utils) {
sframeChan.on('Q_OO_SAVE', function (data, cb) {
diff --git a/www/common/outer/async-store.js b/www/common/outer/async-store.js
index bfbc08b77..62e078050 100644
--- a/www/common/outer/async-store.js
+++ b/www/common/outer/async-store.js
@@ -2647,6 +2647,7 @@ define([
classic: true,
};
var rt = window.rt = Listmap.create(listmapConfig);
+ store.driveSecret = secret;
store.proxy = rt.proxy;
store.loggedIn = typeof(data.userHash) !== "undefined";
@@ -2729,7 +2730,6 @@ define([
* - userHash or anonHash
* Todo in cb
* - LocalStore.setFSHash if needed
- * - sessionStorage.User_Hash
* - stuff with tokenKey
* Event to outer
* - requestLogin
diff --git a/www/common/outer/local-store.js b/www/common/outer/local-store.js
index 774924148..d15c2e8c6 100644
--- a/www/common/outer/local-store.js
+++ b/www/common/outer/local-store.js
@@ -82,19 +82,6 @@ define([
localStorage.setItem(Constants.userNameKey, name);
if (cb) { cb(); }
};
- var eraseTempSessionValues = LocalStore.eraseTempSessionValues = function () {
- // delete sessionStorage values that might have been left over
- // from the main page's /user redirect
- [
- 'login',
- 'login_user',
- 'login_pass',
- 'login_rmb',
- 'register'
- ].forEach(function (k) {
- delete sessionStorage[k];
- });
- };
var logoutHandlers = [];
LocalStore.logout = function (cb, isDeletion) {
[
@@ -104,10 +91,8 @@ define([
'loginToken',
'plan',
].forEach(function (k) {
- sessionStorage.removeItem(k);
localStorage.removeItem(k);
delete localStorage[k];
- delete sessionStorage[k];
});
try {
Object.keys(localStorage || {}).forEach(function (k) {
@@ -122,7 +107,6 @@ define([
if (!LocalStore.getFSHash()) {
LocalStore.setFSHash(Hash.createRandomHash('drive'));
}
- eraseTempSessionValues();
if (!isDeletion) {
logoutHandlers.forEach(function (h) {
diff --git a/www/common/outer/mailbox-handlers.js b/www/common/outer/mailbox-handlers.js
index 573879061..326b4afc7 100644
--- a/www/common/outer/mailbox-handlers.js
+++ b/www/common/outer/mailbox-handlers.js
@@ -2,7 +2,8 @@ define([
'/common/common-messaging.js',
'/common/common-hash.js',
'/common/common-util.js',
-], function (Messaging, Hash, Util) {
+ '/bower_components/chainpad-crypto/crypto.js',
+], function (Messaging, Hash, Util, Crypto) {
// Random timeout between 10 and 30 times your sync time (lag + chainpad sync)
var getRandomTimeout = function (ctx) {
@@ -221,6 +222,11 @@ define([
toRemove = old.data;
}
+ if (content.password) {
+ var key = ctx.store.driveSecret.keys.cryptKey;
+ content.password = Crypto.encrypt(content.password, key);
+ }
+
// Update the data
channels[channel] = {
mode: mode,
@@ -315,6 +321,11 @@ define([
var channel = content.channel || content.teamChannel;
+ if (content.password) {
+ var key = ctx.store.driveSecret.keys.cryptKey;
+ content.password = Crypto.encrypt(content.password, key);
+ }
+
if (addOwners[channel]) { return void cb(true); }
addOwners[channel] = {
type: box.type,
diff --git a/www/common/sframe-channel.js b/www/common/sframe-channel.js
deleted file mode 100644
index a7edf0814..000000000
--- a/www/common/sframe-channel.js
+++ /dev/null
@@ -1,166 +0,0 @@
-// This file provides the API for the channel for talking to and from the sandbox iframe.
-define([
- '/common/sframe-protocol.js',
- '/common/common-util.js'
-], function (SFrameProtocol, Util) {
-
- var mkTxid = function () {
- return Math.random().toString(16).replace('0.', '') + Math.random().toString(16).replace('0.', '');
- };
-
- var create = function (ow, cb, isSandbox, sendData) {
- var otherWindow;
- var evReady = Util.mkEvent(true);
- var handlers = {};
- var queries = {};
-
- // list of handlers which are registered from the other side...
- var insideHandlers = [];
- var callWhenRegistered = {};
-
- var chan = {};
-
- // Send a query. channel.query('Q_SOMETHING', { args: "whatever" }, function (reply) { ... });
- chan.query = function (q, content, cb, opts) {
- if (!otherWindow) { throw new Error('not yet initialized'); }
- if (!SFrameProtocol[q]) {
- throw new Error('please only make queries are defined in sframe-protocol.js');
- }
- opts = opts || {};
- var txid = mkTxid();
- var to = opts.timeout || 30000;
- var timeout = setTimeout(function () {
- delete queries[txid];
- console.log("Timeout making query " + q);
- }, to);
- queries[txid] = function (data, msg) {
- clearTimeout(timeout);
- delete queries[txid];
- cb(undefined, data.content, msg);
- };
- evReady.reg(function () {
- otherWindow.postMessage(JSON.stringify({
- txid: txid,
- content: content,
- q: q
- }), '*');
- });
- };
-
- // Fire an event. channel.event('EV_SOMETHING', { args: "whatever" });
- var event = chan.event = function (e, content) {
- if (!SFrameProtocol[e]) {
- throw new Error('please only fire events that are defined in sframe-protocol.js');
- }
- if (e.indexOf('EV_') !== 0) {
- throw new Error('please only use events (starting with EV_) for event messages');
- }
- evReady.reg(function () {
- otherWindow.postMessage(JSON.stringify({ content: content, q: e }), '*');
- });
- };
-
- // Be notified on query or event. channel.on('EV_SOMETHING', function (args, reply) { ... });
- // If the type is a query, your handler will be invoked with a reply function that takes
- // one argument (the content to reply with).
- chan.on = function (queryType, handler, quiet) {
- if (!SFrameProtocol[queryType]) {
- throw new Error('please only register handlers which are defined in sframe-protocol.js');
- }
- (handlers[queryType] = handlers[queryType] || []).push(function (data, msg) {
- handler(data.content, function (replyContent) {
- if (queryType.indexOf('Q_') !== 0) { throw new Error("replies to events are invalid"); }
- msg.source.postMessage(JSON.stringify({
- txid: data.txid,
- content: replyContent
- }), '*');
- }, msg);
- });
- if (!quiet) {
- event('EV_REGISTER_HANDLER', queryType);
- }
- };
-
- // If a particular handler is registered, call the callback immediately, otherwise it will be called
- // when that handler is first registered.
- // channel.whenReg('Q_SOMETHING', function () { ...query Q_SOMETHING?... });
- chan.whenReg = function (queryType, cb, always) {
- if (!SFrameProtocol[queryType]) {
- throw new Error('please only register handlers which are defined in sframe-protocol.js');
- }
- var reg = always;
- if (insideHandlers.indexOf(queryType) > -1) {
- cb();
- } else {
- reg = true;
- }
- if (reg) {
- (callWhenRegistered[queryType] = callWhenRegistered[queryType] || []).push(cb);
- }
- };
-
- // Same as whenReg except it will invoke every time there is another registration, not just once.
- chan.onReg = function (queryType, cb) { chan.whenReg(queryType, cb, true); };
-
- chan.on('EV_REGISTER_HANDLER', function (content) {
- if (callWhenRegistered[content]) {
- callWhenRegistered[content].forEach(function (f) { f(); });
- delete callWhenRegistered[content];
- }
- insideHandlers.push(content);
- });
- chan.whenReg('EV_REGISTER_HANDLER', evReady.fire);
-
- // Make sure both iframes are ready
- var isReady =false;
- chan.onReady = function (h) {
- if (isReady) {
- return void h();
- }
- if (typeof(h) !== "function") { return; }
- chan.on('EV_RPC_READY', function () { isReady = true; h(); });
- };
- chan.ready = function () {
- chan.whenReg('EV_RPC_READY', function () {
- chan.event('EV_RPC_READY');
- });
- };
-
- var txid;
- window.addEventListener('message', function (msg) {
- var data = JSON.parse(msg.data);
- if (ow !== msg.source) {
- return;
- //console.log("DROP Message from unexpected source");
- //console.log(msg);
- } else if (!otherWindow) {
- otherWindow = ow;
- sendData = sendData || {};
- sendData.txid = data.txid;
- ow.postMessage(JSON.stringify(sendData), '*');
- cb(chan);
- } else if (typeof(data.q) === 'string' && handlers[data.q]) {
- handlers[data.q].forEach(function (f) {
- f(data || JSON.parse(msg.data), msg);
- data = undefined;
- });
- } else if (typeof(data.q) === 'undefined' && queries[data.txid]) {
- queries[data.txid](data, msg);
- } else if (data.txid === txid) {
- // stray message from init
- return;
- } else {
- console.log("DROP Unhandled message");
- console.log(msg);
- }
- });
- if (isSandbox) {
- // we're in the sandbox
- otherWindow = ow;
- evReady.fire();
- cb(chan);
- }
- };
-
- return { create: create };
-});
diff --git a/www/common/sframe-common-outer.js b/www/common/sframe-common-outer.js
index 086841f73..f1fd0ac8d 100644
--- a/www/common/sframe-common-outer.js
+++ b/www/common/sframe-common-outer.js
@@ -26,7 +26,7 @@ define([
};
var AppConfig;
var Test;
- var password;
+ var password, newPadPassword;
var initialPathInDrive;
var burnAfterReading;
@@ -123,6 +123,9 @@ define([
});
SFrameChannel.create(msgEv, postMsg, waitFor(function (sfc) {
Utils.sframeChan = sframeChan = sfc;
+ window.CryptPad_loadingError = function (e) {
+ sfc.event('EV_LOADING_ERROR', e)
+ };
}));
});
window.addEventListener('message', whenReady);
@@ -131,12 +134,28 @@ define([
if (sframeChan) { sframeChan.event('EV_LOADING_INFO', data); }
});
+ try {
+ var parsed = Utils.Hash.parsePadUrl(currentPad.href);
+ var options = parsed.getOptions();
+ if (options.loginOpts) {
+ var loginOpts = Utils.Hash.decodeDataOptions(options.loginOpts);
+ if (loginOpts.createReadme) { Cryptpad.createReadme = true; }
+ if (loginOpts.mergeAnonDrive) { Cryptpad.migrateAnonDrive = true; }
+ // Remove newPadOpts from the hash
+ delete options.loginOpts;
+ currentPad.href = parsed.getUrl(options);
+ currentPad.hash = parsed.hashData.getHash ? parsed.hashData.getHash(options)
+ : '';
+ }
+ } catch (e) { console.error(e); }
+
Cryptpad.ready(waitFor(), {
driveEvents: cfg.driveEvents,
currentPad: currentPad
});
- if (window.history && window.history.replaceState && currentPad.hash) {
+ // Remove the login hash if needed
+ if (window.history && window.history.replaceState && (currentPad.hash || window.location.hash)) {
var nHash = currentPad.hash;
if (!/^#/.test(nHash)) { nHash = '#' + nHash; }
window.history.replaceState({}, window.document.title, nHash);
@@ -196,15 +215,53 @@ define([
}
// Rendered (maybe hidden) hash
var renderedParsed = Utils.Hash.parsePadUrl(window.location.href);
- var ohc = window.onhashchange;
- window.onhashchange = function () {};
- window.location.href = renderedParsed.getUrl(opts);
- window.onhashchange = ohc;
- ohc({reset: true});
+ Cryptpad.setTabHref(renderedParsed.getUrl(opts));
}
}));
};
+ // New pad options
+ var options = parsed.getOptions();
+ if (options.newPadOpts) {
+ try {
+ var newPad = Utils.Hash.decodeDataOptions(options.newPadOpts);
+ Cryptpad.initialTeam = newPad.t;
+ Cryptpad.initialPath = newPad.p;
+ if (newPad.pw) {
+ try {
+ var uHash = Utils.LocalStore.getUserHash();
+ var uSecret = Utils.Hash.getSecrets('drive', uHash);
+ var uKey = uSecret.keys.cryptKey;
+ newPadPassword = Crypto.decrypt(newPad.pw, uKey);
+ } catch (e) { console.error(e); }
+ }
+ if (newPad.d) {
+ Cryptpad.fromFileData = newPad.d;
+ var _parsed1 = Utils.Hash.parsePadUrl(Cryptpad.fromFileData.href);
+ if (_parsed1.hashData.type === 'pad' && _parsed1.type !== parsed.type) {
+ delete Cryptpad.fromFileData;
+ }
+ }
+ } catch (e) {
+ console.error(e, parsed.hashData.newPadOpts);
+ }
+ delete options.newPadOpts;
+
+ currentPad.href = parsed.getUrl(options);
+ currentPad.hash = parsed.hashData.getHash ? parsed.hashData.getHash(options)
+ : '';
+ var version = parsed.hashData.version;
+ parsed = Utils.Hash.parsePadUrl(currentPad.href);
+ Cryptpad.setTabHash(currentPad.hash);
+
+ // If it's a new pad, don't check password
+ if (version === 4) {
+ return void todo();
+ }
+ // Otherwise, continue
+ }
+
+
if (!parsed.hashData) { // No hash, no need to check for a password
return void todo();
}
@@ -335,9 +392,8 @@ define([
password = val;
}), parsed.getUrl());
}).nThen(function (w) {
- if (!password && !stored && sessionStorage.newPadPassword) {
- passwordCfg.value = sessionStorage.newPadPassword;
- delete sessionStorage.newPadPassword;
+ if (!password && !stored && newPadPassword) {
+ passwordCfg.value = newPadPassword;
}
if (parsed.type === "file") {
@@ -357,7 +413,7 @@ define([
waitFor.abort();
return;
}
- if (!isNew) { return void todo(); }
+ if (!e && !isNew) { return void todo(); }
if (parsed.hashData.mode === 'view' && (password || !parsed.hashData.password)) {
// Error, wrong password stored, the view seed has changed with the password
// password will never work
@@ -422,9 +478,6 @@ define([
var defaultTitle = Utils.UserObject.getDefaultName(parsed);
var edPublic, curvePublic, notifications, isTemplate;
var settings = {};
- var forceCreationScreen = cfg.useCreationScreen &&
- sessionStorage[Utils.Constants.displayPadCreationScreen];
- delete sessionStorage[Utils.Constants.displayPadCreationScreen];
var isSafe = ['debug', 'profile', 'drive', 'teams'].indexOf(currentPad.app) !== -1;
var updateMeta = function () {
//console.log('EV_METADATA_UPDATE');
@@ -457,6 +510,8 @@ define([
fileHost: ApiConfig.fileHost,
readOnly: readOnly,
isTemplate: isTemplate,
+ newTemplate: Array.isArray(Cryptpad.initialPath)
+ && Cryptpad.initialPath[0] === "template",
feedbackAllowed: Utils.Feedback.state,
isPresent: parsed.hashData && parsed.hashData.present,
isEmbed: parsed.hashData && parsed.hashData.embed,
@@ -467,7 +522,6 @@ define([
},
isNewFile: isNewFile,
isDeleted: isNewFile && currentPad.hash.length > 0,
- forceCreationScreen: forceCreationScreen,
password: password,
channel: secret.channel,
enableSF: localStorage.CryptPad_SF === "1", // TODO to remove when enabled by default
@@ -508,18 +562,10 @@ define([
sframeChan.onReg('EV_METADATA_UPDATE', updateMeta);
Utils.LocalStore.onLogin(function () {
- var ohc = window.onhashchange;
- window.onhashchange = function () {};
- window.location.hash = currentPad.hash;
- window.onhashchange = ohc;
- ohc({reset: true});
+ Cryptpad.setTabHash(currentPad.hash);
});
Utils.LocalStore.onLogout(function () {
- var ohc = window.onhashchange;
- window.onhashchange = function () {};
- window.location.hash = currentPad.hash;
- window.onhashchange = ohc;
- ohc({reset: true});
+ Cryptpad.setTabHash(currentPad.hash);
sframeChan.event('EV_LOGOUT');
});
@@ -603,9 +649,10 @@ define([
Cryptpad.mailbox.execCommand(data, cb);
});
- sframeChan.on('Q_SET_LOGIN_REDIRECT', function (data, cb) {
- sessionStorage.redirectTo = currentPad.href;
- cb();
+ sframeChan.on('EV_SET_LOGIN_REDIRECT', function (page) {
+ var href = Utils.Hash.hashToHref('', page);
+ var url = Utils.Hash.getNewPadURL(href, { href: currentPad.href });
+ window.location.href = url;
});
sframeChan.on('Q_STORE_IN_TEAM', function (data, cb) {
@@ -1033,11 +1080,10 @@ define([
password: password,
title: currentTitle
};
- sessionStorage[Utils.Constants.newPadFileData] = JSON.stringify(data);
- window.open(window.location.pathname);
- setTimeout(function () {
- delete sessionStorage[Utils.Constants.newPadFileData];
- }, 100);
+ var obj = { d: data };
+ var href = window.location.pathname;
+ var url = Utils.Hash.getNewPadURL(href, obj);
+ window.open(url);
});
// Messaging
@@ -1097,6 +1143,10 @@ define([
nSecret = Utils.Hash.getSecrets('drive', hash, password);
}
}
+ if (data.href) {
+ var _parsed = Utils.Hash.parsePadUrl(data.href);
+ nSecret = Utils.Hash.getSecrets(_parsed.type, _parsed.hash, data.password);
+ }
var channel = nSecret.channel;
var validate = nSecret.keys.validateKey;
var crypto = Crypto.createEncryptor(nSecret.keys);
@@ -1131,15 +1181,6 @@ define([
});
});
- sframeChan.on('Q_SESSIONSTORAGE_PUT', function (data, cb) {
- if (typeof (data.value) === "undefined") {
- delete sessionStorage[data.key];
- } else {
- sessionStorage[data.key] = data.value;
- }
- cb();
- });
-
sframeChan.on('Q_IS_ONLY_IN_SHARED_FOLDER', function (data, cb) {
Cryptpad.isOnlyInSharedFolder(secret.channel, function (err, t) {
if (err) { return void cb({error: err}); }
@@ -1163,11 +1204,7 @@ define([
var hiddenParsed = Utils.Hash.parsePadUrl(window.location.href);
// Update the hash in the address bar
- var ohc = window.onhashchange;
- window.onhashchange = function () {};
- window.location.href = hiddenParsed.getUrl(opts);
- window.onhashchange = ohc;
- ohc({reset: true});
+ Cryptpad.setTabHref(hiddenParsed.getUrl(opts));
});
@@ -1277,6 +1314,10 @@ define([
sframeChan.on('Q_TEMPLATE_USE', function (data, cb) {
Cryptpad.useTemplate(data, Cryptget, cb);
});
+ sframeChan.on('Q_OO_TEMPLATE_USE', function (data, cb) {
+ data.oo = true;
+ Cryptpad.useTemplate(data, Cryptget, cb);
+ });
sframeChan.on('Q_TEMPLATE_EXIST', function (type, cb) {
Cryptpad.listTemplates(type, function (err, templates) {
cb(templates.length > 0);
@@ -1514,11 +1555,7 @@ define([
// 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});
+ Cryptpad.setTabHref(currentPad.href);
});
// Join the netflux channel
@@ -1602,13 +1639,9 @@ define([
Utils.crypto = Utils.Crypto.createEncryptor(Utils.secret.keys);
// Update the hash in the address bar
- var ohc = window.onhashchange;
- window.onhashchange = function () {};
- window.location.hash = newHash;
currentPad.hash = newHash;
currentPad.href = '/' + parsed.type + '/#' + newHash;
- window.onhashchange = ohc;
- ohc({reset: true});
+ Cryptpad.setTabHash(newHash);
// Update metadata values and send new metadata inside
parsed = Utils.Hash.parsePadUrl(currentPad.href);
@@ -1639,19 +1672,44 @@ define([
rtConfig.metadata.validateKey = (secret.keys && secret.keys.validateKey) || undefined;
Utils.rtConfig = rtConfig;
+ var templatePw;
nThen(function(waitFor) {
if (data.templateId) {
if (data.templateId === -1) {
+ isTemplate = true;
initialPathInDrive = ['template'];
return;
}
Cryptpad.getPadData(data.templateId, waitFor(function (err, d) {
data.template = d.href;
+ templatePw = d.password;
}));
}
}).nThen(function () {
var cryptputCfg = $.extend(true, {}, rtConfig, {password: password});
if (data.template) {
+ // Start OO with a template...
+ // Cryptget and give href, password and content to inner
+ if (parsed.type === "sheet") {
+ var then = function () {
+ startRealtime(rtConfig);
+ cb();
+ };
+ var _parsed = Utils.Hash.parsePadUrl(data.template);
+ Cryptget.get(_parsed.hash, function (err, val) {
+ if (err || !val) { return void then(); }
+ try {
+ var parsed = JSON.parse(val);
+ sframeChan.event('EV_OO_TEMPLATE', {
+ href: data.template,
+ password: templatePw,
+ content: parsed
+ });
+ } catch (e) { console.error(e); }
+ then();
+ }, {password: templatePw});
+ return;
+ }
// Pass rtConfig to useTemplate because Cryptput will create the file and
// we need to have the owners and expiration time in the first line on the
// server
diff --git a/www/common/sframe-common.js b/www/common/sframe-common.js
index f7a2c41c3..3eb86ff93 100644
--- a/www/common/sframe-common.js
+++ b/www/common/sframe-common.js
@@ -307,9 +307,8 @@ define([
ctx.sframeChan.event('EV_SET_HASH', hash);
};
- funcs.setLoginRedirect = function (cb) {
- cb = cb || $.noop;
- ctx.sframeChan.query('Q_SET_LOGIN_REDIRECT', null, cb);
+ funcs.setLoginRedirect = function (page) {
+ ctx.sframeChan.query('EV_SET_LOGIN_REDIRECT', page);
};
funcs.isPresentUrl = function (cb) {
@@ -463,15 +462,6 @@ define([
});
};
- funcs.sessionStorage = {
- put: function (key, value, cb) {
- ctx.sframeChan.query('Q_SESSIONSTORAGE_PUT', {
- key: key,
- value: value
- }, cb);
- }
- };
-
funcs.setDisplayName = function (name, cb) {
cb = cb || $.noop;
ctx.sframeChan.query('Q_SETTINGS_SET_DISPLAY_NAME', name, cb);
@@ -758,9 +748,7 @@ define([
var mustLogin = privateData.registeredOnly;
if (mustLogin) {
UI.alert(Messages.mustLogin, function () {
- funcs.setLoginRedirect(function () {
- funcs.gotoURL('/login/');
- });
+ funcs.setLoginRedirect('login');
}, {forefront: true});
return;
}
diff --git a/www/common/sframe-protocol.js b/www/common/sframe-protocol.js
deleted file mode 100644
index 5eb9d829e..000000000
--- a/www/common/sframe-protocol.js
+++ /dev/null
@@ -1,271 +0,0 @@
-// This file defines all of the RPC calls which are used between the inner and outer iframe.
-// Define *querys* (which expect a response) using Q_
-// Define *events* (which expect no response) using EV_
-// Please document the queries and events you create, and please please avoid making generic
-// "do stuff" events/queries which are used for many different things because it makes the
-// protocol unclear.
-//
-// WARNING: At this point, this protocol is still EXPERIMENTAL. This is not it's final form.
-// We need to define protocol one piece at a time and then when we are satisfied that we
-// fully understand the problem, we will define the *right* protocol and this file will be dynomited.
-//
-define({
- // When the iframe first launches, this query is sent repeatedly by the controller
- // to wait for it to awake and give it the requirejs config to use.
- 'Q_INIT': true,
-
- // When either the outside or inside registers a query handler, this is sent.
- 'EV_REGISTER_HANDLER': true,
-
- // When an iframe is ready to receive messages
- 'EV_RPC_READY': true,
-
- // Realtime events called from the outside.
- // When someone joins the pad, argument is a string with their netflux id.
- 'EV_RT_JOIN': true,
- // When someone leaves the pad, argument is a string with their netflux id.
- 'EV_RT_LEAVE': true,
- // When you have been disconnected, no arguments.
- 'EV_RT_DISCONNECT': true,
- // When you have connected, argument is an object with myID: string, members: list, readOnly: boolean.
- 'EV_RT_CONNECT': true,
- // Called after the history is finished synchronizing, no arguments.
- 'EV_RT_READY': true,
- // Called when the server returns an error in a pad (EEXPIRED, EDELETED).
- 'EV_RT_ERROR': true,
- // Called from both outside and inside, argument is a (string) chainpad message.
- 'Q_RT_MESSAGE': true,
-
- // Called from the outside, this informs the inside whenever the user's data has been changed.
- // The argument is the object representing the content of the user profile minus the netfluxID
- // which changes per-reconnect.
- 'EV_METADATA_UPDATE': true,
-
- // Takes one argument only, the title to set for the CURRENT pad which the user is looking at.
- // This changes the pad title in drive ONLY, the pad title needs to be changed inside of the
- // iframe and synchronized with the other users. This will not trigger a EV_METADATA_UPDATE
- // because the metadata contained in EV_METADATA_UPDATE does not contain the pad title.
- // It also sets the page (tab) title to the selected title, unles it is overridden by
- // the EV_SET_TAB_TITLE event.
- 'Q_SET_PAD_TITLE_IN_DRIVE': true,
- // Set the page title (tab title) to the selected value which will override the pad title.
- // The new title value can contain {title}, which will be replaced by the pad title when it
- // is set or modified.
- 'EV_SET_TAB_TITLE': true,
-
- // Update the user's display-name which will be shown to contacts and people in the same pads.
- 'Q_SETTINGS_SET_DISPLAY_NAME': true,
-
- // Log the user out in all the tabs
- 'Q_LOGOUT': true,
- // Tell the user that he has been logged out from outside (probably from another tab)
- 'EV_LOGOUT': true,
-
- // When moving to the login or register page from a pad, we need to redirect to that pad at the
- // end of the login process. This query set the current href to the sessionStorage.
- 'Q_SET_LOGIN_REDIRECT': true,
-
- // Store the editing or readonly link of the current pad to the clipboard (share button).
- 'Q_STORE_LINK_TO_CLIPBOARD': true,
-
- // Use anonymous rpc from inside the iframe (for avatars & pin usage).
- 'Q_ANON_RPC_MESSAGE': true,
-
- // Get the user's pin limit, usage and plan
- 'Q_PIN_GET_USAGE': true,
-
- // Write/update the login block when the account password is changed
- 'Q_WRITE_LOGIN_BLOCK': true,
-
- // Remove login blocks
- 'Q_REMOVE_LOGIN_BLOCK': true,
-
- // Check the pin limit to determine if we can store the pad in the drive or if we should.
- // display a warning
- 'Q_GET_PIN_LIMIT_STATUS': true,
-
- // Move a pad to the trash when using the forget button.
- 'Q_MOVE_TO_TRASH': true,
-
- // Request the full history from the server when the users clicks on the history button.
- // Callback is called when the FULL_HISTORY_END message is received in the outside.
- 'Q_GET_FULL_HISTORY': true,
- 'Q_GET_HISTORY_RANGE': true,
- // When a (full) history message is received from the server.
- 'EV_RT_HIST_MESSAGE': true,
-
- // Save a pad as a template using the toolbar button
- 'Q_SAVE_AS_TEMPLATE': true,
-
- // Friend requests from the userlist
- 'Q_SEND_FRIEND_REQUEST': true, // Up query
- 'Q_INCOMING_FRIEND_REQUEST': true, // Down query
- 'EV_FRIEND_REQUEST': true, // Down event when the request is complete
-
- // Set the tab notification when the content of the pad changes
- 'EV_NOTIFY': true,
-
- // Send the new settings to the inner iframe when they are changed in the proxy
- 'EV_SETTINGS_UPDATE': true,
-
- // Get and set (pad) attributes stored in the drive from the inner iframe
- 'Q_GET_ATTRIBUTE': true,
- 'Q_SET_ATTRIBUTE': true,
- 'Q_GET_PAD_ATTRIBUTE': true,
- 'Q_SET_PAD_ATTRIBUTE': true,
-
- // Check if a pad is only in a shared folder or (also) in the main drive.
- // This allows us to change the behavior of some buttons (trash icon...)
- 'Q_IS_ONLY_IN_SHARED_FOLDER': true,
-
- // Open/close the File picker (sent from the iframe to the outside)
- 'EV_FILE_PICKER_OPEN': true,
- 'EV_FILE_PICKER_CLOSE': true,
- 'EV_FILE_PICKER_REFRESH': true,
- // File selected in the file picker: sent from the filepicker iframe to the outside
- // and then send to the inner iframe
- 'EV_FILE_PICKED': true,
-
- // Get all the files from the drive to display them in a file picker secure app
- 'Q_GET_FILES_LIST': true,
-
- // Template picked, replace the content of the pad
- 'Q_TEMPLATE_USE': true,
- // Check if we have template(s) for the selected pad type
- 'Q_TEMPLATE_EXIST': true,
-
- // File upload queries and events
- 'Q_UPLOAD_FILE': true,
- 'EV_FILE_UPLOAD_STATE': true,
- 'Q_CANCEL_PENDING_FILE_UPLOAD': true,
-
- // Make the browser window navigate to a given URL, if no URL is passed then it will reload.
- 'EV_GOTO_URL': true,
- // Make the parent window open a given URL in a new tab. It allows us to keep sessionStorage
- // form the parent window.
- 'EV_OPEN_URL': true,
-
- // Present mode URL
- 'Q_PRESENT_URL_GET_VALUE': true,
- 'EV_PRESENT_URL_SET_VALUE': true,
-
- // Put one or more entries to the cache which will go in localStorage.
- // Cache is wiped after each new release
- 'EV_CACHE_PUT': true,
-
- // Chat
- 'EV_CHAT_EVENT': true,
- 'Q_CHAT_COMMAND': true,
- 'Q_CHAT_OPENPADCHAT': true,
-
- // Cursor
- 'EV_CURSOR_EVENT': true,
- 'Q_CURSOR_COMMAND': true,
- 'Q_CURSOR_OPENCHANNEL': true,
-
- // Put one or more entries to the localStore which will go in localStorage.
- 'EV_LOCALSTORE_PUT': true,
- // Put one entry in the parent sessionStorage
- 'Q_SESSIONSTORAGE_PUT': true,
-
- // Merge the anonymous drive (FS_hash) into the current logged in user's drive, to keep the pads
- // in the drive at registration.
- 'Q_MERGE_ANON_DRIVE': true,
-
- // Add or remove the avatar from the profile.
- // We have to pin/unpin the avatar and store/remove the value from the user object
- 'Q_PROFILE_AVATAR_ADD': true,
- 'Q_PROFILE_AVATAR_REMOVE': true,
-
- // Store outside and get thumbnails inside (stored with localForage (indexedDB) outside)
- 'Q_THUMBNAIL_SET': true,
- 'Q_THUMBNAIL_GET': true,
-
- // Settings app only
- // Clear all thumbnails
- 'Q_THUMBNAIL_CLEAR': true,
- // Backup and restore a drive
- 'Q_SETTINGS_DRIVE_GET': true,
- 'Q_SETTINGS_DRIVE_SET': true,
- 'Q_SETTINGS_DRIVE_RESET': true,
- // Logout from all the devices where the account is logged in
- 'Q_SETTINGS_LOGOUT': true,
- // Import pads from this computer's anon session into the current user account
- 'Q_SETTINGS_IMPORT_LOCAL': true,
- 'Q_SETTINGS_DELETE_ACCOUNT': true,
-
- // Store the language selected in the iframe into localStorage outside
- 'Q_LANGUAGE_SET': true,
-
- // Anonymous users can empty their drive and remove FS_hash from localStorage
- 'EV_BURN_ANON_DRIVE': true,
- // Inner drive needs to send command and receive updates from the async store
- 'Q_DRIVE_USEROBJECT': true,
- 'Q_DRIVE_GETOBJECT': true,
- 'Q_DRIVE_RESTORE': true,
- // Get the pads deleted from the server by other users to remove them from the drive
- 'Q_DRIVE_GETDELETED': true,
- // Store's userObject need to send log messages to inner to display them in the UI
- 'EV_DRIVE_LOG': true,
- // Refresh the drive when the drive has changed ('change' or 'remove' events)
- 'EV_DRIVE_CHANGE': true,
- 'EV_DRIVE_REMOVE': true,
- // Set shared folder hash in the address bar
- 'EV_DRIVE_SET_HASH': true,
-
- // Remove an owned pad from the server
- 'Q_REMOVE_OWNED_CHANNEL': true,
- // Clear an owned pad from the server (preserve metadata)
- 'Q_CLEAR_OWNED_CHANNEL': true,
-
- // Notifications about connection and disconnection from the network
- 'EV_NETWORK_DISCONNECT': true,
- 'EV_NETWORK_RECONNECT': true,
- // Reload on new version
- 'EV_NEW_VERSION': true,
-
- // Pad creation screen: create a pad with the selected attributes (owned, expire)
- 'Q_CREATE_PAD': true,
- // Get the available templates
- 'Q_CREATE_TEMPLATES': true,
-
- // This is for sending data out of the iframe when we are in testing mode
- // The exact protocol is defined in common/test.js
- 'EV_TESTDATA': true,
-
- // OnlyOffice: save a new version
- 'Q_OO_SAVE': true,
-
- // Ask for the pad password when a pad is protected
- 'EV_PAD_PASSWORD': true,
- 'Q_PAD_PASSWORD_VALUE': true,
- // Change pad password
- 'Q_PAD_PASSWORD_CHANGE': true,
-
- // Migrate drive to owned drive
- 'Q_CHANGE_USER_PASSWORD': true,
-
- // Loading events to display in the loading screen
- 'EV_LOADING_INFO': true,
- // Critical error outside the iframe during loading screen
- 'EV_LOADING_ERROR': true,
-
- // Chrome 68 bug...
- 'EV_CHROME_68': true,
-
- // Get all existing tags
- 'Q_GET_ALL_TAGS': true,
-
- // Store pads in the drive
- 'EV_AUTOSTORE_DISPLAY_POPUP': true,
- 'Q_AUTOSTORE_STORE': true,
- 'Q_IS_PAD_STORED': true,
-
- // Import mediatag from a pad
- 'Q_IMPORT_MEDIATAG': true,
-
- // Ability to get a pad's content from its hash
- 'Q_CRYPTGET': true,
- 'EV_CRYPTGET_DISCONNECT': true,
-
-});
diff --git a/www/common/toolbar.js b/www/common/toolbar.js
index b3187571a..90cd0ff08 100644
--- a/www/common/toolbar.js
+++ b/www/common/toolbar.js
@@ -773,15 +773,11 @@ MessengerUI, Messages) {
]);
$msg.find('a.cp-pnp-login').click(function (ev) {
ev.preventDefault();
- Common.setLoginRedirect(function () {
- window.parent.location = o + '/login/';
- });
+ Common.setLoginRedirect('login');
});
$msg.find('a.cp-pnp-register').click(function (ev) {
ev.preventDefault();
- Common.setLoginRedirect(function () {
- window.parent.location = o + '/register/';
- });
+ Common.setLoginRedirect('register');
});
$('.cp-toolbar-top').append($msg);
//UI.addTooltips();
diff --git a/www/common/translations/messages.fi.json b/www/common/translations/messages.fi.json
index 3b5835ff7..fe4ee1f64 100644
--- a/www/common/translations/messages.fi.json
+++ b/www/common/translations/messages.fi.json
@@ -188,12 +188,12 @@
"help_button": "Ohje",
"historyText": "Historia",
"historyButton": "Näytä asiakirjan historia",
- "history_next": "Uudempi versio",
- "history_prev": "Vanhempi versio",
+ "history_next": "Seuraava versio",
+ "history_prev": "Edellinen versio",
"history_loadMore": "Lataa lisää historiatietoja",
"history_closeTitle": "Sulje historia",
"history_restoreTitle": "Palauta asiakirjan valittu versio",
- "history_restorePrompt": "Oletko varma, että haluat korvata asiakirjan nykyisen version esitetyllä versiolla?",
+ "history_restorePrompt": "Oletko varma, että haluat korvata asiakirjan tämänhetkisen version näytetyllä versiolla?",
"history_restoreDone": "Asiakirja palautettu",
"history_version": "Versio:",
"openLinkInNewTab": "Avaa linkki uuteen välilehteen",
@@ -452,7 +452,7 @@
"settings_backupHint": "Varmuuskopioi tai palauta CryptDrivesi sisältö kokonaisuudessaan. Varmuuskopio ei sisällä padiesi sisältöä, ainoastaan niiden käyttöön tarvittavat avaimet.",
"settings_backup": "Varmuuskopioi",
"settings_restore": "Palauta",
- "settings_backupHint2": "Lataa kaikkien padiesi nykyinen sisältö. Padit ladataan luettavassa tiedostomuodossa, jos sellainen on saatavilla.",
+ "settings_backupHint2": "Lataa kaikkien asiakirjojen nykyinen sisältö tietokoneellesi. Asiakirjat ladataan muissa sovelluksissa toimivissa tiedostomuodoissa, jos se on mahdollista. Jos sopivaa tiedostomuotoa ei ole saatavilla, asiakirjat ladataan CryptPad-yhteensopivassa tiedostomuodossa.",
"settings_backup2": "Lataa oma CryptDrive tietokoneellesi",
"settings_backup2Confirm": "Tämä lataa kaikki CryptDrivesi padit ja tiedostot tietokoneellesi. Jos haluat jatkaa, valitse nimi ja paina OK",
"settings_exportTitle": "Vie oma CryptDrive",
@@ -1176,9 +1176,9 @@
"settings_safeLinksTitle": "Turvalliset linkit",
"settings_cat_security": "Luottamuksellisuus",
"imprint": "Oikeudellinen huomautus",
- "oo_sheetMigration_anonymousEditor": "Taulukon muokkaaminen on poistettu käytöstä anonyymeille käyttäjille, kunnes rekisteröitynyt käyttäjä päivittää sen viimeisimpään versioon.",
+ "oo_sheetMigration_anonymousEditor": "Rekisteröitymättömät käyttäjät eivät voi muokata taulukkoa ennen kuin rekisteröitynyt käyttäjä päivittää sen viimeisimpään versioon.",
"oo_sheetMigration_complete": "Päivitetty versio saatavilla, paina OK ladataksesi uudelleen.",
- "oo_sheetMigration_loading": "Päivitetään taulukkoasi viimeisimpään versioon",
+ "oo_sheetMigration_loading": "Päivitetään taulukkoasi viimeisimpään versioon. Ole hyvä ja odota noin 1 minuutti.",
"oo_exportInProgress": "Vienti menossa",
"oo_importInProgress": "Tuonti menossa",
"oo_invalidFormat": "Tätä tiedostoa ei voida tuoda",
@@ -1404,5 +1404,60 @@
"readme_cat1_l2": "Avaa padeja CryptDrivestasi: kaksoisnapsauta padin kuvaketta avataksesi sen.",
"readme_cat1_l1": "Luo padi: Siirry CryptDriveesi, napsauta {0} ja sitten {1}, ja voit luoda padin.",
"readme_cat1": "Tutustu CryptDriveesi",
- "readme_p2": "Tämä padi toimii pikaisena perehdytyksenä CryptPadin ominaisuuksiin - kuinka tehdä muistiinpanoja, järjestellä niitä ja tehdä yhteistyötä niiden parissa."
+ "readme_p2": "Tämä padi toimii pikaisena perehdytyksenä CryptPadin ominaisuuksiin - kuinka tehdä muistiinpanoja, järjestellä niitä ja tehdä yhteistyötä niiden parissa.",
+ "fm_shareFolderPassword": "Suojaa kansio salasanalla (vapaaehtoinen)",
+ "access_destroyPad": "Tuhoa tämä asiakirja tai kansio lopullisesti",
+ "fm_deletedFolder": "Poistettu kansio",
+ "admin_limitUser": "Käyttäjän julkinen avain",
+ "team_exportButton": "Lataa",
+ "team_exportHint": "Lataa kaikki tiimin CryptDriveen tallennetut asiakirjat tietokoneellesi. Asiakirjat ladataan muissa sovelluksissa toimivissa tiedostomuodoissa, jos se on mahdollista. Jos sopivaa tiedostomuotoa ei ole saatavilla, asiakirjat ladataan CryptPad-yhteensopivassa tiedostomuodossa.",
+ "team_exportTitle": "Lataa tiimin CryptDrive",
+ "admin_cat_quota": "Käyttäjätallennustila",
+ "admin_invalLimit": "Virheellinen arvo kiintiökentässä",
+ "admin_invalKey": "Virheellinen julkinen avain",
+ "admin_limitSetNote": "Huomautus",
+ "admin_limitMB": "Kiintiö (megatavuissa)",
+ "admin_setlimitTitle": "Ota mukautettu kiintiö käyttöön",
+ "admin_setlimitHint": "Aseta mukautettu tallennustilakiintiö käyttäjälle tämän julkisen avaimen avulla. Voit päivittää tai poistaa olemassaolevan tallennustilakiintiön.",
+ "admin_limitNote": "Huomautus: {0}",
+ "admin_limitPlan": "Tilaus: {0}",
+ "admin_defaultlimitHint": "Tallennustilakiintiö käyttäjien ja tiimien CryptDriveille, joilla ei ole erikseen määriteltyjä sääntöjä",
+ "admin_defaultlimitTitle": "Tallennustilakiintiö (Mt)",
+ "admin_getlimitsHint": "Listaa muokatut tallennustilakiintiöt, jotka ovat käytössä CryptPad-palvelimellasi.",
+ "admin_getlimitsTitle": "Muokatut tallennustilakiintiöt",
+ "admin_limit": "Nykyinen rajoitus: {0}",
+ "admin_setlimitButton": "Aseta rajoitus",
+ "admin_registrationAllow": "Avaa",
+ "admin_registrationButton": "Sulje",
+ "admin_registrationTitle": "Sulje rekisteröityminen",
+ "admin_registrationHint": "Älä salli uusien käyttäjien rekisteröitymistä",
+ "snapshots_cantMake": "Tilannevedoksen luominen epäonnistui. Yhteytesi on katkennut.",
+ "snapshots_notFound": "Tämä tilannevedos ei ole enää saatavilla, koska asiakirjan historia on poistettu.",
+ "snapshot_error_exists": "Tästä versiosta on jo olemassa tilannevedos",
+ "snapshots_ooPickVersion": "Valitse versio, jotta voit luoda tilannevedoksen",
+ "oo_version": "Versio: ",
+ "oo_version_latest": "Viimeisin",
+ "snapshots_delete": "Poista",
+ "oo_deletedVersion": "Tämä versio ei ole enää saatavilla historiassa.",
+ "snapshots_close": "Sulje",
+ "snapshots_restore": "Palauta",
+ "snapshots_open": "Avaa",
+ "snapshots_placeholder": "Tilannevedoksen otsikko",
+ "snapshots_new": "Uusi tilannevedos",
+ "snapshots_button": "Tilannevedokset",
+ "snaphot_title": "Tilannevedos",
+ "infobar_versionHash": "Katselet asiakirjan vanhaa versiota ({0}).",
+ "history_restoreDriveDone": "CryptDrive palautettu",
+ "history_restoreDrivePrompt": "Oletko varma, että haluat korvata CryptDriven nykyisen version valitulla versiolla?",
+ "history_restoreDriveTitle": "Palauta CryptDrive valitsemaasi versioon",
+ "history_userNext": "Seuraava laatija",
+ "history_fastNext": "Seuraava muokkaussessio",
+ "history_userPrev": "Edellinen laatija",
+ "history_fastPrev": "Edellinen muokkaussessio",
+ "share_versionHash": "Olet jakamassa valitsemasi historiaversion asiakirjastasi vain luku-tilassa. Tämä antaa myös katseluoikeuden asiakirjan kaikkiin versioihin.",
+ "history_shareTitle": "Jaa linkki tähän versioon",
+ "history_cantRestore": "Palauttaminen epäonnistui. Yhteytesi on katkennut.",
+ "history_close": "Sulje",
+ "history_restore": "Palauta",
+ "share_bar": "Luo linkki"
}
diff --git a/www/common/translations/messages.fr.json b/www/common/translations/messages.fr.json
index ce19c96ad..7d8a84efb 100644
--- a/www/common/translations/messages.fr.json
+++ b/www/common/translations/messages.fr.json
@@ -1459,5 +1459,11 @@
"admin_limitUser": "Clé publique de l'utilisateur",
"fm_shareFolderPassword": "Protéger ce dossier avec un mot de passe (optionnel)",
"access_destroyPad": "Détruire ce document ou dossier définitivement",
- "fm_deletedFolder": "Dossier supprimé"
+ "fm_deletedFolder": "Dossier supprimé",
+ "loading_state_5": "Reconstruction du document",
+ "loading_state_4": "Chargement des équipes",
+ "loading_state_3": "Chargement des dossiers partagés",
+ "loading_state_2": "Mise à jour du contenu",
+ "loading_state_1": "Chargement du drive",
+ "loading_state_0": "Construction de l'interface"
}
diff --git a/www/common/translations/messages.json b/www/common/translations/messages.json
index 010287444..fa96fc5a7 100644
--- a/www/common/translations/messages.json
+++ b/www/common/translations/messages.json
@@ -1459,5 +1459,13 @@
"admin_limitUser": "User's public key",
"fm_deletedFolder": "Deleted folder",
"access_destroyPad": "Destroy this document or folder permanently",
- "fm_shareFolderPassword": "Protect this folder with a password (optional)"
+ "fm_shareFolderPassword": "Protect this folder with a password (optional)",
+ "loading_state_0": "Build interface",
+ "loading_state_1": "Load drive",
+ "loading_state_2": "Update content",
+ "loading_state_3": "Load shared folders",
+ "loading_state_4": "Load Teams",
+ "loading_state_5": "Reconstruct document",
+ "tag_add": "Add",
+ "tag_edit": "Edit"
}
diff --git a/www/debug/main.js b/www/debug/main.js
index 68055b1d4..b901beec0 100644
--- a/www/debug/main.js
+++ b/www/debug/main.js
@@ -53,14 +53,9 @@ define([
};
window.addEventListener('message', onMsg);
}).nThen(function (/*waitFor*/) {
- var hash = localStorage[Constants.userHashKey];
+ var hash = localStorage[Constants.userHashKey] || localStorage[Constants.fileHashKey];
var drive = hash && ('#'+hash === window.location.hash);
if (!window.location.hash) {
- if (!hash) {
- sessionStorage.redirectTo = '/debug/';
- window.location.href = '/login/';
- return;
- }
drive = true;
window.location.hash = hash;
} else {
diff --git a/www/drive/main.js b/www/drive/main.js
index 8db013c0f..5eb9dbc67 100644
--- a/www/drive/main.js
+++ b/www/drive/main.js
@@ -46,9 +46,12 @@ define([
window.addEventListener('message', onMsg);
}).nThen(function (/*waitFor*/) {
var afterSecrets = function (Cryptpad, Utils, secret, cb, sframeChan) {
- var _hash = hash.slice(1);
- if (_hash && Utils.LocalStore.isLoggedIn()) {
- // Add a shared folder!
+ var parsed = Utils.Hash.parsePadUrl(href);
+ var isSf = parsed.hashData && parsed.hashData.type === 'pad';
+ if (!isSf) { return void cb(); }
+
+ // SF and logged in: add shared folder
+ if (Utils.LocalStore.isLoggedIn()) {
Cryptpad.addSharedFolder(null, secret, function (id) {
if (id && typeof(id) === "object" && id.error) {
sframeChan.event("EV_RESTRICTED_ERROR");
@@ -65,16 +68,16 @@ define([
cb();
});
return;
- } else if (_hash) {
- var id = Utils.Util.createRandomInteger();
- window.CryptPad_newSharedFolder = id;
- var data = {
- href: Utils.Hash.getRelativeHref(Cryptpad.currentPad.href),
- password: secret.password
- };
- return void Cryptpad.loadSharedFolder(id, data, cb);
}
- cb();
+
+ // Anon shared folder
+ var id = Utils.Util.createRandomInteger();
+ window.CryptPad_newSharedFolder = id;
+ var data = {
+ href: Utils.Hash.getRelativeHref(Cryptpad.currentPad.href),
+ password: secret.password
+ };
+ Cryptpad.loadSharedFolder(id, data, cb);
};
var addRpc = function (sframeChan, Cryptpad, Utils) {
sframeChan.on('EV_BURN_ANON_DRIVE', function () {
diff --git a/www/file/inner.js b/www/file/inner.js
index 81019d0be..b2aef53ed 100644
--- a/www/file/inner.js
+++ b/www/file/inner.js
@@ -231,9 +231,7 @@ define([
if (!common.isLoggedIn()) {
UI.removeLoadingScreen();
return UI.alert(Messages.upload_mustLogin, function () {
- common.setLoginRedirect(function () {
- common.gotoURL('/login/');
- });
+ common.setLoginRedirect('login');
});
}
diff --git a/www/login/main.js b/www/login/main.js
index 40a82b27e..768c012a8 100644
--- a/www/login/main.js
+++ b/www/login/main.js
@@ -67,10 +67,8 @@ define([
});
});
$('#register').on('click', function () {
- if (sessionStorage) {
- if ($uname.val()) {
- sessionStorage.login_user = $uname.val();
- }
+ if ($uname.val()) {
+ localStorage.login_user = $uname.val();
}
window.location.href = '/register/';
});
diff --git a/www/logout/main.js b/www/logout/main.js
index acd8e8b02..d23bb8969 100644
--- a/www/logout/main.js
+++ b/www/logout/main.js
@@ -1,5 +1,4 @@
define(['/bower_components/localforage/dist/localforage.min.js'], function (localForage) {
localForage.clear();
- sessionStorage.clear();
localStorage.clear();
});
diff --git a/www/pad/inner.html b/www/pad/inner.html
index b7ccd4d00..e4dbcdf95 100644
--- a/www/pad/inner.html
+++ b/www/pad/inner.html
@@ -1,5 +1,5 @@
-
+
diff --git a/www/pad/inner.js b/www/pad/inner.js
index 19c2063d8..eeabbb337 100644
--- a/www/pad/inner.js
+++ b/www/pad/inner.js
@@ -47,6 +47,7 @@ define([
'/bower_components/diff-dom/diffDOM.js',
+ 'css!/customize/src/print.css',
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
'less!/pad/app-pad.less'
@@ -500,6 +501,12 @@ define([
var mkPrintButton = function (framework, editor) {
var $printButton = framework._.sfCommon.createButton('print', true);
$printButton.click(function () {
+ /*
+ // NOTE: alternative print system in case we keep having more issues on Firefox
+ var $iframe = $('html').find('iframe');
+ var iframe = $iframe[0].contentWindow;
+ iframe.print();
+ */
editor.execCommand('print');
framework.feedback('PRINT_PAD');
});
diff --git a/www/profile/inner.js b/www/profile/inner.js
index cddae4611..7a872fdd0 100644
--- a/www/profile/inner.js
+++ b/www/profile/inner.js
@@ -611,15 +611,11 @@ define([
var actions = h('div', [cancel, register, login]);
var modal = UI.cornerPopup(Messages.profile_login, actions, '', {alt: true});
$(register).click(function () {
- common.setLoginRedirect(function () {
- common.gotoURL('/register/');
- });
+ common.setLoginRedirect('register');
modal.delete();
});
$(login).click(function () {
- common.setLoginRedirect(function () {
- common.gotoURL('/login/');
- });
+ common.setLoginRedirect('login');
modal.delete();
});
$(cancel).click(function () {
diff --git a/www/register/main.js b/www/register/main.js
index c6e9cd546..58385b6c8 100644
--- a/www/register/main.js
+++ b/www/register/main.js
@@ -37,9 +37,9 @@ define([
var $passwd = $('#password');
var $confirm = $('#password-confirm');
- if (sessionStorage.login_user) {
- delete sessionStorage.login_user;
- $uname.val(sessionStorage.login_user);
+ if (localStorage.login_user) {
+ $uname.val(localStorage.login_user);
+ delete loginStorage.login_user;
}
[ $uname, $passwd, $confirm]
diff --git a/www/secureiframe/inner.js b/www/secureiframe/inner.js
index 344a4fb39..c20d53a80 100644
--- a/www/secureiframe/inner.js
+++ b/www/secureiframe/inner.js
@@ -124,6 +124,7 @@ define([
}
sframeChan.event("EV_SECURE_ACTION", {
type: parsed.type,
+ password: data.password,
href: data.url,
name: data.name
});
diff --git a/www/secureiframe/main.js b/www/secureiframe/main.js
index eca166592..49e94a252 100644
--- a/www/secureiframe/main.js
+++ b/www/secureiframe/main.js
@@ -74,6 +74,7 @@ define([
};
window.addEventListener('message', whenReady);
}).nThen(function () {
+ var isTemplate = config.data.isTemplate;
var updateMeta = function () {
//console.log('EV_METADATA_UPDATE');
var metaObj;
@@ -96,7 +97,7 @@ define([
feedbackAllowed: Utils.Feedback.state,
hashes: config.data.hashes,
password: config.data.password,
- isTemplate: config.data.isTemplate,
+ isTemplate: isTemplate,
file: config.data.file,
};
for (var k in additionalPriv) { metaObj.priv[k] = additionalPriv[k]; }
diff --git a/www/slide/inner.js b/www/slide/inner.js
index 3af7185c5..de30eb9fc 100644
--- a/www/slide/inner.js
+++ b/www/slide/inner.js
@@ -15,6 +15,7 @@ define([
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
+ 'css!/customize/src/print-landscape.css',
'less!/slide/app-slide.less',
'css!cm/lib/codemirror.css',
diff --git a/www/teams/inner.js b/www/teams/inner.js
index 2eb234b12..a75ed94db 100644
--- a/www/teams/inner.js
+++ b/www/teams/inner.js
@@ -1267,14 +1267,10 @@ define([
anonRegister = h('button.btn.btn-secondary', Messages.login_register),
]));
$(anonLogin).click(function () {
- common.setLoginRedirect(function () {
- common.gotoURL('/login/');
- });
+ common.setLoginRedirect('login');
});
$(anonRegister).click(function () {
- common.setLoginRedirect(function () {
- common.gotoURL('/register/');
- });
+ common.setLoginRedirect('register');
});
waitFor.abort();
}).nThen(function () {
@@ -1402,9 +1398,7 @@ define([
var hash = privateData.teamInviteHash;
if (!hash && !driveAPP.loggedIn) {
UI.alert(Messages.mustLogin, function () {
- common.setLoginRedirect(function () {
- common.gotoURL('/login/');
- });
+ common.setLoginRedirect('login');
}, {forefront: true});
return;
}