Merge branch 'staging' into dapsi

This commit is contained in:
yflory 2021-06-24 11:46:31 +02:00
commit 89844455bb
18 changed files with 905 additions and 550 deletions

File diff suppressed because it is too large Load diff

View file

@ -276,4 +276,13 @@ module.exports = {
* (false by default)
*/
verbose: false,
/* Surplus information:
*
* 'installMethod' is included in server telemetry to voluntarily
* indicate how many instances are using unofficial installation methods
* such as Docker.
*
*/
installMethod: 'unspecified',
};

View file

@ -20,6 +20,7 @@ var canonicalizeOrigin = function (s) {
module.exports.create = function (config) {
const Env = {
version: Package.version,
installMethod: config.installMethod || undefined,
httpUnsafeOrigin: canonicalizeOrigin(config.httpUnsafeOrigin),
httpSafeOrigin: canonicalizeOrigin(config.httpSafeOrigin),

View file

@ -4,6 +4,7 @@ const Stats = module.exports;
Stats.instanceData = function (Env) {
var data = {
version: Env.version,
installMethod: Env.installMethod,
domain: Env.myDomain,
subdomain: Env.mySubdomain,

203
package-lock.json generated
View file

@ -1,6 +1,6 @@
{
"name": "cryptpad",
"version": "4.6.0",
"version": "4.7.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -36,15 +36,15 @@
}
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==",
"dev": true
},
"@types/node": {
"version": "14.14.16",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.16.tgz",
"integrity": "sha512-naXYePhweTi+BMv11TgioE2/FXU4fSl29HAH1ffxVciNsH3rYXjNP2yM8wqmSm7jS20gM8TIklKiTen+1iVncw==",
"version": "15.12.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz",
"integrity": "sha512-zjQ69G564OCIWIOHSXyQEEDpdpGl+G348RAKY0XXy9Z5kU9Vzv1GMNnkar/ZJ8dzXB3COzD9Mo9NtRZ4xfgUww==",
"dev": true
},
"accepts": {
@ -57,9 +57,9 @@
}
},
"ajv": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
"integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==",
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"optional": true,
"requires": {
@ -187,16 +187,16 @@
"optional": true
},
"aws4": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
"integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==",
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==",
"dev": true,
"optional": true
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"base": {
@ -389,9 +389,9 @@
"optional": true
},
"chainpad-crypto": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/chainpad-crypto/-/chainpad-crypto-0.2.5.tgz",
"integrity": "sha512-K9vRsAspuX+uU1goXPz0CawpLIaOHq+1JP3WfDLqaz67LbCX/MLIUt9aMcSeIJcwZ9uMpqnbMGRktyVPoz6MCA==",
"version": "0.2.6",
"resolved": "https://registry.npmjs.org/chainpad-crypto/-/chainpad-crypto-0.2.6.tgz",
"integrity": "sha512-yk7bBj22rs9PaX6LiqQxiw+Vj/afBStsNP1xP/B4Uh9a8iyJ7JrSZJ2Hj3d6fyqxJlBrMAX82Aj5PCZb5dzzHw==",
"requires": {
"tweetnacl": "git+https://github.com/dchest/tweetnacl-js.git#v0.12.2"
},
@ -688,15 +688,15 @@
},
"dependencies": {
"domelementtype": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz",
"integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==",
"dev": true
},
"entities": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz",
"integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
"dev": true
}
}
@ -754,9 +754,9 @@
"dev": true
},
"errno": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
"integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
"integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
"dev": true,
"optional": true,
"requires": {
@ -973,9 +973,9 @@
"optional": true
},
"fast-deep-equal": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
"integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true,
"optional": true
},
@ -1069,9 +1069,9 @@
}
},
"forwarded": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
},
"fragment-cache": {
"version": "0.2.1",
@ -1134,9 +1134,9 @@
}
},
"glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"version": "7.1.7",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
"integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
@ -1191,9 +1191,9 @@
}
},
"graceful-fs": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
"version": "4.2.6",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
},
"har-schema": {
"version": "2.0.0",
@ -1203,13 +1203,13 @@
"optional": true
},
"har-validator": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
"integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
"integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
"dev": true,
"optional": true,
"requires": {
"ajv": "^6.5.5",
"ajv": "^6.12.3",
"har-schema": "^2.0.0"
}
},
@ -1346,9 +1346,9 @@
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"ipaddr.js": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
"integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
},
"is-accessor-descriptor": {
"version": "0.1.6",
@ -1527,16 +1527,16 @@
"optional": true
},
"jshint": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/jshint/-/jshint-2.11.0.tgz",
"integrity": "sha512-ooaD/hrBPhu35xXW4gn+o3SOuzht73gdBuffgJzrZBJZPGgGiiTvJEgTyxFvBO2nz0+X1G6etF8SzUODTlLY6Q==",
"version": "2.13.0",
"resolved": "https://registry.npmjs.org/jshint/-/jshint-2.13.0.tgz",
"integrity": "sha512-Nd+md9wIeyfDK+RGrbOBzwLONSTdihGMtyGYU/t7zYcN2EgUa4iuY3VK2oxtPYrW5ycTj18iC+UbhNTxe4C66g==",
"dev": true,
"requires": {
"cli": "~1.0.0",
"console-browserify": "1.1.x",
"exit": "0.1.x",
"htmlparser2": "3.8.x",
"lodash": "~4.17.11",
"lodash": "~4.17.21",
"minimatch": "~3.0.2",
"shelljs": "0.3.x",
"strip-json-comments": "1.0.x"
@ -1591,9 +1591,9 @@
}
},
"jszip": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.2.2.tgz",
"integrity": "sha512-NmKajvAFQpbg3taXQXr/ccS2wcucR1AZ+NtyWp2Nq7HHVsXhcJFR8p0Baf32C2yVvBylFWVeKf+WI2AnvlPhpA==",
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.6.0.tgz",
"integrity": "sha512-jgnQoG9LKnWO3mnVNBnfhkh0QknICd1FGSrXcgrl67zioyJ4wgx25o9ZqwNtrROSflGBCGYnJfjrIyRIby1OoQ==",
"dev": true,
"requires": {
"lie": "~3.3.0",
@ -1654,15 +1654,6 @@
"promise": "^7.1.1",
"request": "^2.83.0",
"source-map": "~0.6.0"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"optional": true
}
}
},
"lesshint": {
@ -1791,16 +1782,16 @@
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
},
"mime-db": {
"version": "1.43.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
"integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ=="
"version": "1.48.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz",
"integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ=="
},
"mime-types": {
"version": "2.1.26",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
"integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
"version": "2.1.31",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz",
"integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==",
"requires": {
"mime-db": "1.43.0"
"mime-db": "1.48.0"
}
},
"minimatch": {
@ -1841,9 +1832,9 @@
}
},
"mkdirp": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz",
"integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==",
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"dev": true,
"optional": true,
"requires": {
@ -1880,9 +1871,9 @@
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
},
"netflux-websocket": {
"version": "0.1.20",
"resolved": "https://registry.npmjs.org/netflux-websocket/-/netflux-websocket-0.1.20.tgz",
"integrity": "sha512-svFkw4ol4gmkcXKnx5kF/8tR9mmtTCDzUlLy4mSlcNl/4iWlbDmgwp/+aJ3nqtv8fg12m+DAFGX2+fbC0//dcg=="
"version": "0.1.21",
"resolved": "https://registry.npmjs.org/netflux-websocket/-/netflux-websocket-0.1.21.tgz",
"integrity": "sha512-Zjl5lefg8urC0a0T7YCPGiUgRsISZBsTZl1STylmQz8Bq4ohcZ8cP3r6VoCpeVcvJ1Y/e3ZCXPxndWlNP9Jfug=="
},
"nthen": {
"version": "0.1.8",
@ -2049,22 +2040,14 @@
"dev": true
},
"postcss": {
"version": "7.0.35",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
"integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
"version": "7.0.36",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz",
"integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==",
"dev": true,
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
"supports-color": "^6.1.0"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
}
}
},
"postcss-less": {
@ -2115,12 +2098,12 @@
}
},
"proxy-addr": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
"integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
"requires": {
"forwarded": "~0.1.2",
"ipaddr.js": "1.9.0"
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
}
},
"prr": {
@ -2131,9 +2114,9 @@
"optional": true
},
"psl": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz",
"integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==",
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
"integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==",
"dev": true,
"optional": true
},
@ -2193,9 +2176,9 @@
}
},
"repeat-element": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
"integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz",
"integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==",
"dev": true
},
"repeat-string": {
@ -2412,6 +2395,12 @@
"requires": {
"is-extendable": "^0.1.0"
}
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"dev": true
}
}
},
@ -2495,9 +2484,9 @@
}
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
},
"source-map-resolve": {
@ -2514,9 +2503,9 @@
}
},
"source-map-url": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz",
"integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==",
"dev": true
},
"split-string": {
@ -2793,9 +2782,9 @@
}
},
"uri-js": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
"optional": true,
"requires": {

View file

@ -1,20 +1,18 @@
[![An XWiki Labs Project](https://raw.githubusercontent.com/xwiki-labs/xwiki-labs-logo/master/projects/xwikilabs/xlabs-project.png "XWiki labs")](https://labs.xwiki.com/xwiki/bin/view/Main/WebHome)
# CryptPad
CryptPad is a collaboration suite that is end-to-end-encrypted and open-source. It is built to enable collaboration, synchronizing changes to documents in real time. Because all data is encrypted, the service and its administrators have no way of seeing the content being edited and stored.
![CryptPad screenshot](screenshot.png "Private real-time collaboration on a Rich Text document.")
CryptPad is the **Zero Knowledge** realtime collaborative editor.
Encryption carried out in your web browser protects the data from the server, the cloud
and the NSA. It relies on the [ChainPad] realtime engine.
<!--If you'd like to know more, please read [the Whitepaper]().-->
# Installation
Installing CryptPad is pretty straightforward. You can read all about it in the
[installation guide](https://github.com/xwiki-labs/cryptpad/wiki/Installation-guide).
## For development
It also contains information on keeping your instance of CryptPad up to date.
Our [developer guide](https://docs.cryptpad.fr/en/dev_guide/setup.html) provides instructions for setting up a local instance without HTTPS or our more advanced security features.
## For production
Configuring CryptPad for production requires a little more work, but the process is described in our [admin installation guide](https://docs.cryptpad.fr/en/admin_guide/installation.html). From there you can find more information about customization and maintenance.
## Current version
@ -24,33 +22,40 @@ The most recent version and all past release notes can be found [here](https://g
See [Cryptpad-Docker](https://github.com/xwiki-labs/cryptpad-docker) repository for details on how to get up-and-running with Cryptpad in Docker. This repository is maintained by the community and not officially supported.
# Security
CryptPad is *private*, not *anonymous*. Privacy protects your data, anonymity protects you.
As such, it is possible for a collaborator on the pad to include some silly/ugly/nasty things
in a CryptPad such as an image which reveals your IP address when your browser automatically
loads it or a script which plays Rick Astleys's greatest hits. It is possible for anyone
who does not have the key to be able to change anything in the pad or add anything, even the
server, however the clients will notice this because the content hashes in CryptPad will fail to
validate.
CryptPad offers a variety of collaborative tools that encrypt your data in your browser
before it is sent to the server and your collaborators. In the event that the server is
compromized the database holds encrypted data that is not of much value to attackers.
The server does have a certain power, it can send you evil javascript which does the wrong
thing (leaks the key or the data back to the server or to someone else). This is however an
[active attack] which makes it detectable. The NSA really hates doing these because they might
get caught and laughed at and humiliated in front of the whole world (again). If you're making
the NSA mad enough for them to use an active attack against you, Great Success Highfive, now take
the battery out of your computer before it spawns Agent Smith.
The code which performs the encryption is still loaded from the host server like any
other web page, so you still need to trust the administrator to keep their server secure
and to send you the right code. An expert can download code from the server and check
that it isn't doing anything malicious like leaking your encryption keys, which is why
this is considered an [active attack].
Still there are other low-lives in the world so using CryptPad over HTTPS is probably a good idea.
The platform is designed to minimize what data is exposed to its operators. User registration
and account access is based on a cryptographic key that is derived from your username
and password so the server never needs to see either and you don't need to worry about
whether they are being stored securely. It is impossible to verify whether a server's
operators are logging your IP or other activity, so if you consider this information
sensitive it is safest to assume it is being recorded and access your preferred instance
via [Tor browser].
A correctly configured instance has safeguards to prevent collaborators from doing some
nasty things like injecting scripts into collaborative documents or uploads. The project
is actively maintained and bugs that our safeguards don't catch tend to get fixed quickly.
For this reason it is best to only use instances that are running the most recent version,
which is currently on a three-week release cycle. It is difficult for a non-expert to
determine whether an instance is otherwise configured correctly, so we are actively
working on allowing administrators to opt in to a public directory of servers that
meet our strict criteria for safety.
# Translations
We'd like to make it easy for more people to use encryption in their routine activities.
As such, we've tried to make language-specific parts of CryptPad translatable. If you're
able to translate CryptPad's interface, and would like to help, please contact us!
You can also see [our translation guide](/customize.dist/translations/README.md).
CryptPad can be translated with nothing more than a web browser via our
[Weblate instance](https://weblate.cryptpad.fr/projects/cryptpad/app/).
More information about this can be found in [our translation guide](/customize.dist/translations/README.md).
# Contacting Us
@ -61,13 +66,13 @@ via our [GitHub issue tracker](https://github.com/xwiki-labs/cryptpad/issues/),
# Team
CryptPad is actively developed by a team at [XWiki SAS](https://www.xwiki.com), a company that has been building Open-Source software since 2004 with contributors from around the world. Between 2015 and 2019 it was funded by a research grant from the French state through [BPI France](https://www.bpifrance.fr/). It is currently financed by [NLnet PET](https://nlnet.nl/PET/), subscribers of CryptPad.fr and donations to our [Open-Collective campaign](https://opencollective.com/cryptpad).
CryptPad is actively developed by a team at [XWiki SAS](https://www.xwiki.com), a company that has been building Open-Source software since 2004 with contributors from around the world. Between 2015 and 2019 it was funded by a research grant from the French state through [BPI France](https://www.bpifrance.fr/). In the years since we have been funded by [NLnet PET](https://nlnet.nl/PET/), [NGI TRUST](https://www.ngi.eu/ngi-projects/ngi-trust/), [NGI DAPSI](https://dapsi.ngi.eu/), subscribers of CryptPad.fr, and donations to our [Open-Collective campaign](https://opencollective.com/cryptpad).
# Contributing
We love Open Source and we love contribution. Learn more about [contributing](https://docs.cryptpad.fr/en/how_to_contribute.html).
If you have any questions or comments, or if you're interested in contributing to Cryptpad, come say hi on IRC, `#cryptpad` on Freenode.
If you have any questions or comments, or if you're interested in contributing to Cryptpad, come say hi in our [Matrix channel](https://app.element.io/#/room/#cryptpad:matrix.xwiki.com).
# License
@ -78,5 +83,6 @@ published by the Free Software Foundation, either version 3 of the License, or (
any later version. If you wish to use this technology in a proprietary product, please contact
sales@xwiki.com.
[ChainPad]: https://github.com/xwiki-contrib/chainpad
[Tor browser]: https://www.torproject.org/download/
[active attack]: https://en.wikipedia.org/wiki/Attack_(computing)#Types_of_attack

View file

@ -17,6 +17,7 @@ define([
'/customize/application_config.js',
'/lib/calendar/tui-calendar.min.js',
'/calendar/export.js',
'/lib/datepicker/flatpickr.js',
'/common/inner/share.js',
'/common/inner/access.js',
@ -46,6 +47,7 @@ define([
AppConfig,
Calendar,
Export,
Flatpickr,
Share, Access, Properties
)
{
@ -169,9 +171,9 @@ define([
var obj = data.content[uid];
obj.title = obj.title || "";
obj.location = obj.location || "";
if (obj.isAllDay && obj.startDay) { obj.start = +new Date(obj.startDay); }
if (obj.isAllDay && obj.startDay) { obj.start = +Flatpickr.parseDate((obj.startDay)); }
if (obj.isAllDay && obj.endDay) {
var endDate = new Date(obj.endDay);
var endDate = Flatpickr.parseDate(obj.endDay);
endDate.setHours(23);
endDate.setMinutes(59);
endDate.setSeconds(59);

View file

@ -391,21 +391,32 @@ define([
assert(function (cb, msg) {
setWarningClass(msg);
msg.appendChild(h('span', [
"You haven't opted out of participation in Google's ",
code('FLoC'),
" targeted advertizing network. This can be done by adding a ",
code('permissions-policy'),
" HTTP header with a value of ",
code('interest-cohort=()'),
" in your reverse proxy's configuration. See the provided NGINX configuration file for an example. ",
h('p', [
link("https://www.eff.org/deeplinks/2021/04/am-i-floced-launch", 'Learn more'),
]),
]));
var printMessage = function (value) {
msg.appendChild(h('span', [
"This instance hasn't opted out of participation in Google's ",
code('FLoC'),
" targeted advertizing network. ",
"This can be done by setting a ",
code('permissions-policy'),
" HTTP header with a value of ",
code('"interest-cohort=()"'),
" in the configuration of its reverse proxy instead of the current value (",
code(value),
"). See the provided NGINX configuration file for an example. ",
h('p', [
link("https://www.eff.org/deeplinks/2021/04/am-i-floced-launch", 'Learn more'),
]),
]));
};
$.ajax('/?'+ (+new Date()), {
complete: function (xhr) {
cb(xhr.getResponseHeader('permissions-policy') === 'interest-cohort=()');
var header = xhr.getResponseHeader('permissions-policy');
printMessage(JSON.stringify(header));
cb(header === 'interest-cohort=()' || header);
},
});
});
@ -687,6 +698,88 @@ define([
});
});
var isHTTPS = function (host) {
return /^https:\/\//.test(host);
};
var isOnion = function (host) {
return /\.onion$/.test(host);
};
assert(function (cb, msg) {
// provide an exception for development instances
if (/http:\/\/localhost/.test(trimmedUnsafe)) { return void cb(true); }
// if both the main and sandbox domains are onion addresses
// then the HTTPS requirement is unnecessary
if (isOnion(trimmedUnsafe) && isOnion(trimmedSafe)) { return void cb(true); }
// otherwise expect that both inner and outer domains use HTTPS
setWarningClass(msg);
msg.appendChild(h('span', [
"Both ",
code('httpUnsafeOrigin'),
' and ',
code('httpSafeOrigin'),
' should be accessed via HTTPS for production use. ',
"This can be configured via ",
CONFIG_PATH(),
'. ',
RESTART_WARNING(),
]));
console.error("HTTPS?", trimmedUnsafe, trimmedSafe);
cb(isHTTPS(trimmedUnsafe) && isHTTPS(trimmedSafe));
});
assert(function (cb, msg) {
setWarningClass(msg);
$.ajax(cacheBuster('/'), {
dataType: 'text',
complete: function (xhr) {
var serverToken = xhr.getResponseHeader('server');
if (serverToken === null) { return void cb(true); }
var lowered = (serverToken || '').toLowerCase();
var family;
['Apache', 'Caddy', 'NGINX'].some(function (pattern) {
if (lowered.indexOf(pattern.toLowerCase()) !== -1) {
family = pattern;
return true;
}
});
var text = [
"This instance is set to respond with an HTTP ",
code("server"),
" header. This information can make it easier for attackers to find and exploit known vulnerabilities. ",
];
if (family === 'NGINX') {
msg.appendChild(h('span', text.concat([
"This can be addressed by setting ",
code("server_tokens off"),
" in your global NGINX config."
])));
return void cb(serverToken);
}
// handle other
msg.appendChild(h('span', text.concat([
"In this case, it appears that the host server is running ",
code(serverToken),
" instead of ",
code("NGINX"),
" as recommended. As such, you may not benefit from the latest security enhancements that are tested and maintained by the CryptPad development team.",
])));
cb(serverToken);
}
});
});
if (false) {
assert(function (cb, msg) {
msg.innerText = 'fake test to simulate failure';
@ -701,11 +794,18 @@ define([
};
var failureReport = function (obj) {
var printableValue = obj.output;
try {
printableValue = JSON.stringify(obj.output);
} catch (err) {
console.error(err);
}
return h('div.error', [
h('h5', obj.message),
h('table', [
row(["Failed test number", obj.test + 1]),
row(["Returned value", obj.output]),
row(["Returned value", code(printableValue)]),
]),
]);
};

View file

@ -1045,8 +1045,10 @@ define([
var privateDat = common.getMetadataMgr().getPrivateData();
var origin = privateDat.fileHost || privateDat.origin;
var src = data.src = data.src.slice(0,1) === '/' ? origin + data.src : data.src;
cfg.embed($('<media-tag src="' + src +
'" data-crypto-key="cryptpad:' + data.key + '"></media-tag>'), data);
cfg.embed(h('media-tag', {
src: src,
'data-crypto-key': 'cryptpad:' + data.key,
}), data);
});
}

View file

@ -92,7 +92,12 @@ define([
if (!obj || obj.error) { return; }
Object.keys(obj || {}).forEach(function (id) {
var t = obj[id];
var _keys = t.keys.drive || {};
var _keys = {};
try {
_keys = t.keys.drive || {};
} catch (err) {
console.error(err);
}
_keys.id = id;
if (!_keys.edPrivate) { return; }
keys.push(t.keys.drive);

View file

@ -8,11 +8,12 @@ define([
'/common/inner/common-mediatag.js',
'/common/media-tag.js',
'/customize/messages.js',
'/common/less.min.js',
'/common/highlight/highlight.pack.js',
'/lib/diff-dom/diffDOM.js',
'/bower_components/tweetnacl/nacl-fast.min.js',
'css!/common/highlight/styles/'+ (window.CryptPad_theme === 'dark' ? 'dark.css' : 'github.css')
],function ($, ApiConfig, Marked, Hash, Util, h, MT, MediaTag, Messages) {
],function ($, ApiConfig, Marked, Hash, Util, h, MT, MediaTag, Messages, Less) {
var DiffMd = {};
var Highlight = window.hljs;
@ -481,6 +482,75 @@ define([
}
};
var applyCSS = function (el, css) {
var style = h('style');
style.appendChild(document.createTextNode(css));
el.innerText = '';
el.appendChild(style);
};
// trim non-functional text from less input so that
// the compiler is only triggered when there has been a functional change
var canonicalizeLess = function (source) {
return (source || '')
// leading and trailing spaces are irrelevant
.trim()
// line comments are easy to disregard
.replace(/\/\/[^\n]*/g, '')
// lines with nothing but spaces and tabs can be ignored
.replace(/^[ \t]*$/g, '')
// consecutive newlines make no difference
.replace(/\n+/g, '');
};
var rendered_less = {};
var getRenderedLess = (function () {
var timeouts = {};
return function (src) {
if (!rendered_less[src]) { return; }
if (timeouts[src]) {
clearTimeout(timeouts[src]);
}
// avoid memory leaks by deleting cached content
// 15s after it was last accessed
timeouts[src] = setTimeout(function () {
delete rendered_less[src];
delete timeouts[src];
}, 15000);
return rendered_less[src];
};
}());
plugins.less = {
name: 'less',
attr: 'less-src',
render: function renderLess ($el, opt) {
var src = canonicalizeLess($el.text());
if (!src) { return; }
var el = $el[0];
var rendered = getRenderedLess(src);
if (rendered) { return void applyCSS(el, rendered); }
var scope = opt.scope.attr('id') || 'cp-app-code-preview-content';
var scoped_src = '#' + scope + ' { ' + src + '}';
//console.error("RENDERING LESS");
Less.render(scoped_src, {}, function (err, result) {
// the console is the only feedback for users to know that they did something wrong
// but less rendering isn't intended so much as a feature but a useful tool to avoid
// leaking styles from the preview into the rest of the DOM. This is an improvement.
if (err) {
// we assume the compiler is deterministic. Something that returns an error once
// will do it again, so avoid successive calls by caching a truthy
// but non-functional string to block them.
rendered_less[src] = ' ';
return void console.error(err);
}
var css = rendered_less[src] = result.css;
applyCSS(el, css);
});
},
};
var getAvailableCachedElement = function ($content, cache, src) {
var cached = cache[src];
if (!Array.isArray(cached)) { return; }
@ -554,7 +624,9 @@ define([
// caching their source as you go
$(newDomFixed).find('pre[data-plugin]').each(function (index, el) {
if (el.childNodes.length === 1 && el.childNodes[0].nodeType === 3) {
var plugin = plugins[el.getAttribute('data-plugin')];
var type = el.getAttribute('data-plugin');
var plugin = plugins[type];
console.log(type);
if (!plugin) { return; }
var src = canonicalizeMermaidSource(el.childNodes[0].wholeText);
el.setAttribute(plugin.attr, src);
@ -567,7 +639,8 @@ define([
var scrollTop = $parent.scrollTop();
// iterate over rendered mermaid charts
$content.find('pre[data-plugin]:not([processed="true"])').each(function (index, el) {
var plugin = plugins[el.getAttribute('data-plugin')];
var type = el.getAttribute('data-plugin');
var plugin = plugins[type];
if (!plugin) { return; }
// retrieve the attached source code which it was drawn
@ -729,9 +802,23 @@ define([
if (target) { target.scrollIntoView(); }
});
// transform style tags into pre tags with the same content
// to be handled by the less rendering plugin
$content.find('style').each(function (index, el) {
var parent = el.parentElement;
var pre = h('pre', {
'data-plugin': 'less',
'less-src': canonicalizeLess(el.innerText),
style: 'display: none',
}, el.innerText);
parent.replaceChild(pre, el);
});
// loop over plugin elements in the rendered content
$content.find('pre[data-plugin]').each(function (index, el) {
var plugin = plugins[el.getAttribute('data-plugin')];
var type = el.getAttribute('data-plugin');
var plugin = plugins[type];
if (!plugin) { return; }
var $el = $(el);
$el.off('contextmenu').on('contextmenu', function (e) {
@ -750,13 +837,17 @@ define([
// you can assume that the index of your rendered charts matches that
// of those in the markdown source.
var src = plugin.source[index];
el.setAttribute(plugin.attr, src);
if (src) {
el.setAttribute(plugin.attr, src);
}
var cached = getAvailableCachedElement($content, plugin.cache, src);
// check if you had cached a pre-rendered instance of the supplied source
if (typeof(cached) !== 'object') {
try {
plugin.render($el);
plugin.render($el, {
scope: $content,
});
} catch (e) { console.error(e); }
return;
}

View file

@ -8,7 +8,8 @@ define([
'/common/common-constants.js',
'/customize/messages.js',
'/customize/pages.js',
], function($, h, Hash, UI, UIElements, Util, Constants, Messages, Pages) {
'/lib/datepicker/flatpickr.js',
], function($, h, Hash, UI, UIElements, Util, Constants, Messages, Pages, Flatpickr) {
var handlers = {};
@ -477,7 +478,7 @@ define([
var nowDateStr = new Date().toLocaleDateString();
var startDate = new Date(start);
if (msg.isAllDay && msg.startDay) {
startDate = new Date(msg.startDay);
startDate = Flatpickr.parseDate(msg.startDay);
}
// Missed events

View file

@ -1344,7 +1344,6 @@
"mdToolbar_embed": "Datei einbetten",
"admin_checkupButton": "Diagnose ausführen",
"share_formAuditor": "Prüfer",
"form_viewResults": "Gehe zu Antworten",
"form_type_multicheck": "Mehrfachauswahl-Matrix",
"form_type_multiradio": "Einfachauswahl-Matrix",
"form_editMax": "Maximal auswählbare Optionen",
@ -1353,5 +1352,7 @@
"form_isClosed": "Dieses Formular wurde geschlossen am {0}",
"form_isOpen": "Dieses Formular ist offen",
"form_open": "Öffnen",
"form_viewButton": "Anzeigen"
"form_viewButton": "Anzeigen",
"form_poll_hint": "<i></i>: Ja, <i></i>: Nein, <i></i>: Akzeptabel",
"fc_open_formro": "Öffnen (als Teilnehmer)"
}

View file

@ -13,7 +13,8 @@
"todo": "Todo",
"contacts": "Contacts",
"sheet": "Tableur",
"teams": "Équipes"
"teams": "Équipes",
"form": "Formulaire"
},
"button_newpad": "Nouveau document texte",
"button_newcode": "Nouvelle page de code",
@ -1237,5 +1238,121 @@
"admin_supportInitGenerate": "Créer les clés",
"admin_supportPrivTitle": "Clé privée de la messagerie de support",
"admin_emailHint": "Entrez ici l'adresse email de contact pour votre instance",
"admin_emailTitle": "Email de l'administrateur"
"admin_emailTitle": "Email de l'administrateur",
"form_poll_hint": "<i></i> : Oui, <i></i> : Non, <i></i> : Acceptable",
"fc_open_formro": "Ouvrir (en tant que participant)",
"admin_provideAggregateStatisticsHint": "Vous pouvez choisir de fournir des mesures d'utilisation supplémentaires aux développeurs, telles que le nombre approximatif d'utilisateurs enregistrés et quotidiens de votre instance.",
"admin_provideAggregateStatisticsLabel": "Fournir des statistiques agrégées",
"admin_blockDailyCheckLabel": "Désactiver la télémétrie du serveur",
"admin_provideAggregateStatisticsTitle": "Agrégation statistique",
"admin_blockDailyCheckHint": "Les instances CryptPad envoient un message au serveur de l'équipe de développement lors de leur installation et une fois par jour par la suite. Cela permet à l'équipe de savoir quelles versions du logiciel sont en circulation. Vous pouvez refuser cette collecte de données ci-dessous. Le contenu de ces messages peut être examiné dans le log du serveur d'application.",
"admin_blockDailyCheckTitle": "Télémétrie du serveur",
"admin_removeDonateButtonLabel": "Ne pas promouvoir la campagnes de financement",
"admin_removeDonateButtonHint": "Le développement de CryptPad est partiellement financé par des bourses et des dons publics. Faire de la publicité pour notre campagne de financement sur votre instance aide l'équipe de développement à continuer son travail. Vous pouvez désactiver ces notifications.",
"admin_removeDonateButtonTitle": "Participation au financement participatif",
"admin_consentToContactLabel": "Je consens",
"admin_listMyInstanceTitle": "Lister mon instance dans les répertoires publics",
"admin_listMyInstanceHint": "Si votre instance est destinée à un usage public, vous pouvez la répertorier dans les listes d'instances. La télémétrie du serveur doit être activée pour que cela ait un effet.",
"admin_listMyInstanceLabel": "Lister cette instance",
"admin_consentToContactHint": "La télémétrie du serveur comprend l'addresse email de l'administrateur afin que l'équipe de développement puissent vous informer de problèmes sérieux avec le logiciel ou votre configuration. Elle ne sera jamais partagée, vendue ou utilisée à des fins de marketing. Consentez à être contacté si vous souhaitez être informé des problèmes critiques concernant votre serveur.",
"admin_consentToContactTitle": "Consentement à la prise de contact",
"admin_checkupButton": "Exécuter le diagnostic",
"admin_updateAvailableTitle": "Nouvelles versions",
"admin_updateAvailableHint": "Une nouvelle version de Cryptpad est disponible",
"admin_checkupHint": "CryptPad est doté d'une page qui diagnostique automatiquement les problèmes de configuration courants et suggère comment les corriger si nécessaire.",
"admin_checkupTitle": "Valider la configuration de l'instance",
"admin_updateAvailableButton": "Lire les notes de mise à jour",
"admin_cat_network": "Réseau",
"mdToolbar_embed": "Insérer un fichier",
"restrictedLoginPrompt": "Vous n'êtes pas autorisé à accéder à ce document. <a>Connectez-vous</a> si vous pensez que votre compte devrait y avoir accès.",
"copyToClipboard": "Copier",
"settings_driveRedirect": "Rediriger automatiquement",
"settings_driveRedirectHint": "La redirection de la page d'accueil vers le drive lors de la connexion n'est plus automatique. L'ancien comportement peut être activé ci-dessous.",
"settings_driveRedirectTitle": "Redirection depuis la page d'accueil",
"form_anonymousBox": "Répondre de manière anonyme",
"form_page": "Page {0}/{1}",
"form_clear": "Effacer",
"form_addMultipleHint": "Ajouter plusieurs dates et heures",
"form_addMultiple": "Tout ajouter",
"form_anonymous_blocked": "Les réponses anonymes sont bloquées pour ce formulaire. Merci de vous <a href=\"/login/\">connecter</a> ou de vous <a href=\"/register/\">enregistrer</a> pour répondre.",
"form_add_item": "Ajouter un objet",
"form_add_option": "Ajouter une option",
"form_newItem": "Nouvel objet",
"form_newOption": "Nouvelle option",
"form_defaultItem": "Objet {0}",
"form_defaultOption": "Option {0}",
"form_anonymous_off": "Bloquées",
"form_anonymous_on": "Autorisées",
"form_anonymous": "Réponses anonymes",
"form_willClose": "Ce formulaire fermera le {0}",
"form_isClosed": "Ce formulaire a été fermé le {0}",
"form_isOpen": "Ce formulaire est ouvert",
"form_removeEnd": "Annuler la clôture",
"form_setEnd": "Date de clôture",
"form_open": "Ouvrir",
"form_isPrivate": "Les réponses sont privées",
"form_isPublic": "Les réponses sont publiques",
"form_makePublicWarning": "Êtes-vous sûr de vouloir rendre les réponses à ce formulaire publiques ? Cette opération ne peut pas être annulée.",
"form_makePublic": "Publier les réponses",
"form_invalidQuestion": "Questions {0}",
"form_invalidWarning": "Certaines résponses contiennent des erreurs :",
"form_input_ph_url": "https://exemple.fr",
"form_input_ph_email": "courriel@exemple.fr",
"form_notAnswered": "<b>{0}</b> réponses vides",
"form_answerWarning": "Identité non confirmée",
"form_answerName": "Réponse de {0} le {1}",
"form_backButton": "Retour",
"form_viewButton": "Voir",
"form_answerAnonymous": "Réponse anonyme le {0}",
"form_showSummary": "Voir le résumé",
"form_showIndividual": "Voir les réponses individuelles",
"form_form": "Formulaire",
"form_editor": "Éditeur",
"form_results_empty": "Il n'y a pas de réponses",
"form_results": "Réponses",
"form_answered": "Vous avez déjà répondu à ce formulaire",
"form_cantFindAnswers": "Vos réponses à ce formulaire n'ont pas pu être récupérées.",
"form_updateWarning": "Mettre à jour avec erreurs",
"form_submitWarning": "Envoyer avec erreurs",
"form_delete": "Supprimer",
"form_sent": "Envoyé",
"form_reset": "Effacer",
"form_update": "Mettre à jour",
"form_submit": "Envoyer",
"form_maxLength": "Limite de caractères : {0}/{1}",
"form_maxOptions": "{0} réponse(s) maximum",
"form_duplicates": "Les doublons ont été supprimés",
"form_description_default": "Votre texte ici",
"form_type_page": "Saut de page",
"form_type_md": "Description",
"form_sort_hint": "Veuillez faire glisser ces éléments par ordre de préférence de 1 à {0}.",
"form_type_sort": "Liste ordonnée",
"form_type_poll": "Sondage",
"form_type_multicheck": "Grille de cases",
"form_type_checkbox": "Cases",
"form_type_multiradio": "Grille de Choix",
"form_type_radio": "Choix",
"form_type_textarea": "Paragraphe",
"form_type_input": "Texte",
"form_default": "Votre question ici ?",
"form_text_number": "Nombre",
"form_text_email": "Email",
"form_text_url": "Lien",
"form_text_text": "Texte",
"form_textType": "Type de texte",
"form_pollYourAnswers": "Vos réponses",
"form_pollTotal": "Total",
"form_poll_switch": "Inverser les axes",
"form_poll_time": "Heure",
"form_poll_day": "Jour",
"form_poll_text": "Texte",
"form_editType": "Type d'option",
"form_editMaxLength": "Nombre maximum de caractères",
"form_editMax": "Nombre maximum de réponses",
"form_editBlock": "Modifier",
"form_invalid": "Formulaire invalide",
"button_newform": "Nouveau formulaire",
"share_formView": "Participant",
"share_formAuditor": "Auditeur",
"share_formEdit": "Auteur"
}

View file

@ -1288,7 +1288,6 @@
"form_results_empty": "There are no responses",
"form_editor": "Editor",
"form_form": "Form",
"form_viewResults": "Go to responses",
"form_showIndividual": "Show individual answers",
"form_showSummary": "Show summary",
"form_answerAnonymous": "Anonymous answer on {0}",

View file

@ -906,7 +906,6 @@ define([
},
};
var TYPES = {
input: {
defaultOpts: {
@ -1590,7 +1589,6 @@ define([
];
$(pollHint).find('i').each(function (index) {
this.setAttribute('class', classes[index]);
// XXX accessibility options?
});
var tag = h('div.cp-form-type-poll-container', [
@ -2283,7 +2281,7 @@ define([
filter: "input, button, .CodeMirror, .cp-form-type-sort",
preventOnFilter: false,
draggable: ".cp-form-block",
forceFallback: true,
//forceFallback: true,
fallbackTolerance: 5,
onStart: function () {
$container.find('.cp-form-creator-add-inline').remove();
@ -2332,19 +2330,20 @@ define([
var $toolbarContainer = $('#cp-toolbar');
var helpMenu = framework._.sfCommon.createHelpMenu(['text', 'pad']);
$toolbarContainer.after(helpMenu.menu);
framework._.toolbar.$drawer.append(helpMenu.button);
var offlineEl = h('div.alert.alert-danger.cp-burn-after-reading', Messages.disconnected);
var oldFilter;
framework.onEditableChange(function (editable) {
if (editable) {
if (APP.mainSortable) { APP.mainSortable.options.filter = oldFilter; }
if (APP.mainSortable) {
APP.mainSortable.options.disabled = false;
}
if (!APP.isEditor) { $(offlineEl).remove(); }
$body.removeClass('cp-form-readonly');
$('.cp-form-creator-settings').find('input, button').removeAttr('disabled');
} else {
if (APP.mainSortable) {
oldFilter = APP.mainSortable.options.filter;
APP.mainSortable.options.filter = function () { return true; };
APP.mainSortable.options.disabled = true;
}
if (!APP.isEditor) { $('.cp-help-container').before(offlineEl); }
$body.addClass('cp-form-readonly');

20
www/form/templates.js Normal file
View file

@ -0,0 +1,20 @@
define([
'/customize/messages.js'
], function (Messages) {
return [{
id: 'a',
used: 1,
name: Messages.form_type_poll,
content: {
form: {
"1": {
type: 'md'
},
"2": {
type: 'poll'
}
},
order: ["1", "2"]
}
}];
});

View file

@ -133,9 +133,13 @@ define([
'account', // Msg.support_cat_account
'data', // Msg.support_cat_data
'bug', // Msg.support_cat_bug
// TODO report
'other' // Msg.support_cat_other
];
if (all) { categories.push('all'); } // Msg.support_cat_all
categories = categories.map(function (key) {
return {
tag: 'a',
@ -174,6 +178,7 @@ define([
var catContainer = h('div.cp-dropdown-container' + (title ? '.cp-hidden': ''));
makeCategoryDropdown(ctx, catContainer, function (key) {
$(category).val(key);
// TODO add a hint suggesting relevant information to include for the chosen category
});
var attachments, addAttachment;