diff --git a/config.js.dist b/config.js.dist
index 1edfb7f36..76518baea 100644
--- a/config.js.dist
+++ b/config.js.dist
@@ -8,6 +8,31 @@ module.exports = {
httpAddress: '::',
// the port on which your httpd will listen
+
+ /* Cryptpad can be configured to send customized HTTP Headers
+ * These settings may vary widely depending on your needs
+ * Examples are provided below
+ */
+
+/*
+ httpHeaders: {
+ "Content-Security-Policy": [
+ "default-serc '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',
+ },*/
+
httpPort: 3000,
/* your server's websocket url is configurable
diff --git a/customize.dist/DecorateToolbar.js b/customize.dist/DecorateToolbar.js
index 8f155148f..d6f77ea30 100644
--- a/customize.dist/DecorateToolbar.js
+++ b/customize.dist/DecorateToolbar.js
@@ -13,7 +13,7 @@ define([
$.ajax({
url: isHtml ? '/customize/BottomBar.html' : '/customize/Header.html',
success: function (ret) {
- $('iframe').height('96%');
+ //:$('iframe').height('96%');
$('body').append(ret);
LS.main();
Messages._applyTranslation();
diff --git a/customize.dist/Header.html b/customize.dist/Header.html
index 6548f9075..6d7e2a370 100644
--- a/customize.dist/Header.html
+++ b/customize.dist/Header.html
@@ -8,14 +8,16 @@
-
+
diff --git a/customize.dist/cryptofist_mini.png b/customize.dist/cryptofist_mini.png
new file mode 100644
index 000000000..82a5218ef
Binary files /dev/null and b/customize.dist/cryptofist_mini.png differ
diff --git a/customize.dist/index.html b/customize.dist/index.html
index 32e09f4f2..f66d4dbcf 100644
--- a/customize.dist/index.html
+++ b/customize.dist/index.html
@@ -3,7 +3,7 @@
Cryptpad: Zero Knowledge, Collaborative Real Time Editing
-
+
diff --git a/customize.dist/main.css b/customize.dist/main.css
index 0c063e6e8..2455aa465 100644
--- a/customize.dist/main.css
+++ b/customize.dist/main.css
@@ -146,6 +146,7 @@ tr {
.buttons {
margin-bottom: 50px;
margin-top: 20px;
+ line-height: 2.5em;
}
.button {
padding: 4px 12px 4px 12px;
@@ -242,6 +243,34 @@ tbody td:last-child {
margin-right: 4px;
position: relative;
}
+@media screen and (max-width: 800px) {
+ .top-bar .big,
+ .bottom-bar .big {
+ display: none;
+ }
+}
+@media screen and (min-width: 801px) {
+ .top-bar .big,
+ .bottom-bar .big {
+ display: inline-block;
+ }
+}
+@media screen and (max-width: 800px) {
+ .top-bar .small,
+ .bottom-bar .small {
+ display: inline-block;
+ }
+}
+@media screen and (min-width: 801px) {
+ .top-bar .small,
+ .bottom-bar .small {
+ display: none;
+ }
+}
+.top-bar .small img,
+.bottom-bar .small img {
+ height: 1.25em;
+}
.bottom-bar {
bottom: 0px;
right: 0px;
diff --git a/customize.dist/privacy.html b/customize.dist/privacy.html
index b152269da..a3969421a 100644
--- a/customize.dist/privacy.html
+++ b/customize.dist/privacy.html
@@ -3,7 +3,7 @@
Cryptpad: Zero Knowledge, Collaborative Real Time Editing
-
+
diff --git a/customize.dist/src/cryptpad.less b/customize.dist/src/cryptpad.less
index c41af4de9..7492114e9 100644
--- a/customize.dist/src/cryptpad.less
+++ b/customize.dist/src/cryptpad.less
@@ -175,6 +175,7 @@ p, pre, td, a, table, tr {
.buttons {
margin-bottom: 50px;
margin-top: 20px;
+ line-height: 2.5em;
}
.button {
@@ -278,6 +279,27 @@ tbody {
margin-right: 4px;
position: relative;
}
+
+ .big {
+ @media screen and (max-width: 800px) {
+ display: none;
+ }
+ @media screen and (min-width: 801px) {
+ display: inline-block;
+ }
+ }
+ .small {
+ @media screen and (max-width: 800px) {
+ display: inline-block;
+ }
+ @media screen and (min-width: 801px) {
+ display: none;
+ }
+ img {
+ height: 1.25em;
+ }
+ }
+
}
.bottom-bar {
bottom: 0px;
diff --git a/customize.dist/src/template.html b/customize.dist/src/template.html
index e696d42a5..c386ceee8 100644
--- a/customize.dist/src/template.html
+++ b/customize.dist/src/template.html
@@ -3,7 +3,7 @@
Cryptpad: Zero Knowledge, Collaborative Real Time Editing
-
+
diff --git a/customize.dist/src/toolbar.less b/customize.dist/src/toolbar.less
index ff68cb4b7..17e25c232 100644
--- a/customize.dist/src/toolbar.less
+++ b/customize.dist/src/toolbar.less
@@ -16,8 +16,6 @@
color: #666;
font-weight: bold;
- height: 30px;
- margin-bottom: -3px;
display: inline-block;
width: 100%;
z-index: 9001;
@@ -27,32 +25,58 @@
}
div {
- padding: 0 3px;
- height: 1.5em;
- line-height: 25px;
- height: 100%;
+ white-space: normal;
&.cryptpad-back {
padding: 0;
font-weight: bold;
cursor: pointer;
color: #000;
}
+ &.cryptpad-lag {
+ float: right;
+ line-height: 26px;
+ margin: 2px 0px 2px 4px;
+ }
}
- button {
+ button, .rightside-element {
height: 26px;
+ padding-right: 5px;
+ padding-left: 5px;
+ margin: 2px;
+ }
+
+ button {
background-color: inherit;
background-image: linear-gradient(to bottom,#fff,#e4e4e4);
border: 1px solid #A6A6A6;
border-bottom-color: #979797;
border-radius: 3px;
- margin-right: 5px;
- padding-right: 5px;
- padding-left: 5px;
&:hover {
background-image:linear-gradient(to bottom,#f2f2f2,#ccc);
}
+ &.userlist {
+ @media screen and (max-width: 800px) {
+ display: none;
+ }
+ @media screen and (min-width: 801px) {
+ display: inline-block;
+ }
+ &.small {
+ @media screen and (max-width: 800px) {
+ display: inline-block;
+ }
+ @media screen and (min-width: 801px) {
+ display: none;
+ }
+ }
+ }
}
+
+ .cryptpad-state {
+ line-height: 30px; /* equivalent to 26px + 2*2px margin used for buttons */
+ }
+
.rightside-button {
float: right;
cursor: pointer;
@@ -63,30 +87,89 @@
float: left;
}
+ .rightside-element {
+ vertical-align: middle;
+ white-space: nowrap;
+ &.float {
+ float: right;
+ }
+ }
+
select {
border: 0px;
margin-left: 5px;
margin-right: 5px;
padding-left: 5px;
+ border: 1px solid #A6A6A6;
+ border-bottom-color: #979797;
}
}
.cryptpad-toolbar-leftside {
float: left;
- div {
- float: left;
+ margin-bottom: -1px;
+ .cryptpad-dropdown-container {
+ position: relative;
+ display: inline-block;
+ padding: 0px;
+ .cryptpad-dropdown {
+ z-index:1000;
+ display:none;
+ position: absolute;
+ background-color: #f9f9f9;
+ min-width: 160px;
+ overflow: auto;
+ box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
+ height: auto;
+ padding: 5px;
+ white-space: normal;
+ p {
+ width: 210px;
+ padding: 0;
+ margin: 0;
+ white-space: normal;
+ &.cryptpad-dropdown-users {
+ text-align:baseline;
+ .yourself {
+ font-style: italic;
+ }
+ .anonymous {
+ font-style: italic;
+ }
+ }
+ h2 {
+ font-weight: bold;
+ text-align: center;
+ background-color: #EEEEEE;
+ padding: 5px 0px;
+ margin: 5px 0px;
+ font-size: 16px;
+ }
+ }
+ button {
+ margin: 2px 0px;
+ }
+ }
+ }
+ button {
+ margin: 2px 4px 2px 0px;
+ }
+ .cryptpad-userbuttons-container {
+ display: none;
}
-
}
.cryptpad-toolbar-rightside {
text-align: right;
+ margin-right: 30px;
//float: right;
}
-.cryptpad-lag {
- float: right;
-}
.cryptpad-spinner {
float: left;
+ display: inline-block;
+ height: 26px;
+ margin: 2px;
+ line-height: 26px;
+ font-size: 20px;
}
.cryptpad-readonly {
margin-right: 20px;
@@ -94,13 +177,12 @@
text-transform: uppercase;
}
.cryptpad-toolbar-username {
- font-style: italic;
}
.lag {
display: inline-block;
vertical-align: middle;
padding: 0 !important;
- margin: 0 !important;
+ margin: 0 5px !important;
height: 15px !important;
width: 15px !important;
border-radius: 50%;
diff --git a/customize.dist/terms.html b/customize.dist/terms.html
index b2c1d4916..3a78d46a2 100644
--- a/customize.dist/terms.html
+++ b/customize.dist/terms.html
@@ -3,7 +3,7 @@
Cryptpad: Zero Knowledge, Collaborative Real Time Editing
-
+
diff --git a/customize.dist/toolbar.css b/customize.dist/toolbar.css
index 58d3c07ed..930a17eaf 100644
--- a/customize.dist/toolbar.css
+++ b/customize.dist/toolbar.css
@@ -16,8 +16,6 @@
user-select: none;
color: #666;
font-weight: bold;
- height: 30px;
- margin-bottom: -3px;
display: inline-block;
width: 100%;
z-index: 9001;
@@ -26,10 +24,7 @@
float: right;
}
.cryptpad-toolbar div {
- padding: 0 3px;
- height: 1.5em;
- line-height: 25px;
- height: 100%;
+ white-space: normal;
}
.cryptpad-toolbar div.cryptpad-back {
padding: 0;
@@ -37,20 +32,52 @@
cursor: pointer;
color: #000;
}
-.cryptpad-toolbar button {
+.cryptpad-toolbar div.cryptpad-lag {
+ float: right;
+ line-height: 26px;
+ margin: 2px 0px 2px 4px;
+}
+.cryptpad-toolbar button,
+.cryptpad-toolbar .rightside-element {
height: 26px;
+ padding-right: 5px;
+ padding-left: 5px;
+ margin: 2px;
+}
+.cryptpad-toolbar button {
background-color: inherit;
background-image: linear-gradient(to bottom, #fff, #e4e4e4);
border: 1px solid #A6A6A6;
border-bottom-color: #979797;
border-radius: 3px;
- margin-right: 5px;
- padding-right: 5px;
- padding-left: 5px;
}
.cryptpad-toolbar button:hover {
background-image: linear-gradient(to bottom, #f2f2f2, #ccc);
}
+@media screen and (max-width: 800px) {
+ .cryptpad-toolbar button.userlist {
+ display: none;
+ }
+}
+@media screen and (min-width: 801px) {
+ .cryptpad-toolbar button.userlist {
+ display: inline-block;
+ }
+}
+@media screen and (max-width: 800px) {
+ .cryptpad-toolbar button.userlist.small {
+ display: inline-block;
+ }
+}
+@media screen and (min-width: 801px) {
+ .cryptpad-toolbar button.userlist.small {
+ display: none;
+ }
+}
+.cryptpad-toolbar .cryptpad-state {
+ line-height: 30px;
+ /* equivalent to 26px + 2*2px margin used for buttons */
+}
.cryptpad-toolbar .rightside-button {
float: right;
cursor: pointer;
@@ -59,40 +86,96 @@
cursor: pointer;
float: left;
}
+.cryptpad-toolbar .rightside-element {
+ vertical-align: middle;
+ white-space: nowrap;
+}
+.cryptpad-toolbar .rightside-element.float {
+ float: right;
+}
.cryptpad-toolbar select {
border: 0px;
margin-left: 5px;
margin-right: 5px;
padding-left: 5px;
+ border: 1px solid #A6A6A6;
+ border-bottom-color: #979797;
}
.cryptpad-toolbar-leftside {
float: left;
+ margin-bottom: -1px;
}
-.cryptpad-toolbar-leftside div {
- float: left;
+.cryptpad-toolbar-leftside .cryptpad-dropdown-container {
+ position: relative;
+ display: inline-block;
+ padding: 0px;
+}
+.cryptpad-toolbar-leftside .cryptpad-dropdown-container .cryptpad-dropdown {
+ z-index: 1000;
+ display: none;
+ position: absolute;
+ background-color: #f9f9f9;
+ min-width: 160px;
+ overflow: auto;
+ box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
+ height: auto;
+ padding: 5px;
+ white-space: normal;
+}
+.cryptpad-toolbar-leftside .cryptpad-dropdown-container .cryptpad-dropdown p {
+ width: 210px;
+ padding: 0;
+ margin: 0;
+ white-space: normal;
+}
+.cryptpad-toolbar-leftside .cryptpad-dropdown-container .cryptpad-dropdown p.cryptpad-dropdown-users {
+ text-align: baseline;
+}
+.cryptpad-toolbar-leftside .cryptpad-dropdown-container .cryptpad-dropdown p.cryptpad-dropdown-users .yourself {
+ font-style: italic;
+}
+.cryptpad-toolbar-leftside .cryptpad-dropdown-container .cryptpad-dropdown p.cryptpad-dropdown-users .anonymous {
+ font-style: italic;
+}
+.cryptpad-toolbar-leftside .cryptpad-dropdown-container .cryptpad-dropdown p h2 {
+ font-weight: bold;
+ text-align: center;
+ background-color: #EEEEEE;
+ padding: 5px 0px;
+ margin: 5px 0px;
+ font-size: 16px;
+}
+.cryptpad-toolbar-leftside .cryptpad-dropdown-container .cryptpad-dropdown button {
+ margin: 2px 0px;
+}
+.cryptpad-toolbar-leftside button {
+ margin: 2px 4px 2px 0px;
+}
+.cryptpad-toolbar-leftside .cryptpad-userbuttons-container {
+ display: none;
}
.cryptpad-toolbar-rightside {
text-align: right;
-}
-.cryptpad-lag {
- float: right;
+ margin-right: 30px;
}
.cryptpad-spinner {
float: left;
+ display: inline-block;
+ height: 26px;
+ margin: 2px;
+ line-height: 26px;
+ font-size: 20px;
}
.cryptpad-readonly {
margin-right: 20px;
font-weight: bold;
text-transform: uppercase;
}
-.cryptpad-toolbar-username {
- font-style: italic;
-}
.lag {
display: inline-block;
vertical-align: middle;
padding: 0 !important;
- margin: 0 !important;
+ margin: 0 5px !important;
height: 15px !important;
width: 15px !important;
border-radius: 50%;
diff --git a/customize.dist/translations/messages.fr.js b/customize.dist/translations/messages.fr.js
index df9deb63c..7dd8b5bcd 100644
--- a/customize.dist/translations/messages.fr.js
+++ b/customize.dist/translations/messages.fr.js
@@ -17,21 +17,17 @@ define(function () {
out.common_connectionLost = 'Connexion au serveur perdue';
- out.editingAlone = 'Pas d\'autre participant';
- out.editingWithOneOtherPerson = 'Édition avec une autre personne';
- out.editingWith = 'Édition avec';
- out.otherPeople = 'autres personnes';
out.disconnected = 'Déconnecté';
out.synchronizing = 'Synchronisation';
out.reconnecting = 'Reconnexion...';
out.lag = 'Latence';
out.readonly = 'Lecture seule';
- out.nobodyIsEditing = "Personne n'édite le document";
- out.onePersonIsEditing = 'Une personne édite le document';
- out.peopleAreEditing = '{0} personnes éditent le document';
- out.oneViewer = '1 lecteur';
- out.viewers = '{0} lecteurs';
- out.anonymous = "Vous êtes actuellement anonyme";
+ out.anonymous = "Anonyme";
+ out.yourself = "Vous-même";
+ out.anonymousUsers = "utilisateurs anonymes";
+ out.anonymousUser = "utilisateur anonyme";
+ out.share = "Partage";
+ out.users = "Utilisateurs";
out.greenLight = "Tout fonctionne bien";
out.orangeLight = "Votre connexion est lente, ce qui réduit la qualité de l'éditeur";
@@ -82,7 +78,14 @@ define(function () {
out.readonlyUrl = 'Document en lecture seule';
out.copyReadOnly = "Copier l'URL dans le presse-papiers";
out.openReadOnly = "Ouvrir dans un nouvel onglet";
-
+ out.editing = "éditeur(s)";
+ out.viewing = "lecteur(s)";
+ out.editShare = "Partager l'URL";
+ out.editShareTitle = "Copier l'URL d'édition dans le presse-papiers";
+ out.viewShare = "Partager l'URL de lecture";
+ out.viewShareTitle = "Copier l'URL d'accès en lecture seule dans le presse-papiers";
+ out.viewOpen = "Voir dans un nouvel onglet";
+ out.viewOpenTitle = "Ouvrir le document en lecture seule dans un nouvel onglet";
out.disconnectAlert = 'Perte de la connexion au réseau !';
@@ -143,7 +146,7 @@ define(function () {
// index.html
- out.main_p1 = 'CryptPad est l\'éditeur collaboratif en temps réel zero knowledge. Le cryptage est effectué depuis votre navigateur, ce qui protège les données contre le serveur, le cloud, et la NSA. La clé de cryptage est stockée dans l\'identifieur de fragment de l\'URL qui n\'est jamais envoyée au serveur mais est accessible depuis javascript, de sorte qu\'en partageant l\'URL, vous donner l\'accès au pad à ceux qui souhaitent participer.';
+ out.main_p1 = 'CryptPad est l\'éditeur collaboratif en temps réel zero knowledge. Le chiffrement est effectué depuis votre navigateur, ce qui protège les données contre le serveur, le cloud, et la NSA. La clé de chiffrement est stockée dans l\'identifieur de fragment de l\'URL qui n\'est jamais envoyée au serveur mais est accessible depuis javascript, de sorte qu\'en partageant l\'URL, vous donnez l\'accès au pad à ceux qui souhaitent participer.';
out.main_p2 = 'Ce projet utilise l\'éditeur visuel (WYSIWYG) CKEditor, l\'éditeur de code source CodeMirror, et le moteur temps-réel ChainPad.';
out.main_howitworks = 'Comment ça fonctionne';
out.main_howitworks_p1 = 'CryptPad utilise une variante de l\'algorithme d\'Operational transformation qui est capable de trouver un consensus distribué en utilisant une chaîne de bloc Nakamoto, un outil popularisé par le Bitcoin. De cette manière, l\'algorithme évite la nécessité d\'utiliser un serveur central pour résoudre les conflits d\'édition de l\'Operational Transformation, et sans ce besoin de résolution des conflits le serveur peut rester ignorant du contenu qui est édité dans le pad.';
@@ -187,7 +190,7 @@ define(function () {
out.tos_title = "Conditions d'utilisation de Cryptpad";
out.tos_legal = "Veuillez ne pas être malveillant, abusif, ou faire quoi que ce soit d'illégal.";
out.tos_availability = "Nous espérons que vous trouvez ce service utile, mais nous ne pouvons garantir ses performances et disponibilités. Nous vous recommandons d'exporter vos données régurlièrement.";
- out.tos_e2ee = "Les document sur Cryptpad peuvent être lus et modifiés par quiconque est en mesure de deviner ou d'obtenir de quelque manière que ce soit l'identificateur de fragment (hash) du document. Nous vous recommandons d'utiliser des technologies de messagerie cryptées de bout à bout (end-to-end encryption ou e2ee) pour partager les URLs, et déclinons toute responsabilité dans le cas ou une telle URL serait divulguée.";
+ out.tos_e2ee = "Les document sur Cryptpad peuvent être lus et modifiés par quiconque est en mesure de deviner ou d'obtenir de quelque manière que ce soit l'identificateur de fragment (hash) du document. Nous vous recommandons d'utiliser des technologies de messagerie chiffrées de bout à bout (end-to-end encryption ou e2ee) pour partager les URLs, et déclinons toute responsabilité dans le cas ou une telle URL serait divulguée.";
out.tos_logs = "Les meta-données fournies par votre navigateur au serveur peuvent être enregistrées dans le but de maintenir le service.";
out.tos_3rdparties = "Nous ne fournissons aucune donnée individuelle à des tierces parties à moins d'y être contraints par la loi.";
@@ -199,6 +202,7 @@ define(function () {
// Header.html
out.header_france = 'Fait avec en par ';
+ out.header_xwiki = '';
out.header_support = ' ';
out.header_logoTitle = "Aller vers la page d'accueil";
diff --git a/customize.dist/translations/messages.js b/customize.dist/translations/messages.js
index d46fb6e5a..2b2a7a0cb 100644
--- a/customize.dist/translations/messages.js
+++ b/customize.dist/translations/messages.js
@@ -17,21 +17,17 @@ define(function () {
out.common_connectionLost = 'Server Connection Lost';
- out.editingAlone = 'Editing alone';
- out.editingWithOneOtherPerson = 'Editing with one other person';
- out.editingWith = 'Editing with';
- out.otherPeople = 'other people';
out.disconnected = 'Disconnected';
out.synchronizing = 'Synchronizing';
out.reconnecting = 'Reconnecting...';
out.lag = 'Lag';
out.readonly = 'Read only';
- out.nobodyIsEditing = 'Nobody is editing';
- out.onePersonIsEditing = 'One person is editing';
- out.peopleAreEditing = '{0} people are editing';
- out.oneViewer = '1 viewer';
- out.viewers = '{0} viewers';
- out.anonymous = "You are currently anonymous";
+ out.anonymous = "Anonymous";
+ out.yourself = "Yourself";
+ out.anonymousUsers = "anonymous users";
+ out.anonymousUser = "anonymous user";
+ out.share = "Share";
+ out.users = "Users";
out.greenLight = "Everything is working fine";
out.orangeLight = "Your slow connection may impact your experience";
@@ -83,6 +79,14 @@ define(function () {
out.readonlyUrl = 'Read only document';
out.copyReadOnly = "Copy URL to clipboard";
out.openReadOnly = "Open in a new tab";
+ out.editing = "editing";
+ out.viewing = "viewing";
+ out.editShare = "Share";
+ out.editShareTitle = "Copy the edit URL to clipboard";
+ out.viewShare = "Share view URL";
+ out.viewShareTitle = "Copy the read-only URL to clipboard";
+ out.viewOpen = "View in new tab";
+ out.viewOpenTitle = "Open the document in read-only mode in a new tab";
out.disconnectAlert = 'Network connection lost!';
@@ -200,6 +204,7 @@ define(function () {
// Header.html
out.header_france = 'With from by ';
+ out.header_xwiki = '';
out.header_support = ' ';
out.header_logoTitle = 'Go to the main page';
diff --git a/server.js b/server.js
index bc17cccbf..f24117bd1 100644
--- a/server.js
+++ b/server.js
@@ -19,33 +19,20 @@ var app = Express();
var httpsOpts;
-app.use(function (req, res, next) {
- var host = req.headers.host;
- if (config.websocketPort) {
- host = host.replace(/\:[0-9]+/, ':' + config.websocketPort);
+var setHeaders = (function () {
+ if (typeof(config.httpHeaders) !== 'object') { return function () {}; }
+
+ var headers = JSON.parse(JSON.stringify(config.httpHeaders));
+ if (Object.keys(headers).length) {
+ return function (res) {
+ for (var header in headers) { res.setHeader(header, headers[header]); }
+ };
}
- var proto = (httpsOpts || config.useSecureWebsockets) ? 'wss://' : 'ws://';
- res.setHeader('Content-Security-Policy', [
- "default-src 'none'",
- "style-src 'unsafe-inline' 'self'",
-
- // No way to load ckeditor without unsafe-eval and unsafe-inline
- // https://dev.ckeditor.com/ticket/8584
- "script-src 'self' 'unsafe-eval' 'unsafe-inline'",
-
- "connect-src 'self' " + proto + host,
- "child-src 'self'",
- "font-src 'self'",
-
- // data: is used by codemirror, (insecure remote) images are included by people making
- // documents in ckeditor.
- "img-src data: *"
- ].join('; '));
-
- res.setHeader('X-XSS-Protection', '1; mode=block');
- res.setHeader('X-Content-Type-Options', 'nosniff');
- res.setHeader('X-Frame-Options', 'SAMEORIGIN');
+ return function () {};
+}());
+app.use(function (req, res, next) {
+ setHeaders(res);
next();
});
@@ -56,6 +43,10 @@ Fs.exists(__dirname + "/customize", function (e) {
console.log("Cryptpad is customizable, see customize.dist/readme.md for details");
});
+// FIXME I think this is a regression caused by a recent PR
+// correct this hack without breaking the contributor's intended behaviour.
+app.get(/\/(privacy|index|terms)\.html/, Express.static(__dirname + '/customize.dist'));
+
app.use("/customize", Express.static(__dirname + '/customize'));
app.use("/customize", Express.static(__dirname + '/customize.dist'));
app.use(/^\/[^\/]*$/, Express.static('customize'));
diff --git a/storage/README.md b/storage/README.md
index 7f406cf94..03117d95c 100644
--- a/storage/README.md
+++ b/storage/README.md
@@ -7,6 +7,8 @@ There are a few guidelines for creating a module:
Dependencies for your storage engine **should not** be added to Cryptpad.
Instead, write an adaptor, and place it in `cryptpad/storage/yourAdaptor.js`.
+Alternatively, storage adaptors can be published to npm, and required from your config (once installed).
+
## Your adaptor should conform to a simple API.
It must export an object with a single property, `create`, which is a function.
diff --git a/www/code/index.html b/www/code/index.html
index eee5ba3a8..bdef6b6f4 100644
--- a/www/code/index.html
+++ b/www/code/index.html
@@ -19,23 +19,35 @@
html, body {
overflow-y: hidden;
}
+ #iframe-container {
+ position: fixed;
+ top: 2.6em;
+ bottom: 0px;
+ right: 0px;
+ left: 0px;
+ padding: 0px;
+ }
#pad-iframe {
- position:fixed;
- top:2.5em;
- left:0px;
- bottom:0px;
- right:0px;
width:100%;
height:100%;
border:none;
margin:0;
padding:0;
overflow:hidden;
+ box-sizing: border-box;
+ }
+ /* We use !important here to override the 96% set to the element in DecorateToolbar.js
+ when we enter fullscreen mode. It allows us to avoid changing the iframe's size in JS */
+ #pad-iframe.fullscreen {
+ top: 0px;
+ height: 100% !important;
}
-
+
+
+
diff --git a/www/code/inner.html b/www/code/inner.html
index 970171ef0..ff887e387 100644
--- a/www/code/inner.html
+++ b/www/code/inner.html
@@ -31,24 +31,30 @@
diff --git a/www/pad/main.js b/www/pad/main.js
index 27f23f9ec..78b49fc8f 100644
--- a/www/pad/main.js
+++ b/www/pad/main.js
@@ -250,9 +250,16 @@ define([
};
var initializing = true;
- var userList = {}; // List of pretty name of all users (mapped with their server ID)
+ var userList = module.userList = {}; // List of pretty name of all users (mapped with their server ID)
var toolbarList; // List of users still connected to the channel (server IDs)
var addToUserList = function(data) {
+ var users = module.users;
+ if (users && users.length) {
+ for (var userKey in userList) {
+ if (users.indexOf(userKey) === -1) { delete userList[userKey]; }
+ }
+ }
+
for (var attrname in data) { userList[attrname] = data[attrname]; }
if(toolbarList && typeof toolbarList.onChange === "function") {
toolbarList.onChange(userList);
@@ -510,12 +517,16 @@ define([
toolbarList = info.userList;
var config = {
userData: userList,
- readOnly: readOnly
+ readOnly: readOnly,
+ ifrw: ifrw
};
if (readOnly) {delete config.changeNameID; }
toolbar = info.realtime.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, info.userList, config);
var $rightside = $bar.find('.' + Toolbar.constants.rightside);
+ var $userBlock = $bar.find('.' + Toolbar.constants.username);
+ var $editShare = $bar.find('.' + Toolbar.constants.editShare);
+ var $viewShare = $bar.find('.' + Toolbar.constants.viewShare);
var editHash;
var viewHash = Cryptpad.getViewHashFromKeys(info.channel, secret.keys);
@@ -529,8 +540,8 @@ define([
var usernameCb = function (newName) {
setName (newName);
};
- var $username = Cryptpad.createButton('username', true, {lastName: lastName}, usernameCb);
- $rightside.append($username);
+ var $username = Cryptpad.createButton('username', false, {lastName: lastName}, usernameCb);
+ $userBlock.append($username).hide();
});
/* add an export button */
@@ -560,10 +571,15 @@ define([
var $forgetPad = Cryptpad.createButton('forget', true, {}, forgetCb);
$rightside.append($forgetPad);
- if (!readOnly && viewHash) {
+ if (!readOnly) {
+ $editShare.append(Cryptpad.createButton('editshare', false, {editHash: editHash}));
+ }
+ if (viewHash) {
/* add a 'links' button */
- var $links = Cryptpad.createButton('readonly', true, {viewHash: viewHash});
- $rightside.append($links);
+ $viewShare.append(Cryptpad.createButton('viewshare', false, {viewHash: viewHash}));
+ if (!readOnly) {
+ $viewShare.append(Cryptpad.createButton('viewopen', false, {viewHash: viewHash}));
+ }
}
// set the hash
@@ -594,6 +610,7 @@ define([
//logging: true,
});
+ module.users = info.userList.users;
module.realtime = info.realtime;
var shjson = info.realtime.getUserDoc();
diff --git a/www/slide/index.html b/www/slide/index.html
index 3429318fb..b36464b0e 100644
--- a/www/slide/index.html
+++ b/www/slide/index.html
@@ -19,18 +19,22 @@
html, body {
overflow-y: hidden;
}
+ #iframe-container {
+ position: fixed;
+ top: 2.6em;
+ bottom: 0px;
+ right: 0px;
+ left: 0px;
+ padding: 0px;
+ }
#pad-iframe {
- position:fixed;
- top:2.5em;
- left:0px;
- bottom:0px;
- right:0px;
width:100%;
height:100%;
border:none;
margin:0;
padding:0;
overflow:hidden;
+ box-sizing: border-box;
}
/* We use !important here to override the 96% set to the element in DecorateToolbar.js
when we enter fullscreen mode. It allows us to avoid changing the iframe's size in JS */
@@ -38,10 +42,16 @@
top: 0px;
height: 100% !important;
}
-
+ #iframe-container.fullscreen {
+ top: 0px;
+ height: 100% !important;
+ }
+
-
+
+
+
diff --git a/www/slide/inner.html b/www/slide/inner.html
index ad933baa0..a3f3140ef 100644
--- a/www/slide/inner.html
+++ b/www/slide/inner.html
@@ -41,6 +41,10 @@
box-sizing: border-box;
position: relative;
}
+ body {
+ display: flex;
+ flex-flow: column;
+ }
#bar > button {
margin: 5px;
}
@@ -111,21 +115,17 @@
html {
height: 100%;
}
- body {
+ .CodeMirror {
height: 100%;
- margin: 0px;
}
- .CodeMirror {
- position: absolute;
- top: 25px;
- bottom: 0px;
- left: 0px;
- right: 0px;
- height: auto;
+ .cryptpad-toolbar {
+ padding: 0px 6px;
+ }
+ #cme_toolbox div.cryptpad-lag {
+ line-height: 24px;
}
#cme_toolbox {
font: 12px Arial,Helvetica,Tahoma,Verdana,sans-serif;
- height: 25px;
background: -webkit-linear-gradient(#EEEEEE, #DADADA); /* For Safari 5.1 to 6.0 */
background: -o-linear-gradient(white, #DDDDDD); /* For Opera 11.1 to 12.0 */
background: -moz-linear-gradient(white, #DDDDDD); /* For Firefox 3.6 to 15 */
diff --git a/www/slide/main.js b/www/slide/main.js
index 8a96dbd7a..1b57b2629 100644
--- a/www/slide/main.js
+++ b/www/slide/main.js
@@ -328,17 +328,68 @@ define([
onLocal();
};
+ var updateTitle = function (newTitle) {
+ if (newTitle === APP.title) { return; }
+ // Change the title now, and set it back to the old value if there is an error
+ var oldTitle = APP.title;
+ APP.title = newTitle;
+ setTabTitle();
+ Cryptpad.setPadTitle(newTitle, function (err, data) {
+ if (err) {
+ console.log("Couldn't set pad title");
+ console.error(err);
+ APP.title = oldTitle;
+ setTabTitle();
+ return;
+ }
+ });
+ };
+
+ var updateColors = function (text, back) {
+ if (text) {
+ textColor = text;
+ $modal.css('color', text);
+ $pad.contents().find('#' + SLIDE_COLOR_ID).css('color', text);
+ }
+ if (back) {
+ backColor = back;
+ $modal.css('background-color', back);
+ $pad.contents().find('#' + SLIDE_COLOR_ID).css('background', back);
+ $pad.contents().find('#' + SLIDE_BACKCOLOR_ID).css('color', back);
+ }
+ };
+
+ var updateMetadata = function(shjson) {
+ // Extract the user list (metadata) from the hyperjson
+ var json = (shjson === "") ? "" : JSON.parse(shjson);
+ if (json && json.metadata) {
+ if (json.metadata.users) {
+ var userData = json.metadata.users;
+ // Update the local user data
+ addToUserList(userData);
+ }
+ if (json.metadata.title) {
+ updateTitle(json.metadata.title);
+ }
+ updateColors(json.metadata.color, json.metadata.backColor);
+ }
+ };
+
var onInit = config.onInit = function (info) {
var $bar = $('#pad-iframe')[0].contentWindow.$('#cme_toolbox');
toolbarList = info.userList;
var config = {
userData: userList,
- readOnly: readOnly
+ readOnly: readOnly,
+ ifrw: $('#pad-iframe')[0].contentWindow
};
if (readOnly) {delete config.changeNameID; }
toolbar = module.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, info.userList, config);
var $rightside = $bar.find('.' + Toolbar.constants.rightside);
+ var $userBlock = $bar.find('.' + Toolbar.constants.username);
+ var $editShare = $bar.find('.' + Toolbar.constants.editShare);
+ var $viewShare = $bar.find('.' + Toolbar.constants.viewShare);
var editHash;
var viewHash = Cryptpad.getViewHashFromKeys(info.channel, secret.keys);
@@ -352,8 +403,8 @@ define([
var usernameCb = function (newName) {
setName (newName);
};
- var $username = Cryptpad.createButton('username', true, {lastName: lastName}, usernameCb);
- $rightside.append($username);
+ var $username = Cryptpad.createButton('username', false, {lastName: lastName}, usernameCb);
+ $userBlock.append($username).hide();
});
/* add an export button */
@@ -385,10 +436,15 @@ define([
var $forgetPad = Cryptpad.createButton('forget', true, {}, forgetCb);
$rightside.append($forgetPad);
- if (!readOnly && viewHash) {
+ if (!readOnly) {
+ $editShare.append(Cryptpad.createButton('editshare', false, {editHash: editHash}));
+ }
+ if (viewHash) {
/* add a 'links' button */
- var $links = Cryptpad.createButton('readonly', true, {viewHash: viewHash + '/present'});
- $rightside.append($links);
+ $viewShare.append(Cryptpad.createButton('viewshare', false, {viewHash: viewHash + '/present'}));
+ if (!readOnly) {
+ $viewShare.append(Cryptpad.createButton('viewopen', false, {viewHash: viewHash + '/present'}));
+ }
}
var $present = Cryptpad.createButton('present', true)
@@ -407,13 +463,14 @@ define([
}
$rightside.append($leavePresent);
- var $language = $('', {
- 'style': "margin-right: 10px;"
- }).text(Messages.type.slide + " (Markdown)");
- $rightside.append($language);
-
var configureTheme = function () {
+ /*var $language = $('', {
+ 'style': "margin-right: 10px;",
+ 'class': 'rightside-element'
+ }).text("Markdown");
+ $rightside.append($language);*/
+
/* Remember the user's last choice of theme using localStorage */
var themeKey = 'CRYPTPAD_CODE_THEME';
var lastTheme = localStorage.getItem(themeKey) || 'default';
@@ -422,6 +479,7 @@ define([
var $themeDropdown = $('