From 639376f1cb53576bfb8928781e34a05747aa2022 Mon Sep 17 00:00:00 2001 From: ansuz Date: Wed, 1 Mar 2017 12:36:10 +0100 Subject: [PATCH 01/17] don't use hyperjson.toString --- www/pad/main.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/www/pad/main.js b/www/pad/main.js index c3a746d14..a8c3adf50 100644 --- a/www/pad/main.js +++ b/www/pad/main.js @@ -524,13 +524,7 @@ define([ }; var getHTML = function (Dom) { - var data = inner.innerHTML; - Dom = Dom || (new DOMParser()).parseFromString(data,"text/html"); - return ('\n' + - '\n' + - (typeof(Hyperjson.toString) === 'function'? - Hyperjson.toString(Hyperjson.fromDOM(Dom.body)): - Dom.head.outerHTML) + '\n'); + return ('\n' + '\n' + inner.innerHTML); }; var domFromHTML = function (html) { From 26e3971482333749ec9e98182c301226af0e8075 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 1 Mar 2017 13:08:09 +0100 Subject: [PATCH 02/17] Fix XSS in the user dropdown menu --- www/common/cryptpad-common.js | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index c78f938d2..729d0468b 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -163,10 +163,13 @@ define([ // var isArray = function (o) { return Object.prototype.toString.call(o) === '[object Array]'; }; var isArray = common.isArray = $.isArray; - var fixHTML = common.fixHTML = function (html) { - return html.replace(/&"']/g, function (x) { + return ({ "<": "<", ">": ">", "&": "&", '"': """, "'": "'" })[x]; + }); }; + var truncate = common.truncate = function (text, len) { if (typeof(text) === 'string' && text.length > len) { return text.slice(0, len) + '…'; @@ -1142,22 +1145,22 @@ define([ var $displayedName = $('', {'class': config.displayNameCls || 'displayName'}); var accountName = localStorage[common.userNameKey]; var account = isLoggedIn(); - var $userAdminContent = $('

'); - if (account) { - var $userAccount = $('', {'class': 'userAccount'}).append(Messages.user_accountName + ': ' + accountName); - $userAdminContent.append($userAccount); - $userAdminContent.append($('
')); - } var $userName = $('', {'class': 'userDisplayName'}); - if (config.displayName) { - // Hide "Display name:" in read only mode - $userName.append(Messages.user_displayName + ': '); - $userName.append($displayedName.clone()); - } - //$userName.append($displayedName.clone()); TODO remove ? - $userAdminContent.append($userName); var options = []; if (config.displayNameCls) { + var $userAdminContent = $('

'); + if (account) { + var $userAccount = $('', {'class': 'userAccount'}).append(Messages.user_accountName + ': ' + fixHTML(accountName)); + $userAdminContent.append($userAccount); + $userAdminContent.append($('
')); + } + if (config.displayName) { + // Hide "Display name:" in read only mode + $userName.append(Messages.user_displayName + ': '); + $userName.append($displayedName.clone()); + } + //$userName.append($displayedName.clone()); TODO remove ? + $userAdminContent.append($userName); options.push({ tag: 'p', attributes: {'class': 'accountData'}, From 5797aab3f2e09a352301a5e22dc60918fc8b7bde Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 1 Mar 2017 13:08:36 +0100 Subject: [PATCH 03/17] Fix XSS with display names in the user list --- www/common/toolbar.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/www/common/toolbar.js b/www/common/toolbar.js index 1669d8465..ac68e27eb 100644 --- a/www/common/toolbar.js +++ b/www/common/toolbar.js @@ -207,32 +207,35 @@ define([ var anonymous = numberOfEditUsers - editUsersNames.length; // Update the userlist + var $usersTitle = $('

').text(Messages.users); + var $editUsers = $userButtons.find('.' + USERLIST_CLS); + $editUsers.html('').append($usersTitle); + var editUsersList = ''; + var $editUsersList = $('
');
             if (readOnly !== 1) {
-                editUsersNames.unshift('' + Messages.yourself + '');
+                $editUsers.append('' + Messages.yourself + '');
                 anonymous--;
             }
+            if (editUsersNames.length > 0) {
+                $editUsersList.text(editUsersNames.join('\n')); // .text() to avoid XSS
+                $editUsers.append($editUsersList);
+            }
             if (anonymous > 0) {
                 var text = anonymous === 1 ? Messages.anonymousUser : Messages.anonymousUsers;
-                editUsersNames.push('' + anonymous + ' ' + text + '');
+                $editUsers.push('' + anonymous + ' ' + text + '');
             }
             if (numberOfViewUsers > 0) {
                 var viewText = '';
                 if (numberOfEditUsers > 0) {
-                    editUsersNames.push('');
+                    $editUsers.append('
'); viewText += Messages.and + ' '; } var viewerText = numberOfViewUsers !== 1 ? Messages.viewers : Messages.viewer; viewText += numberOfViewUsers + ' ' + viewerText + '
'; - editUsersNames.push(viewText); - } - if (editUsersNames.length > 0) { - editUsersList += editUsersNames.join('
'); + $editUsers.append(viewText); } - var $usersTitle = $('

').text(Messages.users); - var $editUsers = $userButtons.find('.' + USERLIST_CLS); - $editUsers.html('').append($usersTitle).append(editUsersList); // Update the buttons var fa_editusers = ''; From 2c5c6da0d985c7f95a4ef31b79cd09c764ef4f37 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 1 Mar 2017 13:09:14 +0100 Subject: [PATCH 04/17] Fix XSS in alertify logs --- www/common/cryptpad-common.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 729d0468b..896042532 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -1351,11 +1351,11 @@ define([ }; common.log = function (msg) { - Alertify.success(msg); + Alertify.success(fixHTML(msg)); }; common.warn = function (msg) { - Alertify.error(msg); + Alertify.error(fixHTML(msg)); }; /* From 11d54256daf0aec1959dd211bb12984b7fd42f08 Mon Sep 17 00:00:00 2001 From: yflory Date: Wed, 1 Mar 2017 13:10:06 +0100 Subject: [PATCH 05/17] Make sure the display name is displayed in the same way everywhere --- www/drive/main.js | 2 +- www/pad/main.js | 4 ++-- www/poll/main.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/www/drive/main.js b/www/drive/main.js index 94c5d91b2..3aa67815c 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -1940,7 +1940,7 @@ define([ var setName = APP.setName = function (newName) { if (typeof(newName) !== 'string') { return; } - var myUserNameTemp = Cryptpad.fixHTML(newName.trim()); + var myUserNameTemp = newName.trim(); if(myUserNameTemp.length > 32) { myUserNameTemp = myUserNameTemp.substr(0, 32); } diff --git a/www/pad/main.js b/www/pad/main.js index c3a746d14..77ea70b81 100644 --- a/www/pad/main.js +++ b/www/pad/main.js @@ -293,7 +293,7 @@ define([ var setName = module.setName = function (newName) { if (typeof(newName) !== 'string') { return; } - var myUserNameTemp = Cryptpad.fixHTML(newName.trim()); + var myUserNameTemp = newName.trim(); if(myUserNameTemp.length > 32) { myUserNameTemp = myUserNameTemp.substr(0, 32); } @@ -528,7 +528,7 @@ define([ Dom = Dom || (new DOMParser()).parseFromString(data,"text/html"); return ('\n' + '\n' + - (typeof(Hyperjson.toString) === 'function'? + (typeof(Hyperjson.toString) === 'function' ? Hyperjson.toString(Hyperjson.fromDOM(Dom.body)): Dom.head.outerHTML) + '\n'); }; diff --git a/www/poll/main.js b/www/poll/main.js index 69954b409..3e619cb96 100644 --- a/www/poll/main.js +++ b/www/poll/main.js @@ -440,7 +440,7 @@ define([ var setName = APP.setName = function (newName) { if (typeof(newName) !== 'string') { return; } - var myUserNameTemp = Cryptpad.fixHTML(newName.trim()); + var myUserNameTemp = newName.trim(); if(myUserNameTemp.length > 32) { myUserNameTemp = myUserNameTemp.substr(0, 32); } From bd42a7d176276dceeba5e6e49482f855d1cdce3c Mon Sep 17 00:00:00 2001 From: ansuz Date: Wed, 1 Mar 2017 14:36:41 +0100 Subject: [PATCH 06/17] bump hyperjson bower dependency to new major version --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index 5704b3aec..a6fc85b41 100644 --- a/bower.json +++ b/bower.json @@ -29,7 +29,7 @@ "rangy": "rangy-release#~1.3.0", "json.sortify": "~2.1.0", "fabric.js": "fabric#~1.6.0", - "hyperjson": "~1.3.1", + "hyperjson": "~1.4.0", "textpatcher": "^1.3.0", "proxy-polyfill": "^0.1.5", "chainpad": "^0.3.0", From cb5e01815c059a1b98a9ab21bb8f2d0dcfdd225c Mon Sep 17 00:00:00 2001 From: ansuz Date: Wed, 1 Mar 2017 15:07:34 +0100 Subject: [PATCH 07/17] validate all alertify strings by default. require 'force' argument to bypass --- www/common/cryptpad-common.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 896042532..be04d6df2 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -961,7 +961,7 @@ define([ } else { callback(); } - common.alert(Messages.movedToTrash); + common.alert(Messages.movedToTrash, undefined, true); return; }); }); @@ -1292,8 +1292,9 @@ define([ $(window).off('keyup', handler); }; - common.alert = function (msg, cb) { + common.alert = function (msg, cb, force) { cb = cb || function () {}; + if (force !== true) { msg = fixHTML(msg); } var keyHandler = listenForKeys(function (e) { // yes findOKButton().click(); }); @@ -1306,9 +1307,10 @@ define([ }); }; - common.prompt = function (msg, def, cb, opt) { + common.prompt = function (msg, def, cb, opt, force) { opt = opt || {}; cb = cb || function () {}; + if (force !== true) { msg = fixHTML(msg); } var keyHandler = listenForKeys(function (e) { // yes findOKButton().click(); @@ -1329,9 +1331,11 @@ define([ }); }; - common.confirm = function (msg, cb, opt) { + common.confirm = function (msg, cb, opt, force) { opt = opt || {}; cb = cb || function () {}; + if (force !== true) { msg = fixHTML(msg); } + var keyHandler = listenForKeys(function (e) { findOKButton().click(); }, function (e) { From 7db0e14bc0e5ea62028ca09fa69f3c4caad2b3d3 Mon Sep 17 00:00:00 2001 From: ansuz Date: Wed, 1 Mar 2017 17:05:57 +0100 Subject: [PATCH 08/17] add 'force' flag to override removal of html elements --- www/code/main.js | 4 ++-- www/common/cryptpad-common.js | 2 +- www/drive/main.js | 6 +++--- www/pad/main.js | 4 ++-- www/poll/main.js | 2 +- www/settings/main.js | 2 +- www/slide/main.js | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/www/code/main.js b/www/code/main.js index 5ece7a208..e8999ffee 100644 --- a/www/code/main.js +++ b/www/code/main.js @@ -689,7 +689,7 @@ define([ // inform of network disconnect setEditable(false); toolbar.failed(); - Cryptpad.alert(Messages.common_connectionLost); + Cryptpad.alert(Messages.common_connectionLost, undefined, force); }; var onConnectionChange = config.onConnectionChange = function (info) { @@ -700,7 +700,7 @@ define([ toolbar.reconnecting(info.myId); Cryptpad.findOKButton().click(); } else { - Cryptpad.alert(Messages.common_connectionLost); + Cryptpad.alert(Messages.common_connectionLost, undefined, force); } }; diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index be04d6df2..bf0893ae6 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -838,7 +838,7 @@ define([ if (!$('#' + LOADING).is(':visible')) { common.addLoadingScreen(); } $('.spinnerContainer').hide(); if (transparent) { $('#' + LOADING).css('opacity', 0.8); } - $('#' + LOADING).find('p').html(error || Messages.error); + $('#' + LOADING).find('p').text(error || Messages.error); }; /* diff --git a/www/drive/main.js b/www/drive/main.js index 3aa67815c..47d8da2ee 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -1796,7 +1796,7 @@ define([ if (path.length !== 4) { return; } var element = filesOp.getTrashElementData(path); var sPath = stringifyPath(element.path); - Cryptpad.alert('' + Messages.fm_originalPath + ":
" + sPath); + Cryptpad.alert('' + Messages.fm_originalPath + ":
" + sPath, undefined, true); } module.hideMenu(); }); @@ -2058,7 +2058,7 @@ define([ $backupButton.attr('title', Messages.fm_backup_title); $backupButton.on('click', function() { var url = window.location.origin + window.location.pathname + '#' + editHash; - Cryptpad.alert(Messages._getKey('fm_alert_backupUrl', [url])); + Cryptpad.alert(Messages._getKey('fm_alert_backupUrl', [url]), undefined, true); $('#fm_backupUrl').val(url); $('#fm_backupUrl').click(function () { $(this).select(); @@ -2083,7 +2083,7 @@ define([ setEditable(false); if (APP.refresh) { APP.refresh(); } APP.toolbar.failed(); - Cryptpad.alert(Messages.common_connectionLost); + Cryptpad.alert(Messages.common_connectionLost, undefined, true); }; var onReconnect = function (info) { setEditable(true); diff --git a/www/pad/main.js b/www/pad/main.js index 83d8a99cb..28476dd68 100644 --- a/www/pad/main.js +++ b/www/pad/main.js @@ -726,7 +726,7 @@ define([ setEditable(false); // TODO inform them that the session was torn down toolbar.failed(); - Cryptpad.alert(Messages.common_connectionLost); + Cryptpad.alert(Messages.common_connectionLost, undefined, true); }; var onConnectionChange = realtimeOptions.onConnectionChange = function (info) { @@ -737,7 +737,7 @@ define([ toolbar.reconnecting(info.myId); Cryptpad.findOKButton().click(); } else { - Cryptpad.alert(Messages.common_connectionLost); + Cryptpad.alert(Messages.common_connectionLost, undefined, true); } }; diff --git a/www/poll/main.js b/www/poll/main.js index 3e619cb96..d7e391c8b 100644 --- a/www/poll/main.js +++ b/www/poll/main.js @@ -662,7 +662,7 @@ define([ var disconnect = function (info) { //setEditable(false); // TODO - Cryptpad.alert(Messages.common_connectionLost); + Cryptpad.alert(Messages.common_connectionLost, undefined, true); }; var create = function (info) { diff --git a/www/settings/main.js b/www/settings/main.js index 70cf938dc..498b212eb 100644 --- a/www/settings/main.js +++ b/www/settings/main.js @@ -167,7 +167,7 @@ define([ if (val !== "I love CryptPad") { return; } obj.proxy.drive = Cryptpad.getStore().getEmptyObject(); Cryptpad.alert(Messages.settings_resetDone); - }); + }, undefined, true); }); return $div; diff --git a/www/slide/main.js b/www/slide/main.js index 86486227d..ce181b292 100644 --- a/www/slide/main.js +++ b/www/slide/main.js @@ -771,7 +771,7 @@ define([ // inform of network disconnect setEditable(false); toolbar.failed(); - Cryptpad.alert(Messages.common_connectionLost); + Cryptpad.alert(Messages.common_connectionLost, undefined, true); }; var onConnectionChange = config.onConnectionChange = function (info) { @@ -782,7 +782,7 @@ define([ toolbar.reconnecting(info.myId); Cryptpad.findOKButton().click(); } else { - Cryptpad.alert(Messages.common_connectionLost); + Cryptpad.alert(Messages.common_connectionLost, undefined, true); } }; From 9800f036c52f36a18c9e9b94c04e500375747407 Mon Sep 17 00:00:00 2001 From: ansuz Date: Wed, 1 Mar 2017 17:06:18 +0100 Subject: [PATCH 09/17] fix a typo --- customize.dist/translations/messages.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js index cdf113048..23d706a8c 100644 --- a/customize.dist/translations/messages.js +++ b/customize.dist/translations/messages.js @@ -221,7 +221,7 @@ define(function () { out.login_noSuchUser = 'Invalid username or password. Try again, or sign up'; out.login_invalUser = 'Username required'; out.login_invalPass = 'Password required'; - out.login_unhandledError = 'An unexpected error occured :('; + out.login_unhandledError = 'An unexpected error occurred :('; out.register_importRecent = "Import pad history (Recommended)"; out.register_acceptTerms = "I accept the terms of service"; From 91eda5fa83f35628f04a632abf11cc5615efdf4a Mon Sep 17 00:00:00 2001 From: Caleb James DeLisle Date: Wed, 1 Mar 2017 17:23:34 +0100 Subject: [PATCH 10/17] Implement stronger content-security-policy except in /pad/ which does not allow it. Implement a "loader" which allows for applying a version number to everything. Added a cache control for anything which has a version. --- config.js.dist | 41 +++++++++++++-------- customize.dist/about.html | 12 +----- customize.dist/contact.html | 12 +----- customize.dist/index.html | 12 +----- customize.dist/privacy.html | 12 +----- customize.dist/src/fragments/appscript.html | 3 +- customize.dist/src/fragments/empty.html | 1 - customize.dist/src/fragments/script.html | 3 +- customize.dist/src/template.html | 9 +---- customize.dist/terms.html | 12 +----- server.js | 24 ++++++++++-- www/code/index.html | 14 +------ www/common/boot.js | 5 +++ www/common/boot2.js | 6 +++ www/common/cryptpad-common.js | 2 +- www/common/noscriptfix.js | 3 ++ www/drive/index.html | 14 +------ www/drive/main.js | 2 - www/examples/board/index.html | 8 +--- www/examples/canvas/index.html | 5 +-- www/examples/form/index.html | 5 +-- www/examples/hack/index.html | 3 +- www/examples/json/index.html | 3 +- www/examples/read/index.html | 7 +--- www/examples/render/index.html | 4 +- www/examples/style/index.html | 15 ++++---- www/examples/text/index.html | 3 +- www/examples/upload/index.html | 8 +--- www/login/index.html | 10 +---- www/pad/index.html | 14 +------ www/poll/index.html | 6 +-- www/register/index.html | 9 +---- www/settings/index.html | 15 ++------ www/slide/index.html | 14 +------ 34 files changed, 107 insertions(+), 209 deletions(-) create mode 100644 www/common/boot.js create mode 100644 www/common/boot2.js create mode 100644 www/common/noscriptfix.js diff --git a/config.js.dist b/config.js.dist index 91bf38d95..da80bb374 100644 --- a/config.js.dist +++ b/config.js.dist @@ -14,24 +14,35 @@ module.exports = { * Examples are provided below */ -/* httpHeaders: { - "Content-Security-Policy": [ - "default-src 'none'", - "style-src 'unsafe-inline' 'self'", - "script-src 'self' 'unsafe-eval' 'unsafe-inline'", - "child-src 'self' cryptpad.fr *.cryptpad.fr", - "font-src 'self'", - "connect-src 'self' wss://cryptpad.fr", - // data: is used by codemirror, (insecure remote) images are included by - // users of the wysiwyg who embed photos in their pads - "img-src data: *", - ].join('; '), - "X-XSS-Protection": "1; mode=block", "X-Content-Type-Options": "nosniff", // 'X-Frame-Options': 'SAMEORIGIN', - },*/ + }, + + contentSecurity: [ + "default-src 'none'", + "style-src 'unsafe-inline' 'self'", + "script-src 'self'", + "child-src 'self' cryptpad.fr *.cryptpad.fr", + "font-src 'self'", + "connect-src 'self' wss://cryptpad.fr", + // data: is used by codemirror + "img-src 'self' data:", + ].join('; '), + + // CKEditor requires significantly more lax content security policy in order to function. + padContentSecurity: [ + "default-src 'none'", + "style-src 'unsafe-inline' 'self'", + // Unsafe inline, unsafe-eval are needed for ckeditor :( + "script-src 'self' 'unsafe-eval' 'unsafe-inline'", + "child-src 'self' cryptpad.fr *.cryptpad.fr", + "font-src 'self'", + "connect-src 'self' wss://cryptpad.fr", + // (insecure remote) images are included by users of the wysiwyg who embed photos in their pads + "img-src *", + ].join('; '), httpPort: 3000, @@ -51,7 +62,7 @@ module.exports = { //websocketPort: 3000, /* if you want to run a different version of cryptpad but using the same websocket - * server, you should use the other server port as websocketPort and disable + * server, you should use the other server port as websocketPort and disable * the websockets on that server */ //useExternalWebsocket: false, diff --git a/customize.dist/about.html b/customize.dist/about.html index c0f3a0b97..988efafc3 100644 --- a/customize.dist/about.html +++ b/customize.dist/about.html @@ -1,5 +1,6 @@ + Cryptpad: Zero Knowledge, Collaborative Real Time Editing @@ -9,16 +10,8 @@ - + - - -
@@ -126,4 +119,3 @@ - diff --git a/customize.dist/contact.html b/customize.dist/contact.html index 7b2cd03ae..1985d8347 100644 --- a/customize.dist/contact.html +++ b/customize.dist/contact.html @@ -1,5 +1,6 @@ + Cryptpad: Zero Knowledge, Collaborative Real Time Editing @@ -9,16 +10,8 @@ - + - - -
@@ -123,4 +116,3 @@ - diff --git a/customize.dist/index.html b/customize.dist/index.html index eb1815e34..12697787e 100644 --- a/customize.dist/index.html +++ b/customize.dist/index.html @@ -1,5 +1,6 @@ + Cryptpad: Zero Knowledge, Collaborative Real Time Editing @@ -9,16 +10,8 @@ - + - - -
@@ -245,4 +238,3 @@ - diff --git a/customize.dist/privacy.html b/customize.dist/privacy.html index 10910bfff..403a0f1c4 100644 --- a/customize.dist/privacy.html +++ b/customize.dist/privacy.html @@ -1,5 +1,6 @@ + Cryptpad: Zero Knowledge, Collaborative Real Time Editing @@ -9,16 +10,8 @@ - + - - -
@@ -144,4 +137,3 @@ - diff --git a/customize.dist/src/fragments/appscript.html b/customize.dist/src/fragments/appscript.html index 66cc0acea..3f1dd7b58 100644 --- a/customize.dist/src/fragments/appscript.html +++ b/customize.dist/src/fragments/appscript.html @@ -1,3 +1,2 @@ - - + diff --git a/customize.dist/src/fragments/empty.html b/customize.dist/src/fragments/empty.html index 05fd6a0cb..d42a450af 100644 --- a/customize.dist/src/fragments/empty.html +++ b/customize.dist/src/fragments/empty.html @@ -1,2 +1 @@ -
diff --git a/customize.dist/src/fragments/script.html b/customize.dist/src/fragments/script.html index 99ea023b5..35a65e8a1 100644 --- a/customize.dist/src/fragments/script.html +++ b/customize.dist/src/fragments/script.html @@ -1,2 +1 @@ - - + diff --git a/customize.dist/src/template.html b/customize.dist/src/template.html index 314fa29f9..069e23511 100644 --- a/customize.dist/src/template.html +++ b/customize.dist/src/template.html @@ -1,5 +1,6 @@ + Cryptpad: Zero Knowledge, Collaborative Real Time Editing @@ -10,13 +11,6 @@ {{script}} - - {{topbar}} @@ -30,4 +24,3 @@ {{footer}} - diff --git a/customize.dist/terms.html b/customize.dist/terms.html index 205f6c2a7..a92c99c93 100644 --- a/customize.dist/terms.html +++ b/customize.dist/terms.html @@ -1,5 +1,6 @@ + Cryptpad: Zero Knowledge, Collaborative Real Time Editing @@ -9,16 +10,8 @@ - + - - -
@@ -127,4 +120,3 @@ - diff --git a/server.js b/server.js index 548a78949..503558c1f 100644 --- a/server.js +++ b/server.js @@ -7,6 +7,7 @@ var Https = require('https'); var Fs = require('fs'); var WebSocketServer = require('ws').Server; var NetfluxSrv = require('./NetfluxWebsocketSrv'); +var Package = require('./package.json'); var config = require('./config'); var websocketPort = config.websocketPort || config.httpPort; @@ -19,20 +20,31 @@ var app = Express(); var httpsOpts; +const clone = (x) => (JSON.parse(JSON.stringify(x))); + var setHeaders = (function () { if (typeof(config.httpHeaders) !== 'object') { return function () {}; } - var headers = JSON.parse(JSON.stringify(config.httpHeaders)); + const headers = clone(config.httpHeaders); + if (config.contentSecurity) { + headers['Content-Security-Policy'] = clone(config.contentSecurity); + } + const padHeaders = clone(headers); + if (config.padContentSecurity) { + padHeaders['Content-Security-Policy'] = clone(config.padContentSecurity); + } if (Object.keys(headers).length) { - return function (res) { - for (var header in headers) { res.setHeader(header, headers[header]); } + return function (req, res) { + const h = /^\/pad\/inner\.html.*/.test(req.url) ? padHeaders : headers; + for (let header in h) { res.setHeader(header, h[header]); } }; } return function () {}; }()); app.use(function (req, res, next) { - setHeaders(res); + setHeaders(req, res); + if (/[\?\&]ver=[^\/]+$/.test(req.url)) { res.setHeader("Cache-Control", "max-age=31536000"); } next(); }); @@ -82,6 +94,10 @@ app.get('/api/config', function(req, res){ var host = req.headers.host.replace(/\:[0-9]+/, ''); res.setHeader('Content-Type', 'text/javascript'); res.send('define(' + JSON.stringify({ + requireConf: { + waitSeconds: 60, + urlArgs: 'ver=' + Package.version + }, websocketPath: config.useExternalWebsocket ? undefined : config.websocketPath, websocketURL:'ws' + ((useSecureWebsockets) ? 's' : '') + '://' + host + ':' + websocketPort + '/cryptpad_websocket', diff --git a/www/code/index.html b/www/code/index.html index df3fe1142..af6247a40 100644 --- a/www/code/index.html +++ b/www/code/index.html @@ -4,13 +4,7 @@ CryptPad - - +
- - +
- diff --git a/www/common/boot.js b/www/common/boot.js new file mode 100644 index 000000000..406521778 --- /dev/null +++ b/www/common/boot.js @@ -0,0 +1,5 @@ +// Stage 0, this gets cached which means we can't change it. boot2.js is changable. +define(['/api/config?cb=' + (+new Date()).toString(16)], function (Config) { + if (Config.requireConf) { require.config(Config.requireConf); } + require(['/common/boot2.js']); +}); diff --git a/www/common/boot2.js b/www/common/boot2.js new file mode 100644 index 000000000..72519b73e --- /dev/null +++ b/www/common/boot2.js @@ -0,0 +1,6 @@ +// This is stage 1, it can be changed but you must bump the version of the project. +define([], function () { + // fix up locations so that relative urls work. + require.config({ baseUrl: window.location.pathname }); + require([document.querySelector('script[data-bootload]').getAttribute('data-bootload')]); +}); diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index bf0893ae6..80b366766 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -1,5 +1,5 @@ define([ - '/api/config?cb=' + Math.random().toString(16).slice(2), + '/api/config', '/customize/messages.js?app=' + window.location.pathname.split('/').filter(function (x) { return x; }).join('.'), '/customize/fsStore.js', '/bower_components/chainpad-crypto/crypto.js?v=0.1.5', diff --git a/www/common/noscriptfix.js b/www/common/noscriptfix.js new file mode 100644 index 000000000..532393248 --- /dev/null +++ b/www/common/noscriptfix.js @@ -0,0 +1,3 @@ +// Fix for noscript bugs when caching iframe content. +// Caution, this file will get cached, you must change the name if you change it. +document.getElementById('pad-iframe').setAttribute('src', 'inner.html?cb=' + (+new Date())); diff --git a/www/drive/index.html b/www/drive/index.html index d9c792a4c..43fe2b44c 100644 --- a/www/drive/index.html +++ b/www/drive/index.html @@ -10,13 +10,7 @@ data-alt-favicon="/customize/alt-favicon.png" id="favicon" /> - - + - - + - diff --git a/www/drive/main.js b/www/drive/main.js index 47d8da2ee..0bde36d7d 100644 --- a/www/drive/main.js +++ b/www/drive/main.js @@ -18,7 +18,6 @@ define([ // Use `$(function () {});` to make sure the html is loaded before doing anything else $(function () { - var $iframe = $('#pad-iframe').contents(); var ifrw = $('#pad-iframe')[0].contentWindow; @@ -2116,6 +2115,5 @@ define([ onConnectError(); } }); - }); }); diff --git a/www/examples/board/index.html b/www/examples/board/index.html index ed36db678..df0fb5312 100644 --- a/www/examples/board/index.html +++ b/www/examples/board/index.html @@ -10,12 +10,7 @@ data-alt-favicon="/customize/alt-favicon.png" id="favicon" /> - - + Edit this document's style

HTML Ipsum Presents

- +

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.

Header Level 2

- +
  1. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
  2. Aliquam tincidunt mauris eu risus.
  3. @@ -30,10 +30,10 @@
    
    -#header h1 a { 
    -    display: block; 
    -    width: 300px; 
    -    height: 80px; 
    +#header h1 a {
    +    display: block;
    +    width: 300px;
    +    height: 80px;
     }
     
    @@ -58,4 +58,3 @@ - diff --git a/www/examples/text/index.html b/www/examples/text/index.html index 514095e99..b22cb7321 100644 --- a/www/examples/text/index.html +++ b/www/examples/text/index.html @@ -3,7 +3,7 @@ - + - - + - diff --git a/www/poll/index.html b/www/poll/index.html index cdaf574f3..363cae7e6 100644 --- a/www/poll/index.html +++ b/www/poll/index.html @@ -11,11 +11,7 @@ id="favicon" /> - - +