mirror of
https://github.com/Wolvan/poll.horse.git
synced 2024-11-24 13:47:59 +01:00
Implement header based safety features
Using the `helmet` package, a certain set of security critical headers are set to prevent XSS attacks and the like.
This commit is contained in:
parent
26a42333fe
commit
afc7bbad01
8 changed files with 114 additions and 98 deletions
|
@ -9,11 +9,11 @@
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Caveat:wght@400;500;700&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Caveat:wght@400;500;700&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="/static/css/main.css">
|
<link rel="stylesheet" href="/static/css/main.css">
|
||||||
<link rel="stylesheet" href="/static/css/index.css">
|
<link rel="stylesheet" href="/static/css/index.css">
|
||||||
<script type="text/javascript">
|
<script nonce="{{ CORS_SCRIPT_NONCE }}" type="text/javascript">
|
||||||
const MAX_POLL_OPTIONS = "{{ MAX_POLL_OPTIONS }}";
|
const MAX_POLL_OPTIONS = "{{ MAX_POLL_OPTIONS }}";
|
||||||
const MAX_CHARACTER_LENGTH = "{{ MAX_CHARACTER_LENGTH }}";
|
const MAX_CHARACTER_LENGTH = "{{ MAX_CHARACTER_LENGTH }}";
|
||||||
</script>
|
</script>
|
||||||
<script type="text/javascript" src="/static/js/index.js" defer="true" async="true"></script>
|
<script nonce="{{ CORS_SCRIPT_NONCE }}" type="text/javascript" src="/static/js/index.js" defer="true" async="true"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Caveat:wght@400;500;700&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Caveat:wght@400;500;700&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="/static/css/main.css">
|
<link rel="stylesheet" href="/static/css/main.css">
|
||||||
<link rel="stylesheet" href="/static/css/vote.css">
|
<link rel="stylesheet" href="/static/css/vote.css">
|
||||||
<script type="text/javascript" src="/static/vendor/js/textfit.js" defer="true"></script>
|
<script nonce="{{ CORS_SCRIPT_NONCE }}" type="text/javascript" src="/static/vendor/js/textfit.js" defer="true"></script>
|
||||||
<script type="text/javascript">
|
<script nonce="{{ CORS_SCRIPT_NONCE }}" type="text/javascript">
|
||||||
const textFitOptions = {
|
const textFitOptions = {
|
||||||
multiLine: true
|
multiLine: true
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,14 +9,14 @@
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Caveat:wght@400;500;700&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Caveat:wght@400;500;700&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="/static/css/main.css">
|
<link rel="stylesheet" href="/static/css/main.css">
|
||||||
<link rel="stylesheet" href="/static/css/result.css">
|
<link rel="stylesheet" href="/static/css/result.css">
|
||||||
<script type="text/javascript" src="/static/vendor/js/textfit.js" defer="true"></script>
|
<script nonce="{{ CORS_SCRIPT_NONCE }}" type="text/javascript" src="/static/vendor/js/textfit.js" defer="true"></script>
|
||||||
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js" defer="true"></script>
|
<script nonce="{{ CORS_SCRIPT_NONCE }}" type="text/javascript" src="https://www.gstatic.com/charts/loader.js" defer="true"></script>
|
||||||
<script type="text/javascript">
|
<script nonce="{{ CORS_SCRIPT_NONCE }}" type="text/javascript">
|
||||||
const POLL_VOTE_DATA_STRING = `{{ POLL_OPTION_VOTES }}`;
|
const POLL_VOTE_DATA_STRING = `{{ POLL_OPTION_VOTES }}`;
|
||||||
const POLL_BACKEND_URL = "{{ BACKEND_BASE_PATH }}";
|
const POLL_BACKEND_URL = "{{ BACKEND_BASE_PATH }}";
|
||||||
const POLL_ID = "{{ POLL_ID }}";
|
const POLL_ID = "{{ POLL_ID }}";
|
||||||
</script>
|
</script>
|
||||||
<script type="text/javascript" src="/static/js/result.js" defer="true"></script>
|
<script nonce="{{ CORS_SCRIPT_NONCE }}" type="text/javascript" src="/static/js/result.js" defer="true"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
|
|
164
package-lock.json
generated
164
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "poll-horse",
|
"name": "poll-horse",
|
||||||
"version": "1.0.1",
|
"version": "1.0.4",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "poll-horse",
|
"name": "poll-horse",
|
||||||
"version": "1.0.1",
|
"version": "1.0.4",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commander": "^8.3.0",
|
"commander": "^8.3.0",
|
||||||
|
@ -14,6 +14,7 @@
|
||||||
"cookie-parser": "^1.4.6",
|
"cookie-parser": "^1.4.6",
|
||||||
"express": "^4.17.2",
|
"express": "^4.17.2",
|
||||||
"fs-extra": "^10.0.0",
|
"fs-extra": "^10.0.0",
|
||||||
|
"helmet": "^5.0.2",
|
||||||
"mysql2": "^2.3.3",
|
"mysql2": "^2.3.3",
|
||||||
"node-fetch": "^2.6.6",
|
"node-fetch": "^2.6.6",
|
||||||
"node-persist": "^3.1.0"
|
"node-persist": "^3.1.0"
|
||||||
|
@ -830,10 +831,16 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/chokidar": {
|
"node_modules/chokidar": {
|
||||||
"version": "3.5.2",
|
"version": "3.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||||
"integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
|
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"anymatch": "~3.1.2",
|
"anymatch": "~3.1.2",
|
||||||
"braces": "~3.0.2",
|
"braces": "~3.0.2",
|
||||||
|
@ -1715,9 +1722,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/glob": {
|
"node_modules/glob": {
|
||||||
"version": "7.1.7",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||||
"integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
|
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fs.realpath": "^1.0.0",
|
"fs.realpath": "^1.0.0",
|
||||||
|
@ -1834,6 +1841,14 @@
|
||||||
"he": "bin/he"
|
"he": "bin/he"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/helmet": {
|
||||||
|
"version": "5.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/helmet/-/helmet-5.0.2.tgz",
|
||||||
|
"integrity": "sha512-QWlwUZZ8BtlvwYVTSDTBChGf8EOcQ2LkGMnQJxSzD1mUu8CCjXJZq/BXP8eWw4kikRnzlhtYo3lCk0ucmYA3Vg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/http-errors": {
|
"node_modules/http-errors": {
|
||||||
"version": "1.8.1",
|
"version": "1.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
|
||||||
|
@ -2232,32 +2247,32 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mocha": {
|
"node_modules/mocha": {
|
||||||
"version": "9.1.3",
|
"version": "9.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.0.tgz",
|
||||||
"integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==",
|
"integrity": "sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ungap/promise-all-settled": "1.1.2",
|
"@ungap/promise-all-settled": "1.1.2",
|
||||||
"ansi-colors": "4.1.1",
|
"ansi-colors": "4.1.1",
|
||||||
"browser-stdout": "1.3.1",
|
"browser-stdout": "1.3.1",
|
||||||
"chokidar": "3.5.2",
|
"chokidar": "3.5.3",
|
||||||
"debug": "4.3.2",
|
"debug": "4.3.3",
|
||||||
"diff": "5.0.0",
|
"diff": "5.0.0",
|
||||||
"escape-string-regexp": "4.0.0",
|
"escape-string-regexp": "4.0.0",
|
||||||
"find-up": "5.0.0",
|
"find-up": "5.0.0",
|
||||||
"glob": "7.1.7",
|
"glob": "7.2.0",
|
||||||
"growl": "1.10.5",
|
"growl": "1.10.5",
|
||||||
"he": "1.2.0",
|
"he": "1.2.0",
|
||||||
"js-yaml": "4.1.0",
|
"js-yaml": "4.1.0",
|
||||||
"log-symbols": "4.1.0",
|
"log-symbols": "4.1.0",
|
||||||
"minimatch": "3.0.4",
|
"minimatch": "3.0.4",
|
||||||
"ms": "2.1.3",
|
"ms": "2.1.3",
|
||||||
"nanoid": "3.1.25",
|
"nanoid": "3.2.0",
|
||||||
"serialize-javascript": "6.0.0",
|
"serialize-javascript": "6.0.0",
|
||||||
"strip-json-comments": "3.1.1",
|
"strip-json-comments": "3.1.1",
|
||||||
"supports-color": "8.1.1",
|
"supports-color": "8.1.1",
|
||||||
"which": "2.0.2",
|
"which": "2.0.2",
|
||||||
"workerpool": "6.1.5",
|
"workerpool": "6.2.0",
|
||||||
"yargs": "16.2.0",
|
"yargs": "16.2.0",
|
||||||
"yargs-parser": "20.2.4",
|
"yargs-parser": "20.2.4",
|
||||||
"yargs-unparser": "2.0.0"
|
"yargs-unparser": "2.0.0"
|
||||||
|
@ -2274,29 +2289,6 @@
|
||||||
"url": "https://opencollective.com/mochajs"
|
"url": "https://opencollective.com/mochajs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mocha/node_modules/debug": {
|
|
||||||
"version": "4.3.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
|
|
||||||
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"ms": "2.1.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"supports-color": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mocha/node_modules/debug/node_modules/ms": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/mocha/node_modules/ms": {
|
"node_modules/mocha/node_modules/ms": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
@ -2379,9 +2371,9 @@
|
||||||
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
|
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
|
||||||
},
|
},
|
||||||
"node_modules/nanoid": {
|
"node_modules/nanoid": {
|
||||||
"version": "3.1.25",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
|
||||||
"integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==",
|
"integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"nanoid": "bin/nanoid.cjs"
|
"nanoid": "bin/nanoid.cjs"
|
||||||
|
@ -2405,14 +2397,22 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-fetch": {
|
"node_modules/node-fetch": {
|
||||||
"version": "2.6.6",
|
"version": "2.6.7",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||||
"integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==",
|
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"whatwg-url": "^5.0.0"
|
"whatwg-url": "^5.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "4.x || >=6.0.0"
|
"node": "4.x || >=6.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"encoding": "^0.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"encoding": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-persist": {
|
"node_modules/node-persist": {
|
||||||
|
@ -3420,9 +3420,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/workerpool": {
|
"node_modules/workerpool": {
|
||||||
"version": "6.1.5",
|
"version": "6.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
|
||||||
"integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==",
|
"integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/wrap-ansi": {
|
"node_modules/wrap-ansi": {
|
||||||
|
@ -4149,9 +4149,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"chokidar": {
|
"chokidar": {
|
||||||
"version": "3.5.2",
|
"version": "3.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||||
"integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
|
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"anymatch": "~3.1.2",
|
"anymatch": "~3.1.2",
|
||||||
|
@ -4844,9 +4844,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"glob": {
|
"glob": {
|
||||||
"version": "7.1.7",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
|
||||||
"integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
|
"integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"fs.realpath": "^1.0.0",
|
"fs.realpath": "^1.0.0",
|
||||||
|
@ -4929,6 +4929,11 @@
|
||||||
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
|
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"helmet": {
|
||||||
|
"version": "5.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/helmet/-/helmet-5.0.2.tgz",
|
||||||
|
"integrity": "sha512-QWlwUZZ8BtlvwYVTSDTBChGf8EOcQ2LkGMnQJxSzD1mUu8CCjXJZq/BXP8eWw4kikRnzlhtYo3lCk0ucmYA3Vg=="
|
||||||
|
},
|
||||||
"http-errors": {
|
"http-errors": {
|
||||||
"version": "1.8.1",
|
"version": "1.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
|
||||||
|
@ -5220,54 +5225,37 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"mocha": {
|
"mocha": {
|
||||||
"version": "9.1.3",
|
"version": "9.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.0.tgz",
|
||||||
"integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==",
|
"integrity": "sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ungap/promise-all-settled": "1.1.2",
|
"@ungap/promise-all-settled": "1.1.2",
|
||||||
"ansi-colors": "4.1.1",
|
"ansi-colors": "4.1.1",
|
||||||
"browser-stdout": "1.3.1",
|
"browser-stdout": "1.3.1",
|
||||||
"chokidar": "3.5.2",
|
"chokidar": "3.5.3",
|
||||||
"debug": "4.3.2",
|
"debug": "4.3.3",
|
||||||
"diff": "5.0.0",
|
"diff": "5.0.0",
|
||||||
"escape-string-regexp": "4.0.0",
|
"escape-string-regexp": "4.0.0",
|
||||||
"find-up": "5.0.0",
|
"find-up": "5.0.0",
|
||||||
"glob": "7.1.7",
|
"glob": "7.2.0",
|
||||||
"growl": "1.10.5",
|
"growl": "1.10.5",
|
||||||
"he": "1.2.0",
|
"he": "1.2.0",
|
||||||
"js-yaml": "4.1.0",
|
"js-yaml": "4.1.0",
|
||||||
"log-symbols": "4.1.0",
|
"log-symbols": "4.1.0",
|
||||||
"minimatch": "3.0.4",
|
"minimatch": "3.0.4",
|
||||||
"ms": "2.1.3",
|
"ms": "2.1.3",
|
||||||
"nanoid": "3.1.25",
|
"nanoid": "3.2.0",
|
||||||
"serialize-javascript": "6.0.0",
|
"serialize-javascript": "6.0.0",
|
||||||
"strip-json-comments": "3.1.1",
|
"strip-json-comments": "3.1.1",
|
||||||
"supports-color": "8.1.1",
|
"supports-color": "8.1.1",
|
||||||
"which": "2.0.2",
|
"which": "2.0.2",
|
||||||
"workerpool": "6.1.5",
|
"workerpool": "6.2.0",
|
||||||
"yargs": "16.2.0",
|
"yargs": "16.2.0",
|
||||||
"yargs-parser": "20.2.4",
|
"yargs-parser": "20.2.4",
|
||||||
"yargs-unparser": "2.0.0"
|
"yargs-unparser": "2.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": {
|
|
||||||
"version": "4.3.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
|
|
||||||
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"ms": "2.1.2"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"ms": {
|
|
||||||
"version": "2.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
@ -5341,9 +5329,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nanoid": {
|
"nanoid": {
|
||||||
"version": "3.1.25",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
|
||||||
"integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==",
|
"integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"natural-compare": {
|
"natural-compare": {
|
||||||
|
@ -5358,9 +5346,9 @@
|
||||||
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
||||||
},
|
},
|
||||||
"node-fetch": {
|
"node-fetch": {
|
||||||
"version": "2.6.6",
|
"version": "2.6.7",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||||
"integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==",
|
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"whatwg-url": "^5.0.0"
|
"whatwg-url": "^5.0.0"
|
||||||
}
|
}
|
||||||
|
@ -6056,9 +6044,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"workerpool": {
|
"workerpool": {
|
||||||
"version": "6.1.5",
|
"version": "6.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
|
||||||
"integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==",
|
"integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"wrap-ansi": {
|
"wrap-ansi": {
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
"cookie-parser": "^1.4.6",
|
"cookie-parser": "^1.4.6",
|
||||||
"express": "^4.17.2",
|
"express": "^4.17.2",
|
||||||
"fs-extra": "^10.0.0",
|
"fs-extra": "^10.0.0",
|
||||||
|
"helmet": "^5.0.2",
|
||||||
"mysql2": "^2.3.3",
|
"mysql2": "^2.3.3",
|
||||||
"node-fetch": "^2.6.6",
|
"node-fetch": "^2.6.6",
|
||||||
"node-persist": "^3.1.0"
|
"node-persist": "^3.1.0"
|
||||||
|
|
|
@ -110,6 +110,10 @@ export default async function init(router: Router, polls: Storage): Promise<void
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
router.all("*", (req, res, next) => {
|
||||||
|
res.header("Content-Type", "application/json; charset=utf-8");
|
||||||
|
next();
|
||||||
|
});
|
||||||
// #region API
|
// #region API
|
||||||
router.get("/api/poll/:id", async (req, res) => {
|
router.get("/api/poll/:id", async (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -116,6 +116,10 @@ function xss(unsafe: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function init(router: Router): void {
|
export default function init(router: Router): void {
|
||||||
|
router.all("*", (req, res, next) => {
|
||||||
|
res.header("Content-Type", "text/html; charset=utf-8");
|
||||||
|
next();
|
||||||
|
});
|
||||||
router.get("/:id/r", async (req, res) => {
|
router.get("/:id/r", async (req, res) => {
|
||||||
const id = req.params.id;
|
const id = req.params.id;
|
||||||
try {
|
try {
|
||||||
|
@ -145,6 +149,7 @@ export default function init(router: Router): void {
|
||||||
"BACKEND_BASE_PATH": (program.opts().backendBaseUrl || ""),
|
"BACKEND_BASE_PATH": (program.opts().backendBaseUrl || ""),
|
||||||
"POLL_OPTION_VOTES": Buffer.from(JSON.stringify(Object.entries(poll.votes))).toString("base64"),
|
"POLL_OPTION_VOTES": Buffer.from(JSON.stringify(Object.entries(poll.votes))).toString("base64"),
|
||||||
"QR_CODE": `https://chart.googleapis.com/chart?cht=qr&chs=190x190&chld=L|1&chl=${ encodeURIComponent(`${ req.protocol }://${ req.headers.host }/${ id }`) }`,
|
"QR_CODE": `https://chart.googleapis.com/chart?cht=qr&chs=190x190&chld=L|1&chl=${ encodeURIComponent(`${ req.protocol }://${ req.headers.host }/${ id }`) }`,
|
||||||
|
"CORS_SCRIPT_NONCE": res.locals.cspNonce
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
@ -182,6 +187,7 @@ export default function init(router: Router): void {
|
||||||
"FORM_SUBMISSION_ERROR": xss(req.query.error + ""),
|
"FORM_SUBMISSION_ERROR": xss(req.query.error + ""),
|
||||||
"FORM_SUBMISSION_ERROR_SHOWN_CLASS": req.query.error ? "error-visible" : "",
|
"FORM_SUBMISSION_ERROR_SHOWN_CLASS": req.query.error ? "error-visible" : "",
|
||||||
"QR_CODE": `https://chart.googleapis.com/chart?cht=qr&chs=190x190&chld=L|1&chl=${ encodeURIComponent(`${ req.protocol }://${ req.headers.host }/${ id }`) }`,
|
"QR_CODE": `https://chart.googleapis.com/chart?cht=qr&chs=190x190&chld=L|1&chl=${ encodeURIComponent(`${ req.protocol }://${ req.headers.host }/${ id }`) }`,
|
||||||
|
"CORS_SCRIPT_NONCE": res.locals.cspNonce
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
@ -214,7 +220,8 @@ export default function init(router: Router): void {
|
||||||
"FORM_CAPTCHA": req.query.captcha === "true" ? "checked" : "",
|
"FORM_CAPTCHA": req.query.captcha === "true" ? "checked" : "",
|
||||||
"FORM_OPTION_DIVS": pollOptionDivs,
|
"FORM_OPTION_DIVS": pollOptionDivs,
|
||||||
"MAX_POLL_OPTIONS": MAX_POLL_OPTIONS,
|
"MAX_POLL_OPTIONS": MAX_POLL_OPTIONS,
|
||||||
"MAX_CHARACTER_LENGTH": MAX_CHARACTER_LENGTH
|
"MAX_CHARACTER_LENGTH": MAX_CHARACTER_LENGTH,
|
||||||
|
"CORS_SCRIPT_NONCE": res.locals.cspNonce
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
18
src/main.ts
18
src/main.ts
|
@ -2,13 +2,15 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
import loadConfig from "./config-loader";
|
import loadConfig from "./config-loader";
|
||||||
import { program } from "commander";
|
import { program } from "commander";
|
||||||
import express from "express";
|
import express, { Response } from "express";
|
||||||
import compression from "compression";
|
import compression from "compression";
|
||||||
import cookiepaser from "cookie-parser";
|
import cookiepaser from "cookie-parser";
|
||||||
import { resolve } from "path";
|
import { resolve } from "path";
|
||||||
import FlatFileStorage from "./FlatFileStorage";
|
import FlatFileStorage from "./FlatFileStorage";
|
||||||
import Storage from "./Storage";
|
import Storage from "./Storage";
|
||||||
import MySQLStorage from "./MySQLStorage";
|
import MySQLStorage from "./MySQLStorage";
|
||||||
|
import helmet from "helmet";
|
||||||
|
import crypto from "crypto";
|
||||||
|
|
||||||
async function main(): Promise<void> {
|
async function main(): Promise<void> {
|
||||||
await loadConfig([
|
await loadConfig([
|
||||||
|
@ -32,6 +34,20 @@ async function main(): Promise<void> {
|
||||||
app.use(express.urlencoded({ extended: false }));
|
app.use(express.urlencoded({ extended: false }));
|
||||||
app.use(compression());
|
app.use(compression());
|
||||||
app.use(cookiepaser());
|
app.use(cookiepaser());
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
res.locals.cspNonce = crypto.randomBytes(16).toString("hex");
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
app.use(helmet({
|
||||||
|
contentSecurityPolicy: {
|
||||||
|
directives: {
|
||||||
|
defaultSrc: ["'self'"],
|
||||||
|
scriptSrc: ["'self'", "'unsafe-inline'", "'strict-dynamic'", "https: 'self'", "http: 'self'", (req, res) => `'nonce-${(res as Response).locals.cspNonce}'`],
|
||||||
|
imgSrc: ["'self'", "data:", "https://chart.googleapis.com"],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
crossOriginEmbedderPolicy: false
|
||||||
|
}));
|
||||||
|
|
||||||
const storage: Storage = (opts.useMysql) ?
|
const storage: Storage = (opts.useMysql) ?
|
||||||
new MySQLStorage({
|
new MySQLStorage({
|
||||||
|
|
Loading…
Reference in a new issue