diff --git a/packages/testkit-backend/package-lock.json b/packages/testkit-backend/package-lock.json index 202b0a406..7fd416026 100644 --- a/packages/testkit-backend/package-lock.json +++ b/packages/testkit-backend/package-lock.json @@ -9,7 +9,6 @@ "version": "5.0.0-dev", "license": "Apache-2.0", "dependencies": { - "node-static": "^0.7.11", "ws": "^8.11.0" }, "devDependencies": { @@ -194,14 +193,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -399,17 +390,6 @@ "sourcemap-codec": "^1.4.4" } }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -422,11 +402,6 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, "node_modules/nise": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", @@ -449,22 +424,6 @@ "type-detect": "4.0.8" } }, - "node_modules/node-static": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/node-static/-/node-static-0.7.11.tgz", - "integrity": "sha512-zfWC/gICcqb74D9ndyvxZWaI1jzcoHmf4UTHWQchBNuNMxdBLJMDiUgZ1tjGLEIe/BMhj2DxKD8HOuc2062pDQ==", - "dependencies": { - "colors": ">=0.6.0", - "mime": "^1.2.9", - "optimist": ">=0.3.4" - }, - "bin": { - "static": "bin/cli.js" - }, - "engines": { - "node": ">= 0.4.1" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -474,15 +433,6 @@ "wrappy": "1" } }, - "node_modules/optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dependencies": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -681,14 +631,6 @@ "node": ">=4" } }, - "node_modules/wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -871,11 +813,6 @@ "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" - }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -1036,11 +973,6 @@ "sourcemap-codec": "^1.4.4" } }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -1050,11 +982,6 @@ "brace-expansion": "^1.1.7" } }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, "nise": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", @@ -1079,16 +1006,6 @@ } } }, - "node-static": { - "version": "0.7.11", - "resolved": "https://registry.npmjs.org/node-static/-/node-static-0.7.11.tgz", - "integrity": "sha512-zfWC/gICcqb74D9ndyvxZWaI1jzcoHmf4UTHWQchBNuNMxdBLJMDiUgZ1tjGLEIe/BMhj2DxKD8HOuc2062pDQ==", - "requires": { - "colors": ">=0.6.0", - "mime": "^1.2.9", - "optimist": ">=0.3.4" - } - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1098,15 +1015,6 @@ "wrappy": "1" } }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -1253,11 +1161,6 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/packages/testkit-backend/package.json b/packages/testkit-backend/package.json index 923ce63e0..09b0fe41e 100644 --- a/packages/testkit-backend/package.json +++ b/packages/testkit-backend/package.json @@ -34,7 +34,6 @@ "dependencies": { "neo4j-driver": "5.0.0-dev", "neo4j-driver-lite": "5.0.0-dev", - "node-static": "^0.7.11", "ws": "^8.11.0" }, "devDependencies": { diff --git a/packages/testkit-backend/src/controller/remote.js b/packages/testkit-backend/src/controller/remote.js index 83044c8a0..9121f5004 100644 --- a/packages/testkit-backend/src/controller/remote.js +++ b/packages/testkit-backend/src/controller/remote.js @@ -1,7 +1,7 @@ import Controller from './interface' import { WebSocketServer } from 'ws' import { createServer } from 'http' -import { Server } from 'node-static' +import { HttpStaticServer } from '../infrastructure' /** * RemoteController handles the requests by sending them a remote client. @@ -14,7 +14,9 @@ import { Server } from 'node-static' export default class RemoteController extends Controller { constructor (port) { super() - this._staticServer = new Server('./public') + this._staticServer = new HttpStaticServer({ + basePath: './public' + }) this._port = port this._wss = null this._ws = null diff --git a/packages/testkit-backend/src/infrastructure/http-static.server.js b/packages/testkit-backend/src/infrastructure/http-static.server.js new file mode 100644 index 000000000..7d6ffc346 --- /dev/null +++ b/packages/testkit-backend/src/infrastructure/http-static.server.js @@ -0,0 +1,67 @@ +import fs from 'fs' + +const DEFAULT_MIME_TYPES = { + html: 'text/html', + js: 'text/javascript' +} + +const DEFAULT_MIME_TYPE = 'text/plain' + +const DEFAULT_INDEX_FILE = '/index.html' + +/** + * This a very minimal implementation of a static files http server. + * + * This is intend to be used only in the ${@link RemoteController} scenario and + * this is not feature complete. + * + * Some security measures to avoid external elements to sniff to files out of the base + * path are in place. Like Directory Transversal. + */ +export class HttpStaticServer { + constructor ({ + basePath, + mimeTypes, + defaultMimeType, + indexFile + } = {}) { + this._basePath = basePath + this._mimeTypes = mimeTypes || DEFAULT_MIME_TYPES + this._indexFile = indexFile || DEFAULT_INDEX_FILE + this._defaultMimeType = defaultMimeType || DEFAULT_MIME_TYPE + } + + serve (request, response) { + if (request.method === 'GET') { + const file = request.url !== '/' ? request.url : this._indexFile + const filePath = `${this._basePath}${file}` + const [, extension, ...rest] = file.split('.') + if (rest.length > 0) { + writeError(response, 403, '403 Forbidden!') + return + } + + if (!fs.existsSync(filePath)) { + writeError(response, 404, '404 Not Found!') + return + } + + fs.readFile(filePath, 'utf-8', (err, message) => { + if (err) { + console.error(`HttpStaticServer: Error reading file ${filePath}`, err) + writeError(response, 500, '500 Internal Server Error!') + return + } + response.writeHead(200, { 'Content-Type': this._mimeTypes[extension] || this._defaultMimeType }) + response.write(message) + response.end() + }) + } + } +} + +function writeError (response, code, errorMessage) { + response.writeHead(code, { 'Content-Type': 'text/plain' }) + response.write(errorMessage) + response.end() +} diff --git a/packages/testkit-backend/src/infrastructure/index.js b/packages/testkit-backend/src/infrastructure/index.js new file mode 100644 index 000000000..ab9dce6f7 --- /dev/null +++ b/packages/testkit-backend/src/infrastructure/index.js @@ -0,0 +1 @@ +export { HttpStaticServer } from './http-static.server'