diff --git a/.travis.yml b/.travis.yml index d9ccad3fc0c..c4b14acd46d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: node_js node_js: - - 10 - 12 - 14 diff --git a/packages/cactus-cmd-api-server/package-lock.json b/packages/cactus-cmd-api-server/package-lock.json index defb51dc2e2..eac2ae8f411 100644 --- a/packages/cactus-cmd-api-server/package-lock.json +++ b/packages/cactus-cmd-api-server/package-lock.json @@ -136,6 +136,15 @@ "@types/node": "*" } }, + "@types/semver": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.1.tgz", + "integrity": "sha512-ooD/FJ8EuwlDKOI6D9HWxgIgJjMg2cuziXm/42npDC8y4NjxplBUn9loewZiBNCt44450lHAU0OSb51/UqXeag==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/serve-static": { "version": "1.13.3", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz", @@ -938,6 +947,11 @@ } } }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" + }, "send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", diff --git a/packages/cactus-cmd-api-server/package.json b/packages/cactus-cmd-api-server/package.json index fe8c91c9eac..9a4cf5a805d 100755 --- a/packages/cactus-cmd-api-server/package.json +++ b/packages/cactus-cmd-api-server/package.json @@ -16,13 +16,10 @@ "types": "dist/types/main/typescript/index.d.ts", "scripts": { "tsc": "tsc --project ./tsconfig.json", - "webpack": "npm-run-all webpack:dev webpack:prod", - "webpack:dev": "npm-run-all webpack:dev:node webpack:dev:web", "webpack:dev:web": "webpack --env=dev --target=web --config ../../webpack.config.js", "webpack:dev:node": "webpack --env=dev --target=node --config ../../webpack.config.js", - "webpack:prod": "npm-run-all webpack:prod:node webpack:prod:web", "webpack:prod:web": "webpack --env=prod --target=web --config ../../webpack.config.js", "webpack:prod:node": "webpack --env=prod --target=node --config ../../webpack.config.js" @@ -82,6 +79,7 @@ "js-sha3": "0.8.0", "node-fetch": "3.0.0-beta.4", "secp256k1": "4.0.0", + "semver": "7.3.2", "sha3": "2.1.2", "typescript-optional": "2.0.1", "uuid": "7.0.2" @@ -94,6 +92,7 @@ "@types/joi": "14.3.4", "@types/multer": "1.4.2", "@types/secp256k1": "3.5.3", + "@types/semver": "7.3.1", "@types/uuid": "7.0.2" } } diff --git a/packages/cactus-cmd-api-server/src/main/typescript/api-server.ts b/packages/cactus-cmd-api-server/src/main/typescript/api-server.ts index 222aa57a2ca..bc3bea5a760 100644 --- a/packages/cactus-cmd-api-server/src/main/typescript/api-server.ts +++ b/packages/cactus-cmd-api-server/src/main/typescript/api-server.ts @@ -1,5 +1,6 @@ import path from "path"; import { Server } from "http"; +import { gte } from "semver"; import express, { Express, Request, @@ -18,7 +19,10 @@ import { IPluginWebService, PluginRegistry, } from "@hyperledger/cactus-core-api"; -import { ICactusApiServerOptions as ICactusApiServerConfig } from "./config/config-service"; +import { + ICactusApiServerOptions as ICactusApiServerConfig, + ConfigService, +} from "./config/config-service"; import { CACTUS_OPEN_API_JSON } from "./openapi-spec"; import { Logger, LoggerProvider } from "@hyperledger/cactus-common"; import { Servers } from "./common/servers"; @@ -49,6 +53,7 @@ export class ApiServer { } async start(): Promise { + this.checkNodeVersion(); try { await this.startCockpitFileServer(); await this.startApiServer(); @@ -59,6 +64,25 @@ export class ApiServer { } } + /** + * Verifies that the currently running NodeJS process is at least of a certain + * NodeJS version as specified by the configuration. + * + * @throws {Error} if the version contraint is not satisfied by the runtime. + */ + public checkNodeVersion(currentVersion: string = process.version): void { + if (gte(this.options.config.minNodeVersion, currentVersion)) { + const msg = + `ApiServer#checkNodeVersion() detected NodeJS ` + + `v${process.version} that is outdated as per the configuration. ` + + `If you must run on this NodeJS version you can override the minimum ` + + `acceptable version via config parameters of the API server. ` + + `Though doing so may lead to vulnerabilities in your deployment. ` + + `You've been warned.`; + throw new Error(msg); + } + } + public getHttpServerApi(): Server | null { return this.httpServerApi; } diff --git a/packages/cactus-cmd-api-server/src/main/typescript/config/config-service.ts b/packages/cactus-cmd-api-server/src/main/typescript/config/config-service.ts index c87f0101dac..15d3cbf625e 100644 --- a/packages/cactus-cmd-api-server/src/main/typescript/config/config-service.ts +++ b/packages/cactus-cmd-api-server/src/main/typescript/config/config-service.ts @@ -33,6 +33,7 @@ export interface ICactusApiServerOptions { privateKey: string; keychainSuffixPublicKey: string; keychainSuffixPrivateKey: string; + minNodeVersion: string; } export class ConfigService { @@ -107,6 +108,17 @@ export class ConfigService { env: "LOG_LEVEL", arg: "log-level", }, + minNodeVersion: { + doc: + "Determines the lower bound of NodeJS version that the API " + + "server will be willing to start on. Defaults to v12 because v10 " + + "does not support TLS v1.3. If you must run on Node 10, just set " + + "this configuration parameter to 10.0.0 for example.", + format: ConfigService.formatNonBlankString, + default: "12.0.0", + env: "MIN_NODE_VERSION", + arg: "min-node-version", + }, cockpitHost: { doc: "The host to bind the Cockpit webserver to. Secure default is: 127.0.0.1. Use 0.0.0.0 to bind for any host.", @@ -272,6 +284,7 @@ export class ConfigService { configFile: ".config.json", cactusNodeId: uuidV4(), logLevel: "debug", + minNodeVersion: (schema.minNodeVersion as SchemaObj).default, publicKey, privateKey, apiCorsDomainCsv: (schema.apiCorsDomainCsv as SchemaObj).default,