Merge branch 'security2' of git.xwikisas.com:xwiki-labs/cryptpad into security2

pull/1/head
ansuz 8 years ago
commit c9040997d5

@ -29,7 +29,7 @@
"rangy": "rangy-release#~1.3.0", "rangy": "rangy-release#~1.3.0",
"json.sortify": "~2.1.0", "json.sortify": "~2.1.0",
"fabric.js": "fabric#~1.6.0", "fabric.js": "fabric#~1.6.0",
"hyperjson": "~1.3.1", "hyperjson": "~1.4.0",
"textpatcher": "^1.3.0", "textpatcher": "^1.3.0",
"proxy-polyfill": "^0.1.5", "proxy-polyfill": "^0.1.5",
"chainpad": "^0.3.0", "chainpad": "^0.3.0",

@ -14,24 +14,35 @@ module.exports = {
* Examples are provided below * Examples are provided below
*/ */
/*
httpHeaders: { 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-XSS-Protection": "1; mode=block",
"X-Content-Type-Options": "nosniff", "X-Content-Type-Options": "nosniff",
// 'X-Frame-Options': 'SAMEORIGIN', // '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, httpPort: 3000,

@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html class="cp"> <html class="cp">
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
<head> <head>
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title> <title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
@ -9,16 +10,8 @@
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/> <link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
<script src="/bower_components/jquery/dist/jquery.min.js"></script> <script src="/bower_components/jquery/dist/jquery.min.js"></script>
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css">
<script data-main="/customize/main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="/customize/main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<script src="/bower_components/requirejs/require.js"></script>
<script>
require.config({
waitSeconds: 60,
urlArgs: "bust=1.1.0",
});
</script>
</head> </head>
<body class="html"> <body class="html">
<div id="cryptpadTopBar"> <div id="cryptpadTopBar">
@ -126,4 +119,3 @@
</body> </body>
</html> </html>

@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html class="cp"> <html class="cp">
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
<head> <head>
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title> <title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
@ -9,16 +10,8 @@
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/> <link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
<script src="/bower_components/jquery/dist/jquery.min.js"></script> <script src="/bower_components/jquery/dist/jquery.min.js"></script>
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css">
<script data-main="/customize/main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="/customize/main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<script src="/bower_components/requirejs/require.js"></script>
<script>
require.config({
waitSeconds: 60,
urlArgs: "bust=1.1.0",
});
</script>
</head> </head>
<body class="html"> <body class="html">
<div id="cryptpadTopBar"> <div id="cryptpadTopBar">
@ -123,4 +116,3 @@
</body> </body>
</html> </html>

@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html class="cp"> <html class="cp">
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
<head> <head>
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title> <title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
@ -9,16 +10,8 @@
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/> <link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
<script src="/bower_components/jquery/dist/jquery.min.js"></script> <script src="/bower_components/jquery/dist/jquery.min.js"></script>
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css">
<script data-main="/customize/main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="/customize/main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<script src="/bower_components/requirejs/require.js"></script>
<script>
require.config({
waitSeconds: 60,
urlArgs: "bust=1.1.0",
});
</script>
</head> </head>
<body class="html"> <body class="html">
<div id="cryptpadTopBar"> <div id="cryptpadTopBar">
@ -245,4 +238,3 @@
</body> </body>
</html> </html>

@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html class="cp"> <html class="cp">
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
<head> <head>
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title> <title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
@ -9,16 +10,8 @@
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/> <link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
<script src="/bower_components/jquery/dist/jquery.min.js"></script> <script src="/bower_components/jquery/dist/jquery.min.js"></script>
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css">
<script data-main="/customize/main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="/customize/main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<script src="/bower_components/requirejs/require.js"></script>
<script>
require.config({
waitSeconds: 60,
urlArgs: "bust=1.1.0",
});
</script>
</head> </head>
<body class="html"> <body class="html">
<div id="cryptpadTopBar"> <div id="cryptpadTopBar">
@ -144,4 +137,3 @@
</body> </body>
</html> </html>

@ -1,3 +1,2 @@
<link rel="stylesheet" type="text/css" href="main.css" /> <link rel="stylesheet" type="text/css" href="main.css" />
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>

@ -1,2 +1 @@
<script data-main="main" src="/bower_components/requirejs/require.js"></script>
<div id="container"></div> <div id="container"></div>

@ -1,2 +1 @@
<script data-main="/customize/main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="/customize/main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>

@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html class="cp"> <html class="cp">
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
<head> <head>
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title> <title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
@ -10,13 +11,6 @@
<script src="/bower_components/jquery/dist/jquery.min.js"></script> <script src="/bower_components/jquery/dist/jquery.min.js"></script>
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css">
{{script}} {{script}}
<script src="/bower_components/requirejs/require.js"></script>
<script>
require.config({
waitSeconds: 60,
urlArgs: "bust=1.1.0",
});
</script>
</head> </head>
<body class="html"> <body class="html">
{{topbar}} {{topbar}}
@ -30,4 +24,3 @@
{{footer}} {{footer}}
</body> </body>
</html> </html>

@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html class="cp"> <html class="cp">
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
<head> <head>
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title> <title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
@ -9,16 +10,8 @@
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/> <link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
<script src="/bower_components/jquery/dist/jquery.min.js"></script> <script src="/bower_components/jquery/dist/jquery.min.js"></script>
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css">
<script data-main="/customize/main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="/customize/main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<script src="/bower_components/requirejs/require.js"></script>
<script>
require.config({
waitSeconds: 60,
urlArgs: "bust=1.1.0",
});
</script>
</head> </head>
<body class="html"> <body class="html">
<div id="cryptpadTopBar"> <div id="cryptpadTopBar">
@ -127,4 +120,3 @@
</body> </body>
</html> </html>

@ -221,7 +221,7 @@ define(function () {
out.login_noSuchUser = 'Invalid username or password. Try again, or sign up'; out.login_noSuchUser = 'Invalid username or password. Try again, or sign up';
out.login_invalUser = 'Username required'; out.login_invalUser = 'Username required';
out.login_invalPass = 'Password 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_importRecent = "Import pad history (Recommended)";
out.register_acceptTerms = "I accept <a href='/terms.html'>the terms of service</a>"; out.register_acceptTerms = "I accept <a href='/terms.html'>the terms of service</a>";

@ -7,6 +7,7 @@ var Https = require('https');
var Fs = require('fs'); var Fs = require('fs');
var WebSocketServer = require('ws').Server; var WebSocketServer = require('ws').Server;
var NetfluxSrv = require('./NetfluxWebsocketSrv'); var NetfluxSrv = require('./NetfluxWebsocketSrv');
var Package = require('./package.json');
var config = require('./config'); var config = require('./config');
var websocketPort = config.websocketPort || config.httpPort; var websocketPort = config.websocketPort || config.httpPort;
@ -19,20 +20,31 @@ var app = Express();
var httpsOpts; var httpsOpts;
const clone = (x) => (JSON.parse(JSON.stringify(x)));
var setHeaders = (function () { var setHeaders = (function () {
if (typeof(config.httpHeaders) !== 'object') { return 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) { if (Object.keys(headers).length) {
return function (res) { return function (req, res) {
for (var header in headers) { res.setHeader(header, headers[header]); } const h = /^\/pad\/inner\.html.*/.test(req.url) ? padHeaders : headers;
for (let header in h) { res.setHeader(header, h[header]); }
}; };
} }
return function () {}; return function () {};
}()); }());
app.use(function (req, res, next) { app.use(function (req, res, next) {
setHeaders(res); setHeaders(req, res);
if (/[\?\&]ver=[^\/]+$/.test(req.url)) { res.setHeader("Cache-Control", "max-age=31536000"); }
next(); next();
}); });
@ -82,6 +94,10 @@ app.get('/api/config', function(req, res){
var host = req.headers.host.replace(/\:[0-9]+/, ''); var host = req.headers.host.replace(/\:[0-9]+/, '');
res.setHeader('Content-Type', 'text/javascript'); res.setHeader('Content-Type', 'text/javascript');
res.send('define(' + JSON.stringify({ res.send('define(' + JSON.stringify({
requireConf: {
waitSeconds: 60,
urlArgs: 'ver=' + Package.version
},
websocketPath: config.useExternalWebsocket ? undefined : config.websocketPath, websocketPath: config.useExternalWebsocket ? undefined : config.websocketPath,
websocketURL:'ws' + ((useSecureWebsockets) ? 's' : '') + '://' + host + ':' + websocketURL:'ws' + ((useSecureWebsockets) ? 's' : '') + '://' + host + ':' +
websocketPort + '/cryptpad_websocket', websocketPort + '/cryptpad_websocket',

@ -4,13 +4,7 @@
<title>CryptPad</title> <title>CryptPad</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<script>
require.config({
waitSeconds: 60,
urlArgs: "bust=1.1.0",
});
</script>
<link rel="icon" type="image/png" <link rel="icon" type="image/png"
href="/customize/main-favicon.png" href="/customize/main-favicon.png"
@ -49,11 +43,7 @@
</head> </head>
<body> <body>
<div id="iframe-container"> <div id="iframe-container">
<iframe id="pad-iframe"></iframe> <iframe id="pad-iframe"></iframe><script src="/common/noscriptfix.js"></script>
<script>
document.getElementById('pad-iframe').setAttribute('src', 'inner.html?' + new Date().getTime());
</script>
</div> </div>
</body> </body>
</html> </html>

@ -689,7 +689,7 @@ define([
// inform of network disconnect // inform of network disconnect
setEditable(false); setEditable(false);
toolbar.failed(); toolbar.failed();
Cryptpad.alert(Messages.common_connectionLost); Cryptpad.alert(Messages.common_connectionLost, undefined, force);
}; };
var onConnectionChange = config.onConnectionChange = function (info) { var onConnectionChange = config.onConnectionChange = function (info) {
@ -700,7 +700,7 @@ define([
toolbar.reconnecting(info.myId); toolbar.reconnecting(info.myId);
Cryptpad.findOKButton().click(); Cryptpad.findOKButton().click();
} else { } else {
Cryptpad.alert(Messages.common_connectionLost); Cryptpad.alert(Messages.common_connectionLost, undefined, force);
} }
}; };

@ -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']);
});

@ -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')]);
});

@ -1,5 +1,5 @@
define([ 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/messages.js?app=' + window.location.pathname.split('/').filter(function (x) { return x; }).join('.'),
'/customize/fsStore.js', '/customize/fsStore.js',
'/bower_components/chainpad-crypto/crypto.js?v=0.1.5', '/bower_components/chainpad-crypto/crypto.js?v=0.1.5',
@ -163,10 +163,13 @@ define([
// var isArray = function (o) { return Object.prototype.toString.call(o) === '[object Array]'; }; // var isArray = function (o) { return Object.prototype.toString.call(o) === '[object Array]'; };
var isArray = common.isArray = $.isArray; var isArray = common.isArray = $.isArray;
var fixHTML = common.fixHTML = function (html) { var fixHTML = common.fixHTML = function (str) {
return html.replace(/</g, '&lt;'); return str.replace(/[<>&"']/g, function (x) {
return ({ "<": "&lt;", ">": "&gt", "&": "&amp;", '"': "&#34;", "'": "&#39;" })[x];
});
}; };
var truncate = common.truncate = function (text, len) { var truncate = common.truncate = function (text, len) {
if (typeof(text) === 'string' && text.length > len) { if (typeof(text) === 'string' && text.length > len) {
return text.slice(0, len) + '…'; return text.slice(0, len) + '…';
@ -835,7 +838,7 @@ define([
if (!$('#' + LOADING).is(':visible')) { common.addLoadingScreen(); } if (!$('#' + LOADING).is(':visible')) { common.addLoadingScreen(); }
$('.spinnerContainer').hide(); $('.spinnerContainer').hide();
if (transparent) { $('#' + LOADING).css('opacity', 0.8); } if (transparent) { $('#' + LOADING).css('opacity', 0.8); }
$('#' + LOADING).find('p').html(error || Messages.error); $('#' + LOADING).find('p').text(error || Messages.error);
}; };
/* /*
@ -958,7 +961,7 @@ define([
} else { } else {
callback(); callback();
} }
common.alert(Messages.movedToTrash); common.alert(Messages.movedToTrash, undefined, true);
return; return;
}); });
}); });
@ -1142,22 +1145,22 @@ define([
var $displayedName = $('<span>', {'class': config.displayNameCls || 'displayName'}); var $displayedName = $('<span>', {'class': config.displayNameCls || 'displayName'});
var accountName = localStorage[common.userNameKey]; var accountName = localStorage[common.userNameKey];
var account = isLoggedIn(); var account = isLoggedIn();
var $userAdminContent = $('<p>');
if (account) {
var $userAccount = $('<span>', {'class': 'userAccount'}).append(Messages.user_accountName + ': ' + accountName);
$userAdminContent.append($userAccount);
$userAdminContent.append($('<br>'));
}
var $userName = $('<span>', {'class': 'userDisplayName'}); var $userName = $('<span>', {'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 = []; var options = [];
if (config.displayNameCls) { if (config.displayNameCls) {
var $userAdminContent = $('<p>');
if (account) {
var $userAccount = $('<span>', {'class': 'userAccount'}).append(Messages.user_accountName + ': ' + fixHTML(accountName));
$userAdminContent.append($userAccount);
$userAdminContent.append($('<br>'));
}
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({ options.push({
tag: 'p', tag: 'p',
attributes: {'class': 'accountData'}, attributes: {'class': 'accountData'},
@ -1289,8 +1292,9 @@ define([
$(window).off('keyup', handler); $(window).off('keyup', handler);
}; };
common.alert = function (msg, cb) { common.alert = function (msg, cb, force) {
cb = cb || function () {}; cb = cb || function () {};
if (force !== true) { msg = fixHTML(msg); }
var keyHandler = listenForKeys(function (e) { // yes var keyHandler = listenForKeys(function (e) { // yes
findOKButton().click(); findOKButton().click();
}); });
@ -1303,9 +1307,10 @@ define([
}); });
}; };
common.prompt = function (msg, def, cb, opt) { common.prompt = function (msg, def, cb, opt, force) {
opt = opt || {}; opt = opt || {};
cb = cb || function () {}; cb = cb || function () {};
if (force !== true) { msg = fixHTML(msg); }
var keyHandler = listenForKeys(function (e) { // yes var keyHandler = listenForKeys(function (e) { // yes
findOKButton().click(); findOKButton().click();
@ -1326,9 +1331,11 @@ define([
}); });
}; };
common.confirm = function (msg, cb, opt) { common.confirm = function (msg, cb, opt, force) {
opt = opt || {}; opt = opt || {};
cb = cb || function () {}; cb = cb || function () {};
if (force !== true) { msg = fixHTML(msg); }
var keyHandler = listenForKeys(function (e) { var keyHandler = listenForKeys(function (e) {
findOKButton().click(); findOKButton().click();
}, function (e) { }, function (e) {
@ -1348,11 +1355,11 @@ define([
}; };
common.log = function (msg) { common.log = function (msg) {
Alertify.success(msg); Alertify.success(fixHTML(msg));
}; };
common.warn = function (msg) { common.warn = function (msg) {
Alertify.error(msg); Alertify.error(fixHTML(msg));
}; };
/* /*

@ -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()));

@ -207,32 +207,35 @@ define([
var anonymous = numberOfEditUsers - editUsersNames.length; var anonymous = numberOfEditUsers - editUsersNames.length;
// Update the userlist // Update the userlist
var $usersTitle = $('<h2>').text(Messages.users);
var $editUsers = $userButtons.find('.' + USERLIST_CLS);
$editUsers.html('').append($usersTitle);
var editUsersList = ''; var editUsersList = '';
var $editUsersList = $('<pre>');
if (readOnly !== 1) { if (readOnly !== 1) {
editUsersNames.unshift('<span class="yourself">' + Messages.yourself + '</span>'); $editUsers.append('<span class="yourself">' + Messages.yourself + '</span>');
anonymous--; anonymous--;
} }
if (editUsersNames.length > 0) {
$editUsersList.text(editUsersNames.join('\n')); // .text() to avoid XSS
$editUsers.append($editUsersList);
}
if (anonymous > 0) { if (anonymous > 0) {
var text = anonymous === 1 ? Messages.anonymousUser : Messages.anonymousUsers; var text = anonymous === 1 ? Messages.anonymousUser : Messages.anonymousUsers;
editUsersNames.push('<span class="anonymous">' + anonymous + ' ' + text + '</span>'); $editUsers.push('<span class="anonymous">' + anonymous + ' ' + text + '</span>');
} }
if (numberOfViewUsers > 0) { if (numberOfViewUsers > 0) {
var viewText = '<span class="viewer">'; var viewText = '<span class="viewer">';
if (numberOfEditUsers > 0) { if (numberOfEditUsers > 0) {
editUsersNames.push(''); $editUsers.append('<br>');
viewText += Messages.and + ' '; viewText += Messages.and + ' ';
} }
var viewerText = numberOfViewUsers !== 1 ? Messages.viewers : Messages.viewer; var viewerText = numberOfViewUsers !== 1 ? Messages.viewers : Messages.viewer;
viewText += numberOfViewUsers + ' ' + viewerText + '</span>'; viewText += numberOfViewUsers + ' ' + viewerText + '</span>';
editUsersNames.push(viewText); $editUsers.append(viewText);
}
if (editUsersNames.length > 0) {
editUsersList += editUsersNames.join('<br>');
} }
var $usersTitle = $('<h2>').text(Messages.users);
var $editUsers = $userButtons.find('.' + USERLIST_CLS);
$editUsers.html('').append($usersTitle).append(editUsersList);
// Update the buttons // Update the buttons
var fa_editusers = '<span class="fa fa-users"></span>'; var fa_editusers = '<span class="fa fa-users"></span>';

@ -10,13 +10,7 @@
data-alt-favicon="/customize/alt-favicon.png" data-alt-favicon="/customize/alt-favicon.png"
id="favicon" /> id="favicon" />
<link rel="stylesheet" href="/customize/main.css" /> <link rel="stylesheet" href="/customize/main.css" />
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<script>
require.config({
waitSeconds: 60,
urlArgs: "bust=1.1.0",
});
</script>
<style> <style>
html, body { html, body {
margin: 0px; margin: 0px;
@ -38,10 +32,6 @@
</style> </style>
</head> </head>
<body> <body>
<iframe id="pad-iframe"></iframe> <iframe id="pad-iframe"></iframe><script src="/common/noscriptfix.js"></script>
<script>
document.getElementById('pad-iframe').setAttribute('src', 'inner.html?' + new Date().getTime());
</script>
</body> </body>
</html> </html>

@ -18,7 +18,6 @@ define([
// Use `$(function () {});` to make sure the html is loaded before doing anything else // Use `$(function () {});` to make sure the html is loaded before doing anything else
$(function () { $(function () {
var $iframe = $('#pad-iframe').contents(); var $iframe = $('#pad-iframe').contents();
var ifrw = $('#pad-iframe')[0].contentWindow; var ifrw = $('#pad-iframe')[0].contentWindow;
@ -1796,7 +1795,7 @@ define([
if (path.length !== 4) { return; } if (path.length !== 4) { return; }
var element = filesOp.getTrashElementData(path); var element = filesOp.getTrashElementData(path);
var sPath = stringifyPath(element.path); var sPath = stringifyPath(element.path);
Cryptpad.alert('<strong>' + Messages.fm_originalPath + "</strong>:<br>" + sPath); Cryptpad.alert('<strong>' + Messages.fm_originalPath + "</strong>:<br>" + sPath, undefined, true);
} }
module.hideMenu(); module.hideMenu();
}); });
@ -1940,7 +1939,7 @@ define([
var setName = APP.setName = function (newName) { var setName = APP.setName = function (newName) {
if (typeof(newName) !== 'string') { return; } if (typeof(newName) !== 'string') { return; }
var myUserNameTemp = Cryptpad.fixHTML(newName.trim()); var myUserNameTemp = newName.trim();
if(myUserNameTemp.length > 32) { if(myUserNameTemp.length > 32) {
myUserNameTemp = myUserNameTemp.substr(0, 32); myUserNameTemp = myUserNameTemp.substr(0, 32);
} }
@ -2058,7 +2057,7 @@ define([
$backupButton.attr('title', Messages.fm_backup_title); $backupButton.attr('title', Messages.fm_backup_title);
$backupButton.on('click', function() { $backupButton.on('click', function() {
var url = window.location.origin + window.location.pathname + '#' + editHash; 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').val(url);
$('#fm_backupUrl').click(function () { $('#fm_backupUrl').click(function () {
$(this).select(); $(this).select();
@ -2083,7 +2082,7 @@ define([
setEditable(false); setEditable(false);
if (APP.refresh) { APP.refresh(); } if (APP.refresh) { APP.refresh(); }
APP.toolbar.failed(); APP.toolbar.failed();
Cryptpad.alert(Messages.common_connectionLost); Cryptpad.alert(Messages.common_connectionLost, undefined, true);
}; };
var onReconnect = function (info) { var onReconnect = function (info) {
setEditable(true); setEditable(true);
@ -2116,6 +2115,5 @@ define([
onConnectError(); onConnectError();
} }
}); });
}); });
}); });

@ -10,12 +10,7 @@
data-alt-favicon="/customize/alt-favicon.png" data-alt-favicon="/customize/alt-favicon.png"
id="favicon" /> id="favicon" />
<link rel="stylesheet" href="/customize/main.css" /> <link rel="stylesheet" href="/customize/main.css" />
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<script>
require.config({
waitSeconds: 60,
});
</script>
<style> <style>
html, body { html, body {
width: 100; width: 100;
@ -100,4 +95,3 @@
<div id="lists"></div> <div id="lists"></div>
<span id="create-list">Add List</span> <span id="create-list">Add List</span>
</div> </div>

@ -3,7 +3,7 @@
<head> <head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<style> <style>
html, body{ html, body{
padding: 0px; padding: 0px;
@ -76,4 +76,3 @@
</body> </body>
</html> </html>

@ -3,7 +3,7 @@
<head> <head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<style> <style>
html, body{ html, body{
padding: 0px; padding: 0px;
@ -76,4 +76,3 @@
</body> </body>
</html> </html>

@ -3,7 +3,7 @@
<head> <head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<style> <style>
html, body{ html, body{
padding: 0px; padding: 0px;
@ -75,4 +75,3 @@
</div> </div>
</body> </body>
</html> </html>

@ -3,7 +3,7 @@
<head> <head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<style> <style>
html, body{ html, body{
padding: 0px; padding: 0px;
@ -48,4 +48,3 @@
</div> </div>
</body> </body>
</html> </html>

@ -2,12 +2,7 @@
<html> <html>
<head> <head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<script>
require.config({
waitSeconds: 60,
});
</script>
<link rel="icon" type="image/png" <link rel="icon" type="image/png"
href="/customize/main-favicon.png" href="/customize/main-favicon.png"

@ -4,7 +4,7 @@
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/common/render-sd.css" /> <link rel="stylesheet" href="/common/render-sd.css" />
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<style> <style>
html, body { html, body {
padding: 0; padding: 0;

@ -3,7 +3,7 @@
<head> <head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<style></style> <style></style>
</head> </head>
<body> <body>
@ -58,4 +58,3 @@
</body> </body>
</html> </html>

@ -3,7 +3,7 @@
<head> <head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<style> <style>
html, body{ html, body{
padding: 0px; padding: 0px;
@ -36,4 +36,3 @@
<textarea></textarea> <textarea></textarea>
</body> </body>
</html> </html>

@ -2,12 +2,7 @@
<html> <html>
<head> <head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<script>
require.config({
waitSeconds: 60,
});
</script>
<link rel="icon" type="image/png" <link rel="icon" type="image/png"
href="/customize/main-favicon.png" href="/customize/main-favicon.png"
@ -31,4 +26,3 @@ pre {
<h1>Upload</h1> <h1>Upload</h1>
<input type="file"> <input type="file">

@ -9,14 +9,7 @@
<link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/> <link rel="icon" type="image/png" href="/customize/main-favicon.png" id="favicon"/>
<script src="/bower_components/jquery/dist/jquery.min.js"></script> <script src="/bower_components/jquery/dist/jquery.min.js"></script>
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css">
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<script src="/bower_components/requirejs/require.js"></script>
<script>
require.config({
waitSeconds: 60,
urlArgs: "bust=1.1.0",
});
</script>
</head> </head>
<body class="html"> <body class="html">
<div id="cryptpadTopBar"> <div id="cryptpadTopBar">
@ -77,4 +70,3 @@
</body> </body>
</html> </html>

@ -10,13 +10,7 @@
data-alt-favicon="/customize/alt-favicon.png" data-alt-favicon="/customize/alt-favicon.png"
id="favicon" /> id="favicon" />
<link rel="stylesheet" href="/customize/main.css" /> <link rel="stylesheet" href="/customize/main.css" />
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<script>
require.config({
waitSeconds: 60,
urlArgs: "bust=1.1.0",
});
</script>
<style> <style>
html, body { html, body {
margin: 0px; margin: 0px;
@ -61,10 +55,6 @@
</style> </style>
</head> </head>
<body> <body>
<iframe id="pad-iframe"></iframe> <iframe id="pad-iframe"></iframe><script src="/common/noscriptfix.js"></script>
<script>
document.getElementById('pad-iframe').setAttribute('src', 'inner.html?' + new Date().getTime());
</script>
</body> </body>
</html> </html>

@ -293,7 +293,7 @@ define([
var setName = module.setName = function (newName) { var setName = module.setName = function (newName) {
if (typeof(newName) !== 'string') { return; } if (typeof(newName) !== 'string') { return; }
var myUserNameTemp = Cryptpad.fixHTML(newName.trim()); var myUserNameTemp = newName.trim();
if(myUserNameTemp.length > 32) { if(myUserNameTemp.length > 32) {
myUserNameTemp = myUserNameTemp.substr(0, 32); myUserNameTemp = myUserNameTemp.substr(0, 32);
} }
@ -524,13 +524,7 @@ define([
}; };
var getHTML = function (Dom) { var getHTML = function (Dom) {
var data = inner.innerHTML; return ('<!DOCTYPE html>\n' + '<html>\n' + inner.innerHTML);
Dom = Dom || (new DOMParser()).parseFromString(data,"text/html");
return ('<!DOCTYPE html>\n' +
'<html>\n' +
(typeof(Hyperjson.toString) === 'function'?
Hyperjson.toString(Hyperjson.fromDOM(Dom.body)):
Dom.head.outerHTML) + '\n');
}; };
var domFromHTML = function (html) { var domFromHTML = function (html) {
@ -732,7 +726,7 @@ define([
setEditable(false); setEditable(false);
// TODO inform them that the session was torn down // TODO inform them that the session was torn down
toolbar.failed(); toolbar.failed();
Cryptpad.alert(Messages.common_connectionLost); Cryptpad.alert(Messages.common_connectionLost, undefined, true);
}; };
var onConnectionChange = realtimeOptions.onConnectionChange = function (info) { var onConnectionChange = realtimeOptions.onConnectionChange = function (info) {
@ -743,7 +737,7 @@ define([
toolbar.reconnecting(info.myId); toolbar.reconnecting(info.myId);
Cryptpad.findOKButton().click(); Cryptpad.findOKButton().click();
} else { } else {
Cryptpad.alert(Messages.common_connectionLost); Cryptpad.alert(Messages.common_connectionLost, undefined, true);
} }
}; };

@ -11,11 +11,7 @@
id="favicon" /> id="favicon" />
<link rel="stylesheet" href="/bower_components/components-font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="/bower_components/components-font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="/customize/main.css" /> <link rel="stylesheet" href="/customize/main.css" />
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<script> require.config({
waitSeconds: 60,
urlArgs: "bust=1.1.0",
}); </script>
<style> <style>
html, body { html, body {
width: 100%; width: 100%;

@ -440,7 +440,7 @@ define([
var setName = APP.setName = function (newName) { var setName = APP.setName = function (newName) {
if (typeof(newName) !== 'string') { return; } if (typeof(newName) !== 'string') { return; }
var myUserNameTemp = Cryptpad.fixHTML(newName.trim()); var myUserNameTemp = newName.trim();
if(myUserNameTemp.length > 32) { if(myUserNameTemp.length > 32) {
myUserNameTemp = myUserNameTemp.substr(0, 32); myUserNameTemp = myUserNameTemp.substr(0, 32);
} }
@ -662,7 +662,7 @@ define([
var disconnect = function (info) { var disconnect = function (info) {
//setEditable(false); // TODO //setEditable(false); // TODO
Cryptpad.alert(Messages.common_connectionLost); Cryptpad.alert(Messages.common_connectionLost, undefined, true);
}; };
var create = function (info) { var create = function (info) {

@ -5,15 +5,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Cryptpad: login</title> <title>Cryptpad: login</title>
<link rel="stylesheet" href="/bower_components/components-font-awesome/css/font-awesome.min.css"> <link rel="stylesheet" href="/bower_components/components-font-awesome/css/font-awesome.min.css">
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<link rel="stylesheet" href="/customize/main.css" /> <link rel="stylesheet" href="/customize/main.css" />
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css">
<script>
require.config({
waitSeconds: 60,
urlArgs: "bust=1.1.0",
});
</script>
</head> </head>
<body class="html"> <body class="html">
<div id="cryptpadTopBar"> <div id="cryptpadTopBar">
@ -89,4 +83,3 @@
</body> </body>
</html> </html>

@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html class="cp"> <html class="cp">
<!-- If this file is not called customize.dist/src/template.html, it is generated -->
<head> <head>
<title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title> <title data-localization="main_title">Cryptpad: Zero Knowledge, Collaborative Real Time Editing</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
@ -10,16 +11,8 @@
<script src="/bower_components/jquery/dist/jquery.min.js"></script> <script src="/bower_components/jquery/dist/jquery.min.js"></script>
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="main.css" /> <link rel="stylesheet" type="text/css" href="main.css" />
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<script src="/bower_components/requirejs/require.js"></script>
<script>
require.config({
waitSeconds: 60,
urlArgs: "bust=1.1.0",
});
</script>
</head> </head>
<body class="html"> <body class="html">
<div id="cryptpadTopBar"> <div id="cryptpadTopBar">
@ -68,8 +61,7 @@
<div id="mainBlock" class="hidden"> <div id="mainBlock" class="hidden">
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <div id="container"></div>
<div id="container"></div>
</div> </div>
@ -118,4 +110,3 @@
</body> </body>
</html> </html>

@ -167,7 +167,7 @@ define([
if (val !== "I love CryptPad") { return; } if (val !== "I love CryptPad") { return; }
obj.proxy.drive = Cryptpad.getStore().getEmptyObject(); obj.proxy.drive = Cryptpad.getStore().getEmptyObject();
Cryptpad.alert(Messages.settings_resetDone); Cryptpad.alert(Messages.settings_resetDone);
}); }, undefined, true);
}); });
return $div; return $div;

@ -3,13 +3,7 @@
<head> <head>
<title>CryptPad</title> <title>CryptPad</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
<script>
require.config({
waitSeconds: 60,
urlArgs: "bust=1.1.0",
});
</script>
<link rel="icon" type="image/png" <link rel="icon" type="image/png"
href="/customize/main-favicon.png" href="/customize/main-favicon.png"
@ -52,11 +46,7 @@
</head> </head>
<body> <body>
<div id="iframe-container"> <div id="iframe-container">
<iframe id="pad-iframe"></iframe> <iframe id="pad-iframe"></iframe><script src="/common/noscriptfix.js"></script>
<script>
document.getElementById('pad-iframe').setAttribute('src', 'inner.html?' + new Date().getTime());
</script>
</div> </div>
</body> </body>
</html> </html>

@ -138,7 +138,7 @@ define([
Slide.setModal($modal, $content, $pad, ifrw, initialState); Slide.setModal($modal, $content, $pad, ifrw, initialState);
var enterPresentationMode = function (shouldLog) { var enterPresentationMode = function (shouldLog) {
Slide.show(true, $textarea.val()); Slide.show(true, editor.getValue());
if (shouldLog) { if (shouldLog) {
Cryptpad.log(Messages.presentSuccess); Cryptpad.log(Messages.presentSuccess);
} }
@ -771,7 +771,7 @@ define([
// inform of network disconnect // inform of network disconnect
setEditable(false); setEditable(false);
toolbar.failed(); toolbar.failed();
Cryptpad.alert(Messages.common_connectionLost); Cryptpad.alert(Messages.common_connectionLost, undefined, true);
}; };
var onConnectionChange = config.onConnectionChange = function (info) { var onConnectionChange = config.onConnectionChange = function (info) {
@ -782,7 +782,7 @@ define([
toolbar.reconnecting(info.myId); toolbar.reconnecting(info.myId);
Cryptpad.findOKButton().click(); Cryptpad.findOKButton().click();
} else { } else {
Cryptpad.alert(Messages.common_connectionLost); Cryptpad.alert(Messages.common_connectionLost, undefined, true);
} }
}; };

Loading…
Cancel
Save