diff --git a/package.json b/package.json index db231cd..55d83df 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nginx-proxy-manager", - "version": "2.0.1", + "version": "2.0.2", "description": "A beautiful interface for creating Nginx endpoints", "main": "src/backend/index.js", "devDependencies": { diff --git a/src/backend/internal/certificate.js b/src/backend/internal/certificate.js index 90d6f11..f081e5a 100644 --- a/src/backend/internal/certificate.js +++ b/src/backend/internal/certificate.js @@ -183,10 +183,7 @@ const internalCertificate = { }); }); } else { - return internalCertificate.writeCustomCert(certificate) - .then(() => { - return certificate; - }); + return certificate; } }).then(certificate => { @@ -409,6 +406,10 @@ const internalCertificate = { * @returns {Promise} */ writeCustomCert: certificate => { + if (debug_mode) { + logger.info('Writing Custom Certificate:', certificate); + } + let dir = '/data/custom_ssl/npm-' + certificate.id; return new Promise((resolve, reject) => { @@ -549,8 +550,13 @@ const internalCertificate = { id: data.id, expires_on: certificateModel.raw('FROM_UNIXTIME(' + validations.certificate.dates.to + ')'), domain_names: [validations.certificate.cn], - meta: row.meta - }); + meta: _.clone(row.meta) // Prevent the update method from changing this value that we'll use later + }) + .then(certificate => { + console.log('ROWMETA:', row.meta); + certificate.meta = row.meta; + return internalCertificate.writeCustomCert(certificate); + }) }) .then(() => { return _.pick(row.meta, internalCertificate.allowed_ssl_files); diff --git a/src/backend/internal/dead-host.js b/src/backend/internal/dead-host.js index e795620..9c2b8d3 100644 --- a/src/backend/internal/dead-host.js +++ b/src/backend/internal/dead-host.js @@ -189,7 +189,9 @@ const internalDeadHost = { .then(row => { // Configure nginx return internalNginx.configure(deadHostModel, 'dead_host', row) - .then(() => { + .then(new_meta => { + row.meta = new_meta; + row = internalHost.cleanRowCertificateMeta(row); return _.omit(row, omissions()); }); }); @@ -235,6 +237,7 @@ const internalDeadHost = { }) .then(row => { if (row) { + row = internalHost.cleanRowCertificateMeta(row); return _.omit(row, omissions()); } else { throw new error.ItemNotFoundError(data.id); @@ -322,6 +325,13 @@ const internalDeadHost = { } return query; + }) + .then(rows => { + if (typeof expand !== 'undefined' && expand !== null && expand.indexOf('certificate') !== -1) { + return internalHost.cleanAllRowsCertificateMeta(rows); + } + + return rows; }); }, diff --git a/src/backend/internal/host.js b/src/backend/internal/host.js index 4b56003..90c993f 100644 --- a/src/backend/internal/host.js +++ b/src/backend/internal/host.js @@ -6,6 +6,36 @@ const deadHostModel = require('../models/dead_host'); const internalHost = { + /** + * used by the getAll functions of hosts, this removes the certificate meta if present + * + * @param {Array} rows + * @returns {Array} + */ + cleanAllRowsCertificateMeta: function (rows) { + rows.map(function (row, idx) { + if (typeof rows[idx].certificate !== 'undefined' && rows[idx].certificate) { + rows[idx].certificate.meta = {}; + } + }); + + return rows; + }, + + /** + * used by the get/update functions of hosts, this removes the certificate meta if present + * + * @param {Object} row + * @returns {Object} + */ + cleanRowCertificateMeta: function (row) { + if (typeof row.certificate !== 'undefined' && row.certificate) { + row.certificate.meta = {}; + } + + return row; + }, + /** * This returns all the host types with any domain listed in the provided domain_names array. * This is used by the certificates to temporarily disable any host that is using the domain diff --git a/src/backend/internal/nginx.js b/src/backend/internal/nginx.js index a3c3f68..a0d8499 100644 --- a/src/backend/internal/nginx.js +++ b/src/backend/internal/nginx.js @@ -25,6 +25,8 @@ const internalNginx = { * @returns {Promise} */ configure: (model, host_type, host) => { + let combined_meta = {}; + return internalNginx.test() .then(() => { // Nginx is OK @@ -39,30 +41,46 @@ const internalNginx = { return internalNginx.test() .then(() => { // nginx is ok + combined_meta = _.assign({}, host.meta, { + nginx_online: true, + nginx_err: null + }); + return model .query() .where('id', host.id) .patch({ - meta: _.assign({}, host.meta, { - nginx_online: true, - nginx_err: null - }) + meta: combined_meta }); }) .catch(err => { + // Remove the error_log line because it's a docker-ism false positive that doesn't need to be reported. + // It will always look like this: + // nginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (6: No such device or address) + + let valid_lines = []; + let err_lines = err.message.split("\n"); + err_lines.map(function (line) { + if (line.indexOf('/var/log/nginx/error.log') === -1) { + valid_lines.push(line); + } + }); + if (debug_mode) { - logger.error('Nginx test failed:', err.message); + logger.error('Nginx test failed:', valid_lines.join("\n")); } // config is bad, update meta and delete config + combined_meta = _.assign({}, host.meta, { + nginx_online: false, + nginx_err: valid_lines.join("\n") + }); + return model .query() .where('id', host.id) .patch({ - meta: _.assign({}, host.meta, { - nginx_online: false, - nginx_err: err.message - }) + meta: combined_meta }) .then(() => { return internalNginx.deleteConfig(host_type, host, true); @@ -71,7 +89,10 @@ const internalNginx = { }) .then(() => { return internalNginx.reload(); - }); + }) + .then(() => { + return combined_meta; + }) }, /** @@ -82,7 +103,7 @@ const internalNginx = { logger.info('Testing Nginx configuration'); } - return utils.exec('/usr/sbin/nginx -t'); + return utils.exec('/usr/sbin/nginx -t -g "error_log off;"'); }, /** diff --git a/src/backend/internal/proxy-host.js b/src/backend/internal/proxy-host.js index 2d1c9b2..7c627b7 100644 --- a/src/backend/internal/proxy-host.js +++ b/src/backend/internal/proxy-host.js @@ -190,7 +190,9 @@ const internalProxyHost = { .then(row => { // Configure nginx return internalNginx.configure(proxyHostModel, 'proxy_host', row) - .then(() => { + .then(new_meta => { + row.meta = new_meta; + row = internalHost.cleanRowCertificateMeta(row); return _.omit(row, omissions()); }); }); @@ -236,6 +238,7 @@ const internalProxyHost = { }) .then(row => { if (row) { + row = internalHost.cleanRowCertificateMeta(row); return _.omit(row, omissions()); } else { throw new error.ItemNotFoundError(data.id); @@ -323,6 +326,13 @@ const internalProxyHost = { } return query; + }) + .then(rows => { + if (typeof expand !== 'undefined' && expand !== null && expand.indexOf('certificate') !== -1) { + return internalHost.cleanAllRowsCertificateMeta(rows); + } + + return rows; }); }, diff --git a/src/backend/internal/redirection-host.js b/src/backend/internal/redirection-host.js index 15df7d9..57bb9d1 100644 --- a/src/backend/internal/redirection-host.js +++ b/src/backend/internal/redirection-host.js @@ -189,7 +189,9 @@ const internalRedirectionHost = { .then(row => { // Configure nginx return internalNginx.configure(redirectionHostModel, 'redirection_host', row) - .then(() => { + .then(new_meta => { + row.meta = new_meta; + row = internalHost.cleanRowCertificateMeta(row); return _.omit(row, omissions()); }); }); @@ -235,6 +237,7 @@ const internalRedirectionHost = { }) .then(row => { if (row) { + row = internalHost.cleanRowCertificateMeta(row); return _.omit(row, omissions()); } else { throw new error.ItemNotFoundError(data.id); @@ -322,6 +325,13 @@ const internalRedirectionHost = { } return query; + }) + .then(rows => { + if (typeof expand !== 'undefined' && expand !== null && expand.indexOf('certificate') !== -1) { + return internalHost.cleanAllRowsCertificateMeta(rows); + } + + return rows; }); },