diff --git a/packages/core/acme-client/.eslintrc.yml b/packages/core/acme-client/.eslintrc.yml index ec901b2c..55618a5f 100644 --- a/packages/core/acme-client/.eslintrc.yml +++ b/packages/core/acme-client/.eslintrc.yml @@ -9,15 +9,8 @@ env: rules: indent: [2, 4, { SwitchCase: 1, VariableDeclarator: 1 }] brace-style: [2, 'stroustrup', { allowSingleLine: true }] - space-before-function-paren: [2, { anonymous: 'never', named: 'never' }] func-names: 0 - prefer-destructuring: 0 - object-curly-newline: 0 class-methods-use-this: 0 - wrap-iife: [2, 'inside'] no-param-reassign: 0 - comma-dangle: [2, 'never'] max-len: [1, 200, 2, { ignoreUrls: true, ignoreComments: false }] - no-multiple-empty-lines: [2, { max: 2, maxBOF: 0, maxEOF: 0 }] - prefer-object-spread: 0 import/no-useless-path-segments: 0 diff --git a/packages/core/acme-client/.github/workflows/tests.yml b/packages/core/acme-client/.github/workflows/tests.yml index f22e35a9..5d031c5e 100644 --- a/packages/core/acme-client/.github/workflows/tests.yml +++ b/packages/core/acme-client/.github/workflows/tests.yml @@ -1,4 +1,3 @@ ---- name: test on: [push, pull_request] @@ -12,7 +11,6 @@ jobs: node: [16, 18, 20, 22] eab: [0, 1] - # # Environment # @@ -41,7 +39,6 @@ jobs: ACME_HTTP_PORT: 5002 ACME_HTTPS_PORT: 5003 - # # Pipeline # diff --git a/packages/core/acme-client/CHANGELOG.md b/packages/core/acme-client/CHANGELOG.md index ed241954..bf9ea9a7 100644 --- a/packages/core/acme-client/CHANGELOG.md +++ b/packages/core/acme-client/CHANGELOG.md @@ -55,7 +55,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline # Changelog -## v5.3.1 +## v5.3.1 (2024-05-22) * `fixed` Allow `client.auto()` being called with an empty CSR common name * `fixed` Bug when calling `updateAccountKey()` with external account binding @@ -92,7 +92,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline * `fixed` Upgrade `axios@0.26.1` * `fixed` Upgrade `node-forge@1.3.0` - [CVE-2022-24771](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-24771), [CVE-2022-24772](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-24772), [CVE-2022-24773](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-24773) -## 4.2.4 (2022-03-19) +## v4.2.4 (2022-03-19) * `fixed` Use SHA-256 when signing CSRs diff --git a/packages/core/acme-client/README.md b/packages/core/acme-client/README.md index 3dff3cfa..f69dfd18 100644 --- a/packages/core/acme-client/README.md +++ b/packages/core/acme-client/README.md @@ -9,13 +9,13 @@ This module is written to handle communication with a Boulder/Let's Encrypt-styl ## Compatibility -| acme-client | Node.js | | -| ------------- | --------- | ----------------------------------------- | -| v5.x | >= v16 | [Upgrade guide](docs/upgrade-v5.md) | -| v4.x | >= v10 | [Changelog](CHANGELOG.md#v400-2020-05-29) | -| v3.x | >= v8 | [Changelog](CHANGELOG.md#v300-2019-07-13) | -| v2.x | >= v4 | [Changelog](CHANGELOG.md#v200-2018-04-02) | -| v1.x | >= v4 | [Changelog](CHANGELOG.md#v100-2017-10-20) | +| acme-client | Node.js | | +| ----------- | ------- | ----------------------------------------- | +| v5.x | >= v16 | [Upgrade guide](docs/upgrade-v5.md) | +| v4.x | >= v10 | [Changelog](CHANGELOG.md#v400-2020-05-29) | +| v3.x | >= v8 | [Changelog](CHANGELOG.md#v300-2019-07-13) | +| v2.x | >= v4 | [Changelog](CHANGELOG.md#v200-2018-04-02) | +| v1.x | >= v4 | [Changelog](CHANGELOG.md#v100-2017-10-20) | ## Table of contents @@ -49,7 +49,7 @@ const accountPrivateKey = ''; const client = new acme.Client({ directoryUrl: acme.directory.letsencrypt.staging, - accountKey: accountPrivateKey + accountKey: accountPrivateKey, }); ``` @@ -75,8 +75,8 @@ const client = new acme.Client({ accountKey: accountPrivateKey, externalAccountBinding: { kid: 'YOUR-EAB-KID', - hmacKey: 'YOUR-EAB-HMAC-KEY' - } + hmacKey: 'YOUR-EAB-HMAC-KEY', + }, }); ``` @@ -90,7 +90,7 @@ In some cases, for example with some EAB providers, this account creation step m const client = new acme.Client({ directoryUrl: acme.directory.letsencrypt.staging, accountKey: accountPrivateKey, - accountUrl: 'https://acme-v02.api.letsencrypt.org/acme/acct/12345678' + accountUrl: 'https://acme-v02.api.letsencrypt.org/acme/acct/12345678', }); ``` @@ -113,8 +113,7 @@ const privateRsaKey = await acme.crypto.createPrivateRsaKey(); const privateEcdsaKey = await acme.crypto.createPrivateEcdsaKey(); const [certificateKey, certificateCsr] = await acme.crypto.createCsr({ - commonName: '*.example.com', - altNames: ['example.com'] + altNames: ['example.com', '*.example.com'], }); ``` @@ -139,7 +138,7 @@ const autoOpts = { email: 'test@example.com', termsOfServiceAgreed: true, challengeCreateFn: async (authz, challenge, keyAuthorization) => {}, - challengeRemoveFn: async (authz, challenge, keyAuthorization) => {} + challengeRemoveFn: async (authz, challenge, keyAuthorization) => {}, }; const certificate = await client.auto(autoOpts); @@ -156,7 +155,7 @@ To modify challenge priority, provide a list of challenge types in `challengePri ```js await client.auto({ ..., - challengePriority: ['http-01', 'dns-01'] + challengePriority: ['http-01', 'dns-01'], }); ``` @@ -171,7 +170,7 @@ To completely disable `acme-client`s internal challenge verification, enable `sk ```js await client.auto({ ..., - skipChallengeVerification: true + skipChallengeVerification: true, }); ``` @@ -185,14 +184,14 @@ For more fine-grained control you can interact with the ACME API using the metho ```js const account = await client.createAccount({ termsOfServiceAgreed: true, - contact: ['mailto:test@example.com'] + contact: ['mailto:test@example.com'], }); const order = await client.createOrder({ identifiers: [ { type: 'dns', value: 'example.com' }, - { type: 'dns', value: '*.example.com' } - ] + { type: 'dns', value: '*.example.com' }, + ], }); ``` @@ -207,7 +206,7 @@ const acme = require('acme-client'); acme.axios.defaults.proxy = { host: '127.0.0.1', - port: 9000 + port: 9000, }; ``` diff --git a/packages/core/acme-client/docs/client.md b/packages/core/acme-client/docs/client.md index f5f29d22..b1938799 100644 --- a/packages/core/acme-client/docs/client.md +++ b/packages/core/acme-client/docs/client.md @@ -63,7 +63,7 @@ Create ACME client instance ```js const client = new acme.Client({ directoryUrl: acme.directory.letsencrypt.staging, - accountKey: 'Private key goes here' + accountKey: 'Private key goes here', }); ``` **Example** @@ -75,7 +75,7 @@ const client = new acme.Client({ accountUrl: 'Optional account URL goes here', backoffAttempts: 10, backoffMin: 5000, - backoffMax: 30000 + backoffMax: 30000, }); ``` **Example** @@ -86,8 +86,8 @@ const client = new acme.Client({ accountKey: 'Private key goes here', externalAccountBinding: { kid: 'YOUR-EAB-KID', - hmacKey: 'YOUR-EAB-HMAC-KEY' - } + hmacKey: 'YOUR-EAB-HMAC-KEY', + }, }); ``` @@ -145,7 +145,7 @@ https://datatracker.ietf.org/doc/html/rfc8555#section-7.3 Create a new account ```js const account = await client.createAccount({ - termsOfServiceAgreed: true + termsOfServiceAgreed: true, }); ``` **Example** @@ -153,7 +153,7 @@ Create a new account with contact info ```js const account = await client.createAccount({ termsOfServiceAgreed: true, - contact: ['mailto:test@example.com'] + contact: ['mailto:test@example.com'], }); ``` @@ -174,7 +174,7 @@ https://datatracker.ietf.org/doc/html/rfc8555#section-7.3.2 Update existing account ```js const account = await client.updateAccount({ - contact: ['mailto:foo@example.com'] + contact: ['mailto:foo@example.com'], }); ``` @@ -218,8 +218,8 @@ Create a new order const order = await client.createOrder({ identifiers: [ { type: 'dns', value: 'example.com' }, - { type: 'dns', value: 'test.example.com' } - ] + { type: 'dns', value: 'test.example.com' }, + ], }); ``` @@ -452,7 +452,7 @@ Revoke certificate with reason ```js const certificate = { ... }; // Previously created certificate const result = await client.revokeCertificate(certificate, { - reason: 4 + reason: 4, }); ``` @@ -479,7 +479,7 @@ Auto mode Order a certificate using auto mode ```js const [certificateKey, certificateRequest] = await acme.crypto.createCsr({ - commonName: 'test.example.com' + altNames: ['test.example.com'], }); const certificate = await client.auto({ @@ -491,14 +491,14 @@ const certificate = await client.auto({ }, challengeRemoveFn: async (authz, challenge, keyAuthorization) => { // Clean up challenge here - } + }, }); ``` **Example** Order a certificate using auto mode with preferred chain ```js const [certificateKey, certificateRequest] = await acme.crypto.createCsr({ - commonName: 'test.example.com' + altNames: ['test.example.com'], }); const certificate = await client.auto({ @@ -507,7 +507,7 @@ const certificate = await client.auto({ termsOfServiceAgreed: true, preferredChain: 'DST Root CA X3', challengeCreateFn: async () => {}, - challengeRemoveFn: async () => {} + challengeRemoveFn: async () => {}, }); ``` diff --git a/packages/core/acme-client/docs/crypto.md b/packages/core/acme-client/docs/crypto.md index 84660f68..85754ea5 100644 --- a/packages/core/acme-client/docs/crypto.md +++ b/packages/core/acme-client/docs/crypto.md @@ -239,29 +239,30 @@ Create a Certificate Signing Request Create a Certificate Signing Request ```js const [certificateKey, certificateRequest] = await acme.crypto.createCsr({ - commonName: 'test.example.com' + altNames: ['test.example.com'], }); ``` **Example** Certificate Signing Request with both common and alternative names +> *Warning*: Certificate subject common name has been [deprecated](https://letsencrypt.org/docs/glossary/#def-CN) and its use is [discouraged](https://cabforum.org/uploads/BRv1.2.3.pdf). ```js const [certificateKey, certificateRequest] = await acme.crypto.createCsr({ keySize: 4096, commonName: 'test.example.com', - altNames: ['foo.example.com', 'bar.example.com'] + altNames: ['foo.example.com', 'bar.example.com'], }); ``` **Example** Certificate Signing Request with additional information ```js const [certificateKey, certificateRequest] = await acme.crypto.createCsr({ - commonName: 'test.example.com', + altNames: ['test.example.com'], country: 'US', state: 'California', locality: 'Los Angeles', organization: 'The Company Inc.', organizationUnit: 'IT Department', - emailAddress: 'contact@example.com' + emailAddress: 'contact@example.com', }); ``` **Example** @@ -270,8 +271,9 @@ Certificate Signing Request with ECDSA private key const certificateKey = await acme.crypto.createPrivateEcdsaKey(); const [, certificateRequest] = await acme.crypto.createCsr({ - commonName: 'test.example.com' + altNames: ['test.example.com'], }, certificateKey); +``` ## createAlpnCertificate(authz, keyAuthorization, [keyPem]) ⇒ Promise.<Array.<buffer>> @@ -298,6 +300,7 @@ Create a ALPN certificate with ECDSA private key ```js const alpnKey = await acme.crypto.createPrivateEcdsaKey(); const [, alpnCertificate] = await acme.crypto.createAlpnCertificate(authz, keyAuthorization, alpnKey); +``` ## isAlpnCertificateAuthorizationValid(certPem, keyAuthorization) ⇒ boolean diff --git a/packages/core/acme-client/docs/forge.md b/packages/core/acme-client/docs/forge.md index 09a44de1..65dcab8f 100644 --- a/packages/core/acme-client/docs/forge.md +++ b/packages/core/acme-client/docs/forge.md @@ -222,29 +222,30 @@ Create a Certificate Signing Request Create a Certificate Signing Request ```js const [certificateKey, certificateRequest] = await acme.forge.createCsr({ - commonName: 'test.example.com' + altNames: ['test.example.com'], }); ``` **Example** Certificate Signing Request with both common and alternative names +> *Warning*: Certificate subject common name has been [deprecated](https://letsencrypt.org/docs/glossary/#def-CN) and its use is [discouraged](https://cabforum.org/uploads/BRv1.2.3.pdf). ```js const [certificateKey, certificateRequest] = await acme.forge.createCsr({ keySize: 4096, commonName: 'test.example.com', - altNames: ['foo.example.com', 'bar.example.com'] + altNames: ['foo.example.com', 'bar.example.com'], }); ``` **Example** Certificate Signing Request with additional information ```js const [certificateKey, certificateRequest] = await acme.forge.createCsr({ - commonName: 'test.example.com', + altNames: ['test.example.com'], country: 'US', state: 'California', locality: 'Los Angeles', organization: 'The Company Inc.', organizationUnit: 'IT Department', - emailAddress: 'contact@example.com' + emailAddress: 'contact@example.com', }); ``` **Example** @@ -253,5 +254,5 @@ Certificate Signing Request with predefined private key const certificateKey = await acme.forge.createPrivateKey(); const [, certificateRequest] = await acme.forge.createCsr({ - commonName: 'test.example.com' + altNames: ['test.example.com'], }, certificateKey); diff --git a/packages/core/acme-client/examples/api.js b/packages/core/acme-client/examples/api.js index d2b7162a..a5e0e4a8 100644 --- a/packages/core/acme-client/examples/api.js +++ b/packages/core/acme-client/examples/api.js @@ -8,7 +8,6 @@ function log(m) { process.stdout.write(`${m}\n`); } - /** * Function used to satisfy an ACME challenge * @@ -25,7 +24,6 @@ async function challengeCreateFn(authz, challenge, keyAuthorization) { log(keyAuthorization); } - /** * Function used to remove an ACME challenge response * @@ -41,30 +39,29 @@ async function challengeRemoveFn(authz, challenge, keyAuthorization) { log(keyAuthorization); } - /** * Main */ -module.exports = async function() { +module.exports = async () => { /* Init client */ const client = new acme.Client({ directoryUrl: acme.directory.letsencrypt.staging, - accountKey: await acme.crypto.createPrivateKey() + accountKey: await acme.crypto.createPrivateKey(), }); /* Register account */ await client.createAccount({ termsOfServiceAgreed: true, - contact: ['mailto:test@example.com'] + contact: ['mailto:test@example.com'], }); /* Place new order */ const order = await client.createOrder({ identifiers: [ { type: 'dns', value: 'example.com' }, - { type: 'dns', value: '*.example.com' } - ] + { type: 'dns', value: '*.example.com' }, + ], }); /** @@ -138,8 +135,7 @@ module.exports = async function() { /* Finalize order */ const [key, csr] = await acme.crypto.createCsr({ - commonName: '*.example.com', - altNames: ['example.com'] + altNames: ['example.com', '*.example.com'], }); const finalized = await client.finalizeOrder(order, csr); diff --git a/packages/core/acme-client/examples/auto.js b/packages/core/acme-client/examples/auto.js index cd4295d7..bcfa8d46 100644 --- a/packages/core/acme-client/examples/auto.js +++ b/packages/core/acme-client/examples/auto.js @@ -9,7 +9,6 @@ function log(m) { process.stdout.write(`${m}\n`); } - /** * Function used to satisfy an ACME challenge * @@ -47,7 +46,6 @@ async function challengeCreateFn(authz, challenge, keyAuthorization) { } } - /** * Function used to remove an ACME challenge response * @@ -80,25 +78,24 @@ async function challengeRemoveFn(authz, challenge, keyAuthorization) { /* Replace this */ log(`Would remove TXT record "${dnsRecord}" with value "${recordValue}"`); - // await dnsProvider.removeRecord(dnsRecord, 'TXT'); + // await dnsProvider.removeRecord(dnsRecord, 'TXT', recordValue); } } - /** * Main */ -module.exports = async function() { +module.exports = async () => { /* Init client */ const client = new acme.Client({ directoryUrl: acme.directory.letsencrypt.staging, - accountKey: await acme.crypto.createPrivateKey() + accountKey: await acme.crypto.createPrivateKey(), }); /* Create CSR */ const [key, csr] = await acme.crypto.createCsr({ - commonName: 'example.com' + altNames: ['example.com'], }); /* Certificate */ @@ -107,7 +104,7 @@ module.exports = async function() { email: 'test@example.com', termsOfServiceAgreed: true, challengeCreateFn, - challengeRemoveFn + challengeRemoveFn, }); /* Done */ diff --git a/packages/core/acme-client/examples/dns-01/dns-01.js b/packages/core/acme-client/examples/dns-01/dns-01.js index 68bed46e..dadca603 100644 --- a/packages/core/acme-client/examples/dns-01/dns-01.js +++ b/packages/core/acme-client/examples/dns-01/dns-01.js @@ -19,7 +19,6 @@ function log(m) { process.stdout.write(`${(new Date()).toISOString()} ${m}\n`); } - /** * Main */ @@ -33,18 +32,16 @@ function log(m) { log('Initializing ACME client'); const client = new acme.Client({ directoryUrl: acme.directory.letsencrypt.staging, - accountKey: await acme.crypto.createPrivateKey() + accountKey: await acme.crypto.createPrivateKey(), }); - /** * Order wildcard certificate */ log(`Creating CSR for ${WILDCARD_DOMAIN}`); const [key, csr] = await acme.crypto.createCsr({ - commonName: WILDCARD_DOMAIN, - altNames: [`*.${WILDCARD_DOMAIN}`] + altNames: [WILDCARD_DOMAIN, `*.${WILDCARD_DOMAIN}`], }); log(`Ordering certificate for ${WILDCARD_DOMAIN}`); @@ -60,12 +57,11 @@ function log(m) { challengeRemoveFn: (authz, challenge, keyAuthorization) => { /* TODO: Implement this */ log(`[TODO] Remove TXT record key=_acme-challenge.${authz.identifier.value} value=${keyAuthorization}`); - } + }, }); log(`Certificate for ${WILDCARD_DOMAIN} created successfully`); - /** * HTTPS server */ @@ -78,7 +74,7 @@ function log(m) { const httpsServer = https.createServer({ key, - cert + cert, }, requestListener); httpsServer.listen(HTTPS_SERVER_PORT, () => { diff --git a/packages/core/acme-client/examples/http-01/http-01.js b/packages/core/acme-client/examples/http-01/http-01.js index 75153385..bda67eba 100644 --- a/packages/core/acme-client/examples/http-01/http-01.js +++ b/packages/core/acme-client/examples/http-01/http-01.js @@ -23,7 +23,6 @@ function log(m) { process.stdout.write(`${(new Date()).toISOString()} ${m}\n`); } - /** * On-demand certificate generation using http-01 */ @@ -52,7 +51,7 @@ async function getCertOnDemand(client, servername, attempt = 0) { /* Create CSR */ log(`Creating CSR for ${servername}`); const [key, csr] = await acme.crypto.createCsr({ - commonName: servername + altNames: [servername], }); /* Order certificate */ @@ -67,7 +66,7 @@ async function getCertOnDemand(client, servername, attempt = 0) { }, challengeRemoveFn: (authz, challenge) => { delete challengeResponses[challenge.token]; - } + }, }); /* Done, store certificate */ @@ -77,7 +76,6 @@ async function getCertOnDemand(client, servername, attempt = 0) { return certificateStore[servername]; } - /** * Main */ @@ -91,10 +89,9 @@ async function getCertOnDemand(client, servername, attempt = 0) { log('Initializing ACME client'); const client = new acme.Client({ directoryUrl: acme.directory.letsencrypt.staging, - accountKey: await acme.crypto.createPrivateKey() + accountKey: await acme.crypto.createPrivateKey(), }); - /** * HTTP server */ @@ -129,7 +126,6 @@ async function getCertOnDemand(client, servername, attempt = 0) { log(`HTTP server listening on port ${HTTP_SERVER_PORT}`); }); - /** * HTTPS server */ @@ -158,7 +154,7 @@ async function getCertOnDemand(client, servername, attempt = 0) { log(`[ERROR] ${e.message}`); cb(e.message); } - } + }, }, requestListener); httpsServer.listen(HTTPS_SERVER_PORT, () => { diff --git a/packages/core/acme-client/examples/tls-alpn-01/tls-alpn-01.js b/packages/core/acme-client/examples/tls-alpn-01/tls-alpn-01.js index e04d73c1..7e20a280 100644 --- a/packages/core/acme-client/examples/tls-alpn-01/tls-alpn-01.js +++ b/packages/core/acme-client/examples/tls-alpn-01/tls-alpn-01.js @@ -22,7 +22,6 @@ function log(m) { process.stdout.write(`${(new Date()).toISOString()} ${m}\n`); } - /** * On-demand certificate generation using tls-alpn-01 */ @@ -51,7 +50,7 @@ async function getCertOnDemand(client, servername, attempt = 0) { /* Create CSR */ log(`Creating CSR for ${servername}`); const [key, csr] = await acme.crypto.createCsr({ - commonName: servername + altNames: [servername], }); /* Order certificate */ @@ -66,7 +65,7 @@ async function getCertOnDemand(client, servername, attempt = 0) { }, challengeRemoveFn: (authz) => { delete alpnResponses[authz.identifier.value]; - } + }, }); /* Done, store certificate */ @@ -76,7 +75,6 @@ async function getCertOnDemand(client, servername, attempt = 0) { return certificateStore[servername]; } - /** * Main */ @@ -90,10 +88,9 @@ async function getCertOnDemand(client, servername, attempt = 0) { log('Initializing ACME client'); const client = new acme.Client({ directoryUrl: acme.directory.letsencrypt.staging, - accountKey: await acme.crypto.createPrivateKey() + accountKey: await acme.crypto.createPrivateKey(), }); - /** * ALPN responder */ @@ -118,14 +115,14 @@ async function getCertOnDemand(client, servername, attempt = 0) { log(`Found ALPN certificate for ${servername}, serving secure context`); cb(null, tls.createSecureContext({ key: alpnResponses[servername][0], - cert: alpnResponses[servername][1] + cert: alpnResponses[servername][1], })); } catch (e) { log(`[ERROR] ${e.message}`); cb(e.message); } - } + }, }); /* Terminate once TLS handshake has been established */ @@ -137,7 +134,6 @@ async function getCertOnDemand(client, servername, attempt = 0) { log(`ALPN responder listening on port ${ALPN_RESPONDER_PORT}`); }); - /** * HTTPS server */ @@ -166,7 +162,7 @@ async function getCertOnDemand(client, servername, attempt = 0) { log(`[ERROR] ${e.message}`); cb(e.message); } - } + }, }, requestListener); httpsServer.listen(HTTPS_SERVER_PORT, () => { diff --git a/packages/core/acme-client/package.json b/packages/core/acme-client/package.json index 4ff24f08..6f7e3acb 100644 --- a/packages/core/acme-client/package.json +++ b/packages/core/acme-client/package.json @@ -16,24 +16,24 @@ "types" ], "dependencies": { - "@peculiar/x509": "^1.9.7", + "@peculiar/x509": "^1.10.0", "asn1js": "^3.0.5", - "axios": "^1.6.5", + "axios": "^1.7.2", "debug": "^4.1.1", "https-proxy-agent": "^7.0.4", "node-forge": "^1.3.1" }, "devDependencies": { - "@types/node": "^20.11.5", + "@types/node": "^20.12.12", "chai": "^4.4.1", - "chai-as-promised": "^7.1.1", - "eslint": "^8.56.0", + "chai-as-promised": "^7.1.2", + "eslint": "^8.57.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-plugin-import": "^2.29.1", - "jsdoc-to-markdown": "^8.0.0", - "mocha": "^10.2.0", - "nock": "^13.5.0", - "tsd": "^0.30.4", + "jsdoc-to-markdown": "^8.0.1", + "mocha": "^10.4.0", + "nock": "^13.5.4", + "tsd": "^0.31.0", "typescript": "^4.8.4", "uuid": "^8.3.2" }, diff --git a/packages/core/acme-client/src/api.js b/packages/core/acme-client/src/api.js index 31c06f52..2dddf1e2 100644 --- a/packages/core/acme-client/src/api.js +++ b/packages/core/acme-client/src/api.js @@ -4,7 +4,6 @@ const util = require('./util'); - /** * AcmeApi * @@ -18,7 +17,6 @@ class AcmeApi { this.accountUrl = accountUrl; } - /** * Get account URL * @@ -34,7 +32,6 @@ class AcmeApi { return this.accountUrl; } - /** * ACME API request * @@ -59,7 +56,6 @@ class AcmeApi { return resp; } - /** * ACME API request by resource name helper * @@ -78,7 +74,6 @@ class AcmeApi { return this.apiRequest(resourceUrl, payload, validStatusCodes, { includeJwsKid, includeExternalAccountBinding }); } - /** * Get Terms of Service URL if available * @@ -91,7 +86,6 @@ class AcmeApi { return this.http.getMetaField('termsOfService'); } - /** * Create new account * @@ -104,7 +98,7 @@ class AcmeApi { async createAccount(data) { const resp = await this.apiResourceRequest('newAccount', data, [200, 201], { includeJwsKid: false, - includeExternalAccountBinding: (data.onlyReturnExisting !== true) + includeExternalAccountBinding: (data.onlyReturnExisting !== true), }); /* Set account URL */ @@ -115,7 +109,6 @@ class AcmeApi { return resp; } - /** * Update account * @@ -129,7 +122,6 @@ class AcmeApi { return this.apiRequest(this.getAccountUrl(), data, [200, 202]); } - /** * Update account key * @@ -143,7 +135,6 @@ class AcmeApi { return this.apiResourceRequest('keyChange', data, [200]); } - /** * Create new order * @@ -157,7 +148,6 @@ class AcmeApi { return this.apiResourceRequest('newOrder', data, [201]); } - /** * Get order * @@ -171,7 +161,6 @@ class AcmeApi { return this.apiRequest(url, null, [200]); } - /** * Finalize order * @@ -186,7 +175,6 @@ class AcmeApi { return this.apiRequest(url, data, [200]); } - /** * Get identifier authorization * @@ -200,7 +188,6 @@ class AcmeApi { return this.apiRequest(url, null, [200]); } - /** * Update identifier authorization * @@ -215,7 +202,6 @@ class AcmeApi { return this.apiRequest(url, data, [200]); } - /** * Complete challenge * @@ -230,7 +216,6 @@ class AcmeApi { return this.apiRequest(url, data, [200]); } - /** * Revoke certificate * @@ -245,6 +230,5 @@ class AcmeApi { } } - /* Export API */ module.exports = AcmeApi; diff --git a/packages/core/acme-client/src/auto.js b/packages/core/acme-client/src/auto.js index 8f137ebd..ce66ea89 100644 --- a/packages/core/acme-client/src/auto.js +++ b/packages/core/acme-client/src/auto.js @@ -14,10 +14,9 @@ const defaultOpts = { skipChallengeVerification: false, challengePriority: ['http-01', 'dns-01'], challengeCreateFn: async () => { throw new Error('Missing challengeCreateFn()'); }, - challengeRemoveFn: async () => { throw new Error('Missing challengeRemoveFn()'); } + challengeRemoveFn: async () => { throw new Error('Missing challengeRemoveFn()'); }, }; - /** * ACME client auto mode * @@ -26,8 +25,8 @@ const defaultOpts = { * @returns {Promise} Certificate */ -module.exports = async function(client, userOpts) { - const opts = Object.assign({}, defaultOpts, userOpts); +module.exports = async (client, userOpts) => { + const opts = { ...defaultOpts, ...userOpts }; const accountPayload = { termsOfServiceAgreed: opts.termsOfServiceAgreed }; if (!Buffer.isBuffer(opts.csr)) { @@ -38,7 +37,6 @@ module.exports = async function(client, userOpts) { accountPayload.contact = [`mailto:${opts.email}`]; } - /** * Register account */ @@ -54,7 +52,6 @@ module.exports = async function(client, userOpts) { await client.createAccount(accountPayload); } - /** * Parse domains from CSR */ @@ -65,7 +62,6 @@ module.exports = async function(client, userOpts) { log(`[auto] Resolved ${uniqueDomains.length} unique domains from parsing the Certificate Signing Request`); - /** * Place order */ @@ -77,7 +73,6 @@ module.exports = async function(client, userOpts) { log(`[auto] Placed certificate order successfully, received ${authorizations.length} identity authorizations`); - /** * Resolve and satisfy challenges */ @@ -196,7 +191,6 @@ module.exports = async function(client, userOpts) { return Promise.all(results); } - try { log('开始challenge'); await runPromisePa(challengePromises); diff --git a/packages/core/acme-client/src/axios.js b/packages/core/acme-client/src/axios.js index 873d3e37..a4bba60a 100644 --- a/packages/core/acme-client/src/axios.js +++ b/packages/core/acme-client/src/axios.js @@ -5,7 +5,6 @@ const axios = require('axios'); const pkg = require('./../package.json'); - /** * Instance */ @@ -19,9 +18,8 @@ instance.defaults.headers.common['User-Agent'] = `node-${pkg.name}/${pkg.version instance.defaults.acmeSettings = { httpChallengePort: 80, httpsChallengePort: 443, - tlsAlpnChallengePort: 443 + tlsAlpnChallengePort: 443, }; - // instance.defaults.proxy = { // host: '192.168.34.139', // port: 10811 @@ -35,7 +33,6 @@ instance.defaults.acmeSettings = { instance.defaults.adapter = 'http'; - /** * Export instance */ diff --git a/packages/core/acme-client/src/client.js b/packages/core/acme-client/src/client.js index ea16e7e3..42abd1ca 100644 --- a/packages/core/acme-client/src/client.js +++ b/packages/core/acme-client/src/client.js @@ -13,7 +13,6 @@ const verify = require('./verify'); const util = require('./util'); const auto = require('./auto'); - /** * ACME states * @@ -24,7 +23,6 @@ const validStates = ['ready', 'valid']; const pendingStates = ['pending', 'processing']; const invalidStates = ['invalid']; - /** * Default options * @@ -38,10 +36,9 @@ const defaultOpts = { externalAccountBinding: {}, backoffAttempts: 10, backoffMin: 5000, - backoffMax: 30000 + backoffMax: 30000, }; - /** * AcmeClient * @@ -61,7 +58,7 @@ const defaultOpts = { * ```js * const client = new acme.Client({ * directoryUrl: acme.directory.letsencrypt.staging, - * accountKey: 'Private key goes here' + * accountKey: 'Private key goes here', * }); * ``` * @@ -73,7 +70,7 @@ const defaultOpts = { * accountUrl: 'Optional account URL goes here', * backoffAttempts: 10, * backoffMin: 5000, - * backoffMax: 30000 + * backoffMax: 30000, * }); * ``` * @@ -84,8 +81,8 @@ const defaultOpts = { * accountKey: 'Private key goes here', * externalAccountBinding: { * kid: 'YOUR-EAB-KID', - * hmacKey: 'YOUR-EAB-HMAC-KEY' - * } + * hmacKey: 'YOUR-EAB-HMAC-KEY', + * }, * }); * ``` */ @@ -96,19 +93,17 @@ class AcmeClient { opts.accountKey = Buffer.from(opts.accountKey); } - this.opts = Object.assign({}, defaultOpts, opts); - + this.opts = { ...defaultOpts, ...opts }; this.backoffOpts = { attempts: this.opts.backoffAttempts, min: this.opts.backoffMin, - max: this.opts.backoffMax + max: this.opts.backoffMax, }; this.http = new HttpClient(this.opts.directoryUrl, this.opts.accountKey, this.opts.externalAccountBinding); this.api = new AcmeApi(this.http, this.opts.accountUrl); } - /** * Get Terms of Service URL if available * @@ -128,7 +123,6 @@ class AcmeClient { return this.api.getTermsOfServiceUrl(); } - /** * Get current account URL * @@ -150,7 +144,6 @@ class AcmeClient { return this.api.getAccountUrl(); } - /** * Create a new account * @@ -162,7 +155,7 @@ class AcmeClient { * @example Create a new account * ```js * const account = await client.createAccount({ - * termsOfServiceAgreed: true + * termsOfServiceAgreed: true, * }); * ``` * @@ -170,7 +163,7 @@ class AcmeClient { * ```js * const account = await client.createAccount({ * termsOfServiceAgreed: true, - * contact: ['mailto:test@example.com'] + * contact: ['mailto:test@example.com'], * }); * ``` */ @@ -196,7 +189,6 @@ class AcmeClient { } } - /** * Update existing account * @@ -208,7 +200,7 @@ class AcmeClient { * @example Update existing account * ```js * const account = await client.updateAccount({ - * contact: ['mailto:foo@example.com'] + * contact: ['mailto:foo@example.com'], * }); * ``` */ @@ -236,7 +228,6 @@ class AcmeClient { return resp.data; } - /** * Update account private key * @@ -282,7 +273,6 @@ class AcmeClient { return resp.data; } - /** * Create a new order * @@ -296,8 +286,8 @@ class AcmeClient { * const order = await client.createOrder({ * identifiers: [ * { type: 'dns', value: 'example.com' }, - * { type: 'dns', value: 'test.example.com' } - * ] + * { type: 'dns', value: 'test.example.com' }, + * ], * }); * ``` */ @@ -314,7 +304,6 @@ class AcmeClient { return resp.data; } - /** * Refresh order object from CA * @@ -376,7 +365,6 @@ class AcmeClient { return resp.data; } - /** * Get identifier authorizations from order * @@ -406,7 +394,6 @@ class AcmeClient { })); } - /** * Deactivate identifier authorization * @@ -427,10 +414,7 @@ class AcmeClient { throw new Error('Unable to deactivate identifier authorization, URL not found'); } - const data = { - status: 'deactivated' - }; - + const data = { status: 'deactivated' }; const resp = await this.api.updateAuthorization(authz.url, data); /* Add URL to response */ @@ -438,7 +422,6 @@ class AcmeClient { return resp.data; } - /** * Get key authorization for ACME challenge * @@ -480,7 +463,6 @@ class AcmeClient { throw new Error(`Unable to produce key authorization, unknown challenge type: ${challenge.type}`); } - /** * Verify that ACME challenge is satisfied * @@ -515,7 +497,6 @@ class AcmeClient { return util.retry(verifyFn, this.backoffOpts); } - /** * Notify CA that challenge has been completed * @@ -536,7 +517,6 @@ class AcmeClient { return resp.data; } - /** * Wait for ACME provider to verify status on a order, authorization or challenge * @@ -593,7 +573,6 @@ class AcmeClient { return util.retry(verifyFn, this.backoffOpts); } - /** * Get certificate from ACME order * @@ -640,7 +619,6 @@ class AcmeClient { return resp.data; } - /** * Revoke certificate * @@ -660,7 +638,7 @@ class AcmeClient { * ```js * const certificate = { ... }; // Previously created certificate * const result = await client.revokeCertificate(certificate, { - * reason: 4 + * reason: 4, * }); * ``` */ @@ -671,7 +649,6 @@ class AcmeClient { return resp.data; } - /** * Auto mode * @@ -689,7 +666,7 @@ class AcmeClient { * @example Order a certificate using auto mode * ```js * const [certificateKey, certificateRequest] = await acme.crypto.createCsr({ - * commonName: 'test.example.com' + * altNames: ['test.example.com'], * }); * * const certificate = await client.auto({ @@ -701,14 +678,14 @@ class AcmeClient { * }, * challengeRemoveFn: async (authz, challenge, keyAuthorization) => { * // Clean up challenge here - * } + * }, * }); * ``` * * @example Order a certificate using auto mode with preferred chain * ```js * const [certificateKey, certificateRequest] = await acme.crypto.createCsr({ - * commonName: 'test.example.com' + * altNames: ['test.example.com'], * }); * * const certificate = await client.auto({ @@ -717,7 +694,7 @@ class AcmeClient { * termsOfServiceAgreed: true, * preferredChain: 'DST Root CA X3', * challengeCreateFn: async () => {}, - * challengeRemoveFn: async () => {} + * challengeRemoveFn: async () => {}, * }); * ``` */ @@ -727,6 +704,5 @@ class AcmeClient { } } - /* Export client */ module.exports = AcmeClient; diff --git a/packages/core/acme-client/src/crypto/forge.js b/packages/core/acme-client/src/crypto/forge.js index 5b66327a..4bf942c8 100644 --- a/packages/core/acme-client/src/crypto/forge.js +++ b/packages/core/acme-client/src/crypto/forge.js @@ -13,7 +13,6 @@ const forge = require('node-forge'); const generateKeyPair = promisify(forge.pki.rsa.generateKeyPair); - /** * Attempt to parse forge object from PEM encoded string * @@ -54,7 +53,6 @@ function forgeObjectFromPem(input) { return result; } - /** * Parse domain names from a certificate or CSR * @@ -93,11 +91,10 @@ function parseDomains(obj) { return { commonName, - altNames + altNames, }; } - /** * Generate a private RSA key * @@ -123,7 +120,6 @@ async function createPrivateKey(size = 2048) { exports.createPrivateKey = createPrivateKey; - /** * Create public key from a private RSA key * @@ -136,14 +132,13 @@ exports.createPrivateKey = createPrivateKey; * ``` */ -exports.createPublicKey = async function(key) { +exports.createPublicKey = async (key) => { const privateKey = forge.pki.privateKeyFromPem(key); const publicKey = forge.pki.rsa.setPublicKey(privateKey.n, privateKey.e); const pemKey = forge.pki.publicKeyToPem(publicKey); return Buffer.from(pemKey); }; - /** * Parse body of PEM encoded object from buffer or string * If multiple objects are chained, the first body will be returned @@ -157,7 +152,6 @@ exports.getPemBody = (str) => { return forge.util.encode64(msg.body); }; - /** * Split chain of PEM encoded objects from buffer or string into array * @@ -167,7 +161,6 @@ exports.getPemBody = (str) => { exports.splitPemChain = (str) => forge.pem.decode(str).map(forge.pem.encode); - /** * Get modulus * @@ -182,7 +175,7 @@ exports.splitPemChain = (str) => forge.pem.decode(str).map(forge.pem.encode); * ``` */ -exports.getModulus = async function(input) { +exports.getModulus = async (input) => { if (!Buffer.isBuffer(input)) { input = Buffer.from(input); } @@ -191,7 +184,6 @@ exports.getModulus = async function(input) { return Buffer.from(forge.util.hexToBytes(obj.n.toString(16)), 'binary'); }; - /** * Get public exponent * @@ -206,7 +198,7 @@ exports.getModulus = async function(input) { * ``` */ -exports.getPublicExponent = async function(input) { +exports.getPublicExponent = async (input) => { if (!Buffer.isBuffer(input)) { input = Buffer.from(input); } @@ -215,7 +207,6 @@ exports.getPublicExponent = async function(input) { return Buffer.from(forge.util.hexToBytes(obj.e.toString(16)), 'binary'); }; - /** * Read domains from a Certificate Signing Request * @@ -231,7 +222,7 @@ exports.getPublicExponent = async function(input) { * ``` */ -exports.readCsrDomains = async function(csr) { +exports.readCsrDomains = async (csr) => { if (!Buffer.isBuffer(csr)) { csr = Buffer.from(csr); } @@ -240,7 +231,6 @@ exports.readCsrDomains = async function(csr) { return parseDomains(obj); }; - /** * Read information from a certificate * @@ -260,7 +250,7 @@ exports.readCsrDomains = async function(csr) { * ``` */ -exports.readCertificateInfo = async function(cert) { +exports.readCertificateInfo = async (cert) => { if (!Buffer.isBuffer(cert)) { cert = Buffer.from(cert); } @@ -270,15 +260,14 @@ exports.readCertificateInfo = async function(cert) { return { issuer: { - commonName: issuerCn ? issuerCn.value : null + commonName: issuerCn ? issuerCn.value : null, }, domains: parseDomains(obj), notAfter: obj.validity.notAfter, - notBefore: obj.validity.notBefore + notBefore: obj.validity.notBefore, }; }; - /** * Determine ASN.1 type for CSR subject short name * Note: https://datatracker.ietf.org/doc/html/rfc5280 @@ -299,7 +288,6 @@ function getCsrValueTagClass(shortName) { } } - /** * Create array of short names and values for Certificate Signing Request subjects * @@ -319,7 +307,6 @@ function createCsrSubject(subjectObj) { }, []); } - /** * Create array of alt names for Certificate Signing Requests * Note: https://github.com/digitalbazaar/forge/blob/dfdde475677a8a25c851e33e8f81dca60d90cfb9/lib/x509.js#L1444-L1454 @@ -336,7 +323,6 @@ function formatCsrAltNames(altNames) { }); } - /** * Create a Certificate Signing Request * @@ -356,29 +342,30 @@ function formatCsrAltNames(altNames) { * @example Create a Certificate Signing Request * ```js * const [certificateKey, certificateRequest] = await acme.forge.createCsr({ - * commonName: 'test.example.com' + * altNames: ['test.example.com'], * }); * ``` * * @example Certificate Signing Request with both common and alternative names + * > *Warning*: Certificate subject common name has been [deprecated](https://letsencrypt.org/docs/glossary/#def-CN) and its use is [discouraged](https://cabforum.org/uploads/BRv1.2.3.pdf). * ```js * const [certificateKey, certificateRequest] = await acme.forge.createCsr({ * keySize: 4096, * commonName: 'test.example.com', - * altNames: ['foo.example.com', 'bar.example.com'] + * altNames: ['foo.example.com', 'bar.example.com'], * }); * ``` * * @example Certificate Signing Request with additional information * ```js * const [certificateKey, certificateRequest] = await acme.forge.createCsr({ - * commonName: 'test.example.com', + * altNames: ['test.example.com'], * country: 'US', * state: 'California', * locality: 'Los Angeles', * organization: 'The Company Inc.', * organizationUnit: 'IT Department', - * emailAddress: 'contact@example.com' + * emailAddress: 'contact@example.com', * }); * ``` * @@ -387,11 +374,11 @@ function formatCsrAltNames(altNames) { * const certificateKey = await acme.forge.createPrivateKey(); * * const [, certificateRequest] = await acme.forge.createCsr({ - * commonName: 'test.example.com' + * altNames: ['test.example.com'], * }, certificateKey); */ -exports.createCsr = async function(data, key = null) { +exports.createCsr = async (data, key = null) => { if (!key) { key = await createPrivateKey(data.keySize); } @@ -423,7 +410,7 @@ exports.createCsr = async function(data, key = null) { L: data.locality, O: data.organization, OU: data.organizationUnit, - E: data.emailAddress + E: data.emailAddress, }); csr.setSubject(subject); @@ -434,8 +421,8 @@ exports.createCsr = async function(data, key = null) { name: 'extensionRequest', extensions: [{ name: 'subjectAltName', - altNames: formatCsrAltNames(data.altNames) - }] + altNames: formatCsrAltNames(data.altNames), + }], }]); } diff --git a/packages/core/acme-client/src/crypto/index.js b/packages/core/acme-client/src/crypto/index.js index da0df321..f0c3c367 100644 --- a/packages/core/acme-client/src/crypto/index.js +++ b/packages/core/acme-client/src/crypto/index.js @@ -22,7 +22,6 @@ const subjectAltNameOID = '2.5.29.17'; /* id-pe-acmeIdentifier - https://datatracker.ietf.org/doc/html/rfc8737#section-6.1 */ const alpnAcmeIdentifierOID = '1.3.6.1.5.5.7.1.31'; - /** * Determine key type and info by attempting to derive public key * @@ -35,7 +34,7 @@ function getKeyInfo(keyPem) { const result = { isRSA: false, isECDSA: false, - publicKey: crypto.createPublicKey(keyPem) + publicKey: crypto.createPublicKey(keyPem), }; if (result.publicKey.asymmetricKeyType === 'rsa') { @@ -51,7 +50,6 @@ function getKeyInfo(keyPem) { return result; } - /** * Generate a private RSA key * @@ -74,8 +72,8 @@ async function createPrivateRsaKey(modulusLength = 2048) { modulusLength, privateKeyEncoding: { type: 'pkcs8', - format: 'pem' - } + format: 'pem', + }, }); return Buffer.from(pair.privateKey); @@ -83,7 +81,6 @@ async function createPrivateRsaKey(modulusLength = 2048) { exports.createPrivateRsaKey = createPrivateRsaKey; - /** * Alias of `createPrivateRsaKey()` * @@ -92,7 +89,6 @@ exports.createPrivateRsaKey = createPrivateRsaKey; exports.createPrivateKey = createPrivateRsaKey; - /** * Generate a private ECDSA key * @@ -115,14 +111,13 @@ exports.createPrivateEcdsaKey = async (namedCurve = 'P-256') => { namedCurve, privateKeyEncoding: { type: 'pkcs8', - format: 'pem' - } + format: 'pem', + }, }); return Buffer.from(pair.privateKey); }; - /** * Get a public key derived from a RSA or ECDSA key * @@ -140,13 +135,12 @@ exports.getPublicKey = (keyPem) => { const publicKey = info.publicKey.export({ type: info.isECDSA ? 'spki' : 'pkcs1', - format: 'pem' + format: 'pem', }); return Buffer.from(publicKey); }; - /** * Get a JSON Web Key derived from a RSA or ECDSA key * @@ -163,7 +157,7 @@ exports.getPublicKey = (keyPem) => { function getJwk(keyPem) { const jwk = crypto.createPublicKey(keyPem).export({ - format: 'jwk' + format: 'jwk', }); /* Sort keys */ @@ -175,7 +169,6 @@ function getJwk(keyPem) { exports.getJwk = getJwk; - /** * Produce CryptoKeyPair and signing algorithm from a PEM encoded private key * @@ -191,7 +184,7 @@ async function getWebCryptoKeyPair(keyPem) { /* Signing algorithm */ const sigalg = { name: 'RSASSA-PKCS1-v1_5', - hash: { name: 'SHA-256' } + hash: { name: 'SHA-256' }, }; if (info.isECDSA) { @@ -215,7 +208,6 @@ async function getWebCryptoKeyPair(keyPem) { return [{ privateKey, publicKey }, sigalg]; } - /** * Split chain of PEM encoded objects from string into array * @@ -235,7 +227,6 @@ function splitPemChain(chainPem) { exports.splitPemChain = splitPemChain; - /** * Parse body of PEM encoded object and return a Base64URL string * If multiple objects are chained, the first body will be returned @@ -256,7 +247,6 @@ exports.getPemBodyAsB64u = (pem) => { return Buffer.from(dec).toString('base64url'); }; - /** * Parse domains from a certificate or CSR * @@ -277,11 +267,10 @@ function parseDomains(input) { return { commonName, - altNames + altNames, }; } - /** * Read domains from a Certificate Signing Request * @@ -307,7 +296,6 @@ exports.readCsrDomains = (csrPem) => { return parseDomains(csr); }; - /** * Read information from a certificate * If multiple certificates are chained, the first will be read @@ -338,15 +326,14 @@ exports.readCertificateInfo = (certPem) => { return { issuer: { - commonName: cert.issuerName.getField('CN').pop() || null + commonName: cert.issuerName.getField('CN').pop() || null, }, domains: parseDomains(cert), notBefore: cert.notBefore, - notAfter: cert.notAfter + notAfter: cert.notAfter, }; }; - /** * Determine ASN.1 character string type for CSR subject field name * @@ -369,7 +356,6 @@ function getCsrAsn1CharStringType(field) { } } - /** * Create array of subject fields for a Certificate Signing Request * @@ -391,7 +377,6 @@ function createCsrSubject(input) { }, []); } - /** * Create x509 subject alternate name extension * @@ -409,7 +394,6 @@ function createSubjectAltNameExtension(altNames) { })); } - /** * Create a Certificate Signing Request * @@ -429,29 +413,30 @@ function createSubjectAltNameExtension(altNames) { * @example Create a Certificate Signing Request * ```js * const [certificateKey, certificateRequest] = await acme.crypto.createCsr({ - * commonName: 'test.example.com' + * altNames: ['test.example.com'], * }); * ``` * * @example Certificate Signing Request with both common and alternative names + * > *Warning*: Certificate subject common name has been [deprecated](https://letsencrypt.org/docs/glossary/#def-CN) and its use is [discouraged](https://cabforum.org/uploads/BRv1.2.3.pdf). * ```js * const [certificateKey, certificateRequest] = await acme.crypto.createCsr({ * keySize: 4096, * commonName: 'test.example.com', - * altNames: ['foo.example.com', 'bar.example.com'] + * altNames: ['foo.example.com', 'bar.example.com'], * }); * ``` * * @example Certificate Signing Request with additional information * ```js * const [certificateKey, certificateRequest] = await acme.crypto.createCsr({ - * commonName: 'test.example.com', + * altNames: ['test.example.com'], * country: 'US', * state: 'California', * locality: 'Los Angeles', * organization: 'The Company Inc.', * organizationUnit: 'IT Department', - * emailAddress: 'contact@example.com' + * emailAddress: 'contact@example.com', * }); * ``` * @@ -460,8 +445,9 @@ function createSubjectAltNameExtension(altNames) { * const certificateKey = await acme.crypto.createPrivateEcdsaKey(); * * const [, certificateRequest] = await acme.crypto.createCsr({ - * commonName: 'test.example.com' + * altNames: ['test.example.com'], * }, certificateKey); + * ``` */ exports.createCsr = async (data, keyPem = null) => { @@ -489,7 +475,7 @@ exports.createCsr = async (data, keyPem = null) => { new x509.KeyUsagesExtension(x509.KeyUsageFlags.digitalSignature | x509.KeyUsageFlags.keyEncipherment), // eslint-disable-line no-bitwise /* https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.6 */ - createSubjectAltNameExtension(data.altNames) + createSubjectAltNameExtension(data.altNames), ]; /* Create CSR */ @@ -504,8 +490,8 @@ exports.createCsr = async (data, keyPem = null) => { L: data.locality, O: data.organization, OU: data.organizationUnit, - E: data.emailAddress - }) + E: data.emailAddress, + }), }); /* Done */ @@ -513,7 +499,6 @@ exports.createCsr = async (data, keyPem = null) => { return [keyPem, Buffer.from(pem)]; }; - /** * Create a self-signed ALPN certificate for TLS-ALPN-01 challenges * @@ -533,6 +518,7 @@ exports.createCsr = async (data, keyPem = null) => { * ```js * const alpnKey = await acme.crypto.createPrivateEcdsaKey(); * const [, alpnCertificate] = await acme.crypto.createAlpnCertificate(authz, keyAuthorization, alpnKey); + * ``` */ exports.createAlpnCertificate = async (authz, keyAuthorization, keyPem = null) => { @@ -564,7 +550,7 @@ exports.createAlpnCertificate = async (authz, keyAuthorization, keyPem = null) = await x509.SubjectKeyIdentifierExtension.create(keys.publicKey), /* https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.6 */ - createSubjectAltNameExtension([commonName]) + createSubjectAltNameExtension([commonName]), ]; /* ALPN extension */ @@ -581,8 +567,8 @@ exports.createAlpnCertificate = async (authz, keyAuthorization, keyPem = null) = notBefore: now, notAfter: now, name: createCsrSubject({ - CN: commonName - }) + CN: commonName, + }), }); /* Done */ @@ -590,7 +576,6 @@ exports.createAlpnCertificate = async (authz, keyAuthorization, keyPem = null) = return [keyPem, Buffer.from(pem)]; }; - /** * Validate that a ALPN certificate contains the expected key authorization * diff --git a/packages/core/acme-client/src/http.js b/packages/core/acme-client/src/http.js index ed448d31..6f7d8963 100644 --- a/packages/core/acme-client/src/http.js +++ b/packages/core/acme-client/src/http.js @@ -40,7 +40,6 @@ class HttpClient { this.jwk = null; } - /** * HTTP request * @@ -70,7 +69,6 @@ class HttpClient { return resp; } - /** * Ensure provider directory exists * @@ -95,7 +93,6 @@ class HttpClient { } } - /** * Get JSON Web Key * @@ -110,7 +107,6 @@ class HttpClient { return this.jwk; } - /** * Get nonce from directory API endpoint * @@ -130,7 +126,6 @@ class HttpClient { return resp.headers['replay-nonce']; } - /** * Get URL for a directory resource * @@ -148,7 +143,6 @@ class HttpClient { return this.directory[resource]; } - /** * Get directory meta field * @@ -166,7 +160,6 @@ class HttpClient { return null; } - /** * Prepare HTTP request body for signature * @@ -199,11 +192,10 @@ class HttpClient { /* Body */ return { payload: payload ? Buffer.from(JSON.stringify(payload)).toString('base64url') : '', - protected: Buffer.from(JSON.stringify(header)).toString('base64url') + protected: Buffer.from(JSON.stringify(header)).toString('base64url'), }; } - /** * Create JWS HTTP request body using HMAC * @@ -226,7 +218,6 @@ class HttpClient { return result; } - /** * Create JWS HTTP request body using RSA or ECC * @@ -267,13 +258,12 @@ class HttpClient { result.signature = signer.sign({ key: this.accountKey, padding: RSA_PKCS1_PADDING, - dsaEncoding: 'ieee-p1363' + dsaEncoding: 'ieee-p1363', }, 'base64url'); return result; } - /** * Signed HTTP request * @@ -309,7 +299,7 @@ class HttpClient { const data = this.createSignedBody(url, payload, { nonce, kid }); const resp = await this.request(url, 'post', { data }); - /* Retry on bad nonce - https://datatracker.ietf.org/doc/html/draft-ietf-acme-acme-10#section-6.4 */ + /* Retry on bad nonce - https://datatracker.ietf.org/doc/html/rfc8555#section-6.5 */ if (resp.data && resp.data.type && (resp.status === 400) && (resp.data.type === 'urn:ietf:params:acme:error:badNonce') && (attempts < this.maxBadNonceRetries)) { nonce = resp.headers['replay-nonce'] || null; attempts += 1; @@ -323,6 +313,5 @@ class HttpClient { } } - /* Export client */ module.exports = HttpClient; diff --git a/packages/core/acme-client/src/index.js b/packages/core/acme-client/src/index.js index a2552e11..209cf1da 100644 --- a/packages/core/acme-client/src/index.js +++ b/packages/core/acme-client/src/index.js @@ -4,7 +4,6 @@ exports.Client = require('./client'); - /** * Directory URLs */ @@ -12,18 +11,17 @@ exports.Client = require('./client'); exports.directory = { buypass: { staging: 'https://api.test4.buypass.no/acme/directory', - production: 'https://api.buypass.com/acme/directory' + production: 'https://api.buypass.com/acme/directory', }, letsencrypt: { staging: 'https://acme-staging-v02.api.letsencrypt.org/directory', - production: 'https://acme-v02.api.letsencrypt.org/directory' + production: 'https://acme-v02.api.letsencrypt.org/directory', }, zerossl: { - production: 'https://acme.zerossl.com/v2/DV90' - } + production: 'https://acme.zerossl.com/v2/DV90', + }, }; - /** * Crypto */ @@ -31,14 +29,12 @@ exports.directory = { exports.crypto = require('./crypto'); exports.forge = require('./crypto/forge'); - /** * Axios */ exports.axios = require('./axios'); - /** * Logger */ diff --git a/packages/core/acme-client/src/logger.js b/packages/core/acme-client/src/logger.js index 3d592409..3659c517 100644 --- a/packages/core/acme-client/src/logger.js +++ b/packages/core/acme-client/src/logger.js @@ -6,7 +6,6 @@ const debug = require('debug')('acme-client'); let logger = () => {}; - /** * Set logger function * @@ -17,11 +16,10 @@ exports.setLogger = (fn) => { logger = fn; }; - /** * Log message * - * @param {string} Message + * @param {string} msg Message */ exports.log = (msg) => { diff --git a/packages/core/acme-client/src/util.js b/packages/core/acme-client/src/util.js index c0c56370..be2cdd49 100644 --- a/packages/core/acme-client/src/util.js +++ b/packages/core/acme-client/src/util.js @@ -7,7 +7,6 @@ const dns = require('dns').promises; const { readCertificateInfo, splitPemChain } = require('./crypto'); const { log } = require('./logger'); - /** * Exponential backoff * @@ -26,7 +25,6 @@ class Backoff { this.attempts = 0; } - /** * Get backoff duration * @@ -40,7 +38,6 @@ class Backoff { } } - /** * Retry promise * @@ -70,7 +67,6 @@ async function retryPromise(fn, attempts, backoff) { } } - /** * Retry promise * @@ -87,7 +83,6 @@ function retry(fn, { attempts = 5, min = 5000, max = 30000 } = {}) { return retryPromise(fn, attempts, backoff); } - /** * Parse URLs from link header * @@ -107,7 +102,6 @@ function parseLinkHeader(header, rel = 'alternate') { return results.filter((r) => r); } - /** * Find certificate chain with preferred issuer common name * - If issuer is found in multiple chains, the closest to root wins @@ -157,7 +151,6 @@ function findCertificateChainForIssuer(chains, issuer) { return chains[0]; } - /** * Find and format error in response object * @@ -178,7 +171,6 @@ function formatResponseError(resp) { return result.replace(/\n/g, ''); } - /** * Resolve root domain name by looking for SOA record * @@ -204,7 +196,6 @@ async function resolveDomainBySoaRecord(recordName) { } } - /** * Get DNS resolver using domains authoritative NS records * @@ -245,7 +236,6 @@ async function getAuthoritativeDnsResolver(recordName) { return resolver; } - /** * Attempt to retrieve TLS ALPN certificate from peer * @@ -267,7 +257,7 @@ async function retrieveTlsAlpnCertificate(host, port, timeout = 30000) { port, servername: host, rejectUnauthorized: false, - ALPNProtocols: ['acme-tls/1'] + ALPNProtocols: ['acme-tls/1'], }); socket.setTimeout(timeout); @@ -299,7 +289,6 @@ async function retrieveTlsAlpnCertificate(host, port, timeout = 30000) { }); } - /** * Export utils */ @@ -310,5 +299,5 @@ module.exports = { findCertificateChainForIssuer, formatResponseError, getAuthoritativeDnsResolver, - retrieveTlsAlpnCertificate + retrieveTlsAlpnCertificate, }; diff --git a/packages/core/acme-client/src/verify.js b/packages/core/acme-client/src/verify.js index c0456497..7fb429ce 100644 --- a/packages/core/acme-client/src/verify.js +++ b/packages/core/acme-client/src/verify.js @@ -9,7 +9,6 @@ const axios = require('./axios'); const util = require('./util'); const { isAlpnCertificateAuthorizationValid } = require('./crypto'); - /** * Verify ACME HTTP challenge * @@ -43,7 +42,6 @@ async function verifyHttpChallenge(authz, challenge, keyAuthorization, suffix = return true; } - /** * Walk DNS until TXT records are found */ @@ -81,7 +79,6 @@ async function walkDnsChallengeRecord(recordName, resolver = dns) { throw new Error(`No TXT records found for name: ${recordName}`); } - /** * Verify ACME DNS challenge * @@ -121,7 +118,6 @@ async function verifyDnsChallenge(authz, challenge, keyAuthorization, prefix = ' return true; } - /** * Verify ACME TLS ALPN challenge * @@ -149,7 +145,6 @@ async function verifyTlsAlpnChallenge(authz, challenge, keyAuthorization) { return true; } - /** * Export API */ @@ -157,5 +152,5 @@ async function verifyTlsAlpnChallenge(authz, challenge, keyAuthorization) { module.exports = { 'http-01': verifyHttpChallenge, 'dns-01': verifyDnsChallenge, - 'tls-alpn-01': verifyTlsAlpnChallenge + 'tls-alpn-01': verifyTlsAlpnChallenge, }; diff --git a/packages/core/acme-client/test/00-pebble.spec.js b/packages/core/acme-client/test/00-pebble.spec.js index 992fc6bd..03633583 100644 --- a/packages/core/acme-client/test/00-pebble.spec.js +++ b/packages/core/acme-client/test/00-pebble.spec.js @@ -16,7 +16,6 @@ const httpPort = axios.defaults.acmeSettings.httpChallengePort || 80; const httpsPort = axios.defaults.acmeSettings.httpsChallengePort || 443; const tlsAlpnPort = axios.defaults.acmeSettings.tlsAlpnChallengePort || 443; - describe('pebble', () => { const httpsAgent = new https.Agent({ rejectUnauthorized: false }); @@ -39,18 +38,16 @@ describe('pebble', () => { const testTlsAlpn01ChallengeHost = `${uuid()}.${domainName}`; const testTlsAlpn01ChallengeValue = uuid(); - /** * Pebble CTS required */ - before(function() { + before(function () { if (!cts.isEnabled()) { this.skip(); } }); - /** * DNS mocking */ @@ -92,7 +89,6 @@ describe('pebble', () => { }); }); - /** * HTTP-01 challenge response */ @@ -118,7 +114,6 @@ describe('pebble', () => { }); }); - /** * HTTPS-01 challenge response */ @@ -143,7 +138,7 @@ describe('pebble', () => { /* Assert HTTP 302 */ const resp = await axios.get(`http://${testHttps01ChallengeHost}:${httpPort}/.well-known/acme-challenge/${testHttps01ChallengeToken}`, { maxRedirects: 0, - validateStatus: null + validateStatus: null, }); assert.strictEqual(resp.status, 302); @@ -165,7 +160,6 @@ describe('pebble', () => { }); }); - /** * DNS-01 challenge response */ @@ -188,7 +182,6 @@ describe('pebble', () => { }); }); - /** * TLS-ALPN-01 challenge response */ diff --git a/packages/core/acme-client/test/10-http.spec.js b/packages/core/acme-client/test/10-http.spec.js index a2a54de4..6967d9ec 100644 --- a/packages/core/acme-client/test/10-http.spec.js +++ b/packages/core/acme-client/test/10-http.spec.js @@ -9,7 +9,6 @@ const axios = require('./../src/axios'); const HttpClient = require('./../src/http'); const pkg = require('./../package.json'); - describe('http', () => { let testClient; @@ -20,7 +19,6 @@ describe('http', () => { const defaultUaEndpoint = `http://${uuid()}.example.com`; const customUaEndpoint = `http://${uuid()}.example.com`; - /** * HTTP mocking */ @@ -43,7 +41,6 @@ describe('http', () => { axios.defaults.headers.common['User-Agent'] = defaultUserAgent; }); - /** * Initialize */ @@ -52,7 +49,6 @@ describe('http', () => { testClient = new HttpClient(); }); - /** * HTTP verbs */ @@ -65,7 +61,6 @@ describe('http', () => { assert.strictEqual(resp.data, 'ok'); }); - /** * User-Agent */ diff --git a/packages/core/acme-client/test/10-logger.spec.js b/packages/core/acme-client/test/10-logger.spec.js index ac9200bc..daea2697 100644 --- a/packages/core/acme-client/test/10-logger.spec.js +++ b/packages/core/acme-client/test/10-logger.spec.js @@ -5,7 +5,6 @@ const { assert } = require('chai'); const logger = require('./../src/logger'); - describe('logger', () => { let lastLogMessage = null; @@ -13,7 +12,6 @@ describe('logger', () => { lastLogMessage = msg; } - /** * Logger */ @@ -23,7 +21,6 @@ describe('logger', () => { assert.isNull(lastLogMessage); }); - it('should log with custom logger', () => { logger.setLogger(customLoggerFn); diff --git a/packages/core/acme-client/test/10-verify.spec.js b/packages/core/acme-client/test/10-verify.spec.js index 284cc3a0..dbbcbbe2 100644 --- a/packages/core/acme-client/test/10-verify.spec.js +++ b/packages/core/acme-client/test/10-verify.spec.js @@ -9,7 +9,6 @@ const verify = require('./../src/verify'); const domainName = process.env.ACME_DOMAIN_NAME || 'example.com'; - describe('verify', () => { const challengeTypes = ['http-01', 'dns-01']; @@ -30,18 +29,16 @@ describe('verify', () => { const testTlsAlpn01Challenge = { type: 'dns-01', status: 'pending', token: uuid() }; const testTlsAlpn01Key = uuid(); - /** * Pebble CTS required */ - before(function() { + before(function () { if (!cts.isEnabled()) { this.skip(); } }); - /** * API */ @@ -50,7 +47,6 @@ describe('verify', () => { assert.containsAllKeys(verify, challengeTypes); }); - /** * http-01 */ @@ -81,7 +77,6 @@ describe('verify', () => { }); }); - /** * https-01 */ @@ -102,7 +97,6 @@ describe('verify', () => { }); }); - /** * dns-01 */ @@ -133,7 +127,6 @@ describe('verify', () => { }); }); - /** * tls-alpn-01 */ diff --git a/packages/core/acme-client/test/20-crypto-legacy.spec.js b/packages/core/acme-client/test/20-crypto-legacy.spec.js index b039e74a..eeacda46 100644 --- a/packages/core/acme-client/test/20-crypto-legacy.spec.js +++ b/packages/core/acme-client/test/20-crypto-legacy.spec.js @@ -9,10 +9,9 @@ const spec = require('./spec'); const forge = require('./../src/crypto/forge'); const cryptoEngines = { - forge + forge, }; - describe('crypto-legacy', () => { let testPemKey; let testCert; @@ -28,7 +27,6 @@ describe('crypto-legacy', () => { const testCertPath = path.join(__dirname, 'fixtures', 'certificate.crt'); const testSanCertPath = path.join(__dirname, 'fixtures', 'san-certificate.crt'); - /** * Fixtures */ @@ -50,7 +48,6 @@ describe('crypto-legacy', () => { }); }); - /** * Engines */ @@ -62,7 +59,6 @@ describe('crypto-legacy', () => { let testNonCnCsr; let testNonAsciiCsr; - /** * Key generation */ @@ -83,14 +79,13 @@ describe('crypto-legacy', () => { publicKeyStore.push(key.toString().replace(/[\r\n]/gm, '')); }); - /** * Certificate Signing Request */ it('should generate a csr', async () => { const [key, csr] = await engine.createCsr({ - commonName: testCsrDomain + commonName: testCsrDomain, }); assert.isTrue(Buffer.isBuffer(key)); @@ -102,7 +97,7 @@ describe('crypto-legacy', () => { it('should generate a san csr', async () => { const [key, csr] = await engine.createCsr({ commonName: testSanCsrDomains[0], - altNames: testSanCsrDomains.slice(1, testSanCsrDomains.length) + altNames: testSanCsrDomains.slice(1, testSanCsrDomains.length), }); assert.isTrue(Buffer.isBuffer(key)); @@ -113,7 +108,7 @@ describe('crypto-legacy', () => { it('should generate a csr without common name', async () => { const [key, csr] = await engine.createCsr({ - altNames: testSanCsrDomains + altNames: testSanCsrDomains, }); assert.isTrue(Buffer.isBuffer(key)); @@ -126,7 +121,7 @@ describe('crypto-legacy', () => { const [key, csr] = await engine.createCsr({ commonName: testCsrDomain, organization: '大安區', - organizationUnit: '中文部門' + organizationUnit: '中文部門', }); assert.isTrue(Buffer.isBuffer(key)); @@ -167,7 +162,6 @@ describe('crypto-legacy', () => { assert.deepStrictEqual(result.altNames, [testCsrDomain]); }); - /** * Certificate */ @@ -188,7 +182,6 @@ describe('crypto-legacy', () => { assert.deepEqual(info.domains.altNames, testSanCsrDomains.slice(1, testSanCsrDomains.length)); }); - /** * PEM utils */ @@ -214,7 +207,6 @@ describe('crypto-legacy', () => { }); }); - /** * Modulus and exponent */ @@ -246,7 +238,6 @@ describe('crypto-legacy', () => { }); }); - /** * Verify identical results */ diff --git a/packages/core/acme-client/test/20-crypto.spec.js b/packages/core/acme-client/test/20-crypto.spec.js index 71e5277f..148ca464 100644 --- a/packages/core/acme-client/test/20-crypto.spec.js +++ b/packages/core/acme-client/test/20-crypto.spec.js @@ -50,7 +50,6 @@ dGVzdGluZ3Rlc3Rpbmd0ZXN0aW5ndGVzdGluZ3Rlc3Rpbmd0ZXN0aW5ndGVzdGluZ3Rlc3Rpbmd0ZXN0 -----END TEST----- `; - describe('crypto', () => { const testCsrDomain = 'example.com'; const testSanCsrDomains = ['example.com', 'test.example.com', 'abc.example.com']; @@ -58,7 +57,6 @@ describe('crypto', () => { const testCertPath = path.join(__dirname, 'fixtures', 'certificate.crt'); const testSanCertPath = path.join(__dirname, 'fixtures', 'san-certificate.crt'); - /** * Key types */ @@ -68,24 +66,23 @@ describe('crypto', () => { createKeyFns: { s1024: () => crypto.createPrivateRsaKey(1024), s2048: () => crypto.createPrivateRsaKey(), - s4096: () => crypto.createPrivateRsaKey(4096) + s4096: () => crypto.createPrivateRsaKey(4096), }, - jwkSpecFn: spec.jwk.rsa + jwkSpecFn: spec.jwk.rsa, }, ecdsa: { createKeyFns: { p256: () => crypto.createPrivateEcdsaKey(), p384: () => crypto.createPrivateEcdsaKey('P-384'), - p521: () => crypto.createPrivateEcdsaKey('P-521') + p521: () => crypto.createPrivateEcdsaKey('P-521'), }, - jwkSpecFn: spec.jwk.ecdsa - } + jwkSpecFn: spec.jwk.ecdsa, + }, }).forEach(([name, { createKeyFns, jwkSpecFn }]) => { describe(name, () => { const testPrivateKeys = {}; const testPublicKeys = {}; - /** * Iterate through all generator variations */ @@ -97,7 +94,6 @@ describe('crypto', () => { let testNonAsciiCsr; let testAlpnCertificate; - /** * Keys and JWK */ @@ -132,14 +128,13 @@ describe('crypto', () => { jwkSpecFn(jwk); }); - /** * Certificate Signing Request */ it(`${n}/should generate a csr`, async () => { const [key, csr] = await crypto.createCsr({ - commonName: testCsrDomain + commonName: testCsrDomain, }, testPrivateKeys[n]); assert.isTrue(Buffer.isBuffer(key)); @@ -151,7 +146,7 @@ describe('crypto', () => { it(`${n}/should generate a san csr`, async () => { const [key, csr] = await crypto.createCsr({ commonName: testSanCsrDomains[0], - altNames: testSanCsrDomains.slice(1, testSanCsrDomains.length) + altNames: testSanCsrDomains.slice(1, testSanCsrDomains.length), }, testPrivateKeys[n]); assert.isTrue(Buffer.isBuffer(key)); @@ -162,7 +157,7 @@ describe('crypto', () => { it(`${n}/should generate a csr without common name`, async () => { const [key, csr] = await crypto.createCsr({ - altNames: testSanCsrDomains + altNames: testSanCsrDomains, }, testPrivateKeys[n]); assert.isTrue(Buffer.isBuffer(key)); @@ -175,7 +170,7 @@ describe('crypto', () => { const [key, csr] = await crypto.createCsr({ commonName: testCsrDomain, organization: '大安區', - organizationUnit: '中文部門' + organizationUnit: '中文部門', }, testPrivateKeys[n]); assert.isTrue(Buffer.isBuffer(key)); @@ -186,7 +181,7 @@ describe('crypto', () => { it(`${n}/should generate a csr with key as string`, async () => { const [key, csr] = await crypto.createCsr({ - commonName: testCsrDomain + commonName: testCsrDomain, }, testPrivateKeys[n].toString()); assert.isTrue(Buffer.isBuffer(key)); @@ -195,11 +190,10 @@ describe('crypto', () => { it(`${n}/should throw with invalid key`, async () => { await assert.isRejected(crypto.createCsr({ - commonName: testCsrDomain + commonName: testCsrDomain, }, testPublicKeys[n])); }); - /** * Domain and info resolver */ @@ -243,7 +237,6 @@ describe('crypto', () => { }); }); - /** * ALPN */ @@ -284,7 +277,6 @@ describe('crypto', () => { }); }); - /** * Common functionality */ @@ -294,7 +286,6 @@ describe('crypto', () => { let testCert; let testSanCert; - it('should read private key fixture', async () => { testPemKey = await fs.readFile(testKeyPath); assert.isTrue(Buffer.isBuffer(testPemKey)); @@ -310,21 +301,19 @@ describe('crypto', () => { assert.isTrue(Buffer.isBuffer(testSanCert)); }); - /** * CSR with auto-generated key */ it('should generate a csr with default key', async () => { const [key, csr] = await crypto.createCsr({ - commonName: testCsrDomain + commonName: testCsrDomain, }); assert.isTrue(Buffer.isBuffer(key)); assert.isTrue(Buffer.isBuffer(csr)); }); - /** * Certificate */ @@ -352,7 +341,6 @@ describe('crypto', () => { }); }); - /** * ALPN */ @@ -365,7 +353,6 @@ describe('crypto', () => { assert.isTrue(Buffer.isBuffer(cert)); }); - /** * PEM utils */ diff --git a/packages/core/acme-client/test/50-client.spec.js b/packages/core/acme-client/test/50-client.spec.js index 31784ca3..248913d8 100644 --- a/packages/core/acme-client/test/50-client.spec.js +++ b/packages/core/acme-client/test/50-client.spec.js @@ -20,35 +20,32 @@ const clientOpts = { directoryUrl, backoffAttempts: 5, backoffMin: 1000, - backoffMax: 5000 + backoffMax: 5000, }; if (capEabEnabled && process.env.ACME_EAB_KID && process.env.ACME_EAB_HMAC_KEY) { clientOpts.externalAccountBinding = { kid: process.env.ACME_EAB_KID, - hmacKey: process.env.ACME_EAB_HMAC_KEY + hmacKey: process.env.ACME_EAB_HMAC_KEY, }; } - describe('client', () => { const testDomain = `${uuid()}.${domainName}`; const testDomainAlpn = `${uuid()}.${domainName}`; const testDomainWildcard = `*.${testDomain}`; const testContact = `mailto:test-${uuid()}@nope.com`; - /** * Pebble CTS required */ - before(function() { + before(function () { if (!cts.isEnabled()) { this.skip(); } }); - /** * Key types */ @@ -58,18 +55,18 @@ describe('client', () => { createKeyFn: () => acme.crypto.createPrivateRsaKey(), createKeyAltFns: { s1024: () => acme.crypto.createPrivateRsaKey(1024), - s4096: () => acme.crypto.createPrivateRsaKey(4096) + s4096: () => acme.crypto.createPrivateRsaKey(4096), }, - jwkSpecFn: spec.jwk.rsa + jwkSpecFn: spec.jwk.rsa, }, ecdsa: { createKeyFn: () => acme.crypto.createPrivateEcdsaKey(), createKeyAltFns: { p384: () => acme.crypto.createPrivateEcdsaKey('P-384'), - p521: () => acme.crypto.createPrivateEcdsaKey('P-521') + p521: () => acme.crypto.createPrivateEcdsaKey('P-521'), }, - jwkSpecFn: spec.jwk.ecdsa - } + jwkSpecFn: spec.jwk.ecdsa, + }, }).forEach(([name, { createKeyFn, createKeyAltFns, jwkSpecFn }]) => { describe(name, () => { let testIssuers; @@ -97,7 +94,6 @@ describe('client', () => { let testCertificateAlpn; let testCertificateWildcard; - /** * Fixtures */ @@ -114,11 +110,11 @@ describe('client', () => { it('should generate certificate signing request', async () => { [, testCsr] = await acme.crypto.createCsr({ commonName: testDomain }, await createKeyFn()); - [, testCsrAlpn] = await acme.crypto.createCsr({ commonName: testDomainAlpn }, await createKeyFn()); - [, testCsrWildcard] = await acme.crypto.createCsr({ commonName: testDomainWildcard }, await createKeyFn()); + [, testCsrAlpn] = await acme.crypto.createCsr({ altNames: [testDomainAlpn] }, await createKeyFn()); + [, testCsrWildcard] = await acme.crypto.createCsr({ altNames: [testDomainWildcard] }, await createKeyFn()); }); - it('should resolve certificate issuers [ACME_CAP_ALTERNATE_CERT_ROOTS]', async function() { + it('should resolve certificate issuers [ACME_CAP_ALTERNATE_CERT_ROOTS]', async function () { if (!capAlternateCertRoots) { this.skip(); } @@ -134,7 +130,6 @@ describe('client', () => { }); }); - /** * Initialize clients */ @@ -142,7 +137,7 @@ describe('client', () => { it('should initialize client', () => { testClient = new acme.Client({ ...clientOpts, - accountKey: testAccountKey + accountKey: testAccountKey, }); }); @@ -151,12 +146,11 @@ describe('client', () => { jwkSpecFn(jwk); }); - /** * Terms of Service */ - it('should produce tos url [ACME_CAP_META_TOS_FIELD]', async function() { + it('should produce tos url [ACME_CAP_META_TOS_FIELD]', async function () { if (!capMetaTosField) { this.skip(); } @@ -165,7 +159,7 @@ describe('client', () => { assert.isString(tos); }); - it('should not produce tos url [!ACME_CAP_META_TOS_FIELD]', async function() { + it('should not produce tos url [!ACME_CAP_META_TOS_FIELD]', async function () { if (capMetaTosField) { this.skip(); } @@ -174,12 +168,11 @@ describe('client', () => { assert.isNull(tos); }); - /** * Create account */ - it('should refuse account creation without tos [ACME_CAP_META_TOS_FIELD]', async function() { + it('should refuse account creation without tos [ACME_CAP_META_TOS_FIELD]', async function () { if (!capMetaTosField) { this.skip(); } @@ -187,7 +180,7 @@ describe('client', () => { await assert.isRejected(testClient.createAccount()); }); - it('should refuse account creation without eab [ACME_CAP_EAB_ENABLED]', async function() { + it('should refuse account creation without eab [ACME_CAP_EAB_ENABLED]', async function () { if (!capEabEnabled) { this.skip(); } @@ -195,17 +188,17 @@ describe('client', () => { const client = new acme.Client({ ...clientOpts, accountKey: testAccountKey, - externalAccountBinding: null + externalAccountBinding: null, }); await assert.isRejected(client.createAccount({ - termsOfServiceAgreed: true + termsOfServiceAgreed: true, })); }); it('should create an account', async () => { testAccount = await testClient.createAccount({ - termsOfServiceAgreed: true + termsOfServiceAgreed: true, }); spec.rfc8555.account(testAccount); @@ -217,7 +210,6 @@ describe('client', () => { assert.isString(testAccountUrl); }); - /** * Create account with alternate key sizes */ @@ -226,11 +218,11 @@ describe('client', () => { it(`should create account with key=${k}`, async () => { const client = new acme.Client({ ...clientOpts, - accountKey: await altKeyFn() + accountKey: await altKeyFn(), }); const account = await client.createAccount({ - termsOfServiceAgreed: true + termsOfServiceAgreed: true, }); spec.rfc8555.account(account); @@ -238,7 +230,6 @@ describe('client', () => { }); }); - /** * Find existing account using secondary client */ @@ -246,22 +237,22 @@ describe('client', () => { it('should throw when trying to find account using invalid account key', async () => { const client = new acme.Client({ ...clientOpts, - accountKey: testAccountSecondaryKey + accountKey: testAccountSecondaryKey, }); await assert.isRejected(client.createAccount({ - onlyReturnExisting: true + onlyReturnExisting: true, })); }); it('should find existing account using account key', async () => { const client = new acme.Client({ ...clientOpts, - accountKey: testAccountKey + accountKey: testAccountKey, }); const account = await client.createAccount({ - onlyReturnExisting: true + onlyReturnExisting: true, }); spec.rfc8555.account(account); @@ -269,7 +260,6 @@ describe('client', () => { assert.deepStrictEqual(account.key, testAccount.key); }); - /** * Account URL */ @@ -278,7 +268,7 @@ describe('client', () => { const client = new acme.Client({ ...clientOpts, accountKey: testAccountKey, - accountUrl: 'https://acme-staging-v02.api.letsencrypt.org/acme/acct/1' + accountUrl: 'https://acme-staging-v02.api.letsencrypt.org/acme/acct/1', }); await assert.isRejected(client.updateAccount()); @@ -288,11 +278,11 @@ describe('client', () => { const client = new acme.Client({ ...clientOpts, accountKey: testAccountKey, - accountUrl: testAccountUrl + accountUrl: testAccountUrl, }); const account = await client.createAccount({ - onlyReturnExisting: true + onlyReturnExisting: true, }); spec.rfc8555.account(account); @@ -300,7 +290,6 @@ describe('client', () => { assert.deepStrictEqual(account.key, testAccount.key); }); - /** * Update account contact info */ @@ -316,12 +305,11 @@ describe('client', () => { assert.include(account.contact, testContact); }); - /** * Change account private key */ - it('should change account private key [ACME_CAP_UPDATE_ACCOUNT_KEY]', async function() { + it('should change account private key [ACME_CAP_UPDATE_ACCOUNT_KEY]', async function () { if (!capUpdateAccountKey) { this.skip(); } @@ -329,7 +317,7 @@ describe('client', () => { await testClient.updateAccountKey(testAccountSecondaryKey); const account = await testClient.createAccount({ - onlyReturnExisting: true + onlyReturnExisting: true, }); spec.rfc8555.account(account); @@ -337,7 +325,6 @@ describe('client', () => { assert.notDeepEqual(account.key, testAccount.key); }); - /** * Create new certificate order */ @@ -357,7 +344,6 @@ describe('client', () => { }); }); - /** * Get status of existing certificate order */ @@ -371,7 +357,6 @@ describe('client', () => { })); }); - /** * Get identifier authorization */ @@ -401,7 +386,6 @@ describe('client', () => { }); }); - /** * Generate challenge key authorization */ @@ -418,7 +402,6 @@ describe('client', () => { [testKeyAuthorization, testKeyAuthorizationAlpn, testKeyAuthorizationWildcard].forEach((k) => assert.isString(k)); }); - /** * Deactivate identifier authorization */ @@ -427,8 +410,8 @@ describe('client', () => { const order = await testClient.createOrder({ identifiers: [ { type: 'dns', value: `${uuid()}.${domainName}` }, - { type: 'dns', value: `${uuid()}.${domainName}` } - ] + { type: 'dns', value: `${uuid()}.${domainName}` }, + ], }); const authzCollection = await testClient.getAuthorizations(order); @@ -445,7 +428,6 @@ describe('client', () => { }); }); - /** * Verify satisfied challenge */ @@ -460,7 +442,6 @@ describe('client', () => { await testClient.verifyChallenge(testAuthzWildcard, testChallengeWildcard); }); - /** * Complete challenge */ @@ -474,7 +455,6 @@ describe('client', () => { })); }); - /** * Wait for valid challenge */ @@ -483,7 +463,6 @@ describe('client', () => { await Promise.all([testChallenge, testChallengeAlpn, testChallengeWildcard].map(async (c) => testClient.waitForValidStatus(c))); }); - /** * Finalize order */ @@ -500,7 +479,6 @@ describe('client', () => { assert.strictEqual(testOrderWildcard.url, finalizeWildcard.url); }); - /** * Wait for valid order */ @@ -509,7 +487,6 @@ describe('client', () => { await Promise.all([testOrder, testOrderAlpn, testOrderWildcard].map(async (o) => testClient.waitForValidStatus(o))); }); - /** * Get certificate */ @@ -525,7 +502,7 @@ describe('client', () => { }); }); - it('should get alternate certificate chain [ACME_CAP_ALTERNATE_CERT_ROOTS]', async function() { + it('should get alternate certificate chain [ACME_CAP_ALTERNATE_CERT_ROOTS]', async function () { if (!capAlternateCertRoots) { this.skip(); } @@ -539,7 +516,7 @@ describe('client', () => { })); }); - it('should get default chain with invalid preference [ACME_CAP_ALTERNATE_CERT_ROOTS]', async function() { + it('should get default chain with invalid preference [ACME_CAP_ALTERNATE_CERT_ROOTS]', async function () { if (!capAlternateCertRoots) { this.skip(); } @@ -551,7 +528,6 @@ describe('client', () => { assert.strictEqual(testIssuers[0], info.issuer.commonName); }); - /** * Revoke certificate */ @@ -568,7 +544,6 @@ describe('client', () => { await assert.isRejected(testClient.getCertificate(testOrderWildcard)); }); - /** * Deactivate account */ @@ -581,7 +556,6 @@ describe('client', () => { assert.strictEqual(account.status, 'deactivated'); }); - /** * Verify that no new orders can be made */ diff --git a/packages/core/acme-client/test/70-auto.spec.js b/packages/core/acme-client/test/70-auto.spec.js index b5fe270f..16812aac 100644 --- a/packages/core/acme-client/test/70-auto.spec.js +++ b/packages/core/acme-client/test/70-auto.spec.js @@ -18,17 +18,16 @@ const clientOpts = { directoryUrl, backoffAttempts: 5, backoffMin: 1000, - backoffMax: 5000 + backoffMax: 5000, }; if (capEabEnabled && process.env.ACME_EAB_KID && process.env.ACME_EAB_HMAC_KEY) { clientOpts.externalAccountBinding = { kid: process.env.ACME_EAB_KID, - hmacKey: process.env.ACME_EAB_HMAC_KEY + hmacKey: process.env.ACME_EAB_HMAC_KEY, }; } - describe('client.auto', () => { const testDomain = `${uuid()}.${domainName}`; const testHttpDomain = `${uuid()}.${domainName}`; @@ -40,21 +39,19 @@ describe('client.auto', () => { const testSanDomains = [ `${uuid()}.${domainName}`, `${uuid()}.${domainName}`, - `${uuid()}.${domainName}` + `${uuid()}.${domainName}`, ]; - /** * Pebble CTS required */ - before(function() { + before(function () { if (!cts.isEnabled()) { this.skip(); } }); - /** * Key types */ @@ -64,16 +61,16 @@ describe('client.auto', () => { createKeyFn: () => acme.crypto.createPrivateRsaKey(), createKeyAltFns: { s1024: () => acme.crypto.createPrivateRsaKey(1024), - s4096: () => acme.crypto.createPrivateRsaKey(4096) - } + s4096: () => acme.crypto.createPrivateRsaKey(4096), + }, }, ecdsa: { createKeyFn: () => acme.crypto.createPrivateEcdsaKey(), createKeyAltFns: { p384: () => acme.crypto.createPrivateEcdsaKey('P-384'), - p521: () => acme.crypto.createPrivateEcdsaKey('P-521') - } - } + p521: () => acme.crypto.createPrivateEcdsaKey('P-521'), + }, + }, }).forEach(([name, { createKeyFn, createKeyAltFns }]) => { describe(name, () => { let testIssuers; @@ -82,12 +79,11 @@ describe('client.auto', () => { let testSanCertificate; let testWildcardCertificate; - /** * Fixtures */ - it('should resolve certificate issuers [ACME_CAP_ALTERNATE_CERT_ROOTS]', async function() { + it('should resolve certificate issuers [ACME_CAP_ALTERNATE_CERT_ROOTS]', async function () { if (!capAlternateCertRoots) { this.skip(); } @@ -103,7 +99,6 @@ describe('client.auto', () => { }); }); - /** * Initialize client */ @@ -111,31 +106,30 @@ describe('client.auto', () => { it('should initialize client', async () => { testClient = new acme.Client({ ...clientOpts, - accountKey: await createKeyFn() + accountKey: await createKeyFn(), }); }); - /** * Invalid challenge response */ it('should throw on invalid challenge response', async () => { const [, csr] = await acme.crypto.createCsr({ - commonName: `${uuid()}.${domainName}` + commonName: `${uuid()}.${domainName}`, }, await createKeyFn()); await assert.isRejected(testClient.auto({ csr, termsOfServiceAgreed: true, challengeCreateFn: cts.challengeNoopFn, - challengeRemoveFn: cts.challengeNoopFn + challengeRemoveFn: cts.challengeNoopFn, }), /^authorization not found/i); }); it('should throw on invalid challenge response with opts.skipChallengeVerification=true', async () => { const [, csr] = await acme.crypto.createCsr({ - commonName: `${uuid()}.${domainName}` + commonName: `${uuid()}.${domainName}`, }, await createKeyFn()); await assert.isRejected(testClient.auto({ @@ -143,38 +137,37 @@ describe('client.auto', () => { termsOfServiceAgreed: true, skipChallengeVerification: true, challengeCreateFn: cts.challengeNoopFn, - challengeRemoveFn: cts.challengeNoopFn + challengeRemoveFn: cts.challengeNoopFn, })); }); - /** * Challenge function exceptions */ it('should throw on challengeCreate exception', async () => { const [, csr] = await acme.crypto.createCsr({ - commonName: `${uuid()}.${domainName}` + commonName: `${uuid()}.${domainName}`, }, await createKeyFn()); await assert.isRejected(testClient.auto({ csr, termsOfServiceAgreed: true, challengeCreateFn: cts.challengeThrowFn, - challengeRemoveFn: cts.challengeNoopFn + challengeRemoveFn: cts.challengeNoopFn, }), /^oops$/); }); it('should not throw on challengeRemove exception', async () => { const [, csr] = await acme.crypto.createCsr({ - commonName: `${uuid()}.${domainName}` + commonName: `${uuid()}.${domainName}`, }, await createKeyFn()); const cert = await testClient.auto({ csr, termsOfServiceAgreed: true, challengeCreateFn: cts.challengeCreateFn, - challengeRemoveFn: cts.challengeThrowFn + challengeRemoveFn: cts.challengeThrowFn, }); assert.isString(cert); @@ -188,8 +181,8 @@ describe('client.auto', () => { `${uuid()}.${domainName}`, `${uuid()}.${domainName}`, `${uuid()}.${domainName}`, - `${uuid()}.${domainName}` - ] + `${uuid()}.${domainName}`, + ], }, await createKeyFn()); await assert.isRejected(testClient.auto({ @@ -205,28 +198,27 @@ describe('client.auto', () => { results.push(true); return cts.challengeCreateFn(...args); }, - challengeRemoveFn: cts.challengeRemoveFn + challengeRemoveFn: cts.challengeRemoveFn, })); assert.strictEqual(results.length, 5); assert.deepStrictEqual(results, [false, false, false, true, true]); }); - /** * Order certificates */ it('should order certificate', async () => { const [, csr] = await acme.crypto.createCsr({ - commonName: testDomain + commonName: testDomain, }, await createKeyFn()); const cert = await testClient.auto({ csr, termsOfServiceAgreed: true, challengeCreateFn: cts.challengeCreateFn, - challengeRemoveFn: cts.challengeRemoveFn + challengeRemoveFn: cts.challengeRemoveFn, }); assert.isString(cert); @@ -235,7 +227,7 @@ describe('client.auto', () => { it('should order certificate using http-01', async () => { const [, csr] = await acme.crypto.createCsr({ - commonName: testHttpDomain + commonName: testHttpDomain, }, await createKeyFn()); const cert = await testClient.auto({ @@ -243,7 +235,7 @@ describe('client.auto', () => { termsOfServiceAgreed: true, challengeCreateFn: cts.assertHttpChallengeCreateFn, challengeRemoveFn: cts.challengeRemoveFn, - challengePriority: ['http-01'] + challengePriority: ['http-01'], }); assert.isString(cert); @@ -251,7 +243,7 @@ describe('client.auto', () => { it('should order certificate using https-01', async () => { const [, csr] = await acme.crypto.createCsr({ - commonName: testHttpsDomain + commonName: testHttpsDomain, }, await createKeyFn()); const cert = await testClient.auto({ @@ -259,7 +251,7 @@ describe('client.auto', () => { termsOfServiceAgreed: true, challengeCreateFn: cts.assertHttpsChallengeCreateFn, challengeRemoveFn: cts.challengeRemoveFn, - challengePriority: ['http-01'] + challengePriority: ['http-01'], }); assert.isString(cert); @@ -267,7 +259,7 @@ describe('client.auto', () => { it('should order certificate using dns-01', async () => { const [, csr] = await acme.crypto.createCsr({ - commonName: testDnsDomain + commonName: testDnsDomain, }, await createKeyFn()); const cert = await testClient.auto({ @@ -275,7 +267,7 @@ describe('client.auto', () => { termsOfServiceAgreed: true, challengeCreateFn: cts.assertDnsChallengeCreateFn, challengeRemoveFn: cts.challengeRemoveFn, - challengePriority: ['dns-01'] + challengePriority: ['dns-01'], }); assert.isString(cert); @@ -283,7 +275,7 @@ describe('client.auto', () => { it('should order certificate using tls-alpn-01', async () => { const [, csr] = await acme.crypto.createCsr({ - commonName: testAlpnDomain + commonName: testAlpnDomain, }, await createKeyFn()); const cert = await testClient.auto({ @@ -291,7 +283,7 @@ describe('client.auto', () => { termsOfServiceAgreed: true, challengeCreateFn: cts.assertTlsAlpnChallengeCreateFn, challengeRemoveFn: cts.challengeRemoveFn, - challengePriority: ['tls-alpn-01'] + challengePriority: ['tls-alpn-01'], }); assert.isString(cert); @@ -299,14 +291,14 @@ describe('client.auto', () => { it('should order san certificate', async () => { const [, csr] = await acme.crypto.createCsr({ - altNames: testSanDomains + altNames: testSanDomains, }, await createKeyFn()); const cert = await testClient.auto({ csr, termsOfServiceAgreed: true, challengeCreateFn: cts.challengeCreateFn, - challengeRemoveFn: cts.challengeRemoveFn + challengeRemoveFn: cts.challengeRemoveFn, }); assert.isString(cert); @@ -315,15 +307,14 @@ describe('client.auto', () => { it('should order wildcard certificate', async () => { const [, csr] = await acme.crypto.createCsr({ - commonName: testWildcardDomain, - altNames: [`*.${testWildcardDomain}`] + altNames: [testWildcardDomain, `*.${testWildcardDomain}`], }, await createKeyFn()); const cert = await testClient.auto({ csr, termsOfServiceAgreed: true, challengeCreateFn: cts.challengeCreateFn, - challengeRemoveFn: cts.challengeRemoveFn + challengeRemoveFn: cts.challengeRemoveFn, }); assert.isString(cert); @@ -332,7 +323,7 @@ describe('client.auto', () => { it('should order certificate with opts.skipChallengeVerification=true', async () => { const [, csr] = await acme.crypto.createCsr({ - commonName: `${uuid()}.${domainName}` + commonName: `${uuid()}.${domainName}`, }, await createKeyFn()); const cert = await testClient.auto({ @@ -340,20 +331,20 @@ describe('client.auto', () => { termsOfServiceAgreed: true, skipChallengeVerification: true, challengeCreateFn: cts.challengeCreateFn, - challengeRemoveFn: cts.challengeRemoveFn + challengeRemoveFn: cts.challengeRemoveFn, }); assert.isString(cert); }); - it('should order alternate certificate chain [ACME_CAP_ALTERNATE_CERT_ROOTS]', async function() { + it('should order alternate certificate chain [ACME_CAP_ALTERNATE_CERT_ROOTS]', async function () { if (!capAlternateCertRoots) { this.skip(); } await Promise.all(testIssuers.map(async (issuer) => { const [, csr] = await acme.crypto.createCsr({ - commonName: `${uuid()}.${domainName}` + commonName: `${uuid()}.${domainName}`, }, await createKeyFn()); const cert = await testClient.auto({ @@ -361,7 +352,7 @@ describe('client.auto', () => { termsOfServiceAgreed: true, preferredChain: issuer, challengeCreateFn: cts.challengeCreateFn, - challengeRemoveFn: cts.challengeRemoveFn + challengeRemoveFn: cts.challengeRemoveFn, }); const rootCert = acme.crypto.splitPemChain(cert).pop(); @@ -371,13 +362,13 @@ describe('client.auto', () => { })); }); - it('should get default chain with invalid preference [ACME_CAP_ALTERNATE_CERT_ROOTS]', async function() { + it('should get default chain with invalid preference [ACME_CAP_ALTERNATE_CERT_ROOTS]', async function () { if (!capAlternateCertRoots) { this.skip(); } const [, csr] = await acme.crypto.createCsr({ - commonName: `${uuid()}.${domainName}` + commonName: `${uuid()}.${domainName}`, }, await createKeyFn()); const cert = await testClient.auto({ @@ -385,7 +376,7 @@ describe('client.auto', () => { termsOfServiceAgreed: true, preferredChain: uuid(), challengeCreateFn: cts.challengeCreateFn, - challengeRemoveFn: cts.challengeRemoveFn + challengeRemoveFn: cts.challengeRemoveFn, }); const rootCert = acme.crypto.splitPemChain(cert).pop(); @@ -394,7 +385,6 @@ describe('client.auto', () => { assert.strictEqual(testIssuers[0], info.issuer.commonName); }); - /** * Order certificate with alternate key sizes */ @@ -402,21 +392,20 @@ describe('client.auto', () => { Object.entries(createKeyAltFns).forEach(([k, altKeyFn]) => { it(`should order certificate with key=${k}`, async () => { const [, csr] = await acme.crypto.createCsr({ - commonName: testDomain + commonName: testDomain, }, await altKeyFn()); const cert = await testClient.auto({ csr, termsOfServiceAgreed: true, challengeCreateFn: cts.challengeCreateFn, - challengeRemoveFn: cts.challengeRemoveFn + challengeRemoveFn: cts.challengeRemoveFn, }); assert.isString(cert); }); }); - /** * Read certificates */ diff --git a/packages/core/acme-client/test/challtestsrv.js b/packages/core/acme-client/test/challtestsrv.js index 71ed91b6..07878864 100644 --- a/packages/core/acme-client/test/challtestsrv.js +++ b/packages/core/acme-client/test/challtestsrv.js @@ -8,7 +8,6 @@ const axios = require('./../src/axios'); const apiBaseUrl = process.env.ACME_CHALLTESTSRV_URL || null; const httpsPort = axios.defaults.acmeSettings.httpsChallengePort || 443; - /** * Send request */ @@ -21,20 +20,18 @@ async function request(apiPath, data = {}) { await axios.request({ url: `${apiBaseUrl}/${apiPath}`, method: 'post', - data + data, }); return true; } - /** * State */ exports.isEnabled = () => !!apiBaseUrl; - /** * DNS */ @@ -42,7 +39,6 @@ exports.isEnabled = () => !!apiBaseUrl; exports.addDnsARecord = async (host, addresses) => request('add-a', { host, addresses }); exports.setDnsCnameRecord = async (host, target) => request('set-cname', { host, target }); - /** * Challenge response */ @@ -55,7 +51,7 @@ async function addHttps01ChallengeResponse(token, content, targetHostname) { await addHttp01ChallengeResponse(token, content); return request('add-redirect', { path: `/.well-known/acme-challenge/${token}`, - targetURL: `https://${targetHostname}:${httpsPort}/.well-known/acme-challenge/${token}` + targetURL: `https://${targetHostname}:${httpsPort}/.well-known/acme-challenge/${token}`, }); } @@ -72,7 +68,6 @@ exports.addHttps01ChallengeResponse = addHttps01ChallengeResponse; exports.addDns01ChallengeResponse = addDns01ChallengeResponse; exports.addTlsAlpn01ChallengeResponse = addTlsAlpn01ChallengeResponse; - /** * Challenge response mock functions */ diff --git a/packages/core/acme-client/test/get-cert-issuers.js b/packages/core/acme-client/test/get-cert-issuers.js index 8813b06e..0a4237ea 100644 --- a/packages/core/acme-client/test/get-cert-issuers.js +++ b/packages/core/acme-client/test/get-cert-issuers.js @@ -7,7 +7,6 @@ const util = require('./../src/util'); const pebbleManagementUrl = process.env.ACME_PEBBLE_MANAGEMENT_URL || null; - /** * Pebble */ @@ -26,7 +25,6 @@ async function getPebbleCertIssuers() { return info.map((i) => i.issuer.commonName); } - /** * Get certificate issuers */ diff --git a/packages/core/acme-client/test/setup.js b/packages/core/acme-client/test/setup.js index 4e0f5bee..9be01fc0 100644 --- a/packages/core/acme-client/test/setup.js +++ b/packages/core/acme-client/test/setup.js @@ -7,14 +7,12 @@ const chai = require('chai'); const chaiAsPromised = require('chai-as-promised'); const axios = require('./../src/axios'); - /** * Add promise support to Chai */ chai.use(chaiAsPromised); - /** * Challenge test server ports */ @@ -31,7 +29,6 @@ if (process.env.ACME_TLSALPN_PORT) { axios.defaults.acmeSettings.tlsAlpnChallengePort = process.env.ACME_TLSALPN_PORT; } - /** * External account binding */ diff --git a/packages/core/acme-client/test/spec.js b/packages/core/acme-client/test/spec.js index 3663e4f2..625c1965 100644 --- a/packages/core/acme-client/test/spec.js +++ b/packages/core/acme-client/test/spec.js @@ -7,7 +7,6 @@ const { assert } = require('chai'); const spec = {}; module.exports = spec; - /** * ACME */ @@ -120,7 +119,6 @@ spec.rfc8555.challenge = (obj) => { } }; - /** * Crypto */ @@ -150,7 +148,6 @@ spec.crypto.certificateInfo = (obj) => { assert.strictEqual(Object.prototype.toString.call(obj.notAfter), '[object Date]'); }; - /** * JWK */ diff --git a/packages/core/acme-client/types/index.d.ts b/packages/core/acme-client/types/index.d.ts index 3a58ad02..13455c3d 100644 --- a/packages/core/acme-client/types/index.d.ts +++ b/packages/core/acme-client/types/index.d.ts @@ -15,7 +15,6 @@ export type PublicKeyString = string; export type CertificateString = string; export type CsrString = string; - /** * Augmented ACME interfaces */ @@ -28,7 +27,6 @@ export interface Authorization extends rfc8555.Authorization { url: string; } - /** * Client */ @@ -80,7 +78,6 @@ export class Client { auto(opts: ClientAutoOptions): Promise; } - /** * Directory URLs */ @@ -99,7 +96,6 @@ export const directory: { } }; - /** * Crypto */ @@ -177,14 +173,12 @@ export interface CryptoLegacyInterface { export const forge: CryptoLegacyInterface; - /** * Axios */ export const axios: AxiosInstance; - /** * Logger */ diff --git a/packages/core/acme-client/types/index.test-d.ts b/packages/core/acme-client/types/index.test-d.ts index 5f19212a..db20f9a0 100644 --- a/packages/core/acme-client/types/index.test-d.ts +++ b/packages/core/acme-client/types/index.test-d.ts @@ -4,7 +4,6 @@ import * as acme from 'acme-client'; - (async () => { /* Client */ const accountKey = await acme.crypto.createPrivateKey(); diff --git a/packages/core/acme-client/types/rfc8555.d.ts b/packages/core/acme-client/types/rfc8555.d.ts index 2f88ab75..26b759bb 100644 --- a/packages/core/acme-client/types/rfc8555.d.ts +++ b/packages/core/acme-client/types/rfc8555.d.ts @@ -27,7 +27,6 @@ export interface AccountUpdateRequest { termsOfServiceAgreed?: boolean; } - /** * Order * @@ -53,7 +52,6 @@ export interface OrderCreateRequest { notAfter?: string; } - /** * Authorization * @@ -73,7 +71,6 @@ export interface Identifier { value: string; } - /** * Challenge * @@ -102,7 +99,6 @@ export interface DnsChallenge extends ChallengeAbstract { export type Challenge = HttpChallenge | DnsChallenge; - /** * Certificate *