From 1df3b0e68613c2439e31bee85ee80471822063a6 Mon Sep 17 00:00:00 2001 From: supaiku <1311798+supaiku0@users.noreply.github.com> Date: Tue, 9 Jul 2019 04:19:17 +0200 Subject: [PATCH] backport: some fixes for the deployer (#2782) --- .../unit/core-utils/is-whitelisted.test.ts | 23 +++++++++++++++++++ packages/core-api/src/defaults.ts | 2 +- .../core-container/src/registrars/plugin.ts | 8 +++++++ .../src/repositories/transactions.ts | 2 +- .../core-http-utils/src/plugins/whitelist.ts | 16 +++---------- .../src/core-container/container.ts | 1 + packages/core-utils/package.json | 3 ++- packages/core-utils/src/index.ts | 2 ++ packages/core-utils/src/is-whitelisted.ts | 21 +++++++++++++++++ packages/core-wallet-api/package.json | 6 +++-- packages/core-wallet-api/src/plugin.ts | 12 +++++++--- packages/core-wallet-api/src/server/index.ts | 12 ++++++++++ packages/core/bin/config/devnet/plugins.js | 1 - packages/core/bin/config/mainnet/plugins.js | 1 - packages/core/bin/config/testnet/plugins.js | 1 - yarn.lock | 8 +++++++ 16 files changed, 95 insertions(+), 24 deletions(-) create mode 100644 __tests__/unit/core-utils/is-whitelisted.test.ts create mode 100644 packages/core-utils/src/is-whitelisted.ts mode change 100755 => 100644 packages/core-wallet-api/src/server/index.ts diff --git a/__tests__/unit/core-utils/is-whitelisted.test.ts b/__tests__/unit/core-utils/is-whitelisted.test.ts new file mode 100644 index 0000000000..ade5380ec2 --- /dev/null +++ b/__tests__/unit/core-utils/is-whitelisted.test.ts @@ -0,0 +1,23 @@ +import "jest-extended"; + +import { isWhitelisted } from "../../../packages/core-utils/src"; + +describe("isWhitelisted", () => { + it("should allow everyone", () => { + expect(isWhitelisted(["*"], "127.0.0.1")).toBeTrue(); + expect(isWhitelisted(["*"], "192.168.1.1")).toBeTrue(); + expect(isWhitelisted(["*"], "168.1.1.1")).toBeTrue(); + }); + + it("should allow addresses with prefixes", () => { + expect(isWhitelisted(["127.*"], "127.0.0.1")).toBeTrue(); + expect(isWhitelisted(["127.*"], "127.0.0.2")).toBeTrue(); + expect(isWhitelisted(["127.*"], "128.0.0.1")).toBeFalse(); + }); + + it("should allow addresses with suffixes", () => { + expect(isWhitelisted(["*.127"], "1.1.1.127")).toBeTrue(); + expect(isWhitelisted(["*.127"], "1.1.1.127")).toBeTrue(); + expect(isWhitelisted(["*.127"], "1.1.1.128")).toBeFalse(); + }); +}); diff --git a/packages/core-api/src/defaults.ts b/packages/core-api/src/defaults.ts index adf9bff722..9084c06ca2 100644 --- a/packages/core-api/src/defaults.ts +++ b/packages/core-api/src/defaults.ts @@ -79,7 +79,6 @@ export const defaults = { "/api/v2/wallets/search", ], }, - whitelist: ["127.0.0.1", "::ffff:127.0.0.1"], plugins: [ { plugin: resolve(__dirname, "./versions/1"), @@ -90,4 +89,5 @@ export const defaults = { routes: { prefix: "/api/v2" }, }, ], + whitelist: ["*"], }; diff --git a/packages/core-container/src/registrars/plugin.ts b/packages/core-container/src/registrars/plugin.ts index 9afc871382..5ab9f8ccfc 100644 --- a/packages/core-container/src/registrars/plugin.ts +++ b/packages/core-container/src/registrars/plugin.ts @@ -100,11 +100,19 @@ export class PluginRegistrar { await this.registerWithContainer(item.plugin.extends); } + if (item.plugin.depends) { + await this.registerWithContainer(item.plugin.depends, this.plugins[item.plugin.depends]); + } + const name = item.plugin.name || item.plugin.pkg.name; const version = item.plugin.version || item.plugin.pkg.version; const defaults = item.plugin.defaults || item.plugin.pkg.defaults; const alias = item.plugin.alias || item.plugin.pkg.alias; + if (this.container.has(alias || name)) { + return; + } + if (!semver.valid(version)) { throw new Error( // tslint:disable-next-line:max-line-length diff --git a/packages/core-database-postgres/src/repositories/transactions.ts b/packages/core-database-postgres/src/repositories/transactions.ts index 66b1cf8bc4..23e64496c0 100644 --- a/packages/core-database-postgres/src/repositories/transactions.ts +++ b/packages/core-database-postgres/src/repositories/transactions.ts @@ -85,7 +85,7 @@ export class TransactionsRepository extends Repository implements Database.ITran .valueOf(), ); - return this.db.many(queries.transactions.feeStatistics, { age, minFee }); + return this.db.manyOrNone(queries.transactions.feeStatistics, { age, minFee }); } public async findAllByWallet( diff --git a/packages/core-http-utils/src/plugins/whitelist.ts b/packages/core-http-utils/src/plugins/whitelist.ts index 9fbaf172b3..5516ccf635 100644 --- a/packages/core-http-utils/src/plugins/whitelist.ts +++ b/packages/core-http-utils/src/plugins/whitelist.ts @@ -1,5 +1,5 @@ +import { isWhitelisted } from "@arkecosystem/core-utils"; import Boom from "@hapi/boom"; -import nm from "nanomatch"; export const whitelist = { name: "whitelist", @@ -8,18 +8,8 @@ export const whitelist = { server.ext({ type: "onRequest", async method(request, h) { - const remoteAddress: string = request.info.remoteAddress; - - if (Array.isArray(options.whitelist)) { - for (const ip of options.whitelist) { - try { - if (nm.isMatch(remoteAddress, ip)) { - return h.continue; - } - } catch { - return Boom.forbidden(); - } - } + if (isWhitelisted(options.whitelist, request.info.remoteAddress)) { + return h.continue; } return Boom.forbidden(); diff --git a/packages/core-interfaces/src/core-container/container.ts b/packages/core-interfaces/src/core-container/container.ts index b5e886000a..fd20c4438b 100644 --- a/packages/core-interfaces/src/core-container/container.ts +++ b/packages/core-interfaces/src/core-container/container.ts @@ -6,6 +6,7 @@ export interface IPluginDescriptor { required?: boolean; defaults?: any; extends?: string; + depends?: string; register(container: IContainer, options?: IPluginOptions): Promise; deregister?(container: IContainer, options?: any): Promise; } diff --git a/packages/core-utils/package.json b/packages/core-utils/package.json index 57ac068d50..5b62b1b078 100644 --- a/packages/core-utils/package.json +++ b/packages/core-utils/package.json @@ -25,7 +25,8 @@ "dayjs": "^1.8.14", "fast-json-parse": "^1.0.3", "got": "^9.6.0", - "immutable": "^4.0.0-rc.12" + "immutable": "^4.0.0-rc.12", + "nanomatch": "^1.2.13" }, "devDependencies": { "@types/got": "^9.4.4" diff --git a/packages/core-utils/src/index.ts b/packages/core-utils/src/index.ts index 70ed364609..be1d9ce74b 100644 --- a/packages/core-utils/src/index.ts +++ b/packages/core-utils/src/index.ts @@ -4,6 +4,7 @@ import { formatTimestamp } from "./format-timestamp"; import { hasSomeProperty } from "./has-some-property"; import { httpie, IHttpieResponse } from "./httpie"; import { isBlockChained } from "./is-block-chained"; +import { isWhitelisted } from "./is-whitelisted"; import { NSect } from "./nsect"; import { OrderedCappedMap } from "./ordered-capped-map"; import { calculateRound, isNewRound } from "./round-calculator"; @@ -21,6 +22,7 @@ export { httpie, IHttpieResponse, isBlockChained, + isWhitelisted, NSect, OrderedCappedMap, Plugins, diff --git a/packages/core-utils/src/is-whitelisted.ts b/packages/core-utils/src/is-whitelisted.ts new file mode 100644 index 0000000000..871646af01 --- /dev/null +++ b/packages/core-utils/src/is-whitelisted.ts @@ -0,0 +1,21 @@ +import nm from "nanomatch"; + +export const isWhitelisted = (whitelist: string[], remoteAddress: string): boolean => { + if (!Array.isArray(whitelist) || !whitelist.length) { + return true; + } + + if (Array.isArray(whitelist)) { + for (const ip of whitelist) { + try { + if (nm.isMatch(remoteAddress, ip)) { + return true; + } + } catch { + return false; + } + } + } + + return false; +}; diff --git a/packages/core-wallet-api/package.json b/packages/core-wallet-api/package.json index 8021a82c76..4e86272c5c 100644 --- a/packages/core-wallet-api/package.json +++ b/packages/core-wallet-api/package.json @@ -25,7 +25,9 @@ "@arkecosystem/core-http-utils": "^2.4.14", "@arkecosystem/core-interfaces": "^2.4.14", "@arkecosystem/core-utils": "^2.4.14", - "@hapi/h2o2": "^8.3.0" + "@hapi/h2o2": "^8.3.0", + "hapi-rate-limit": "^4.0.0", + "ip": "^1.1.5" }, "devDependencies": { "@types/hapi__h2o2": "^8.3.0" @@ -36,4 +38,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/packages/core-wallet-api/src/plugin.ts b/packages/core-wallet-api/src/plugin.ts index b662d83478..ecd39e376b 100644 --- a/packages/core-wallet-api/src/plugin.ts +++ b/packages/core-wallet-api/src/plugin.ts @@ -1,4 +1,6 @@ import { Container, Logger } from "@arkecosystem/core-interfaces"; +import { isWhitelisted } from "@arkecosystem/core-utils"; +import ip from "ip"; import { defaults } from "./defaults"; import { startServer } from "./server"; @@ -6,19 +8,23 @@ export const plugin: Container.IPluginDescriptor = { pkg: require("../package.json"), defaults, alias: "wallet-api", + depends: "@arkecosystem/core-api", async register(container: Container.IContainer, options) { - if (!options.enabled) { + if (!isWhitelisted(container.resolveOptions("api").whitelist, ip.address())) { container.resolvePlugin("logger").info("Wallet API is disabled"); + return undefined; } - container.resolvePlugin("logger").info("Starting Wallet API"); return startServer(options.server); }, async deregister(container: Container.IContainer, options) { - if (options.enabled) { + try { container.resolvePlugin("logger").info("Stopping Wallet API"); + await container.resolvePlugin("wallet-api").stop(); + } catch (error) { + // do nothing... } }, }; diff --git a/packages/core-wallet-api/src/server/index.ts b/packages/core-wallet-api/src/server/index.ts old mode 100755 new mode 100644 index b5db2dde0c..dbb93b9828 --- a/packages/core-wallet-api/src/server/index.ts +++ b/packages/core-wallet-api/src/server/index.ts @@ -26,6 +26,18 @@ export const startServer = async config => { server.route([{ method: "GET", path: "/config", ...handlers.config }]); if (app.has("api")) { + await server.register({ + plugin: require("hapi-rate-limit"), + options: app.resolveOptions("api").rateLimit, + }); + + await server.register({ + plugin: plugins.whitelist, + options: { + whitelist: app.resolveOptions("api").whitelist, + }, + }); + server.route({ method: "*", path: "/{path*}", diff --git a/packages/core/bin/config/devnet/plugins.js b/packages/core/bin/config/devnet/plugins.js index 7daa176b5b..1b24f07976 100644 --- a/packages/core/bin/config/devnet/plugins.js +++ b/packages/core/bin/config/devnet/plugins.js @@ -44,7 +44,6 @@ module.exports = { enabled: !process.env.CORE_API_DISABLED, host: process.env.CORE_API_HOST || "0.0.0.0", port: process.env.CORE_API_PORT || 4003, - whitelist: ["*"], }, "@arkecosystem/core-webhooks": { enabled: process.env.CORE_WEBHOOKS_ENABLED, diff --git a/packages/core/bin/config/mainnet/plugins.js b/packages/core/bin/config/mainnet/plugins.js index 8676d90338..dc34b2a416 100644 --- a/packages/core/bin/config/mainnet/plugins.js +++ b/packages/core/bin/config/mainnet/plugins.js @@ -43,7 +43,6 @@ module.exports = { enabled: !process.env.CORE_API_DISABLED, host: process.env.CORE_API_HOST || "0.0.0.0", port: process.env.CORE_API_PORT || 4003, - whitelist: ["*"], }, "@arkecosystem/core-webhooks": { enabled: process.env.CORE_WEBHOOKS_ENABLED, diff --git a/packages/core/bin/config/testnet/plugins.js b/packages/core/bin/config/testnet/plugins.js index f59872b3e4..2101644abe 100644 --- a/packages/core/bin/config/testnet/plugins.js +++ b/packages/core/bin/config/testnet/plugins.js @@ -44,7 +44,6 @@ module.exports = { enabled: !process.env.CORE_API_DISABLED, host: process.env.CORE_API_HOST || "0.0.0.0", port: process.env.CORE_API_PORT || 4003, - whitelist: ["*"], }, "@arkecosystem/core-webhooks": { enabled: process.env.CORE_WEBHOOKS_ENABLED, diff --git a/yarn.lock b/yarn.lock index 474ef425ef..904db614bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6936,6 +6936,14 @@ hapi-rate-limit@^3.1.2: boom "^7.2.0" joi "^14.3.0" +hapi-rate-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/hapi-rate-limit/-/hapi-rate-limit-4.0.0.tgz#4ba294a1f28aec9b7ac70e686796330f32fbe633" + integrity sha512-2Nkj/5358XLdH/jL6W1bLBrZm82CbCCEVsgFEBY07eRUhMMLBB8kteANnm62UgE7HZr54uDQjYk0cQGBj1bwuA== + dependencies: + "@hapi/boom" "^7.4.2" + "@hapi/joi" "^15.0.3" + hapi-trailing-slash@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/hapi-trailing-slash/-/hapi-trailing-slash-3.1.0.tgz#b400bad4129782a49f7cd1001d9cd2cada9fe368"