mirror of
https://github.com/NginxProxyManager/nginx-proxy-manager.git
synced 2025-09-14 02:42:34 +00:00
245 lines
5.6 KiB
JavaScript
245 lines
5.6 KiB
JavaScript
import fs from "node:fs";
|
|
import NodeRSA from "node-rsa";
|
|
import { global as logger } from "../logger.js";
|
|
|
|
const keysFile = '/data/keys.json';
|
|
const mysqlEngine = 'mysql2';
|
|
const postgresEngine = 'pg';
|
|
const sqliteClientName = 'sqlite3';
|
|
|
|
let instance = null;
|
|
|
|
// 1. Load from config file first (not recommended anymore)
|
|
// 2. Use config env variables next
|
|
const configure = () => {
|
|
const filename = `${process.env.NODE_CONFIG_DIR || "./config"}/${process.env.NODE_ENV || "default"}.json`;
|
|
if (fs.existsSync(filename)) {
|
|
let configData;
|
|
try {
|
|
// Load this json synchronously
|
|
const rawData = fs.readFileSync(filename);
|
|
configData = JSON.parse(rawData);
|
|
} catch (_) {
|
|
// do nothing
|
|
}
|
|
|
|
if (configData?.database) {
|
|
logger.info(`Using configuration from file: ${filename}`);
|
|
instance = configData;
|
|
instance.keys = getKeys();
|
|
return;
|
|
}
|
|
}
|
|
|
|
const envMysqlHost = process.env.DB_MYSQL_HOST || null;
|
|
const envMysqlUser = process.env.DB_MYSQL_USER || null;
|
|
const envMysqlName = process.env.DB_MYSQL_NAME || null;
|
|
if (envMysqlHost && envMysqlUser && envMysqlName) {
|
|
// we have enough mysql creds to go with mysql
|
|
logger.info("Using MySQL configuration");
|
|
instance = {
|
|
database: {
|
|
engine: mysqlEngine,
|
|
host: envMysqlHost,
|
|
port: process.env.DB_MYSQL_PORT || 3306,
|
|
user: envMysqlUser,
|
|
password: process.env.DB_MYSQL_PASSWORD,
|
|
name: envMysqlName,
|
|
},
|
|
keys: getKeys(),
|
|
};
|
|
return;
|
|
}
|
|
|
|
const envPostgresHost = process.env.DB_POSTGRES_HOST || null;
|
|
const envPostgresUser = process.env.DB_POSTGRES_USER || null;
|
|
const envPostgresName = process.env.DB_POSTGRES_NAME || null;
|
|
if (envPostgresHost && envPostgresUser && envPostgresName) {
|
|
// we have enough postgres creds to go with postgres
|
|
logger.info("Using Postgres configuration");
|
|
instance = {
|
|
database: {
|
|
engine: postgresEngine,
|
|
host: envPostgresHost,
|
|
port: process.env.DB_POSTGRES_PORT || 5432,
|
|
user: envPostgresUser,
|
|
password: process.env.DB_POSTGRES_PASSWORD,
|
|
name: envPostgresName,
|
|
},
|
|
keys: getKeys(),
|
|
};
|
|
return;
|
|
}
|
|
|
|
const envSqliteFile = process.env.DB_SQLITE_FILE || "/data/database.sqlite";
|
|
logger.info(`Using Sqlite: ${envSqliteFile}`);
|
|
instance = {
|
|
database: {
|
|
engine: "knex-native",
|
|
knex: {
|
|
client: sqliteClientName,
|
|
connection: {
|
|
filename: envSqliteFile,
|
|
},
|
|
useNullAsDefault: true,
|
|
},
|
|
},
|
|
keys: getKeys(),
|
|
};
|
|
};
|
|
|
|
const getKeys = () => {
|
|
// Get keys from file
|
|
logger.debug("Cheecking for keys file:", keysFile);
|
|
if (!fs.existsSync(keysFile)) {
|
|
generateKeys();
|
|
} else if (process.env.DEBUG) {
|
|
logger.info("Keys file exists OK");
|
|
}
|
|
try {
|
|
// Load this json keysFile synchronously and return the json object
|
|
const rawData = fs.readFileSync(keysFile);
|
|
return JSON.parse(rawData);
|
|
} catch (err) {
|
|
logger.error(`Could not read JWT key pair from config file: ${keysFile}`, err);
|
|
process.exit(1);
|
|
}
|
|
};
|
|
|
|
const generateKeys = () => {
|
|
logger.info("Creating a new JWT key pair...");
|
|
// Now create the keys and save them in the config.
|
|
const key = new NodeRSA({ b: 2048 });
|
|
key.generateKeyPair();
|
|
|
|
const keys = {
|
|
key: key.exportKey("private").toString(),
|
|
pub: key.exportKey("public").toString(),
|
|
};
|
|
|
|
// Write keys config
|
|
try {
|
|
fs.writeFileSync(keysFile, JSON.stringify(keys, null, 2));
|
|
} catch (err) {
|
|
logger.error(`Could not write JWT key pair to config file: ${keysFile}: ${err.message}`);
|
|
process.exit(1);
|
|
}
|
|
logger.info(`Wrote JWT key pair to config file: ${keysFile}`);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @param {string} key ie: 'database' or 'database.engine'
|
|
* @returns {boolean}
|
|
*/
|
|
const configHas = (key) => {
|
|
instance === null && configure();
|
|
const keys = key.split(".");
|
|
let level = instance;
|
|
let has = true;
|
|
keys.forEach((keyItem) => {
|
|
if (typeof level[keyItem] === "undefined") {
|
|
has = false;
|
|
} else {
|
|
level = level[keyItem];
|
|
}
|
|
});
|
|
|
|
return has;
|
|
};
|
|
|
|
/**
|
|
* Gets a specific key from the top level
|
|
*
|
|
* @param {string} key
|
|
* @returns {*}
|
|
*/
|
|
const configGet = (key) => {
|
|
instance === null && configure();
|
|
if (key && typeof instance[key] !== "undefined") {
|
|
return instance[key];
|
|
}
|
|
return instance;
|
|
};
|
|
|
|
/**
|
|
* Is this a sqlite configuration?
|
|
*
|
|
* @returns {boolean}
|
|
*/
|
|
const isSqlite = () => {
|
|
instance === null && configure();
|
|
return instance.database.knex && instance.database.knex.client === sqliteClientName;
|
|
};
|
|
|
|
/**
|
|
* Is this a mysql configuration?
|
|
*
|
|
* @returns {boolean}
|
|
*/
|
|
const isMysql = () => {
|
|
instance === null && configure();
|
|
return instance.database.engine === mysqlEngine;
|
|
};
|
|
|
|
/**
|
|
* Is this a postgres configuration?
|
|
*
|
|
* @returns {boolean}
|
|
*/
|
|
const isPostgres = () => {
|
|
instance === null && configure();
|
|
return instance.database.engine === postgresEngine;
|
|
};
|
|
|
|
/**
|
|
* Are we running in debug mdoe?
|
|
*
|
|
* @returns {boolean}
|
|
*/
|
|
const isDebugMode = () => !!process.env.DEBUG;
|
|
|
|
/**
|
|
* Are we running in CI?
|
|
*
|
|
* @returns {boolean}
|
|
*/
|
|
const isCI = () => process.env.CI === 'true' && process.env.DEBUG === 'true';
|
|
|
|
/**
|
|
* Returns a public key
|
|
*
|
|
* @returns {string}
|
|
*/
|
|
const getPublicKey = () => {
|
|
instance === null && configure();
|
|
return instance.keys.pub;
|
|
};
|
|
|
|
/**
|
|
* Returns a private key
|
|
*
|
|
* @returns {string}
|
|
*/
|
|
const getPrivateKey = () => {
|
|
instance === null && configure();
|
|
return instance.keys.key;
|
|
};
|
|
|
|
/**
|
|
* @returns {boolean}
|
|
*/
|
|
const useLetsencryptStaging = () => !!process.env.LE_STAGING;
|
|
|
|
/**
|
|
* @returns {string|null}
|
|
*/
|
|
const useLetsencryptServer = () => {
|
|
if (process.env.LE_SERVER) {
|
|
return process.env.LE_SERVER;
|
|
}
|
|
return null;
|
|
};
|
|
|
|
export { isCI, configHas, configGet, isSqlite, isMysql, isPostgres, isDebugMode, getPrivateKey, getPublicKey, useLetsencryptStaging, useLetsencryptServer };
|