reverseproxy: async'ify
This commit is contained in:
@@ -4,7 +4,7 @@ exports = module.exports = {
|
||||
setAppCertificate,
|
||||
setFallbackCertificate,
|
||||
|
||||
generateFallbackCertificateSync,
|
||||
generateFallbackCertificate,
|
||||
|
||||
validateCertificate,
|
||||
|
||||
@@ -47,7 +47,6 @@ const acme2 = require('./acme2.js'),
|
||||
os = require('os'),
|
||||
path = require('path'),
|
||||
paths = require('./paths.js'),
|
||||
rimraf = require('rimraf'),
|
||||
safe = require('safetydance'),
|
||||
settings = require('./settings.js'),
|
||||
shell = require('./shell.js'),
|
||||
@@ -58,8 +57,6 @@ const acme2 = require('./acme2.js'),
|
||||
|
||||
const NGINX_APPCONFIG_EJS = fs.readFileSync(__dirname + '/nginxconfig.ejs', { encoding: 'utf8' });
|
||||
const RESTART_SERVICE_CMD = path.join(__dirname, 'scripts/restartservice.sh');
|
||||
const domainsGet = util.callbackify(domains.get),
|
||||
domainsList = util.callbackify(domains.list);
|
||||
|
||||
function nginxLocation(s) {
|
||||
if (!s.startsWith('!')) return s;
|
||||
@@ -185,17 +182,14 @@ function validateCertificate(location, domainObject, certificate) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function reload(callback) {
|
||||
if (constants.TEST) return callback(null);
|
||||
async function reload() {
|
||||
if (constants.TEST) return;
|
||||
|
||||
shell.sudo('reload', [ RESTART_SERVICE_CMD, 'nginx' ], {}, function (error) {
|
||||
if (error) return callback(new BoxError(BoxError.NGINX_ERROR, `Error reloading nginx: ${error.message}`));
|
||||
|
||||
callback(null);
|
||||
});
|
||||
const [error] = await safe(shell.promises.sudo('reload', [ RESTART_SERVICE_CMD, 'nginx' ], {}));
|
||||
if (error) throw new BoxError(BoxError.NGINX_ERROR, `Error reloading nginx: ${error.message}`);
|
||||
}
|
||||
|
||||
function generateFallbackCertificateSync(domain) {
|
||||
async function generateFallbackCertificate(domain) {
|
||||
assert.strictEqual(typeof domain, 'string');
|
||||
|
||||
const certFilePath = path.join(os.tmpdir(), `${domain}-${crypto.randomBytes(4).readUInt32LE(0)}.cert`);
|
||||
@@ -237,21 +231,15 @@ async function setFallbackCertificate(domain, fallback) {
|
||||
if (!safe.fs.writeFileSync(path.join(paths.NGINX_CERT_DIR, `${domain}.host.key`), fallback.key)) throw new BoxError(BoxError.FS_ERROR, safe.error.message);
|
||||
|
||||
// TODO: maybe the cert is being used by the mail container
|
||||
await util.promisify(reload)();
|
||||
await reload();
|
||||
}
|
||||
|
||||
function restoreFallbackCertificates(callback) {
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
async function restoreFallbackCertificates() {
|
||||
const result = await domains.list();
|
||||
|
||||
domainsList(function (error, result) {
|
||||
if (error) return callback(error);
|
||||
|
||||
result.forEach(function (domain) {
|
||||
if (!safe.fs.writeFileSync(path.join(paths.NGINX_CERT_DIR, `${domain.domain}.host.cert`), domain.fallbackCertificate.cert)) return callback(new BoxError(BoxError.FS_ERROR, safe.error.message));
|
||||
if (!safe.fs.writeFileSync(path.join(paths.NGINX_CERT_DIR, `${domain.domain}.host.key`), domain.fallbackCertificate.key)) return callback(new BoxError(BoxError.FS_ERROR, safe.error.message));
|
||||
});
|
||||
|
||||
callback(null);
|
||||
result.forEach(function (domain) {
|
||||
if (!safe.fs.writeFileSync(path.join(paths.NGINX_CERT_DIR, `${domain.domain}.host.cert`), domain.fallbackCertificate.cert)) throw new BoxError(BoxError.FS_ERROR, safe.error.message);
|
||||
if (!safe.fs.writeFileSync(path.join(paths.NGINX_CERT_DIR, `${domain.domain}.host.key`), domain.fallbackCertificate.key)) throw new BoxError(BoxError.FS_ERROR, safe.error.message);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -294,48 +282,44 @@ function getAcmeCertificatePathSync(vhost, domainObject) {
|
||||
return { certName, certFilePath, keyFilePath, csrFilePath, acmeChallengesDir };
|
||||
}
|
||||
|
||||
function setAppCertificate(location, domainObject, certificate, callback) {
|
||||
async function setAppCertificate(location, domainObject, certificate) {
|
||||
assert.strictEqual(typeof location, 'string');
|
||||
assert.strictEqual(typeof domainObject, 'object');
|
||||
assert.strictEqual(typeof certificate, 'object');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
const fqdn = dns.fqdn(location, domainObject);
|
||||
const { certFilePath, keyFilePath } = getAppCertificatePathSync(fqdn);
|
||||
|
||||
if (certificate.cert && certificate.key) {
|
||||
if (!safe.fs.writeFileSync(certFilePath, certificate.cert)) return callback(safe.error);
|
||||
if (!safe.fs.writeFileSync(keyFilePath, certificate.key)) return callback(safe.error);
|
||||
if (!safe.fs.writeFileSync(certFilePath, certificate.cert)) throw safe.error;
|
||||
if (!safe.fs.writeFileSync(keyFilePath, certificate.key)) throw safe.error;
|
||||
} else { // remove existing cert/key
|
||||
if (!safe.fs.unlinkSync(certFilePath)) debug(`Error removing cert: ${safe.error.message}`);
|
||||
if (!safe.fs.unlinkSync(keyFilePath)) debug(`Error removing key: ${safe.error.message}`);
|
||||
}
|
||||
|
||||
reload(callback);
|
||||
await reload();
|
||||
}
|
||||
|
||||
function getCertificatePath(fqdn, domain, callback) {
|
||||
async function getCertificatePath(fqdn, domain) {
|
||||
assert.strictEqual(typeof fqdn, 'string');
|
||||
assert.strictEqual(typeof domain, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
// 1. user cert always wins
|
||||
// 2. if using fallback provider, return that cert
|
||||
// 3. look for LE certs
|
||||
|
||||
domainsGet(domain, function (error, domainObject) {
|
||||
if (error) return callback(error);
|
||||
const domainObject = await domains.get(domain);
|
||||
|
||||
const appCertPath = getAppCertificatePathSync(fqdn); // user cert always wins
|
||||
if (fs.existsSync(appCertPath.certFilePath) && fs.existsSync(appCertPath.keyFilePath)) return callback(null, appCertPath);
|
||||
const appCertPath = getAppCertificatePathSync(fqdn); // user cert always wins
|
||||
if (fs.existsSync(appCertPath.certFilePath) && fs.existsSync(appCertPath.keyFilePath)) return appCertPath;
|
||||
|
||||
if (domainObject.tlsConfig.provider === 'fallback') return callback(null, getFallbackCertificatePathSync(domain));
|
||||
if (domainObject.tlsConfig.provider === 'fallback') return getFallbackCertificatePathSync(domain);
|
||||
|
||||
const acmeCertPath = getAcmeCertificatePathSync(fqdn, domainObject);
|
||||
if (fs.existsSync(acmeCertPath.certFilePath) && fs.existsSync(acmeCertPath.keyFilePath)) return callback(null, acmeCertPath);
|
||||
const acmeCertPath = getAcmeCertificatePathSync(fqdn, domainObject);
|
||||
if (fs.existsSync(acmeCertPath.certFilePath) && fs.existsSync(acmeCertPath.keyFilePath)) return acmeCertPath;
|
||||
|
||||
return callback(null, getFallbackCertificatePathSync(domain));
|
||||
});
|
||||
return getFallbackCertificatePathSync(domain);
|
||||
}
|
||||
|
||||
async function checkAppCertificate(vhost, domainObject) {
|
||||
@@ -394,70 +378,63 @@ async function updateCertBlobs(vhost, domainObject) {
|
||||
await blobs.set(`${blobs.CERT_PREFIX}-${certName}.csr`, csr);
|
||||
}
|
||||
|
||||
function ensureCertificate(vhost, domain, auditSource, callback) {
|
||||
async function ensureCertificate(vhost, domain, auditSource) {
|
||||
assert.strictEqual(typeof vhost, 'string');
|
||||
assert.strictEqual(typeof domain, 'string');
|
||||
assert.strictEqual(typeof auditSource, 'object');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
domainsGet(domain, async function (error, domainObject) {
|
||||
if (error) return callback(error);
|
||||
const domainObject = await domains.get(domain);
|
||||
|
||||
let bundle;
|
||||
[error, bundle] = await safe(checkAppCertificate(vhost, domainObject));
|
||||
if (error) return callback(error);
|
||||
if (bundle) return callback(null, bundle, { renewed: false });
|
||||
let bundle = await checkAppCertificate(vhost, domainObject);
|
||||
if (bundle) return { bundle, renewed: false };
|
||||
|
||||
if (domainObject.tlsConfig.provider === 'fallback') {
|
||||
debug(`ensureCertificate: ${vhost} will use fallback certs`);
|
||||
if (domainObject.tlsConfig.provider === 'fallback') {
|
||||
debug(`ensureCertificate: ${vhost} will use fallback certs`);
|
||||
|
||||
return callback(null, getFallbackCertificatePathSync(domain), { renewed: false });
|
||||
}
|
||||
return { bundle: getFallbackCertificatePathSync(domain), renewed: false };
|
||||
}
|
||||
|
||||
const { acmeApi, apiOptions } = await getAcmeApi(domainObject);
|
||||
let notAfter = null;
|
||||
const { acmeApi, apiOptions } = await getAcmeApi(domainObject);
|
||||
let notAfter = null;
|
||||
|
||||
const [, currentBundle] = await safe(checkAcmeCertificate(vhost, domainObject));
|
||||
if (currentBundle) {
|
||||
debug(`ensureCertificate: ${vhost} certificate already exists at ${currentBundle.keyFilePath}`);
|
||||
notAfter = getExpiryDate(currentBundle.certFilePath);
|
||||
const isExpiring = (notAfter - new Date()) <= (30 * 24 * 60 * 60 * 1000); // expiring in a month
|
||||
if (!isExpiring && providerMatchesSync(domainObject, currentBundle.certFilePath, apiOptions)) return callback(null, currentBundle, { renewed: false });
|
||||
debug(`ensureCertificate: ${vhost} cert requires renewal`);
|
||||
} else {
|
||||
debug(`ensureCertificate: ${vhost} cert does not exist`);
|
||||
}
|
||||
const [, currentBundle] = await safe(checkAcmeCertificate(vhost, domainObject));
|
||||
if (currentBundle) {
|
||||
debug(`ensureCertificate: ${vhost} certificate already exists at ${currentBundle.keyFilePath}`);
|
||||
notAfter = getExpiryDate(currentBundle.certFilePath);
|
||||
const isExpiring = (notAfter - new Date()) <= (30 * 24 * 60 * 60 * 1000); // expiring in a month
|
||||
if (!isExpiring && providerMatchesSync(domainObject, currentBundle.certFilePath, apiOptions)) return { bundle: currentBundle, renewed: false };
|
||||
debug(`ensureCertificate: ${vhost} cert requires renewal`);
|
||||
} else {
|
||||
debug(`ensureCertificate: ${vhost} cert does not exist`);
|
||||
}
|
||||
|
||||
debug('ensureCertificate: getting certificate for %s with options %j', vhost, _.omit(apiOptions, 'accountKeyPem'));
|
||||
debug('ensureCertificate: getting certificate for %s with options %j', vhost, _.omit(apiOptions, 'accountKeyPem'));
|
||||
|
||||
const acmePaths = getAcmeCertificatePathSync(vhost, domainObject);
|
||||
acmeApi.getCertificate(vhost, domain, acmePaths, apiOptions, async function (error) {
|
||||
debug(`ensureCertificate: error: ${error ? error.message : 'null'} cert: ${acmePaths.certFilePath || 'null'}`);
|
||||
const acmePaths = getAcmeCertificatePathSync(vhost, domainObject);
|
||||
let [error] = await safe(util.promisify(acmeApi.getCertificate)(vhost, domain, acmePaths, apiOptions));
|
||||
debug(`ensureCertificate: error: ${error ? error.message : 'null'} cert: ${acmePaths.certFilePath || 'null'}`);
|
||||
|
||||
await safe(eventlog.add(currentBundle ? eventlog.ACTION_CERTIFICATE_RENEWAL : eventlog.ACTION_CERTIFICATE_NEW, auditSource, { domain: vhost, errorMessage: error ? error.message : '', notAfter }));
|
||||
await safe(eventlog.add(currentBundle ? eventlog.ACTION_CERTIFICATE_RENEWAL : eventlog.ACTION_CERTIFICATE_NEW, auditSource, { domain: vhost, errorMessage: error ? error.message : '', notAfter }));
|
||||
|
||||
if (error && currentBundle && (notAfter - new Date() > 0)) { // still some life left in this certificate
|
||||
debug('ensureCertificate: continue using existing bundle since renewal failed');
|
||||
return callback(null, currentBundle, { renewed: false });
|
||||
}
|
||||
if (error && currentBundle && (notAfter - new Date() > 0)) { // still some life left in this certificate
|
||||
debug('ensureCertificate: continue using existing bundle since renewal failed');
|
||||
return { bundle: currentBundle, renewed: false };
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
[error] = await safe(updateCertBlobs(vhost, domainObject));
|
||||
if (!error) return callback(null, { certFilePath: acmePaths.certFilePath, keyFilePath: acmePaths.keyFilePath }, { renewed: true });
|
||||
}
|
||||
if (!error) {
|
||||
[error] = await safe(updateCertBlobs(vhost, domainObject));
|
||||
if (!error) return { bundle: { certFilePath: acmePaths.certFilePath, keyFilePath: acmePaths.keyFilePath }, renewed: true };
|
||||
}
|
||||
|
||||
debug(`ensureCertificate: renewal of ${vhost} failed. using fallback certificates for ${domain}`);
|
||||
debug(`ensureCertificate: renewal of ${vhost} failed. using fallback certificates for ${domain}`);
|
||||
|
||||
callback(null, getFallbackCertificatePathSync(domain), { renewed: false });
|
||||
});
|
||||
});
|
||||
return { bundle: getFallbackCertificatePathSync(domain), renewed: false };
|
||||
}
|
||||
|
||||
function writeDashboardNginxConfig(bundle, configFileName, vhost, callback) {
|
||||
async function writeDashboardNginxConfig(bundle, configFileName, vhost) {
|
||||
assert.strictEqual(typeof bundle, 'object');
|
||||
assert.strictEqual(typeof configFileName, 'string');
|
||||
assert.strictEqual(typeof vhost, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
const data = {
|
||||
sourceDir: path.resolve(__dirname, '..'),
|
||||
@@ -473,35 +450,29 @@ function writeDashboardNginxConfig(bundle, configFileName, vhost, callback) {
|
||||
const nginxConf = ejs.render(NGINX_APPCONFIG_EJS, data);
|
||||
const nginxConfigFilename = path.join(paths.NGINX_APPCONFIG_DIR, configFileName);
|
||||
|
||||
if (!safe.fs.writeFileSync(nginxConfigFilename, nginxConf)) return callback(new BoxError(BoxError.FS_ERROR, safe.error));
|
||||
if (!safe.fs.writeFileSync(nginxConfigFilename, nginxConf)) throw new BoxError(BoxError.FS_ERROR, safe.error);
|
||||
|
||||
reload(callback);
|
||||
await reload();
|
||||
}
|
||||
|
||||
function writeDashboardConfig(domain, callback) {
|
||||
async function writeDashboardConfig(domain) {
|
||||
assert.strictEqual(typeof domain, 'string');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
debug(`writeDashboardConfig: writing admin config for ${domain}`);
|
||||
|
||||
domainsGet(domain, function (error, domainObject) {
|
||||
if (error) return callback(error);
|
||||
const domainObject = await domains.get(domain);
|
||||
|
||||
const dashboardFqdn = dns.fqdn(constants.DASHBOARD_LOCATION, domainObject);
|
||||
const dashboardFqdn = dns.fqdn(constants.DASHBOARD_LOCATION, domainObject);
|
||||
|
||||
getCertificatePath(dashboardFqdn, domainObject.domain, function (error, bundle) {
|
||||
if (error) return callback(error);
|
||||
const bundle = await getCertificatePath(dashboardFqdn, domainObject.domain);
|
||||
|
||||
writeDashboardNginxConfig(bundle, `${dashboardFqdn}.conf`, dashboardFqdn, callback);
|
||||
});
|
||||
});
|
||||
await writeDashboardNginxConfig(bundle, `${dashboardFqdn}.conf`, dashboardFqdn);
|
||||
}
|
||||
|
||||
function writeAppNginxConfig(app, fqdn, bundle, callback) {
|
||||
async function writeAppNginxConfig(app, fqdn, bundle) {
|
||||
assert.strictEqual(typeof app, 'object');
|
||||
assert.strictEqual(typeof fqdn, 'string');
|
||||
assert.strictEqual(typeof bundle, 'object');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
var sourceDir = path.resolve(__dirname, '..');
|
||||
var endpoint = 'app';
|
||||
@@ -543,17 +514,16 @@ function writeAppNginxConfig(app, fqdn, bundle, callback) {
|
||||
|
||||
if (!safe.fs.writeFileSync(nginxConfigFilename, nginxConf)) {
|
||||
debug('Error creating nginx config for "%s" : %s', app.fqdn, safe.error.message);
|
||||
return callback(new BoxError(BoxError.FS_ERROR, safe.error));
|
||||
throw new BoxError(BoxError.FS_ERROR, safe.error);
|
||||
}
|
||||
|
||||
reload(callback);
|
||||
await reload();
|
||||
}
|
||||
|
||||
function writeAppRedirectNginxConfig(app, fqdn, bundle, callback) {
|
||||
async function writeAppRedirectNginxConfig(app, fqdn, bundle) {
|
||||
assert.strictEqual(typeof app, 'object');
|
||||
assert.strictEqual(typeof fqdn, 'string');
|
||||
assert.strictEqual(typeof bundle, 'object');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
const data = {
|
||||
sourceDir: path.resolve(__dirname, '..'),
|
||||
@@ -577,15 +547,14 @@ function writeAppRedirectNginxConfig(app, fqdn, bundle, callback) {
|
||||
|
||||
if (!safe.fs.writeFileSync(nginxConfigFilename, nginxConf)) {
|
||||
debug('Error creating nginx redirect config for "%s" : %s', app.fqdn, safe.error.message);
|
||||
return callback(new BoxError(BoxError.FS_ERROR, safe.error));
|
||||
throw new BoxError(BoxError.FS_ERROR, safe.error);
|
||||
}
|
||||
|
||||
reload(callback);
|
||||
await reload();
|
||||
}
|
||||
|
||||
function writeAppConfig(app, callback) {
|
||||
async function writeAppConfig(app) {
|
||||
assert.strictEqual(typeof app, 'object');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
let appDomains = [];
|
||||
appDomains.push({ domain: app.domain, fqdn: app.fqdn, type: 'primary' });
|
||||
@@ -598,25 +567,22 @@ function writeAppConfig(app, callback) {
|
||||
appDomains.push({ domain: aliasDomain.domain, fqdn: aliasDomain.fqdn, type: 'alias' });
|
||||
});
|
||||
|
||||
async.eachSeries(appDomains, function (appDomain, iteratorDone) {
|
||||
getCertificatePath(appDomain.fqdn, appDomain.domain, function (error, bundle) {
|
||||
if (error) return iteratorDone(error);
|
||||
for (const appDomain of appDomains) {
|
||||
const bundle = await getCertificatePath(appDomain.fqdn, appDomain.domain);
|
||||
|
||||
if (appDomain.type === 'primary') {
|
||||
writeAppNginxConfig(app, appDomain.fqdn, bundle, iteratorDone);
|
||||
} else if (appDomain.type === 'alternate') {
|
||||
writeAppRedirectNginxConfig(app, appDomain.fqdn, bundle, iteratorDone);
|
||||
} else if (appDomain.type === 'alias') {
|
||||
writeAppNginxConfig(app, appDomain.fqdn, bundle, iteratorDone);
|
||||
}
|
||||
});
|
||||
}, callback);
|
||||
if (appDomain.type === 'primary') {
|
||||
await writeAppNginxConfig(app, appDomain.fqdn, bundle);
|
||||
} else if (appDomain.type === 'alternate') {
|
||||
await writeAppRedirectNginxConfig(app, appDomain.fqdn, bundle);
|
||||
} else if (appDomain.type === 'alias') {
|
||||
await writeAppNginxConfig(app, appDomain.fqdn, bundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function configureApp(app, auditSource, callback) {
|
||||
async function configureApp(app, auditSource) {
|
||||
assert.strictEqual(typeof app, 'object');
|
||||
assert.strictEqual(typeof auditSource, 'object');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
let appDomains = [];
|
||||
appDomains.push({ domain: app.domain, fqdn: app.fqdn, type: 'primary' });
|
||||
@@ -629,31 +595,32 @@ function configureApp(app, auditSource, callback) {
|
||||
appDomains.push({ domain: aliasDomain.domain, fqdn: aliasDomain.fqdn, type: 'alias' });
|
||||
});
|
||||
|
||||
async.eachSeries(appDomains, function (appDomain, iteratorDone) {
|
||||
ensureCertificate(appDomain.fqdn, appDomain.domain, auditSource, function (error, bundle) {
|
||||
if (error) return iteratorDone(error);
|
||||
for (const appDomain of appDomains) {
|
||||
const { bundle } = await ensureCertificate(appDomain.fqdn, appDomain.domain, auditSource);
|
||||
|
||||
if (appDomain.type === 'primary') {
|
||||
writeAppNginxConfig(app, appDomain.fqdn, bundle, iteratorDone);
|
||||
} else if (appDomain.type === 'alternate') {
|
||||
writeAppRedirectNginxConfig(app, appDomain.fqdn, bundle, iteratorDone);
|
||||
} else if (appDomain.type === 'alias') {
|
||||
writeAppNginxConfig(app, appDomain.fqdn, bundle, iteratorDone);
|
||||
}
|
||||
});
|
||||
}, callback);
|
||||
if (appDomain.type === 'primary') {
|
||||
await writeAppNginxConfig(app, appDomain.fqdn, bundle);
|
||||
} else if (appDomain.type === 'alternate') {
|
||||
await writeAppRedirectNginxConfig(app, appDomain.fqdn, bundle);
|
||||
} else if (appDomain.type === 'alias') {
|
||||
await writeAppNginxConfig(app, appDomain.fqdn, bundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function unconfigureApp(app, callback) {
|
||||
async function unconfigureApp(app) {
|
||||
assert.strictEqual(typeof app, 'object');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
// we use globbing to find all nginx configs for an app
|
||||
rimraf(path.join(paths.NGINX_APPCONFIG_DIR, `${app.id}*.conf`), function (error) {
|
||||
if (error) debug('Error removing nginx configurations of "%s":', app.fqdn, error);
|
||||
const configFilenames = safe.fs.readdirSync(paths.NGINX_APPCONFIG_DIR);
|
||||
if (!configFilenames) throw new BoxError(BoxError.FS_ERROR, `Error loading nginx config files: ${safe.error.message}`);
|
||||
|
||||
reload(callback);
|
||||
});
|
||||
for (const filename of configFilenames) {
|
||||
if (!filename.startsWith(app.id)) continue;
|
||||
|
||||
safe.fs.unlinkSync(path.join(paths.NGINX_APPCONFIG_DIR, filename));
|
||||
}
|
||||
|
||||
await reload();
|
||||
}
|
||||
|
||||
function renewCerts(options, auditSource, progressCallback, callback) {
|
||||
@@ -695,36 +662,34 @@ function renewCerts(options, auditSource, progressCallback, callback) {
|
||||
|
||||
let progress = 1, renewed = [];
|
||||
|
||||
async.eachSeries(appDomains, function (appDomain, iteratorCallback) {
|
||||
async.eachSeries(appDomains, async function (appDomain) {
|
||||
progressCallback({ percent: progress, message: `Ensuring certs of ${appDomain.fqdn}` });
|
||||
progress += Math.round(100/appDomains.length);
|
||||
|
||||
ensureCertificate(appDomain.fqdn, appDomain.domain, auditSource, function (error, bundle, state) {
|
||||
if (error) return iteratorCallback(error); // this can happen if cloudron is not setup yet
|
||||
const { bundle, renewed } = ensureCertificate(appDomain.fqdn, appDomain.domain, auditSource);
|
||||
|
||||
if (state.renewed) renewed.push(appDomain.fqdn);
|
||||
if (renewed) renewed.push(appDomain.fqdn);
|
||||
|
||||
if (appDomain.type === 'mail') return iteratorCallback(); // mail has no nginx config to check current cert
|
||||
if (appDomain.type === 'mail') return; // mail has no nginx config to check current cert
|
||||
|
||||
// hack to check if the app's cert changed or not. this doesn't handle prod/staging le change since they use same file name
|
||||
let currentNginxConfig = safe.fs.readFileSync(appDomain.nginxConfigFilename, 'utf8') || '';
|
||||
if (currentNginxConfig.includes(bundle.certFilePath)) return iteratorCallback();
|
||||
// hack to check if the app's cert changed or not. this doesn't handle prod/staging le change since they use same file name
|
||||
let currentNginxConfig = safe.fs.readFileSync(appDomain.nginxConfigFilename, 'utf8') || '';
|
||||
if (currentNginxConfig.includes(bundle.certFilePath)) return;
|
||||
|
||||
debug(`renewCerts: creating new nginx config since ${appDomain.nginxConfigFilename} does not have ${bundle.certFilePath}`);
|
||||
debug(`renewCerts: creating new nginx config since ${appDomain.nginxConfigFilename} does not have ${bundle.certFilePath}`);
|
||||
|
||||
// reconfigure since the cert changed
|
||||
if (appDomain.type === 'webadmin' || appDomain.type === 'webadmin+mail') {
|
||||
return writeDashboardNginxConfig(bundle, `${settings.dashboardFqdn()}.conf`, settings.dashboardFqdn(), iteratorCallback);
|
||||
} else if (appDomain.type === 'primary') {
|
||||
return writeAppNginxConfig(appDomain.app, appDomain.fqdn, bundle, iteratorCallback);
|
||||
} else if (appDomain.type === 'alternate') {
|
||||
return writeAppRedirectNginxConfig(appDomain.app, appDomain.fqdn, bundle, iteratorCallback);
|
||||
} else if (appDomain.type === 'alias') {
|
||||
return writeAppNginxConfig(appDomain.app, appDomain.fqdn, bundle, iteratorCallback);
|
||||
}
|
||||
|
||||
iteratorCallback(new BoxError(BoxError.INTERNAL_ERROR, `Unknown domain type for ${appDomain.fqdn}. This should never happen`));
|
||||
});
|
||||
// reconfigure since the cert changed
|
||||
if (appDomain.type === 'webadmin' || appDomain.type === 'webadmin+mail') {
|
||||
await writeDashboardNginxConfig(bundle, `${settings.dashboardFqdn()}.conf`, settings.dashboardFqdn());
|
||||
} else if (appDomain.type === 'primary') {
|
||||
await writeAppNginxConfig(appDomain.app, appDomain.fqdn, bundle);
|
||||
} else if (appDomain.type === 'alternate') {
|
||||
await writeAppRedirectNginxConfig(appDomain.app, appDomain.fqdn, bundle);
|
||||
} else if (appDomain.type === 'alias') {
|
||||
await writeAppNginxConfig(appDomain.app, appDomain.fqdn, bundle);
|
||||
} else {
|
||||
throw new BoxError(BoxError.INTERNAL_ERROR, `Unknown domain type for ${appDomain.fqdn}. This should never happen`);
|
||||
}
|
||||
}, function (error) {
|
||||
if (error) return callback(error);
|
||||
|
||||
@@ -793,9 +758,8 @@ function removeAppConfigs() {
|
||||
}
|
||||
}
|
||||
|
||||
function writeDefaultConfig(options, callback) {
|
||||
async function writeDefaultConfig(options) {
|
||||
assert.strictEqual(typeof options, 'object');
|
||||
assert.strictEqual(typeof callback, 'function');
|
||||
|
||||
const certFilePath = path.join(paths.NGINX_CERT_DIR, 'default.cert');
|
||||
const keyFilePath = path.join(paths.NGINX_CERT_DIR, 'default.key');
|
||||
@@ -807,7 +771,7 @@ function writeDefaultConfig(options, callback) {
|
||||
// the days field is chosen to be less than 825 days per apple requirement (https://support.apple.com/en-us/HT210176)
|
||||
if (!safe.child_process.execSync(`openssl req -x509 -newkey rsa:2048 -keyout ${keyFilePath} -out ${certFilePath} -days 800 -subj /CN=${cn} -nodes`)) {
|
||||
debug(`writeDefaultConfig: could not generate certificate: ${safe.error.message}`);
|
||||
return callback(new BoxError(BoxError.OPENSSL_ERROR, safe.error));
|
||||
throw new BoxError(BoxError.OPENSSL_ERROR, safe.error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -827,7 +791,7 @@ function writeDefaultConfig(options, callback) {
|
||||
|
||||
debug(`writeDefaultConfig: writing configs for endpoint "${data.endpoint}"`);
|
||||
|
||||
if (!safe.fs.writeFileSync(nginxConfigFilename, nginxConf)) return callback(new BoxError(BoxError.FS_ERROR, safe.error));
|
||||
if (!safe.fs.writeFileSync(nginxConfigFilename, nginxConf)) throw new BoxError(BoxError.FS_ERROR, safe.error);
|
||||
|
||||
reload(callback);
|
||||
await reload();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user