config.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. const fs = require('fs');
  2. const NodeRSA = require('node-rsa');
  3. const { config } = require('process');
  4. const logger = require('../logger').global;
  5. const keysFile = '/data/keys.json';
  6. let instance = null;
  7. // 1. Load from config file first (not recommended anymore)
  8. // 2. Use config env variables next
  9. const configure = () => {
  10. const filename = (process.env.NODE_CONFIG_DIR || './config') + '/' + (process.env.NODE_ENV || 'default') + '.json';
  11. if (fs.existsSync(filename)) {
  12. let configData;
  13. try {
  14. configData = require(filename);
  15. } catch (err) {
  16. // do nothing
  17. }
  18. if (configData?.database && configData?.database?.engine) {
  19. logger.info(`Using configuration from file: ${filename}`);
  20. instance = configData;
  21. return;
  22. }
  23. }
  24. const envMysqlHost = process.env.DB_MYSQL_HOST || null;
  25. const envMysqlUser = process.env.DB_MYSQL_USER || null;
  26. const envMysqlName = process.env.DB_MYSQL_NAME || null;
  27. if (envMysqlHost && envMysqlUser && envMysqlName) {
  28. // we have enough mysql creds to go with mysql
  29. logger.info('Using MySQL configuration');
  30. instance = {
  31. database: {
  32. engine: 'mysql',
  33. host: envMysqlHost,
  34. port: process.env.DB_MYSQL_PORT || 3306,
  35. user: envMysqlUser,
  36. password: process.env.DB_MYSQL_PASSWORD,
  37. name: envMysqlName,
  38. }
  39. };
  40. return;
  41. }
  42. const envSqliteFile = process.env.DB_SQLITE_FILE || '/data/database.sqlite';
  43. logger.info(`Using Sqlite: ${envSqliteFile}`);
  44. instance = {
  45. database: {
  46. engine: 'knex-native',
  47. knex: {
  48. client: 'sqlite3',
  49. connection: {
  50. filename: envSqliteFile
  51. },
  52. useNullAsDefault: true
  53. }
  54. }
  55. };
  56. // Get keys from file
  57. if (!fs.existsSync(keysFile)) {
  58. generateKeys();
  59. } else if (!!process.env.DEBUG) {
  60. logger.info('Keys file exists OK');
  61. }
  62. try {
  63. instance.keys = require(keysFile);
  64. } catch (err) {
  65. logger.error('Could not read JWT key pair from config file: ' + keysFile, err);
  66. process.exit(1);
  67. }
  68. logger.debug('Configuration: ' + JSON.stringify(instance, null, 2));
  69. };
  70. const generateKeys = () => {
  71. logger.info('Creating a new JWT key pair...');
  72. // Now create the keys and save them in the config.
  73. const key = new NodeRSA({ b: 2048 });
  74. key.generateKeyPair();
  75. const keys = {
  76. key: key.exportKey('private').toString(),
  77. pub: key.exportKey('public').toString(),
  78. };
  79. // Write keys config
  80. try {
  81. fs.writeFileSync(keysFile, JSON.stringify(keys, null, 2));
  82. } catch (err) {
  83. logger.error('Could not write JWT key pair to config file: ' + keysFile + ': ' . err.message);
  84. process.exit(1);
  85. }
  86. logger.info('Wrote JWT key pair to config file: ' + keysFile);
  87. };
  88. module.exports = {
  89. /**
  90. *
  91. * @param {string} key ie: 'database' or 'database.engine'
  92. * @returns {boolean}
  93. */
  94. has: function(key) {
  95. instance === null && configure();
  96. const keys = key.split('.');
  97. let level = instance;
  98. let has = true;
  99. keys.forEach((keyItem) =>{
  100. if (typeof level[keyItem] === 'undefined') {
  101. has = false;
  102. } else {
  103. level = level[keyItem];
  104. }
  105. });
  106. return has;
  107. },
  108. /**
  109. * Gets a specific key from the top level
  110. *
  111. * @param {string} key
  112. * @returns {*}
  113. */
  114. get: function (key) {
  115. instance === null && configure();
  116. if (key && typeof instance[key] !== 'undefined') {
  117. return instance[key];
  118. }
  119. return instance;
  120. },
  121. /**
  122. * Is this a sqlite configuration?
  123. *
  124. * @returns {boolean}
  125. */
  126. isSqlite: function () {
  127. instance === null && configure();
  128. return instance.database?.knex && instance.database?.knex?.client === 'sqlite3';
  129. },
  130. /**
  131. * Are we running in debug mdoe?
  132. *
  133. * @returns {boolean}
  134. */
  135. debug: function () {
  136. return !!process.env.DEBUG;
  137. },
  138. /**
  139. * Returns a public key
  140. *
  141. * @returns {string}
  142. */
  143. getPublicKey: function () {
  144. instance === null && configure();
  145. return instance?.keys?.pub
  146. },
  147. /**
  148. * Returns a private key
  149. *
  150. * @returns {string}
  151. */
  152. getPrivateKey: function () {
  153. instance === null && configure();
  154. return instance?.keys?.key;
  155. },
  156. /**
  157. * @returns {boolean}
  158. */
  159. useLetsencryptStaging: function () {
  160. return !!process.env.LE_STAGING;
  161. }
  162. };