Source: saltcorn-data/db/connect.js

  1. /**
  2. * Controls Saltcorn configuration
  3. * @type {path.PlatformPath | path}
  4. */
  5. const path = require("path");
  6. const fs = require("fs");
  7. const envPaths = require("env-paths");
  8. const pathsNoApp = envPaths("", { suffix: "" });
  9. const pathsWithApp = envPaths("saltcorn", { suffix: "" });
  10. /**
  11. * Default data path?
  12. * @type {string}
  13. */
  14. const defaultDataPath = pathsWithApp.data;
  15. const stringToJSON = (x) => (typeof x === "string" ? JSON.parse(x) : x);
  16. /**
  17. * Get Git revision of Saltcorn source.
  18. * Required to work:
  19. * - Git client installed,
  20. * - Local git with repo Saltcorn sources.
  21. * @returns {null} - Return current Git commit
  22. */
  23. const getGitRevision = () => {
  24. let revision = null;
  25. let options = { stdio: "pipe", cwd: __dirname };
  26. try {
  27. revision = require("child_process")
  28. .execSync("git rev-parse HEAD", options)
  29. .toString()
  30. .trim();
  31. } catch (error) {}
  32. return revision;
  33. };
  34. /**
  35. * Prepare Saltcorn connection object that controls main Saltcorn instance settings like:
  36. * - PostgreSQL or SQLite
  37. * - Connection to DB settings
  38. * - Multitenant mode
  39. * - Web Session secret
  40. * - File store path
  41. * - Saltcorn confuration inheritance and fixed configuration
  42. * For all parameters and priority see the code of function.
  43. * @param connSpec
  44. * @returns {{sc_version: string, connectionString: *, git_commit: *, version_tag: (*|string)}|{sqlite_path}|boolean}
  45. */
  46. const getConnectObject = (connSpec = {}) => {
  47. const git_commit = getGitRevision();
  48. const sc_version = require("../package.json").version;
  49. const version_tag = git_commit || sc_version;
  50. var connObj = { version_tag, git_commit, sc_version };
  51. const fileCfg = getConfigFile() || {};
  52. function setKey(k, envnm, opts = {}) {
  53. const f = opts.transform || ((x) => x);
  54. // Priorities:
  55. // 1. getConnectObject argument
  56. if (typeof connSpec[k] !== "undefined") connObj[k] = f(connSpec[k]);
  57. // 2. Environment variables
  58. else if (typeof process.env[envnm] !== "undefined")
  59. connObj[k] = f(process.env[envnm]);
  60. // 3. Config file
  61. else if (typeof fileCfg[k] !== "undefined") connObj[k] = f(fileCfg[k]);
  62. // 4. default
  63. else if (typeof opts.default !== "undefined") connObj[k] = f(opts.default);
  64. }
  65. setKey("user", "PGUSER");
  66. setKey("sqlite_path", "SQLITE_FILEPATH");
  67. setKey("host", "PGHOST");
  68. setKey("port", "PGPORT");
  69. setKey("password", "PGPASSWORD");
  70. setKey("database", "PGDATABASE");
  71. setKey("session_secret", "SALTCORN_SESSION_SECRET");
  72. setKey("multi_tenant", "SALTCORN_MULTI_TENANT", { default: false });
  73. setKey("file_store", "SALTCORN_FILE_STORE", { default: pathsWithApp.data });
  74. setKey("default_schema", "SALTCORN_DEFAULT_SCHEMA", { default: "public" });
  75. setKey("fixed_configuration", "SALTCORN_FIXED_CONFIGURATION", {
  76. default: {},
  77. transform: stringToJSON,
  78. });
  79. setKey("inherit_configuration", "SALTCORN_INHERIT_CONFIGURATION", {
  80. default: [],
  81. transform: stringToJSON,
  82. });
  83. if (process.env.DATABASE_URL) {
  84. delete connObj[user];
  85. delete connObj[password];
  86. delete connObj[database];
  87. delete connObj[sqlite_path];
  88. return { ...connObj, connectionString: process.env.DATABASE_URL };
  89. } else if (
  90. connObj.sqlite_path ||
  91. (connObj.user && connObj.password && connObj.database)
  92. ) {
  93. return connObj;
  94. } else {
  95. return false;
  96. }
  97. };
  98. /**
  99. * Path to Config directory
  100. * @type {string}
  101. */
  102. const configFileDir = pathsNoApp.config;
  103. /**
  104. * Path to config file .saltcorn
  105. * @type {string}
  106. */
  107. const configFilePath = path.join(configFileDir, ".saltcorn");
  108. /**
  109. * Reads Saltcorn configuration file
  110. * @returns {boolean|any} - Returns JSON presentation of Saltcorn confuration file. Returns false in case of Exception.
  111. */
  112. const getConfigFile = () => {
  113. try {
  114. let rawdata = fs.readFileSync(configFilePath);
  115. return JSON.parse(rawdata);
  116. } catch (e) {
  117. return false;
  118. }
  119. };
  120. /**
  121. * Check that Saltcorn configured to use SQLite as database
  122. * @param connObj - connectin object
  123. * @returns {boolean} - Returns true if Saltcorn configured to use SQLite as database
  124. */
  125. const is_sqlite = (connObj) => {
  126. if (connObj.connectionString)
  127. return connObj.connectionString.startsWith("sqlite");
  128. return !!connObj.sqlite_path;
  129. };
  130. module.exports = {
  131. getConnectObject,
  132. getConfigFile,
  133. configFileDir,
  134. configFilePath,
  135. is_sqlite,
  136. defaultDataPath,
  137. };