From 6fd40d0d88d31f918792355501de8a83f7a1427f Mon Sep 17 00:00:00 2001 From: Micah Riggan Date: Wed, 2 Jan 2019 13:53:51 -0500 Subject: [PATCH] fix(node): config properties could be undefined Object.assign doesn't work with nested objects, so various things can be undefined --- packages/bitcore-node/src/config.ts | 21 ++++++------------- .../bitcore-node/src/models/transaction.ts | 3 ++- .../chain-state/internal/internal.ts | 4 +++- .../bitcore-node/src/routes/api/wallet.ts | 5 +++-- .../bitcore-node/src/routes/middleware.ts | 5 +++-- packages/bitcore-node/src/services/config.ts | 10 ++++++--- packages/bitcore-node/src/services/p2p.ts | 2 +- packages/bitcore-node/src/services/socket.ts | 2 +- packages/bitcore-node/src/types/Config.d.ts | 14 ++++++------- 9 files changed, 33 insertions(+), 33 deletions(-) diff --git a/packages/bitcore-node/src/config.ts b/packages/bitcore-node/src/config.ts index ab129b5b8c4..c7de5d8acf6 100644 --- a/packages/bitcore-node/src/config.ts +++ b/packages/bitcore-node/src/config.ts @@ -1,6 +1,6 @@ import { homedir, cpus } from 'os'; import parseArgv from './utils/parseArgv'; -import { ConfigType } from "./types/Config"; +import { ConfigType } from './types/Config'; let program = parseArgv([], ['config']); function findConfig(): ConfigType | undefined { @@ -60,7 +60,6 @@ const Config = function(): ConfigType { chains: {}, services: { api: { - enabled: true, rateLimiter: { whitelist: ['::ffff:127.0.0.1'] }, @@ -69,23 +68,15 @@ const Config = function(): ConfigType { allowUnauthenticatedCalls: false } }, - event: { - enabled: true - }, - p2p: { - enabled: true - }, - socket: { - enabled: true - }, - storage: { - enabled: true - } + event: {}, + p2p: {}, + socket: {}, + storage: {} } }; let foundConfig = findConfig(); - Object.assign(config, foundConfig, {}); + Object.assign(config.services, foundConfig, {}); if (!Object.keys(config.chains).length) { Object.assign(config.chains, { BTC: { diff --git a/packages/bitcore-node/src/models/transaction.ts b/packages/bitcore-node/src/models/transaction.ts index a5f126a2e48..4f113d6c453 100644 --- a/packages/bitcore-node/src/models/transaction.ts +++ b/packages/bitcore-node/src/models/transaction.ts @@ -334,7 +334,8 @@ export class TransactionModel extends BaseModel { } } - if (initialSyncComplete || Config.for('api').wallets.allowCreationBeforeCompleteSync) { + const walletConfig = Config.for('api').wallets; + if (initialSyncComplete || (walletConfig && walletConfig.allowCreationBeforeCompleteSync)) { let mintOpsAddresses = {}; for (const mintOp of mintOps) { mintOpsAddresses[mintOp.updateOne.update.$set.address] = true; diff --git a/packages/bitcore-node/src/providers/chain-state/internal/internal.ts b/packages/bitcore-node/src/providers/chain-state/internal/internal.ts index 57399f8deea..01c1b705969 100644 --- a/packages/bitcore-node/src/providers/chain-state/internal/internal.ts +++ b/packages/bitcore-node/src/providers/chain-state/internal/internal.ts @@ -230,7 +230,9 @@ export class InternalStateProvider implements CSP.IChainStateService { const state = await StateStorage.collection.findOne({}); const initialSyncComplete = state && state.initialSyncComplete && state.initialSyncComplete.includes(`${chain}:${network}`); - if (!initialSyncComplete && !Config.for('api').wallets.allowCreationBeforeCompleteSync) { + const walletConfig = Config.for('api').wallets; + const canCreate = walletConfig && walletConfig.allowCreationBeforeCompleteSync; + if (!initialSyncComplete && !canCreate) { throw 'Wallet creation not permitted before intitial sync is complete'; } const wallet: IWallet = { diff --git a/packages/bitcore-node/src/routes/api/wallet.ts b/packages/bitcore-node/src/routes/api/wallet.ts index 5a339be7169..837332e47e6 100644 --- a/packages/bitcore-node/src/routes/api/wallet.ts +++ b/packages/bitcore-node/src/routes/api/wallet.ts @@ -1,4 +1,4 @@ -import { Config } from "../../services/config"; +import { Config } from '../../services/config'; import { Request, Response, Router } from 'express'; import { ChainNetwork } from '../../types/ChainNetwork'; import { IWallet } from '../../models/wallet'; @@ -53,7 +53,8 @@ const authenticate: RequestHandler = async (req: PreAuthRequest, res: Response, return res.status(404).send('Wallet not found'); } Object.assign(req, { wallet }); - if(Config.for('api').wallets.allowUnauthenticatedCalls) { + const walletConfig = Config.for('api').wallets; + if (walletConfig && walletConfig.allowUnauthenticatedCalls) { return next(); } try { diff --git a/packages/bitcore-node/src/routes/middleware.ts b/packages/bitcore-node/src/routes/middleware.ts index 2806efdaa2a..906aa3f48c5 100644 --- a/packages/bitcore-node/src/routes/middleware.ts +++ b/packages/bitcore-node/src/routes/middleware.ts @@ -1,7 +1,7 @@ import logger from '../logger'; import * as express from 'express'; import { RateLimitStorage } from '../models/rateLimit'; -import { Config } from "../services/config"; +import { Config } from '../services/config'; type TimedRequest = { startTime?: Date; @@ -71,7 +71,8 @@ export function RateLimiter(method: string, perSecond: number, perMinute: number return async (req: express.Request, res: express.Response, next: express.NextFunction) => { try { const identifier = req.header('CF-Connecting-IP') || req.socket.remoteAddress || ''; - if (Config.for('api').rateLimiter.whitelist.includes(identifier)) { + const rateLimiter = Config.for('api').rateLimiter; + if (rateLimiter && rateLimiter.whitelist.includes(identifier)) { return next(); } let [perSecondResult, perMinuteResult, perHourResult] = await RateLimitStorage.incrementAndCheck( diff --git a/packages/bitcore-node/src/services/config.ts b/packages/bitcore-node/src/services/config.ts index 80385954796..3d2201797fe 100644 --- a/packages/bitcore-node/src/services/config.ts +++ b/packages/bitcore-node/src/services/config.ts @@ -1,6 +1,7 @@ import { ConfigType } from '../types/Config'; import config from '../config'; import { ChainNetwork } from '../types/ChainNetwork'; +import { valueOrDefault } from '../utils/check'; type RecursivePartial = { [P in keyof T]?: RecursivePartial }; type ServiceName = keyof ConfigType['services']; @@ -39,16 +40,19 @@ export class ConfigService { return chainNetworks; } - public chainConfig({chain, network}: ChainNetwork) { + public chainConfig({ chain, network }: ChainNetwork) { return this.get().chains[chain][network]; } public for(service: T): ConfigType['services'][T] { - return this.get().services[service]; + return this.get().services[service] || {}; } public isEnabled(service: ServiceName) { - return this.for(service) && this.for(service).enabled; + const serviceConfig = this.for(service); + const isDefined = x => x !== undefined; + const disabled = isDefined(serviceConfig) ? valueOrDefault(serviceConfig.disabled, false) : false; + return !disabled; } } diff --git a/packages/bitcore-node/src/services/p2p.ts b/packages/bitcore-node/src/services/p2p.ts index 1f9ab35def9..7b095164f6a 100644 --- a/packages/bitcore-node/src/services/p2p.ts +++ b/packages/bitcore-node/src/services/p2p.ts @@ -375,7 +375,7 @@ export class P2pWorker { } async start(config: ConfigType) { - if (!config.services.p2p.enabled) { + if (!config.services.p2p.disabled) { return; } logger.debug(`Started worker for chain ${this.chain}`); diff --git a/packages/bitcore-node/src/services/socket.ts b/packages/bitcore-node/src/services/socket.ts index 14ac0e51d49..5212be3562c 100644 --- a/packages/bitcore-node/src/services/socket.ts +++ b/packages/bitcore-node/src/services/socket.ts @@ -38,7 +38,7 @@ export class SocketService { } start({ server, config = this.configService.get() }: { server: http.Server; config: ConfigType }) { - if (!config.services.socket.enabled) { + if (!config.services.socket.disabled) { return; } logger.info('Starting Socket Service'); diff --git a/packages/bitcore-node/src/types/Config.d.ts b/packages/bitcore-node/src/types/Config.d.ts index 8971f5334b1..c7084f1cff1 100644 --- a/packages/bitcore-node/src/types/Config.d.ts +++ b/packages/bitcore-node/src/types/Config.d.ts @@ -11,26 +11,26 @@ export interface ConfigType { }; services: { api: { - enabled: boolean; - rateLimiter: { + disabled?: boolean; + rateLimiter?: { whitelist: [string]; }; - wallets: { + wallets?: { allowCreationBeforeCompleteSync?: boolean; allowUnauthenticatedCalls?: boolean; }; }; event: { - enabled: boolean; + disabled?: boolean; }; p2p: { - enabled: boolean; + disabled?: boolean; }; socket: { - enabled: boolean; + disabled?: boolean; }; storage: { - enabled: boolean; + disabled?: boolean; }; }; }