added postgresql support for broken functions

This commit is contained in:
jeff 2024-10-18 15:48:32 -03:00
parent b0b234ff7d
commit 9a03a247d9
15 changed files with 933 additions and 621 deletions

View File

@ -29,6 +29,7 @@ if (config.debug()) {
app.set('json spaces', 2); app.set('json spaces', 2);
} }
// CORS for everything // CORS for everything
app.use(require('./lib/express/cors')); app.use(require('./lib/express/cors'));

View File

@ -252,10 +252,14 @@ const internalAccessList = {
let query = accessListModel let query = accessListModel
.query() .query()
.select('access_list.*', accessListModel.raw('COUNT(proxy_host.id) as proxy_host_count')) .select('access_list.*', accessListModel.raw('COUNT(proxy_host.id) as proxy_host_count'))
.joinRaw('LEFT JOIN `proxy_host` ON `proxy_host`.`access_list_id` = `access_list`.`id` AND `proxy_host`.`is_deleted` = 0') .leftJoin('proxy_host', function() {
this.on('proxy_host.access_list_id', '=', 'access_list.id')
.andOn('proxy_host.is_deleted', '=', 0);
})
.where('access_list.is_deleted', 0) .where('access_list.is_deleted', 0)
.andWhere('access_list.id', data.id) .andWhere('access_list.id', data.id)
.allowGraph('[owner,items,clients,proxy_hosts.[certificate,access_list.[clients,items]]]') .allowGraph('[owner,items,clients,proxy_hosts.[certificate,access_list.[clients,items]]]')
.groupBy('access_list.id')
.first(); .first();
if (access_data.permission_visibility !== 'all') { if (access_data.permission_visibility !== 'all') {
@ -373,7 +377,10 @@ const internalAccessList = {
let query = accessListModel let query = accessListModel
.query() .query()
.select('access_list.*', accessListModel.raw('COUNT(proxy_host.id) as proxy_host_count')) .select('access_list.*', accessListModel.raw('COUNT(proxy_host.id) as proxy_host_count'))
.joinRaw('LEFT JOIN `proxy_host` ON `proxy_host`.`access_list_id` = `access_list`.`id` AND `proxy_host`.`is_deleted` = 0') .leftJoin('proxy_host', function() {
this.on('proxy_host.access_list_id', '=', 'access_list.id')
.andOn('proxy_host.is_deleted', '=', 0);
})
.where('access_list.is_deleted', 0) .where('access_list.is_deleted', 0)
.groupBy('access_list.id') .groupBy('access_list.id')
.allowGraph('[owner,items,clients]') .allowGraph('[owner,items,clients]')

View File

@ -22,9 +22,9 @@ const internalAuditLog = {
.allowGraph('[user]'); .allowGraph('[user]');
// Query is used for searching // Query is used for searching
if (typeof search_query === 'string') { if (typeof search_query === 'string' && search_query.length > 0) {
query.where(function () { query.where(function () {
this.where('meta', 'like', '%' + search_query + '%'); this.whereRaw('CAST(meta AS VARCHAR(65535)) like ? ESCAPE \'\'', '%' + search_query + '%');
}); });
} }

View File

@ -409,16 +409,16 @@ const internalDeadHost = {
.where('is_deleted', 0) .where('is_deleted', 0)
.groupBy('id') .groupBy('id')
.allowGraph('[owner,certificate]') .allowGraph('[owner,certificate]')
.orderBy('domain_names', 'ASC'); .orderByRaw('CAST(domain_names AS VARCHAR(65535)) ASC');
if (access_data.permission_visibility !== 'all') { if (access_data.permission_visibility !== 'all') {
query.andWhere('owner_user_id', access.token.getUserId(1)); query.andWhere('owner_user_id', access.token.getUserId(1));
} }
// Query is used for searching // Query is used for searching
if (typeof search_query === 'string') { if (typeof search_query === 'string' && search_query.length > 0) {
query.where(function () { query.where(function () {
this.where('domain_names', 'like', '%' + search_query + '%'); this.whereRaw('CAST(domain_names AS VARCHAR(65535)) like ? ESCAPE \'\'', '%' + search_query + '%');
}); });
} }

View File

@ -129,15 +129,15 @@ const internalHost = {
proxyHostModel proxyHostModel
.query() .query()
.where('is_deleted', 0) .where('is_deleted', 0)
.andWhere('domain_names', 'like', '%' + hostname + '%'), .whereRaw('CAST(domain_names AS VARCHAR(65535)) like ? ESCAPE \'\'', '%'+hostname + '%'),
redirectionHostModel redirectionHostModel
.query() .query()
.where('is_deleted', 0) .where('is_deleted', 0)
.andWhere('domain_names', 'like', '%' + hostname + '%'), .whereRaw('CAST(domain_names AS VARCHAR(65535)) like ? ESCAPE \'\'', '%'+hostname + '%'),
deadHostModel deadHostModel
.query() .query()
.where('is_deleted', 0) .where('is_deleted', 0)
.andWhere('domain_names', 'like', '%' + hostname + '%') .whereRaw('CAST(domain_names AS VARCHAR(65535)) like ? ESCAPE \'\'', '%'+hostname + '%'),
]; ];
return Promise.all(promises) return Promise.all(promises)

View File

@ -409,6 +409,7 @@ const internalProxyHost = {
* @returns {Promise} * @returns {Promise}
*/ */
getAll: (access, expand, search_query) => { getAll: (access, expand, search_query) => {
return access.can('proxy_hosts:list') return access.can('proxy_hosts:list')
.then((access_data) => { .then((access_data) => {
let query = proxyHostModel let query = proxyHostModel
@ -416,16 +417,17 @@ const internalProxyHost = {
.where('is_deleted', 0) .where('is_deleted', 0)
.groupBy('id') .groupBy('id')
.allowGraph('[owner,access_list,certificate]') .allowGraph('[owner,access_list,certificate]')
.orderBy('domain_names', 'ASC'); .orderByRaw('CAST(domain_names AS VARCHAR(65535) ) ASC')
;
if (access_data.permission_visibility !== 'all') { if (access_data.permission_visibility !== 'all') {
query.andWhere('owner_user_id', access.token.getUserId(1)); query.andWhere('owner_user_id', access.token.getUserId(1));
} }
// Query is used for searching // Query is used for searching
if (typeof search_query === 'string') { if (typeof search_query === 'string' && search_query.length > 0) {
query.where(function () { query.where(function () {
this.where('domain_names', 'like', '%' + search_query + '%'); this.whereRaw('CAST(domain_names AS VARCHAR(65535) ) like ? ESCAPE \'\'', '%'+search_query + '%');
}); });
} }
@ -436,6 +438,7 @@ const internalProxyHost = {
return query.then(utils.omitRows(omissions())); return query.then(utils.omitRows(omissions()));
}) })
.then((rows) => { .then((rows) => {
if (typeof expand !== 'undefined' && expand !== null && expand.indexOf('certificate') !== -1) { if (typeof expand !== 'undefined' && expand !== null && expand.indexOf('certificate') !== -1) {
return internalHost.cleanAllRowsCertificateMeta(rows); return internalHost.cleanAllRowsCertificateMeta(rows);
} }

View File

@ -20,7 +20,6 @@ const internalRedirectionHost = {
*/ */
create: (access, data) => { create: (access, data) => {
let create_certificate = data.certificate_id === 'new'; let create_certificate = data.certificate_id === 'new';
if (create_certificate) { if (create_certificate) {
delete data.certificate_id; delete data.certificate_id;
} }
@ -409,16 +408,16 @@ const internalRedirectionHost = {
.where('is_deleted', 0) .where('is_deleted', 0)
.groupBy('id') .groupBy('id')
.allowGraph('[owner,certificate]') .allowGraph('[owner,certificate]')
.orderBy('domain_names', 'ASC'); .orderByRaw('CAST(domain_names AS VARCHAR(65535) ) ASC');
if (access_data.permission_visibility !== 'all') { if (access_data.permission_visibility !== 'all') {
query.andWhere('owner_user_id', access.token.getUserId(1)); query.andWhere('owner_user_id', access.token.getUserId(1));
} }
// Query is used for searching // Query is used for searching
if (typeof search_query === 'string') { if (typeof search_query === 'string' && search_query.length > 0) {
query.where(function () { query.where(function () {
this.where('domain_names', 'like', '%' + search_query + '%'); this.whereRaw('CAST(domain_names AS VARCHAR(65535) ) like ? ESCAPE \'\'', '%' + search_query + '%');
}); });
} }

View File

@ -298,16 +298,18 @@ const internalStream = {
.where('is_deleted', 0) .where('is_deleted', 0)
.groupBy('id') .groupBy('id')
.allowGraph('[owner]') .allowGraph('[owner]')
.orderBy('incoming_port', 'ASC'); //.orderBy('incoming_port', 'ASC')
.orderByRaw('CAST(incoming_port AS INTEGER) ASC')
;
if (access_data.permission_visibility !== 'all') { if (access_data.permission_visibility !== 'all') {
query.andWhere('owner_user_id', access.token.getUserId(1)); query.andWhere('owner_user_id', access.token.getUserId(1));
} }
// Query is used for searching // Query is used for searching
if (typeof search_query === 'string') { if (typeof search_query === 'string' && search_query.length > 0) {
query.where(function () { query.where(function () {
this.where('incoming_port', 'like', '%' + search_query + '%'); this.whereRaw('CAST(incoming_port AS VARCHAR(65535)) like ? ESCAPE \'\'', '%' + search_query+ '%');
}); });
} }

View File

@ -55,7 +55,7 @@ const configure = () => {
database: { database: {
engine: 'pg', engine: 'pg',
host: envPostgresqlHost, host: envPostgresqlHost,
port: process.env.DB_POSTGRESQL_PORT || 3306, port: process.env.DB_POSTGRESQL_PORT || 5432,
user: envPostgresqlUser, user: envPostgresqlUser,
password: process.env.DB_POSTGRESQL_PASSWORD, password: process.env.DB_POSTGRESQL_PASSWORD,
name: envPostgresqlName, name: envPostgresqlName,

View File

@ -17,6 +17,9 @@ const boolFields = [
'preserve_path', 'preserve_path',
'ssl_forced', 'ssl_forced',
'block_exploits', 'block_exploits',
'hsts_enabled',
'hsts_subdomains',
'http2_support',
]; ];
class RedirectionHost extends Model { class RedirectionHost extends Model {

View File

@ -21,9 +21,10 @@
"moment": "^2.29.4", "moment": "^2.29.4",
"mysql2": "^3.11.1", "mysql2": "^3.11.1",
"node-rsa": "^1.0.8", "node-rsa": "^1.0.8",
"objection": "3.0.1", "objection": "^3.0.1",
"path": "^0.12.7", "path": "^0.12.7",
"pg": "^8.13.0", "pg": "^8.13.0",
"postgraphile": "^4.13.0",
"signale": "1.4.0", "signale": "1.4.0",
"sqlite3": "5.1.6", "sqlite3": "5.1.6",
"temp-write": "^4.0.0" "temp-write": "^4.0.0"

View File

@ -18,7 +18,8 @@ const setupDefaultUser = () => {
.select('id') .select('id')
.where('is_deleted', 0) .where('is_deleted', 0)
.then((row) => { .then((row) => {
if (!row.length || !row[0].id) { if (row.length === 0) {
// Create a new user and set password // Create a new user and set password
let email = process.env.INITIAL_ADMIN_EMAIL || 'admin@example.com'; let email = process.env.INITIAL_ADMIN_EMAIL || 'admin@example.com';
let password = process.env.INITIAL_ADMIN_PASSWORD || 'changeme'; let password = process.env.INITIAL_ADMIN_PASSWORD || 'changeme';

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,16 @@
# WARNING: This is a DEVELOPMENT docker-compose file, it should not be used for production. # WARNING: This is a DEVELOPMENT docker-compose file, it should not be used for production.
services: services:
npm: npm1:
image: nginxproxymanager:dev image: nginxproxymanager:dev
container_name: npm_core container_name: npm_core1
build: build:
context: ./ context: ./
dockerfile: ./dev/Dockerfile dockerfile: ./dev/Dockerfile
ports: ports:
- 3080:80 - 4080:80
- 3081:81 - 4081:81
- 3443:443 - 4443:443
networks: networks:
- nginx_proxy_manager - nginx_proxy_manager
environment: environment:
@ -22,7 +22,7 @@ services:
DEVELOPMENT: 'true' DEVELOPMENT: 'true'
LE_STAGING: 'true' LE_STAGING: 'true'
# db: # db:
DB_POSTGRESQL_HOST: 'db' DB_POSTGRESQL_HOST: 'db1'
DB_POSTGRESQL_PORT: '5432' DB_POSTGRESQL_PORT: '5432'
DB_POSTGRESQL_USER: 'npm' DB_POSTGRESQL_USER: 'npm'
DB_POSTGRESQL_PASSWORD: 'npmpass' DB_POSTGRESQL_PASSWORD: 'npmpass'
@ -30,18 +30,18 @@ services:
# DB_SQLITE_FILE: "/data/database.sqlite" # DB_SQLITE_FILE: "/data/database.sqlite"
# DISABLE_IPV6: "true" # DISABLE_IPV6: "true"
volumes: volumes:
- npm_data:/data - npm_data1:/data
- le_data:/etc/letsencrypt - le_data1:/etc/letsencrypt
- ../backend:/app - ../backend:/app
- ../frontend:/app/frontend - ../frontend:/app/frontend
- ../global:/app/global - ../global:/app/global
depends_on: depends_on:
- db - db1
working_dir: /app working_dir: /app
db: db1:
image: postgres:14.2-alpine image: postgis/postgis:17-3.5-alpine
container_name: npm_db container_name: npm_db1
ports: ports:
- 5432:5432 - 5432:5432
networks: networks:
@ -51,7 +51,7 @@ services:
POSTGRES_USER: "npm" POSTGRES_USER: "npm"
POSTGRES_DB: "npm" POSTGRES_DB: "npm"
volumes: volumes:
- db_data:/var/lib/postgresql/data - db_data1:/var/lib/postgresql/data
pgadmin: pgadmin:
image: dpage/pgadmin4 image: dpage/pgadmin4
environment: environment:
@ -62,27 +62,25 @@ services:
networks: networks:
- nginx_proxy_manager - nginx_proxy_manager
depends_on: depends_on:
- db - db1
swagger: swagger1:
image: swaggerapi/swagger-ui:latest image: swaggerapi/swagger-ui:latest
container_name: npm_swagger container_name: npm_swagger1
ports: ports:
- 3082:80 - 5082:80
environment: environment:
URL: "http://npm:81/api/schema" URL: "http://npm:81/api/schema"
PORT: '80' PORT: '80'
depends_on: depends_on:
- npm - npm1
volumes: volumes:
npm_data: npm_data1:
name: npm_core_data name: npm_core_data
le_data: le_data1:
name: npm_le_data name: npm_le_data
db_data:
name: npm_db_data
db_data1: db_data1:
name: npm_db_data1 name: npm_db_data1