diff --git a/DOCKER-VARIABLES.md b/DOCKER-VARIABLES.md index e203f361..9ac0afb4 100644 --- a/DOCKER-VARIABLES.md +++ b/DOCKER-VARIABLES.md @@ -2,6 +2,8 @@ * `BASE_URL`: Base URL of the servce. Example: `https://tom.company.com` * `CRON_SERVICE`: Boolean (1 or 0): enable cron tasks or not + * `CROWDSEC_URI`: optional URI of local CrowdSec server + * `CROWDSEC_KEY`: CrowdSec API key _(required if `CROWDSEC_URI` is set) * `DATABASE_ENGINE`: `sqlite` or `pg` * `DATABASE_HOST`: * case `pg`: hostname diff --git a/Dockerfile b/Dockerfile index c5b9e43d..6f74baf4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,6 +2,8 @@ FROM node:18 env BASE_URL= \ CRON_SERVICE= \ + CROWDSEC_URI= \ + CROWDSEC_KEY= \ DATABASE_ENGINE= \ DATABASE_HOST= \ DATABASE_NAME= \ diff --git a/package-lock.json b/package-lock.json index b6c7a429..a7f7242b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "landing" ], "devDependencies": { + "@crowdsec/express-bouncer": "^0.1.0", "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-json": "^6.0.1", "@rollup/plugin-node-resolve": "^15.2.3", @@ -2254,6 +2255,38 @@ "node": ">=0.1.90" } }, + "node_modules/@crowdsec/express-bouncer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@crowdsec/express-bouncer/-/express-bouncer-0.1.0.tgz", + "integrity": "sha512-cS5ATNInb914yOubWznMB02lheDLImtIZ8A7n99sn7q2YI+P3Zt6G/Mttp+d1NL1PDUkFBMFlBreOslkcWwLFQ==", + "devOptional": true, + "dependencies": { + "ip-address": "^7.1.0", + "isomorphic-fetch": "^3.0.0", + "lodash": "^4.17.21", + "svg-captcha": "^1.4.0", + "winston": "^3.3.3" + } + }, + "node_modules/@crowdsec/express-bouncer/node_modules/ip-address": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-7.1.0.tgz", + "integrity": "sha512-V9pWC/VJf2lsXqP7IWJ+pe3P1/HCYGBMZrrnT62niLGjAfCbeiwXMUxaeHvnVlz19O27pvXP4azs+Pj/A0x+SQ==", + "devOptional": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "1.1.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@crowdsec/express-bouncer/node_modules/sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "devOptional": true + }, "node_modules/@dabh/diagnostics": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", @@ -13518,6 +13551,36 @@ "node": ">=0.10.0" } }, + "node_modules/isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "devOptional": true, + "dependencies": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + } + }, + "node_modules/isomorphic-fetch/node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "devOptional": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -18639,6 +18702,18 @@ "dev": true, "peer": true }, + "node_modules/opentype.js": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-0.7.3.tgz", + "integrity": "sha512-Veui5vl2bLonFJ/SjX/WRWJT3SncgiZNnKUyahmXCc2sa1xXW15u3R/3TN5+JFiP7RsjK5ER4HA5eWaEmV9deA==", + "devOptional": true, + "dependencies": { + "tiny-inflate": "^1.0.2" + }, + "bin": { + "ot": "bin/ot" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -23386,6 +23461,18 @@ } } }, + "node_modules/svg-captcha": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/svg-captcha/-/svg-captcha-1.4.0.tgz", + "integrity": "sha512-/fkkhavXPE57zRRCjNqAP3txRCSncpMx3NnNZL7iEoyAtYwUjPhJxW6FQTQPG5UPEmCrbFoXS10C3YdJlW7PDg==", + "devOptional": true, + "dependencies": { + "opentype.js": "^0.7.3" + }, + "engines": { + "node": ">=4.x" + } + }, "node_modules/swagger-jsdoc": { "version": "6.2.8", "resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-6.2.8.tgz", @@ -23948,6 +24035,12 @@ "globrex": "^0.1.2" } }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "devOptional": true + }, "node_modules/tinybench": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.1.tgz", @@ -24074,7 +24167,7 @@ "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "devOptional": true }, "node_modules/trim-newlines": { "version": "3.0.1", @@ -25704,13 +25797,19 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true + "devOptional": true + }, + "node_modules/whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "devOptional": true }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, + "devOptional": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -26350,6 +26449,9 @@ "express-validator": "^7.0.1", "ip-address": "^9.0.5", "lodash": "^4.17.21" + }, + "optionalDependencies": { + "@crowdsec/express-bouncer": "^0.1.0" } }, "packages/logger": { @@ -26477,6 +26579,7 @@ "validator": "^13.11.0" }, "optionalDependencies": { + "@crowdsec/express-bouncer": "^0.1.0", "ldapjs": "^2.3.3", "pg": "^8.10.0", "sqlite3": "^5.1.6" @@ -27990,6 +28093,37 @@ "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==" }, + "@crowdsec/express-bouncer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@crowdsec/express-bouncer/-/express-bouncer-0.1.0.tgz", + "integrity": "sha512-cS5ATNInb914yOubWznMB02lheDLImtIZ8A7n99sn7q2YI+P3Zt6G/Mttp+d1NL1PDUkFBMFlBreOslkcWwLFQ==", + "devOptional": true, + "requires": { + "ip-address": "^7.1.0", + "isomorphic-fetch": "^3.0.0", + "lodash": "^4.17.21", + "svg-captcha": "^1.4.0", + "winston": "^3.3.3" + }, + "dependencies": { + "ip-address": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-7.1.0.tgz", + "integrity": "sha512-V9pWC/VJf2lsXqP7IWJ+pe3P1/HCYGBMZrrnT62niLGjAfCbeiwXMUxaeHvnVlz19O27pvXP4azs+Pj/A0x+SQ==", + "devOptional": true, + "requires": { + "jsbn": "1.1.0", + "sprintf-js": "1.1.2" + } + }, + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "devOptional": true + } + } + }, "@dabh/diagnostics": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", @@ -30338,6 +30472,7 @@ "@twake/federation-server": { "version": "file:packages/federation-server", "requires": { + "@crowdsec/express-bouncer": "^0.1.0", "@twake/config-parser": "*", "@twake/crypto": "*", "@twake/logger": "*", @@ -30470,6 +30605,7 @@ "@twake/server": { "version": "file:packages/tom-server", "requires": { + "@crowdsec/express-bouncer": "^0.1.0", "@twake/matrix-application-server": "*", "@twake/matrix-identity-server": "*", "ldapjs": "^2.3.3", @@ -36510,6 +36646,27 @@ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true }, + "isomorphic-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", + "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", + "devOptional": true, + "requires": { + "node-fetch": "^2.6.1", + "whatwg-fetch": "^3.4.1" + }, + "dependencies": { + "node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "devOptional": true, + "requires": { + "whatwg-url": "^5.0.0" + } + } + } + }, "istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -40384,6 +40541,15 @@ "dev": true, "peer": true }, + "opentype.js": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-0.7.3.tgz", + "integrity": "sha512-Veui5vl2bLonFJ/SjX/WRWJT3SncgiZNnKUyahmXCc2sa1xXW15u3R/3TN5+JFiP7RsjK5ER4HA5eWaEmV9deA==", + "devOptional": true, + "requires": { + "tiny-inflate": "^1.0.2" + } + }, "optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -43914,6 +44080,15 @@ "strip-indent": "^3.0.0" } }, + "svg-captcha": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/svg-captcha/-/svg-captcha-1.4.0.tgz", + "integrity": "sha512-/fkkhavXPE57zRRCjNqAP3txRCSncpMx3NnNZL7iEoyAtYwUjPhJxW6FQTQPG5UPEmCrbFoXS10C3YdJlW7PDg==", + "devOptional": true, + "requires": { + "opentype.js": "^0.7.3" + } + }, "swagger-jsdoc": { "version": "6.2.8", "resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-6.2.8.tgz", @@ -44383,6 +44558,12 @@ "globrex": "^0.1.2" } }, + "tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "devOptional": true + }, "tinybench": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.5.1.tgz", @@ -44478,7 +44659,7 @@ "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true + "devOptional": true }, "trim-newlines": { "version": "3.0.1", @@ -45532,13 +45713,19 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true + "devOptional": true + }, + "whatwg-fetch": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz", + "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==", + "devOptional": true }, "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dev": true, + "devOptional": true, "requires": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" diff --git a/package.json b/package.json index 899ff1db..5578f2e0 100644 --- a/package.json +++ b/package.json @@ -36,11 +36,13 @@ "test": "lerna run test" }, "devDependencies": { + "@crowdsec/express-bouncer": "^0.1.0", "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-json": "^6.0.1", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.5", + "@small-tech/syswide-cas": "^6.0.2", "@types/events": "^3.0.0", "@types/express": "^4.17.17", "@types/jest": "^29.4.0", @@ -76,7 +78,6 @@ "rimraf": "^4.3.1", "rollup": "^3.18.0", "rollup-plugin-cleaner": "^1.0.0", - "@small-tech/syswide-cas": "^6.0.2", "supertest": "^6.3.3", "swagger-jsdoc": "^6.2.8", "swagger-ui-dist": "^4.18.3", diff --git a/packages/federation-server/Dockerfile b/packages/federation-server/Dockerfile index c517649b..cb0511d5 100644 --- a/packages/federation-server/Dockerfile +++ b/packages/federation-server/Dockerfile @@ -1,6 +1,8 @@ FROM node:18 ENV BASE_URL= \ + CRON_SERVICE= \ + CROWDSEC_URI= \ DATABASE_ENGINE= \ DATABASE_HOST= \ DATABASE_NAME= \ diff --git a/packages/federation-server/package.json b/packages/federation-server/package.json index 4b6a6ab4..8aaeb317 100644 --- a/packages/federation-server/package.json +++ b/packages/federation-server/package.json @@ -46,5 +46,8 @@ "express-validator": "^7.0.1", "ip-address": "^9.0.5", "lodash": "^4.17.21" + }, + "optionalDependencies": { + "@crowdsec/express-bouncer": "^0.1.0" } } diff --git a/packages/federation-server/server.mjs b/packages/federation-server/server.mjs index 60949215..403a4dcb 100644 --- a/packages/federation-server/server.mjs +++ b/packages/federation-server/server.mjs @@ -50,8 +50,31 @@ const conf = { const federationServer = new FederationServer(conf) const app = express() +const promises = [federationServer.ready] -federationServer.ready +if (process.env.CROWDSEC_URI) { + if (!process.env.CROWDSEC_KEY) { + throw new Error('Missing CROWDSEC_KEY') + } + promises.push( + new Promise((resolve, reject) => { + import('@crowdsec/express-bouncer') + .then((m) => + m.default({ + url: process.env.CROWDSEC_URI, + apiKey: process.env.CROWDSEC_KEY + }) + ) + .then((crowdsecMiddleware) => { + app.use(crowdsecMiddleware) + resolve() + }) + .catch(reject) + }) + ) +} + +Promise.all(promises) .then(() => { app.use(federationServer.routes) const port = process.argv[2] != null ? parseInt(process.argv[2]) : 3000 diff --git a/packages/tom-server/package.json b/packages/tom-server/package.json index ada48c90..b4bdd36e 100644 --- a/packages/tom-server/package.json +++ b/packages/tom-server/package.json @@ -47,6 +47,7 @@ "validator": "^13.11.0" }, "optionalDependencies": { + "@crowdsec/express-bouncer": "^0.1.0", "ldapjs": "^2.3.3", "pg": "^8.10.0", "sqlite3": "^5.1.6" diff --git a/server.mjs b/server.mjs index 6c04dd14..486a1a09 100644 --- a/server.mjs +++ b/server.mjs @@ -71,6 +71,29 @@ if (process.argv[2] === 'generate') { } else { const tomServer = new TomServer(conf) const app = express() + const promises = [tomServer.ready] + + if (process.env.CROWDSEC_URI) { + if (!process.env.CROWDSEC_KEY) { + throw new Error('Missing CROWDSEC_KEY') + } + promises.push( + new Promise((resolve, reject) => { + import('@crowdsec/express-bouncer') + .then((m) => + m.default({ + url: process.env.CROWDSEC_URI, + apiKey: process.env.CROWDSEC_KEY + }) + ) + .then((crowdsecMiddleware) => { + app.use(crowdsecMiddleware) + resolve() + }) + .catch(reject) + }) + ) + } app.use( '/build', @@ -95,7 +118,7 @@ if (process.argv[2] === 'generate') { }) ) - tomServer.ready + Promise.all(promises) .then(() => { app.use(tomServer.endpoints) const port = process.argv[2] != null ? parseInt(process.argv[2]) : 3000