diff --git a/src/reverseproxy.js b/src/reverseproxy.js index c7ecc7084..4281ed319 100644 --- a/src/reverseproxy.js +++ b/src/reverseproxy.js @@ -26,9 +26,6 @@ exports = module.exports = { removeAppConfigs, restoreFallbackCertificates, - - // exported for testing - _getAcmeApiOptions: getAcmeApiOptions }; const acme2 = require('./acme2.js'), @@ -52,7 +49,6 @@ const acme2 = require('./acme2.js'), settings = require('./settings.js'), shell = require('./shell.js'), sysinfo = require('./sysinfo.js'), - users = require('./users.js'), util = require('util'); const NGINX_APPCONFIG_EJS = fs.readFileSync(__dirname + '/nginxconfig.ejs', { encoding: 'utf8' }); @@ -65,24 +61,6 @@ function nginxLocation(s) { return `~ ^(?!(${re.slice(1)}))`; // negative regex assertion - https://stackoverflow.com/questions/16302897/nginx-location-not-equal-to-regex } -async function getAcmeApiOptions(domainObject) { - assert.strictEqual(typeof domainObject, 'object'); - - const apiOptions = { prod: false, performHttpAuthorization: false, wildcard: false, email: '' }; - apiOptions.prod = domainObject.tlsConfig.provider.match(/.*-prod/) !== null; // matches 'le-prod' or 'letsencrypt-prod' - apiOptions.performHttpAuthorization = domainObject.provider.match(/noop|manual|wildcard/) !== null; - apiOptions.wildcard = !!domainObject.tlsConfig.wildcard; - - // registering user with an email requires A or MX record (https://github.com/letsencrypt/boulder/issues/1197) - // we cannot use admin@fqdn because the user might not have set it up. - // we simply update the account with the latest email we have each time when getting letsencrypt certs - // https://github.com/ietf-wg-acme/acme/issues/30 - const [error, owner] = await safe(users.getOwner()); - apiOptions.email = (error || !owner) ? 'webmaster@cloudron.io' : owner.email; // can error if not activated yet - - return apiOptions; -} - function getExpiryDate(certFilePath) { assert.strictEqual(typeof certFilePath, 'string'); @@ -112,10 +90,9 @@ async function isOcspEnabled(certFilePath) { } // checks if the certificate matches the options provided by user (like wildcard, le-staging etc) -function providerMatchesSync(domainObject, certFilePath, apiOptions) { +function providerMatchesSync(domainObject, certFilePath) { assert.strictEqual(typeof domainObject, 'object'); assert.strictEqual(typeof certFilePath, 'string'); - assert.strictEqual(typeof apiOptions, 'object'); if (!fs.existsSync(certFilePath)) return false; // not found @@ -128,14 +105,17 @@ function providerMatchesSync(domainObject, certFilePath, apiOptions) { const isWildcardCert = domain.includes('*'); const isLetsEncryptProd = issuer.includes('Let\'s Encrypt') && !issuer.includes('STAGING'); - const issuerMismatch = (apiOptions.prod && !isLetsEncryptProd) || (!apiOptions.prod && isLetsEncryptProd); + const prod = domainObject.tlsConfig.provider.match(/.*-prod/) !== null; // matches 'le-prod' or 'letsencrypt-prod' + const wildcard = !!domainObject.tlsConfig.wildcard; + + const issuerMismatch = (prod && !isLetsEncryptProd) || (!prod && isLetsEncryptProd); // bare domain is not part of wildcard SAN - const wildcardMismatch = (domain !== domainObject.domain) && (apiOptions.wildcard && !isWildcardCert) || (!apiOptions.wildcard && isWildcardCert); + const wildcardMismatch = (domain !== domainObject.domain) && (wildcard && !isWildcardCert) || (!wildcard && isWildcardCert); const mismatch = issuerMismatch || wildcardMismatch; debug(`providerMatchesSync: ${certFilePath} subject=${subject} domain=${domain} issuer=${issuer} ` - + `wildcard=${isWildcardCert}/${apiOptions.wildcard} prod=${isLetsEncryptProd}/${apiOptions.prod} ` + + `wildcard=${isWildcardCert}/${wildcard} prod=${isLetsEncryptProd}/${prod} ` + `issuerMismatch=${issuerMismatch} wildcardMismatch=${wildcardMismatch} match=${!mismatch}`); return !mismatch; @@ -352,12 +332,11 @@ async function needsRenewal(fqdn, domainObject) { assert.strictEqual(typeof fqdn, 'string'); assert.strictEqual(typeof domainObject, 'object'); - const apiOptions = await getAcmeApiOptions(domainObject); const { certFilePath } = getAcmeCertificatePathSync(fqdn, domainObject); const notAfter = getExpiryDate(certFilePath); const isExpiring = (notAfter - new Date()) <= (30 * 24 * 60 * 60 * 1000); // expiring in a month - if (!isExpiring && providerMatchesSync(domainObject, certFilePath, apiOptions)) return false; + if (!isExpiring && providerMatchesSync(domainObject, certFilePath)) return false; debug(`needsRenewal: ${certFilePath} cert requires renewal`); return true; } diff --git a/src/test/reverseproxy-test.js b/src/test/reverseproxy-test.js index 28acfcbd6..1b068d206 100644 --- a/src/test/reverseproxy-test.js +++ b/src/test/reverseproxy-test.js @@ -139,34 +139,6 @@ describe('Reverse Proxy', function () { }); }); - describe('getApi - letsencrypt-prod', function () { - before(async function () { - domainCopy.tlsConfig = { provider: 'letsencrypt-prod' }; - - await domains.setConfig(domainCopy.domain, domainCopy, auditSource); - }); - - it('returns prod acme in prod cloudron', async function () { - const apiOptions = await reverseProxy._getAcmeApiOptions(domainCopy); - expect(apiOptions.prod).to.be(true); - expect(apiOptions.email).to.be(admin.email); - }); - }); - - describe('getApi - letsencrypt-staging', function () { - before(async function () { - domainCopy.tlsConfig = { provider: 'letsencrypt-staging' }; - - await domains.setConfig(domainCopy.domain, domainCopy, auditSource); - }); - - it('returns staging acme in prod cloudron', async function () { - const apiOptions = await reverseProxy._getAcmeApiOptions(domainCopy); - expect(apiOptions.prod).to.be(false); - expect(apiOptions.email).to.be(admin.email); - }); - }); - describe('configureApp', function () { before(async function () { domainCopy.tlsConfig = { provider: 'fallback' };