diff --git a/backend/internal/host.js b/backend/internal/host.js index 9c91b416..354b382b 100644 --- a/backend/internal/host.js +++ b/backend/internal/host.js @@ -118,8 +118,8 @@ const internalHost = { if (promises_results[3]) { // SSL Passthrough Hosts - response_object.ssl_passthrough_hosts = internalHost._getHostsWithDomains(promises_results[3], domain_names); - response_object.total_count += response_object.ssl_passthrough_hosts.length; + response_object.ssl_passthrough_hosts = internalHost._getHostsWithDomains(promises_results[3], domain_names); + response_object.total_count += response_object.ssl_passthrough_hosts.length; } return response_object; diff --git a/backend/internal/nginx.js b/backend/internal/nginx.js index 0bf31ac2..98225c19 100644 --- a/backend/internal/nginx.js +++ b/backend/internal/nginx.js @@ -1,11 +1,11 @@ -const _ = require('lodash'); -const fs = require('fs'); -const logger = require('../logger').nginx; -const utils = require('../lib/utils'); -const error = require('../lib/error'); -const { Liquid } = require('liquidjs'); -const passthroughHostModel = require('../models/ssl_passthrough_host'); -const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG; +const _ = require('lodash'); +const fs = require('fs'); +const logger = require('../logger').nginx; +const utils = require('../lib/utils'); +const error = require('../lib/error'); +const { Liquid } = require('liquidjs'); +const passthroughHostModel = require('../models/ssl_passthrough_host'); +const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG; const internalNginx = { @@ -24,7 +24,7 @@ const internalNginx = { * @returns {Promise} */ configure: (model, host_type, host) => { - let combined_meta = {}; + let combined_meta = {}; const sslPassthroughEnabled = internalNginx.sslPassthroughEnabled(); return internalNginx.test() @@ -34,7 +34,7 @@ const internalNginx = { return internalNginx.deleteConfig(host_type, host); // Don't throw errors, as the file may not exist at all }) .then(() => { - if(host_type === 'ssl_passthrough_host' && !sslPassthroughEnabled){ + if (host_type === 'ssl_passthrough_host' && !sslPassthroughEnabled){ // ssl passthrough is disabled const meta = { nginx_online: false, @@ -64,7 +64,7 @@ const internalNginx = { nginx_err: null }); - if(host_type === 'ssl_passthrough_host'){ + if (host_type === 'ssl_passthrough_host'){ // If passthrough is disabled we have already marked the hosts as offline if (sslPassthroughEnabled) { return passthroughHostModel @@ -109,7 +109,7 @@ const internalNginx = { nginx_err: valid_lines.join('\n') }); - if(host_type === 'ssl_passthrough_host'){ + if (host_type === 'ssl_passthrough_host'){ return passthroughHostModel .query() .where('is_deleted', 0) @@ -235,7 +235,7 @@ const internalNginx = { * @param {Object} host * @returns {Promise} */ - generateConfig: (host_type, host) => { + generateConfig: async (host_type, host) => { host_type = host_type.replace(new RegExp('-', 'g'), '_'); if (debug_mode) { @@ -248,90 +248,87 @@ const internalNginx = { root: __dirname + '/../templates/' }); - return new Promise(async (resolve, reject) => { - let template = null; - let filename = internalNginx.getConfigName(host_type, host.id); + let template = null; + let filename = internalNginx.getConfigName(host_type, host.id); - try { - template = fs.readFileSync(__dirname + '/../templates/' + host_type + '.conf', {encoding: 'utf8'}); - } catch (err) { - reject(new error.ConfigurationError(err.message)); - return; - } + try { + template = fs.readFileSync(__dirname + '/../templates/' + host_type + '.conf', {encoding: 'utf8'}); + } catch (err) { + throw new error.ConfigurationError(err.message); + } - let locationsPromise; - let origLocations; - - // Manipulate the data a bit before sending it to the template - if (host_type === 'ssl_passthrough_host') { - if(internalNginx.sslPassthroughEnabled()){ - const allHosts = await passthroughHostModel - .query() - .where('is_deleted', 0) - .groupBy('id') - .omit(['is_deleted']); - host = { - all_passthrough_hosts: allHosts.map((host) => { - // Replace dots in domain - host.forwarding_host = internalNginx.addIpv6Brackets(host.forwarding_host); - return host; - }), - } - } else { - internalNginx.deleteConfig(host_type, host, false) - } - - } else if (host_type !== 'default') { - host.use_default_location = true; - if (typeof host.advanced_config !== 'undefined' && host.advanced_config) { - host.use_default_location = !internalNginx.advancedConfigHasDefaultLocation(host.advanced_config); - } - } - - if (host.locations) { - //logger.info ('host.locations = ' + JSON.stringify(host.locations, null, 2)); - origLocations = [].concat(host.locations); - locationsPromise = internalNginx.renderLocations(host).then((renderedLocations) => { - host.locations = renderedLocations; - }); - - // Allow someone who is using / custom location path to use it, and skip the default / location - _.map(host.locations, (location) => { - if (location.path === '/') { - host.use_default_location = false; - } - }); + let locationsPromise; + let origLocations; + // Manipulate the data a bit before sending it to the template + if (host_type === 'ssl_passthrough_host') { + if (internalNginx.sslPassthroughEnabled()){ + const allHosts = await passthroughHostModel + .query() + .where('is_deleted', 0) + .groupBy('id') + .omit(['is_deleted']); + host = { + all_passthrough_hosts: allHosts.map((host) => { + // Replace dots in domain + host.forwarding_host = internalNginx.addIpv6Brackets(host.forwarding_host); + return host; + }), + }; } else { - locationsPromise = Promise.resolve(); + internalNginx.deleteConfig(host_type, host, false); } + + } else if (host_type !== 'default') { + host.use_default_location = true; + if (typeof host.advanced_config !== 'undefined' && host.advanced_config) { + host.use_default_location = !internalNginx.advancedConfigHasDefaultLocation(host.advanced_config); + } + } - // Set the IPv6 setting for the host - host.ipv6 = internalNginx.ipv6Enabled(); - - locationsPromise.then(() => { - renderEngine - .parseAndRender(template, host) - .then((config_text) => { - fs.writeFileSync(filename, config_text, {encoding: 'utf8'}); - - if (debug_mode) { - logger.success('Wrote config:', filename, config_text); - } - - // Restore locations array - host.locations = origLocations; - - resolve(true); - }) - .catch((err) => { - if (debug_mode) { - logger.warn('Could not write ' + filename + ':', err.message); - } - - reject(new error.ConfigurationError(err.message)); - }); + if (host.locations) { + //logger.info ('host.locations = ' + JSON.stringify(host.locations, null, 2)); + origLocations = [].concat(host.locations); + locationsPromise = internalNginx.renderLocations(host).then((renderedLocations) => { + host.locations = renderedLocations; }); + + // Allow someone who is using / custom location path to use it, and skip the default / location + _.map(host.locations, (location) => { + if (location.path === '/') { + host.use_default_location = false; + } + }); + + } else { + locationsPromise = Promise.resolve(); + } + + // Set the IPv6 setting for the host + host.ipv6 = internalNginx.ipv6Enabled(); + + return locationsPromise.then(() => { + renderEngine + .parseAndRender(template, host) + .then((config_text) => { + fs.writeFileSync(filename, config_text, {encoding: 'utf8'}); + + if (debug_mode) { + logger.success('Wrote config:', filename, config_text); + } + + // Restore locations array + host.locations = origLocations; + + return true; + }) + .catch((err) => { + if (debug_mode) { + logger.warn('Could not write ' + filename + ':', err.message); + } + + throw new error.ConfigurationError(err.message); + }); }); }, @@ -514,12 +511,12 @@ const internalNginx = { * Helper function to add brackets to an IP if it is IPv6 * @returns {string} */ - addIpv6Brackets: function (ip) { + addIpv6Brackets: function (ip) { // Only run check if ipv6 is enabled if (internalNginx.ipv6Enabled()) { const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/gi; - if(ipv6Regex.test(ip)){ - return `[${ip}]` + if (ipv6Regex.test(ip)){ + return `[${ip}]`; } } return ip; diff --git a/backend/migrations/20211010141200_ssl_passthrough_host.js b/backend/migrations/20211010141200_ssl_passthrough_host.js index 32538686..1d19813d 100644 --- a/backend/migrations/20211010141200_ssl_passthrough_host.js +++ b/backend/migrations/20211010141200_ssl_passthrough_host.js @@ -27,23 +27,23 @@ exports.up = function (knex/*, Promise*/) { }).then(() => { logger.info('[' + migrate_name + '] Table created'); }) - .then(() => { - return knex.schema.table('user_permission', (table) => { - table.string('ssl_passthrough_hosts').notNull(); - }) - .then(() => { - return knex('user_permission').update('ssl_passthrough_hosts', knex.ref('streams')); - }) - .then(() => { - return knex.schema.alterTable('user_permission', (table) => { - table.string('ssl_passthrough_hosts').notNullable().alter(); - }); - }) - .then(() => { - logger.info('[' + migrate_name + '] permissions updated'); - }); - }) - ; + .then(() => { + return knex.schema.table('user_permission', (table) => { + table.string('ssl_passthrough_hosts').notNull(); + }) + .then(() => { + return knex('user_permission').update('ssl_passthrough_hosts', knex.ref('streams')); + }) + .then(() => { + return knex.schema.alterTable('user_permission', (table) => { + table.string('ssl_passthrough_hosts').notNullable().alter(); + }); + }) + .then(() => { + logger.info('[' + migrate_name + '] permissions updated'); + }); + }) + ; }; /** @@ -59,7 +59,7 @@ exports.down = function (knex/*, Promise*/) { return knex.schema.dropTable('stream').then(() => { return knex.schema.table('user_permission', (table) => { table.dropColumn('ssl_passthrough_hosts'); - }) + }); }) .then(function () { logger.info('[' + migrate_name + '] Table altered and permissions updated'); diff --git a/backend/routes/api/main.js b/backend/routes/api/main.js index 3ccf9398..209d4770 100644 --- a/backend/routes/api/main.js +++ b/backend/routes/api/main.js @@ -42,7 +42,7 @@ router.use('/nginx/certificates', require('./nginx/certificates')); router.get('/ssl-passthrough-enabled', (req, res/*, next*/) => { res.status(200).send({ - status: 'OK', + status: 'OK', ssl_passthrough_enabled: internalNginx.sslPassthroughEnabled() }); }); diff --git a/backend/routes/api/nginx/ssl_passthrough_hosts.js b/backend/routes/api/nginx/ssl_passthrough_hosts.js index dfa2eac3..2c7f090e 100644 --- a/backend/routes/api/nginx/ssl_passthrough_hosts.js +++ b/backend/routes/api/nginx/ssl_passthrough_hosts.js @@ -98,7 +98,7 @@ router } }, { host_id: req.params.host_id, - expand: (typeof req.query.expand === 'string' ? req.query.expand.split(',') : null) + expand: (typeof req.query.expand === 'string' ? req.query.expand.split(',') : null) }) .then((data) => { return internalSslPassthrough.get(res.locals.access, {