From 0c0c1659b877faf67511fa2f46dd68c1ebd85703 Mon Sep 17 00:00:00 2001 From: Anwar <21956329+anvarknian@users.noreply.github.com> Date: Sat, 27 Sep 2025 19:25:57 -0300 Subject: [PATCH 1/5] Enhance PostgreSQL configuration support in the backend - Updated db.js to include PostgreSQL-specific connection options such as schema and SSL mode. - Modified config.js to read new environment variables for PostgreSQL schema and SSL mode. - Added PostgreSQL configuration section in knexfile.js. - Updated docker-compose.dev.yml and documentation to reflect new environment variables for PostgreSQL schema and SSL mode. --- backend/db.js | 29 ++++++++++++++++++++++------- backend/knexfile.js | 9 +++++++++ backend/lib/config.js | 16 +++++++++++++--- docker/docker-compose.dev.yml | 2 ++ docs/src/setup/index.md | 12 ++++++++++-- 5 files changed, 56 insertions(+), 12 deletions(-) diff --git a/backend/db.js b/backend/db.js index 1a8b1634e..ba7818141 100644 --- a/backend/db.js +++ b/backend/db.js @@ -9,15 +9,30 @@ function generateDbConfig() { if (cfg.engine === 'knex-native') { return cfg.knex; } + const connection = { + host: cfg.host, + user: cfg.user, + password: cfg.password, + database: cfg.name, + port: cfg.port + }; + + // Add PostgreSQL-specific options + if (cfg.engine === 'pg') { + if (cfg.schema) { + connection.schema = cfg.schema; + } + if (cfg.sslMode) { + connection.ssl = cfg.sslMode === 'require' ? true : + cfg.sslMode === 'prefer' ? { rejectUnauthorized: false } : + cfg.sslMode === 'disable' ? false : + cfg.sslMode === 'allow' ? { rejectUnauthorized: false } : false; + } + } + return { client: cfg.engine, - connection: { - host: cfg.host, - user: cfg.user, - password: cfg.password, - database: cfg.name, - port: cfg.port - }, + connection: connection, migrations: { tableName: 'migrations' } diff --git a/backend/knexfile.js b/backend/knexfile.js index 607552f6f..ddf454de1 100644 --- a/backend/knexfile.js +++ b/backend/knexfile.js @@ -15,5 +15,14 @@ module.exports = { stub: 'lib/migrate_template.js', directory: 'migrations' } + }, + + postgres: { + client: 'pg', + migrations: { + tableName: 'migrations', + stub: 'lib/migrate_template.js', + directory: 'migrations' + } } }; diff --git a/backend/lib/config.js b/backend/lib/config.js index 23184f3e8..492de0b59 100644 --- a/backend/lib/config.js +++ b/backend/lib/config.js @@ -50,19 +50,29 @@ const configure = () => { } const envPostgresHost = process.env.DB_POSTGRES_HOST || null; + const envPostgresPort = process.env.DB_POSTGRES_PORT || process.env.DB_POSTGRES_PORT || 5432; + const envPostgresUser = process.env.DB_POSTGRES_USER || null; + const envPostgresPassword = process.env.DB_POSTGRES_PASSWORD; + const envPostgresName = process.env.DB_POSTGRES_NAME || null; - if (envPostgresHost && envPostgresUser && envPostgresName) { + const envPostgresSchema = process.env.DB_POSTGRES_SCHEMA || 'public'; + + const envPostgresSSLMode = process.env.DB_POSTGRES_SSL_MODE || 'prefer'; + + if (envPostgresHost && envPostgresUser && envPostgresName && envPostgresPassword) { // 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, + port: envPostgresPort, user: envPostgresUser, - password: process.env.DB_POSTGRES_PASSWORD, + password: envPostgresPassword, name: envPostgresName, + schema: envPostgresSchema, + sslMode: envPostgresSSLMode }, keys: getKeys(), }; diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml index 5abe057b0..6a5814537 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -37,6 +37,8 @@ services: DB_POSTGRES_USER: 'npm' DB_POSTGRES_PASSWORD: 'npmpass' DB_POSTGRES_NAME: 'npm' + DB_POSTGRES_SCHEMA: 'public' + DB_POSTGRES_SSL_MODE: 'prefer' # DB_SQLITE_FILE: "/data/database.sqlite" # DISABLE_IPV6: "true" # Required for DNS Certificate provisioning testing: diff --git a/docs/src/setup/index.md b/docs/src/setup/index.md index c2296da7f..af350e83f 100644 --- a/docs/src/setup/index.md +++ b/docs/src/setup/index.md @@ -121,6 +121,8 @@ services: DB_POSTGRES_USER: 'npm' DB_POSTGRES_PASSWORD: 'npmpass' DB_POSTGRES_NAME: 'npm' + DB_POSTGRES_SCHEMA: 'public' # Optional: PostgreSQL schema (default: 'public') + DB_POSTGRES_SSL_MODE: 'prefer' # Optional: SSL mode (disable, allow, prefer, require) # Uncomment this if IPv6 is not enabled on your host # DISABLE_IPV6: 'true' volumes: @@ -139,9 +141,15 @@ services: - ./postgres:/var/lib/postgresql/data ``` -::: warning +::: info -Custom Postgres schema is not supported, as such `public` will be used. +PostgreSQL Configuration Options: +- `DB_POSTGRES_SCHEMA`: PostgreSQL schema to use (default: 'public') +- `DB_POSTGRES_SSL_MODE`: SSL connection mode + - `disable`: No SSL + - `allow`: Try non-SSL first, then SSL + - `prefer`: Try SSL first, then non-SSL (default) + - `require`: SSL required ::: From d8d7469971ca5ec1d59069c5407f8a4fc3ff2371 Mon Sep 17 00:00:00 2001 From: Anwar <21956329+anvarknian@users.noreply.github.com> Date: Sat, 27 Sep 2025 19:31:37 -0300 Subject: [PATCH 2/5] Refactor PostgreSQL configuration handling in backend - Cleaned up formatting in db.js for better readability of SSL mode handling. - Aligned variable declarations in config.js for consistency and clarity. - No functional changes were made, only code style improvements. --- backend/db.js | 4 ++-- backend/lib/config.js | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/backend/db.js b/backend/db.js index ba7818141..0378b5b69 100644 --- a/backend/db.js +++ b/backend/db.js @@ -23,9 +23,9 @@ function generateDbConfig() { connection.schema = cfg.schema; } if (cfg.sslMode) { - connection.ssl = cfg.sslMode === 'require' ? true : + connection.ssl = cfg.sslMode === 'require' ? true : cfg.sslMode === 'prefer' ? { rejectUnauthorized: false } : - cfg.sslMode === 'disable' ? false : + cfg.sslMode === 'disable' ? false : cfg.sslMode === 'allow' ? { rejectUnauthorized: false } : false; } } diff --git a/backend/lib/config.js b/backend/lib/config.js index 492de0b59..4fec498d5 100644 --- a/backend/lib/config.js +++ b/backend/lib/config.js @@ -49,16 +49,16 @@ const configure = () => { return; } - const envPostgresHost = process.env.DB_POSTGRES_HOST || null; - const envPostgresPort = process.env.DB_POSTGRES_PORT || process.env.DB_POSTGRES_PORT || 5432; + const envPostgresHost = process.env.DB_POSTGRES_HOST || null; + const envPostgresPort = process.env.DB_POSTGRES_PORT || process.env.DB_POSTGRES_PORT || 5432; - const envPostgresUser = process.env.DB_POSTGRES_USER || null; + const envPostgresUser = process.env.DB_POSTGRES_USER || null; const envPostgresPassword = process.env.DB_POSTGRES_PASSWORD; - const envPostgresName = process.env.DB_POSTGRES_NAME || null; - const envPostgresSchema = process.env.DB_POSTGRES_SCHEMA || 'public'; - - const envPostgresSSLMode = process.env.DB_POSTGRES_SSL_MODE || 'prefer'; + const envPostgresName = process.env.DB_POSTGRES_NAME || null; + const envPostgresSchema = process.env.DB_POSTGRES_SCHEMA || 'public'; + + const envPostgresSSLMode = process.env.DB_POSTGRES_SSL_MODE || 'prefer'; if (envPostgresHost && envPostgresUser && envPostgresName && envPostgresPassword) { // we have enough postgres creds to go with postgres From c887dd4a7c0a5c4c4899c06291b902d45298dbd7 Mon Sep 17 00:00:00 2001 From: Anwar <21956329+anvarknian@users.noreply.github.com> Date: Sat, 27 Sep 2025 19:38:42 -0300 Subject: [PATCH 3/5] Refactor code style in backend configuration files - Improved formatting in db.js and config.js for better readability and consistency. - Aligned variable declarations and indentation throughout both files. - No functional changes were made, focusing solely on code style enhancements. --- backend/db.js | 14 +++++----- backend/lib/config.js | 62 +++++++++++++++++++++---------------------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/backend/db.js b/backend/db.js index 0378b5b69..a34702671 100644 --- a/backend/db.js +++ b/backend/db.js @@ -10,11 +10,11 @@ function generateDbConfig() { return cfg.knex; } const connection = { - host: cfg.host, - user: cfg.user, + host: cfg.host, + user: cfg.user, password: cfg.password, database: cfg.name, - port: cfg.port + port: cfg.port }; // Add PostgreSQL-specific options @@ -24,14 +24,14 @@ function generateDbConfig() { } if (cfg.sslMode) { connection.ssl = cfg.sslMode === 'require' ? true : - cfg.sslMode === 'prefer' ? { rejectUnauthorized: false } : - cfg.sslMode === 'disable' ? false : - cfg.sslMode === 'allow' ? { rejectUnauthorized: false } : false; + cfg.sslMode === 'prefer' ? { rejectUnauthorized: false } : + cfg.sslMode === 'disable' ? false : + cfg.sslMode === 'allow' ? { rejectUnauthorized: false } : false; } } return { - client: cfg.engine, + client: cfg.engine, connection: connection, migrations: { tableName: 'migrations' diff --git a/backend/lib/config.js b/backend/lib/config.js index 4fec498d5..8502931df 100644 --- a/backend/lib/config.js +++ b/backend/lib/config.js @@ -1,10 +1,10 @@ -const fs = require('fs'); +const fs = require('fs'); const NodeRSA = require('node-rsa'); -const logger = require('../logger').global; +const logger = require('../logger').global; -const keysFile = '/data/keys.json'; -const mysqlEngine = 'mysql2'; -const postgresEngine = 'pg'; +const keysFile = '/data/keys.json'; +const mysqlEngine = 'mysql2'; +const postgresEngine = 'pg'; const sqliteClientName = 'sqlite3'; let instance = null; @@ -23,7 +23,7 @@ const configure = () => { if (configData && configData.database) { logger.info(`Using configuration from file: ${filename}`); - instance = configData; + instance = configData; instance.keys = getKeys(); return; } @@ -37,42 +37,42 @@ const configure = () => { logger.info('Using MySQL configuration'); instance = { database: { - engine: mysqlEngine, - host: envMysqlHost, - port: process.env.DB_MYSQL_PORT || 3306, - user: envMysqlUser, + engine: mysqlEngine, + host: envMysqlHost, + port: process.env.DB_MYSQL_PORT || 3306, + user: envMysqlUser, password: process.env.DB_MYSQL_PASSWORD, - name: envMysqlName, + name: envMysqlName, }, keys: getKeys(), }; return; } - const envPostgresHost = process.env.DB_POSTGRES_HOST || null; - const envPostgresPort = process.env.DB_POSTGRES_PORT || process.env.DB_POSTGRES_PORT || 5432; + const envPostgresHost = process.env.DB_POSTGRES_HOST || null; + const envPostgresPort = process.env.DB_POSTGRES_PORT || process.env.DB_POSTGRES_PORT || 5432; - const envPostgresUser = process.env.DB_POSTGRES_USER || null; + const envPostgresUser = process.env.DB_POSTGRES_USER || null; const envPostgresPassword = process.env.DB_POSTGRES_PASSWORD; - const envPostgresName = process.env.DB_POSTGRES_NAME || null; - const envPostgresSchema = process.env.DB_POSTGRES_SCHEMA || 'public'; + const envPostgresName = process.env.DB_POSTGRES_NAME || null; + const envPostgresSchema = process.env.DB_POSTGRES_SCHEMA || 'public'; - const envPostgresSSLMode = process.env.DB_POSTGRES_SSL_MODE || 'prefer'; + const envPostgresSSLMode = process.env.DB_POSTGRES_SSL_MODE || 'prefer'; if (envPostgresHost && envPostgresUser && envPostgresName && envPostgresPassword) { // we have enough postgres creds to go with postgres logger.info('Using Postgres configuration'); instance = { database: { - engine: postgresEngine, - host: envPostgresHost, - port: envPostgresPort, - user: envPostgresUser, + engine: postgresEngine, + host: envPostgresHost, + port: envPostgresPort, + user: envPostgresUser, password: envPostgresPassword, - name: envPostgresName, - schema: envPostgresSchema, - sslMode: envPostgresSSLMode + name: envPostgresName, + schema: envPostgresSchema, + sslMode: envPostgresSSLMode }, keys: getKeys(), }; @@ -84,8 +84,8 @@ const configure = () => { instance = { database: { engine: 'knex-native', - knex: { - client: sqliteClientName, + knex: { + client: sqliteClientName, connection: { filename: envSqliteFile }, @@ -139,12 +139,12 @@ module.exports = { * @param {string} key ie: 'database' or 'database.engine' * @returns {boolean} */ - has: function(key) { + has: function (key) { instance === null && configure(); const keys = key.split('.'); - let level = instance; - let has = true; - keys.forEach((keyItem) =>{ + let level = instance; + let has = true; + keys.forEach((keyItem) => { if (typeof level[keyItem] === 'undefined') { has = false; } else { @@ -188,7 +188,7 @@ module.exports = { instance === null && configure(); return instance.database.engine === mysqlEngine; }, - + /** * Is this a postgres configuration? * From f3a0ccb94aabf1f16b48e8c172ebfd54bf7d01ea Mon Sep 17 00:00:00 2001 From: Anwar <21956329+anvarknian@users.noreply.github.com> Date: Sat, 27 Sep 2025 19:41:36 -0300 Subject: [PATCH 4/5] Fix formatting --- backend/db.js | 8 ++++---- backend/lib/config.js | 48 +++++++++++++++++++++---------------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/backend/db.js b/backend/db.js index a34702671..932e382a5 100644 --- a/backend/db.js +++ b/backend/db.js @@ -10,11 +10,11 @@ function generateDbConfig() { return cfg.knex; } const connection = { - host: cfg.host, - user: cfg.user, + host: cfg.host, + user: cfg.user, password: cfg.password, database: cfg.name, - port: cfg.port + port: cfg.port }; // Add PostgreSQL-specific options @@ -31,7 +31,7 @@ function generateDbConfig() { } return { - client: cfg.engine, + client: cfg.engine, connection: connection, migrations: { tableName: 'migrations' diff --git a/backend/lib/config.js b/backend/lib/config.js index 8502931df..482298ae3 100644 --- a/backend/lib/config.js +++ b/backend/lib/config.js @@ -1,10 +1,10 @@ -const fs = require('fs'); +const fs = require('fs'); const NodeRSA = require('node-rsa'); -const logger = require('../logger').global; +const logger = require('../logger').global; -const keysFile = '/data/keys.json'; -const mysqlEngine = 'mysql2'; -const postgresEngine = 'pg'; +const keysFile = '/data/keys.json'; +const mysqlEngine = 'mysql2'; +const postgresEngine = 'pg'; const sqliteClientName = 'sqlite3'; let instance = null; @@ -23,7 +23,7 @@ const configure = () => { if (configData && configData.database) { logger.info(`Using configuration from file: ${filename}`); - instance = configData; + instance = configData; instance.keys = getKeys(); return; } @@ -37,12 +37,12 @@ const configure = () => { logger.info('Using MySQL configuration'); instance = { database: { - engine: mysqlEngine, - host: envMysqlHost, - port: process.env.DB_MYSQL_PORT || 3306, - user: envMysqlUser, + engine: mysqlEngine, + host: envMysqlHost, + port: process.env.DB_MYSQL_PORT || 3306, + user: envMysqlUser, password: process.env.DB_MYSQL_PASSWORD, - name: envMysqlName, + name: envMysqlName, }, keys: getKeys(), }; @@ -52,10 +52,10 @@ const configure = () => { const envPostgresHost = process.env.DB_POSTGRES_HOST || null; const envPostgresPort = process.env.DB_POSTGRES_PORT || process.env.DB_POSTGRES_PORT || 5432; - const envPostgresUser = process.env.DB_POSTGRES_USER || null; + const envPostgresUser = process.env.DB_POSTGRES_USER || null; const envPostgresPassword = process.env.DB_POSTGRES_PASSWORD; - const envPostgresName = process.env.DB_POSTGRES_NAME || null; + const envPostgresName = process.env.DB_POSTGRES_NAME || null; const envPostgresSchema = process.env.DB_POSTGRES_SCHEMA || 'public'; const envPostgresSSLMode = process.env.DB_POSTGRES_SSL_MODE || 'prefer'; @@ -65,14 +65,14 @@ const configure = () => { logger.info('Using Postgres configuration'); instance = { database: { - engine: postgresEngine, - host: envPostgresHost, - port: envPostgresPort, - user: envPostgresUser, + engine: postgresEngine, + host: envPostgresHost, + port: envPostgresPort, + user: envPostgresUser, password: envPostgresPassword, - name: envPostgresName, - schema: envPostgresSchema, - sslMode: envPostgresSSLMode + name: envPostgresName, + schema: envPostgresSchema, + sslMode: envPostgresSSLMode }, keys: getKeys(), }; @@ -84,8 +84,8 @@ const configure = () => { instance = { database: { engine: 'knex-native', - knex: { - client: sqliteClientName, + knex: { + client: sqliteClientName, connection: { filename: envSqliteFile }, @@ -142,8 +142,8 @@ module.exports = { has: function (key) { instance === null && configure(); const keys = key.split('.'); - let level = instance; - let has = true; + let level = instance; + let has = true; keys.forEach((keyItem) => { if (typeof level[keyItem] === 'undefined') { has = false; From a5cd7b27d477d1ed04882be23e24492e9f4038b6 Mon Sep 17 00:00:00 2001 From: Anwar <21956329+anvarknian@users.noreply.github.com> Date: Sat, 27 Sep 2025 20:06:06 -0300 Subject: [PATCH 5/5] Eslint: db.js and lib/config.js --- backend/db.js | 11 ++++------- backend/lib/config.js | 19 +++++++++---------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/backend/db.js b/backend/db.js index 932e382a5..840b3dbce 100644 --- a/backend/db.js +++ b/backend/db.js @@ -14,7 +14,7 @@ function generateDbConfig() { user: cfg.user, password: cfg.password, database: cfg.name, - port: cfg.port + port: cfg.port, }; // Add PostgreSQL-specific options @@ -23,10 +23,7 @@ function generateDbConfig() { connection.schema = cfg.schema; } if (cfg.sslMode) { - connection.ssl = cfg.sslMode === 'require' ? true : - cfg.sslMode === 'prefer' ? { rejectUnauthorized: false } : - cfg.sslMode === 'disable' ? false : - cfg.sslMode === 'allow' ? { rejectUnauthorized: false } : false; + connection.ssl = cfg.sslMode === 'require' ? true : cfg.sslMode === 'prefer' ? { rejectUnauthorized: false } : cfg.sslMode === 'disable' ? false : cfg.sslMode === 'allow' ? { rejectUnauthorized: false } : false; } } @@ -34,8 +31,8 @@ function generateDbConfig() { client: cfg.engine, connection: connection, migrations: { - tableName: 'migrations' - } + tableName: 'migrations', + }, }; } diff --git a/backend/lib/config.js b/backend/lib/config.js index 482298ae3..eb079d09b 100644 --- a/backend/lib/config.js +++ b/backend/lib/config.js @@ -72,7 +72,7 @@ const configure = () => { password: envPostgresPassword, name: envPostgresName, schema: envPostgresSchema, - sslMode: envPostgresSSLMode + sslMode: envPostgresSSLMode, }, keys: getKeys(), }; @@ -87,10 +87,10 @@ const configure = () => { knex: { client: sqliteClientName, connection: { - filename: envSqliteFile + filename: envSqliteFile, }, - useNullAsDefault: true - } + useNullAsDefault: true, + }, }, keys: getKeys(), }; @@ -133,7 +133,6 @@ const generateKeys = () => { }; module.exports = { - /** * * @param {string} key ie: 'database' or 'database.engine' @@ -190,10 +189,10 @@ module.exports = { }, /** - * Is this a postgres configuration? - * - * @returns {boolean} - */ + * Is this a postgres configuration? + * + * @returns {boolean} + */ isPostgres: function () { instance === null && configure(); return instance.database.engine === postgresEngine; @@ -243,5 +242,5 @@ module.exports = { return process.env.LE_SERVER; } return null; - } + }, };