config-loader.ts 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. import { envUtils } from '@growi/core';
  2. import loggerFactory from '~/utils/logger';
  3. import ConfigModel, {
  4. Config, defaultCrowiConfigs, defaultMarkdownConfigs, defaultNotificationConfigs,
  5. } from '../models/config';
  6. const logger = loggerFactory('growi:service:ConfigLoader');
  7. enum ValueType { NUMBER, STRING, BOOLEAN }
  8. interface ValueParser<T> {
  9. parse(value: string): T;
  10. }
  11. interface EnvConfig {
  12. ns: string,
  13. key: string,
  14. type: ValueType,
  15. default?: number | string | boolean | null,
  16. }
  17. type EnumDictionary<T extends string | symbol | number, U> = {
  18. [K in T]: U;
  19. };
  20. const parserDictionary: EnumDictionary<ValueType, ValueParser<number | string | boolean>> = {
  21. [ValueType.NUMBER]: { parse: (v: string) => { return parseInt(v, 10) } },
  22. [ValueType.STRING]: { parse: (v: string) => { return v } },
  23. [ValueType.BOOLEAN]: { parse: (v: string) => { return envUtils.toBoolean(v) } },
  24. };
  25. /**
  26. * The following env vars are excluded because these are currently used before the configuration setup.
  27. * - MONGO_URI
  28. * - NODE_ENV
  29. * - PORT
  30. * - REDIS_URI
  31. * - SESSION_NAME
  32. * - PASSWORD_SEED
  33. * - SECRET_TOKEN
  34. *
  35. * The commented out item has not yet entered the migration work.
  36. * So, parameters of these are under consideration.
  37. */
  38. const ENV_VAR_NAME_TO_CONFIG_INFO = {
  39. FILE_UPLOAD: {
  40. ns: 'crowi',
  41. key: 'app:fileUploadType',
  42. type: ValueType.STRING,
  43. default: 'aws',
  44. },
  45. FILE_UPLOAD_USES_ONLY_ENV_VAR_FOR_FILE_UPLOAD_TYPE: {
  46. ns: 'crowi',
  47. key: 'app:useOnlyEnvVarForFileUploadType',
  48. type: ValueType.BOOLEAN,
  49. default: false,
  50. },
  51. HACKMD_URI: {
  52. ns: 'crowi',
  53. key: 'app:hackmdUri',
  54. type: ValueType.STRING,
  55. default: null,
  56. },
  57. HACKMD_URI_FOR_SERVER: {
  58. ns: 'crowi',
  59. key: 'app:hackmdUriForServer',
  60. type: ValueType.STRING,
  61. default: null,
  62. },
  63. MATHJAX: {
  64. ns: 'crowi',
  65. key: 'app:mathJax',
  66. type: ValueType.STRING,
  67. default: null,
  68. },
  69. NO_CDN: {
  70. ns: 'crowi',
  71. key: 'app:noCdn',
  72. type: ValueType.STRING,
  73. default: null,
  74. },
  75. // PLANTUML_URI: {
  76. // ns: ,
  77. // key: ,
  78. // type: ,
  79. // default:
  80. // },
  81. // BLOCKDIAG_URI: {
  82. // ns: ,
  83. // key: ,
  84. // type: ,
  85. // default:
  86. // },
  87. // OAUTH_GOOGLE_CLIENT_ID: {
  88. // ns: 'crowi',
  89. // key: 'security:passport-google:clientId',
  90. // type: ,
  91. // default:
  92. // },
  93. // OAUTH_GOOGLE_CLIENT_SECRET: {
  94. // ns: 'crowi',
  95. // key: 'security:passport-google:clientSecret',
  96. // type: ,
  97. // default:
  98. // },
  99. // OAUTH_GOOGLE_CALLBACK_URI: {
  100. // ns: 'crowi',
  101. // key: 'security:passport-google:callbackUrl',
  102. // type: ,
  103. // default:
  104. // },
  105. // OAUTH_GITHUB_CLIENT_ID: {
  106. // ns: 'crowi',
  107. // key: 'security:passport-github:clientId',
  108. // type: ,
  109. // default:
  110. // },
  111. // OAUTH_GITHUB_CLIENT_SECRET: {
  112. // ns: 'crowi',
  113. // key: 'security:passport-github:clientSecret',
  114. // type: ,
  115. // default:
  116. // },
  117. // OAUTH_GITHUB_CALLBACK_URI: {
  118. // ns: 'crowi',
  119. // key: 'security:passport-github:callbackUrl',
  120. // type: ,
  121. // default:
  122. // },
  123. // OAUTH_TWITTER_CONSUMER_KEY: {
  124. // ns: 'crowi',
  125. // key: 'security:passport-twitter:consumerKey',
  126. // type: ,
  127. // default:
  128. // },
  129. // OAUTH_TWITTER_CONSUMER_SECRET: {
  130. // ns: 'crowi',
  131. // key: 'security:passport-twitter:consumerSecret',
  132. // type: ,
  133. // default:
  134. // },
  135. // OAUTH_TWITTER_CALLBACK_URI: {
  136. // ns: 'crowi',
  137. // key: 'security:passport-twitter:callbackUrl',
  138. // type: ,
  139. // default:
  140. // },
  141. DRAWIO_URI: {
  142. ns: 'crowi',
  143. key: 'app:drawioUri',
  144. type: ValueType.STRING,
  145. default: 'https://embed.diagrams.net/',
  146. },
  147. NCHAN_URI: {
  148. ns: 'crowi',
  149. key: 'app:nchanUri',
  150. type: ValueType.STRING,
  151. default: null,
  152. },
  153. APP_SITE_URL: {
  154. ns: 'crowi',
  155. key: 'app:siteUrl',
  156. type: ValueType.STRING,
  157. default: null,
  158. },
  159. PUBLISH_OPEN_API: {
  160. ns: 'crowi',
  161. key: 'app:publishOpenAPI',
  162. type: ValueType.BOOLEAN,
  163. default: false,
  164. },
  165. AUTO_INSTALL_ADMIN_USERNAME: {
  166. ns: 'crowi',
  167. key: 'autoInstall:adminUsername',
  168. type: ValueType.STRING,
  169. default: null,
  170. },
  171. AUTO_INSTALL_ADMIN_NAME: {
  172. ns: 'crowi',
  173. key: 'autoInstall:adminName',
  174. type: ValueType.STRING,
  175. default: null,
  176. },
  177. AUTO_INSTALL_ADMIN_EMAIL: {
  178. ns: 'crowi',
  179. key: 'autoInstall:adminEmail',
  180. type: ValueType.STRING,
  181. default: null,
  182. },
  183. AUTO_INSTALL_ADMIN_PASSWORD: {
  184. ns: 'crowi',
  185. key: 'autoInstall:adminPassword',
  186. type: ValueType.STRING,
  187. default: null,
  188. },
  189. AUTO_INSTALL_GLOBAL_LANG: {
  190. ns: 'crowi',
  191. key: 'autoInstall:globalLang',
  192. type: ValueType.STRING,
  193. default: null,
  194. },
  195. S2SMSG_PUBSUB_SERVER_TYPE: {
  196. ns: 'crowi',
  197. key: 's2sMessagingPubsub:serverType',
  198. type: ValueType.STRING,
  199. default: null,
  200. },
  201. S2SMSG_PUBSUB_NCHAN_PUBLISH_PATH: {
  202. ns: 'crowi',
  203. key: 's2sMessagingPubsub:nchan:publishPath',
  204. type: ValueType.STRING,
  205. default: '/pubsub',
  206. },
  207. S2SMSG_PUBSUB_NCHAN_SUBSCRIBE_PATH: {
  208. ns: 'crowi',
  209. key: 's2sMessagingPubsub:nchan:subscribePath',
  210. type: ValueType.STRING,
  211. default: '/pubsub',
  212. },
  213. S2SMSG_PUBSUB_NCHAN_CHANNEL_ID: {
  214. ns: 'crowi',
  215. key: 's2sMessagingPubsub:nchan:channelId',
  216. type: ValueType.STRING,
  217. default: null,
  218. },
  219. S2CMSG_PUBSUB_CONNECTIONS_LIMIT: {
  220. ns: 'crowi',
  221. key: 's2cMessagingPubsub:connectionsLimit',
  222. type: ValueType.NUMBER,
  223. default: 5000,
  224. },
  225. S2CMSG_PUBSUB_CONNECTIONS_LIMIT_FOR_ADMIN: {
  226. ns: 'crowi',
  227. key: 's2cMessagingPubsub:connectionsLimitForAdmin',
  228. type: ValueType.NUMBER,
  229. default: 100,
  230. },
  231. S2CMSG_PUBSUB_CONNECTIONS_LIMIT_FOR_GUEST: {
  232. ns: 'crowi',
  233. key: 's2cMessagingPubsub:connectionsLimitForGuest',
  234. type: ValueType.NUMBER,
  235. default: 2000,
  236. },
  237. MAX_FILE_SIZE: {
  238. ns: 'crowi',
  239. key: 'app:maxFileSize',
  240. type: ValueType.NUMBER,
  241. default: Infinity,
  242. },
  243. FILE_UPLOAD_TOTAL_LIMIT: {
  244. ns: 'crowi',
  245. key: 'app:fileUploadTotalLimit',
  246. type: ValueType.NUMBER,
  247. default: Infinity,
  248. },
  249. FILE_UPLOAD_DISABLED: {
  250. ns: 'crowi',
  251. key: 'app:fileUploadDisabled',
  252. type: ValueType.BOOLEAN,
  253. default: false,
  254. },
  255. FILE_UPLOAD_LOCAL_USE_INTERNAL_REDIRECT: {
  256. ns: 'crowi',
  257. key: 'fileUpload:local:useInternalRedirect',
  258. type: ValueType.BOOLEAN,
  259. default: false,
  260. },
  261. FILE_UPLOAD_LOCAL_INTERNAL_REDIRECT_PATH: {
  262. ns: 'crowi',
  263. key: 'fileUpload:local:internalRedirectPath',
  264. type: ValueType.STRING,
  265. default: '/growi-internal/',
  266. },
  267. ELASTICSEARCH_URI: {
  268. ns: 'crowi',
  269. key: 'app:elasticsearchUri',
  270. type: ValueType.STRING,
  271. default: null,
  272. },
  273. ELASTICSEARCH_REQUEST_TIMEOUT: {
  274. ns: 'crowi',
  275. key: 'app:elasticsearchRequestTimeout',
  276. type: ValueType.NUMBER,
  277. default: 8000, // msec
  278. },
  279. SEARCHBOX_SSL_URL: {
  280. ns: 'crowi',
  281. key: 'app:searchboxSslUrl',
  282. type: ValueType.STRING,
  283. default: null,
  284. },
  285. MONGO_GRIDFS_TOTAL_LIMIT: {
  286. ns: 'crowi',
  287. key: 'gridfs:totalLimit',
  288. type: ValueType.NUMBER,
  289. default: null, // set null in default for backward compatibility
  290. // cz: Newer system respects FILE_UPLOAD_TOTAL_LIMIT.
  291. // If the default value of MONGO_GRIDFS_TOTAL_LIMIT is Infinity,
  292. // the system can't distinguish between "not specified" and "Infinity is specified".
  293. },
  294. FORCE_WIKI_MODE: {
  295. ns: 'crowi',
  296. key: 'security:wikiMode',
  297. type: ValueType.STRING,
  298. default: undefined,
  299. },
  300. SESSION_MAX_AGE: {
  301. ns: 'crowi',
  302. key: 'security:sessionMaxAge',
  303. type: ValueType.NUMBER,
  304. default: undefined,
  305. },
  306. USER_UPPER_LIMIT: {
  307. ns: 'crowi',
  308. key: 'security:userUpperLimit',
  309. type: ValueType.NUMBER,
  310. default: Infinity,
  311. },
  312. DISABLE_LINK_SHARING: {
  313. ns: 'crowi',
  314. key: 'security:disableSharing',
  315. type: ValueType.BOOLEAN,
  316. default: false,
  317. },
  318. LOCAL_STRATEGY_ENABLED: {
  319. ns: 'crowi',
  320. key: 'security:passport-local:isEnabled',
  321. type: ValueType.BOOLEAN,
  322. default: true,
  323. },
  324. LOCAL_STRATEGY_USES_ONLY_ENV_VARS_FOR_SOME_OPTIONS: {
  325. ns: 'crowi',
  326. key: 'security:passport-local:useOnlyEnvVarsForSomeOptions',
  327. type: ValueType.BOOLEAN,
  328. default: false,
  329. },
  330. LOCAL_STRATEGY_PASSWORD_RESET_ENABLED: {
  331. ns: 'crowi',
  332. key: 'security:passport-local:isPasswordResetEnabled',
  333. type: ValueType.BOOLEAN,
  334. default: true,
  335. },
  336. LOCAL_STRATEGY_EMAIL_AUTHENTICATION_ENABLED: {
  337. ns: 'crowi',
  338. key: 'security:passport-local:isEmailAuthenticationEnabled',
  339. type: ValueType.BOOLEAN,
  340. default: false,
  341. },
  342. SAML_USES_ONLY_ENV_VARS_FOR_SOME_OPTIONS: {
  343. ns: 'crowi',
  344. key: 'security:passport-saml:useOnlyEnvVarsForSomeOptions',
  345. type: ValueType.BOOLEAN,
  346. default: false,
  347. },
  348. SAML_ENABLED: {
  349. ns: 'crowi',
  350. key: 'security:passport-saml:isEnabled',
  351. type: ValueType.BOOLEAN,
  352. default: null,
  353. },
  354. SAML_ENTRY_POINT: {
  355. ns: 'crowi',
  356. key: 'security:passport-saml:entryPoint',
  357. type: ValueType.STRING,
  358. default: null,
  359. },
  360. SAML_CALLBACK_URI: {
  361. ns: 'crowi',
  362. key: 'security:passport-saml:callbackUrl',
  363. type: ValueType.STRING,
  364. default: null,
  365. },
  366. SAML_ISSUER: {
  367. ns: 'crowi',
  368. key: 'security:passport-saml:issuer',
  369. type: ValueType.STRING,
  370. default: null,
  371. },
  372. SAML_ATTR_MAPPING_ID: {
  373. ns: 'crowi',
  374. key: 'security:passport-saml:attrMapId',
  375. type: ValueType.STRING,
  376. default: null,
  377. },
  378. SAML_ATTR_MAPPING_USERNAME: {
  379. ns: 'crowi',
  380. key: 'security:passport-saml:attrMapUsername',
  381. type: ValueType.STRING,
  382. default: null,
  383. },
  384. SAML_ATTR_MAPPING_MAIL: {
  385. ns: 'crowi',
  386. key: 'security:passport-saml:attrMapMail',
  387. type: ValueType.STRING,
  388. default: null,
  389. },
  390. SAML_ATTR_MAPPING_FIRST_NAME: {
  391. ns: 'crowi',
  392. key: 'security:passport-saml:attrMapFirstName',
  393. type: ValueType.STRING,
  394. default: null,
  395. },
  396. SAML_ATTR_MAPPING_LAST_NAME: {
  397. ns: 'crowi',
  398. key: 'security:passport-saml:attrMapLastName',
  399. type: ValueType.STRING,
  400. default: null,
  401. },
  402. SAML_CERT: {
  403. ns: 'crowi',
  404. key: 'security:passport-saml:cert',
  405. type: ValueType.STRING,
  406. default: null,
  407. },
  408. SAML_ABLC_RULE: {
  409. ns: 'crowi',
  410. key: 'security:passport-saml:ABLCRule',
  411. type: ValueType.STRING,
  412. default: null,
  413. },
  414. OIDC_TIMEOUT_MULTIPLIER: {
  415. ns: 'crowi',
  416. key: 'security:passport-oidc:timeoutMultiplier',
  417. type: ValueType.NUMBER,
  418. default: 1.5,
  419. },
  420. OIDC_DISCOVERY_RETRIES: {
  421. ns: 'crowi',
  422. key: 'security:passport-oidc:discoveryRetries',
  423. type: ValueType.NUMBER,
  424. default: 3,
  425. },
  426. OIDC_CLIENT_CLOCK_TOLERANCE: {
  427. ns: 'crowi',
  428. key: 'security:passport-oidc:oidcClientClockTolerance',
  429. type: ValueType.NUMBER,
  430. default: 60,
  431. },
  432. OIDC_ISSUER_TIMEOUT_OPTION: {
  433. ns: 'crowi',
  434. key: 'security:passport-oidc:oidcIssuerTimeoutOption',
  435. type: ValueType.NUMBER,
  436. default: 5000,
  437. },
  438. S3_REFERENCE_FILE_WITH_RELAY_MODE: {
  439. ns: 'crowi',
  440. key: 'aws:referenceFileWithRelayMode',
  441. type: ValueType.BOOLEAN,
  442. default: false,
  443. },
  444. S3_LIFETIME_SEC_FOR_TEMPORARY_URL: {
  445. ns: 'crowi',
  446. key: 'aws:lifetimeSecForTemporaryUrl',
  447. type: ValueType.NUMBER,
  448. default: 120,
  449. },
  450. GCS_API_KEY_JSON_PATH: {
  451. ns: 'crowi',
  452. key: 'gcs:apiKeyJsonPath',
  453. type: ValueType.STRING,
  454. default: null,
  455. },
  456. GCS_BUCKET: {
  457. ns: 'crowi',
  458. key: 'gcs:bucket',
  459. type: ValueType.STRING,
  460. default: null,
  461. },
  462. GCS_UPLOAD_NAMESPACE: {
  463. ns: 'crowi',
  464. key: 'gcs:uploadNamespace',
  465. type: ValueType.STRING,
  466. default: null,
  467. },
  468. GCS_REFERENCE_FILE_WITH_RELAY_MODE: {
  469. ns: 'crowi',
  470. key: 'gcs:referenceFileWithRelayMode',
  471. type: ValueType.BOOLEAN,
  472. default: false,
  473. },
  474. GCS_USES_ONLY_ENV_VARS_FOR_SOME_OPTIONS: {
  475. ns: 'crowi',
  476. key: 'gcs:useOnlyEnvVarsForSomeOptions',
  477. type: ValueType.BOOLEAN,
  478. default: false,
  479. },
  480. GCS_LIFETIME_SEC_FOR_TEMPORARY_URL: {
  481. ns: 'crowi',
  482. key: 'gcs:lifetimeSecForTemporaryUrl',
  483. type: ValueType.NUMBER,
  484. default: 120,
  485. },
  486. PROMSTER_ENABLED: {
  487. ns: 'crowi',
  488. key: 'promster:isEnabled',
  489. type: ValueType.BOOLEAN,
  490. default: false,
  491. },
  492. PROMSTER_PORT: {
  493. ns: 'crowi',
  494. key: 'promster:port',
  495. type: ValueType.NUMBER,
  496. default: 7788,
  497. },
  498. GROWI_CLOUD_URI: {
  499. ns: 'crowi',
  500. key: 'app:growiCloudUri',
  501. type: ValueType.STRING,
  502. default: null,
  503. },
  504. GROWI_APP_ID_FOR_GROWI_CLOUD: {
  505. ns: 'crowi',
  506. key: 'app:growiAppIdForCloud',
  507. type: ValueType.STRING,
  508. default: null,
  509. },
  510. DEFAULT_EMAIL_PUBLISHED: {
  511. ns: 'crowi',
  512. key: 'customize:isEmailPublishedForNewUser',
  513. type: ValueType.BOOLEAN,
  514. default: true,
  515. },
  516. SLACKBOT_TYPE: {
  517. ns: 'crowi',
  518. key: 'slackbot:currentBotType', // enum SlackbotType
  519. type: ValueType.STRING,
  520. default: null,
  521. },
  522. SLACKBOT_INTEGRATION_PROXY_URI: {
  523. ns: 'crowi',
  524. key: 'slackbot:proxyUri',
  525. type: ValueType.STRING,
  526. default: null,
  527. },
  528. SLACKBOT_WITHOUT_PROXY_SIGNING_SECRET: {
  529. ns: 'crowi',
  530. key: 'slackbot:withoutProxy:signingSecret',
  531. type: ValueType.STRING,
  532. default: null,
  533. },
  534. SLACKBOT_WITHOUT_PROXY_BOT_TOKEN: {
  535. ns: 'crowi',
  536. key: 'slackbot:withoutProxy:botToken',
  537. type: ValueType.STRING,
  538. default: null,
  539. },
  540. SLACKBOT_WITHOUT_PROXY_COMMAND_PERMISSION: {
  541. ns: 'crowi',
  542. key: 'slackbot:withoutProxy:commandPermission',
  543. type: ValueType.STRING,
  544. default: null,
  545. },
  546. SLACKBOT_WITHOUT_PROXY_EVENT_ACTIONS_PERMISSION: {
  547. ns: 'crowi',
  548. key: 'slackbot:withoutProxy:eventActionsPermission',
  549. type: ValueType.STRING,
  550. default: null,
  551. },
  552. SLACKBOT_WITH_PROXY_SALT_FOR_GTOP: {
  553. ns: 'crowi',
  554. key: 'slackbot:withProxy:saltForGtoP',
  555. type: ValueType.STRING,
  556. default: 'gtop',
  557. },
  558. SLACKBOT_WITH_PROXY_SALT_FOR_PTOG: {
  559. ns: 'crowi',
  560. key: 'slackbot:withProxy:saltForPtoG',
  561. type: ValueType.STRING,
  562. default: 'ptog',
  563. },
  564. OGP_URI: {
  565. ns: 'crowi',
  566. key: 'app:ogpUri',
  567. type: ValueType.STRING,
  568. default: null,
  569. },
  570. };
  571. /**
  572. * return whether env belongs to Security settings
  573. * @param key ex. 'security:passport-saml:isEnabled' is true
  574. * @returns
  575. */
  576. const isSecurityEnv = (key) => {
  577. const array = key.split(':');
  578. return (array[0] === 'security');
  579. };
  580. export interface ConfigObject extends Record<string, any> {
  581. fromDB: any,
  582. fromEnvVars: any,
  583. }
  584. export default class ConfigLoader {
  585. /**
  586. * return a config object
  587. */
  588. async load(): Promise<ConfigObject> {
  589. const configFromDB: any = await this.loadFromDB();
  590. const configFromEnvVars: any = this.loadFromEnvVars();
  591. // merge defaults per ns
  592. const mergedConfigFromDB = {
  593. crowi: Object.assign(defaultCrowiConfigs, configFromDB.crowi),
  594. markdown: Object.assign(defaultMarkdownConfigs, configFromDB.markdown),
  595. notification: Object.assign(defaultNotificationConfigs, configFromDB.notification),
  596. };
  597. // In getConfig API, only null is used as a value to indicate that a config is not set.
  598. // So, if a value loaded from the database is empty,
  599. // it is converted to null because an empty string is used as the same meaning in the config model.
  600. // By this processing, whether a value is loaded from the database or from the environment variable,
  601. // only null indicates a config is not set.
  602. for (const namespace of Object.keys(mergedConfigFromDB)) {
  603. for (const key of Object.keys(mergedConfigFromDB[namespace])) {
  604. if (mergedConfigFromDB[namespace][key] === '') {
  605. mergedConfigFromDB[namespace][key] = null;
  606. }
  607. }
  608. }
  609. return {
  610. fromDB: mergedConfigFromDB,
  611. fromEnvVars: configFromEnvVars,
  612. };
  613. }
  614. async loadFromDB(): Promise<any> {
  615. const config = {};
  616. const docs: Config[] = await ConfigModel.find().exec();
  617. for (const doc of docs) {
  618. if (!config[doc.ns]) {
  619. config[doc.ns] = {};
  620. }
  621. config[doc.ns][doc.key] = doc.value ? JSON.parse(doc.value) : null;
  622. }
  623. logger.debug('ConfigLoader#loadFromDB', config);
  624. return config;
  625. }
  626. loadFromEnvVars(): any {
  627. const config = {};
  628. for (const ENV_VAR_NAME of Object.keys(ENV_VAR_NAME_TO_CONFIG_INFO)) {
  629. const configInfo = ENV_VAR_NAME_TO_CONFIG_INFO[ENV_VAR_NAME];
  630. if (config[configInfo.ns] === undefined) {
  631. config[configInfo.ns] = {};
  632. }
  633. if (process.env[ENV_VAR_NAME] === undefined) {
  634. config[configInfo.ns][configInfo.key] = configInfo.default;
  635. }
  636. else {
  637. const parser: ValueParser<number | string | boolean> = parserDictionary[configInfo.type];
  638. config[configInfo.ns][configInfo.key] = parser.parse(process.env[ENV_VAR_NAME] as string);
  639. }
  640. }
  641. logger.debug('ConfigLoader#loadFromEnvVars', config);
  642. return config;
  643. }
  644. /**
  645. * get config from the environment variables for display admin page
  646. *
  647. * **use this only admin home page.**
  648. */
  649. static getEnvVarsForDisplay(avoidSecurity = false): any {
  650. const config = {};
  651. for (const ENV_VAR_NAME of Object.keys(ENV_VAR_NAME_TO_CONFIG_INFO)) {
  652. const configInfo = ENV_VAR_NAME_TO_CONFIG_INFO[ENV_VAR_NAME];
  653. if (process.env[ENV_VAR_NAME] === undefined) {
  654. continue;
  655. }
  656. if (isSecurityEnv(configInfo.key) && avoidSecurity) {
  657. continue;
  658. }
  659. const parser: ValueParser<number | string | boolean> = parserDictionary[configInfo.type];
  660. config[ENV_VAR_NAME] = parser.parse(process.env[ENV_VAR_NAME] as string);
  661. }
  662. logger.debug('ConfigLoader#getEnvVarsForDisplay', config);
  663. return config;
  664. }
  665. }