config.js 4.0 KB

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