@small-tech/auto-encrypt 2.3.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  Adds automatic provisioning and renewal of [Let’s Encrypt](https://letsencrypt.org) TLS certificates with [OCSP Stapling](https://letsencrypt.org/docs/integration-guide/#implement-ocsp-stapling) to [Node.js](https://nodejs.org) [https](https://nodejs.org/dist/latest-v12.x/docs/api/https.html) servers (including [Express.js](https://expressjs.com/), etc.)
4
4
 
5
- __Note:__ this is the CommonJS (CJS) branch of Auto Encrypt. Please see the main branch for the ECMAScript Modules (ESM) version. Security updates are backported to this branch.
6
-
7
5
  ## How it works
8
6
 
9
7
  The first time your web site is hit, it will take a couple of seconds to load as your Let’s Encrypt TLS certificates are automatically provisioned for you. From there on, your certificates will be seamlessly renewed 30 days before their expiry date.
@@ -13,7 +11,7 @@ When not provisioning certificates, Auto Encrypt will also forward HTTP calls to
13
11
  ## Installation
14
12
 
15
13
  ```sh
16
- npm i @small-tech/auto-encrypt@cjs
14
+ npm i @small-tech/auto-encrypt
17
15
  ```
18
16
 
19
17
  ## Usage
@@ -23,7 +21,7 @@ npm i @small-tech/auto-encrypt@cjs
23
21
  1. Import the module:
24
22
 
25
23
  ```js
26
- const AutoEncrypt = require('@small-tech/auto-encrypt')
24
+ import AutoEncrypt from '@small-tech/auto-encrypt'
27
25
  ```
28
26
 
29
27
  2. Prefix your server creation code with a reference to the Auto Encrypt class:
@@ -47,7 +45,7 @@ The following code creates an HTTPS server running on port 443 with [OCSP Stapli
47
45
 
48
46
 
49
47
  ```js
50
- const AutoEncrypt = require('@small-tech/auto-encrypt')
48
+ import AutoEncrypt from '@small-tech/auto-encrypt'
51
49
 
52
50
  const server = AutoEncrypt.https.createServer((request, response) => {
53
51
  response.end('Hello, world')
@@ -75,7 +73,7 @@ You can specify the domains you want the certificate to support, whether the Let
75
73
  ### Example
76
74
 
77
75
  ```js
78
- const AutoEncrypt = require('@small-tech/auto-encrypt')
76
+ import AutoEncrypt from '@small-tech/auto-encrypt'
79
77
 
80
78
  const options = {
81
79
  // Regular HTTPS server and TLS server options, if any, go here.
@@ -113,7 +111,7 @@ If you want to help improve Auto Encrypt or better understand how it is structur
113
111
  ### Regular https
114
112
 
115
113
  ```js
116
- const AutoEncrypt = require('@small-tech/auto-encrypt')
114
+ import AutoEncrypt from '@small-tech/auto-encrypt'
117
115
 
118
116
  const server = AutoEncrypt.https.createServer({ domains: ['dev.ar.al'] }, (request, response) => {
119
117
  response.end('Hello, world!')
@@ -134,7 +132,7 @@ server.close(() => {
134
132
 
135
133
  ```js
136
134
  const express = require('express')
137
- const AutoEncrypt = require('@small-tech/auto-encrypt')
135
+ import AutoEncrypt from '@small-tech/auto-encrypt'
138
136
 
139
137
  const app = express()
140
138
  app.get('/', (request, response) => {
@@ -221,7 +219,7 @@ A complete [small technology](https://small-tech.org/about/#small-technology) to
221
219
 
222
220
  ## Tests and coverage
223
221
 
224
- This project aims for > 80% coverage. At a recent check, coverage was at 95.29% (statements), 82.69% (branch), 95.19% (functions), 95.68% (lines).
222
+ This project aims for > 80% coverage. At a recent check, coverage was at 97.42% (statements), 92.64% (branch), 91.49% (functions), 97.42% (lines).
225
223
 
226
224
  To see the current state of code coverage, run `npm run coverage`.
227
225
 
@@ -268,7 +266,7 @@ We exist in part thanks to patronage by people like you. If you share [our visio
268
266
 
269
267
  ## Copyright
270
268
 
271
- © 2020 - present [Aral Balkan](https://ar.al), [Small Technology Foundation](https://small-tech.org).
269
+ © 2020-present [Aral Balkan](https://ar.al), [Small Technology Foundation](https://small-tech.org).
272
270
 
273
271
  Let’s Encrypt is a trademark of the Internet Security Research Group (ISRG). All rights reserved. Node.js is a trademark of Joyent, Inc. and is used with its permission. We are not endorsed by or affiliated with Joyent or ISRG.
274
272
 
package/index.js CHANGED
@@ -11,19 +11,18 @@
11
11
  * @copyright © 2020 Aral Balkan, Small Technology Foundation.
12
12
  * @license AGPLv3 or later.
13
13
  */
14
-
15
- const os = require('os')
16
- const util = require('util')
17
- const https = require('https')
18
- const ocsp = require('ocsp')
19
- const monkeyPatchTls = require('./lib/staging/monkeyPatchTls')
20
- const LetsEncryptServer = require('./lib/LetsEncryptServer')
21
- const Configuration = require('./lib/Configuration')
22
- const Certificate = require('./lib/Certificate')
23
- const Pluralise = require('./lib/util/Pluralise')
24
- const Throws = require('./lib/util/Throws')
25
- const HttpServer = require('./lib/HttpServer')
26
- const log = require('./lib/util/log')
14
+ import os from 'os'
15
+ import util from 'util'
16
+ import https from 'https'
17
+ import ocsp from 'ocsp'
18
+ import monkeyPatchTls from './lib/staging/monkeyPatchTls.js'
19
+ import LetsEncryptServer from './lib/LetsEncryptServer.js'
20
+ import Configuration from './lib/Configuration.js'
21
+ import Certificate from './lib/Certificate.js'
22
+ import Pluralise from './lib/util/Pluralise.js'
23
+ import Throws from './lib/util/Throws.js'
24
+ import HttpServer from './lib/HttpServer.js'
25
+ import log from './lib/util/log.js'
27
26
 
28
27
  // Custom errors thrown by the autoEncrypt function.
29
28
  const throws = new Throws({
@@ -44,13 +43,13 @@ const throws = new Throws({
44
43
  * @alias module:@small-tech/auto-encrypt
45
44
  * @hideconstructor
46
45
  */
47
- class AutoEncrypt {
48
- static #letsEncryptServer = null
49
- static #defaultDomains = null
50
- static #domains = null
51
- static #settingsPath = null
52
- static #listener = null
53
- static #certificate = null
46
+ export default class AutoEncrypt {
47
+ static letsEncryptServer = null
48
+ static defaultDomains = null
49
+ static domains = null
50
+ static settingsPath = null
51
+ static listener = null
52
+ static certificate = null
54
53
 
55
54
  /**
56
55
  * Enumeration.
@@ -66,7 +65,7 @@ class AutoEncrypt {
66
65
  * people to add AutoEncrypt to their existing apps by requiring the module
67
66
  * and prefixing their https.createServer(…) line with AutoEncrypt:
68
67
  *
69
- * @example const AutoEncrypt = require('@small-tech/auto-encrypt')
68
+ * @example import AutoEncrypt from '@small-tech/auto-encrypt'
70
69
  * const server = AutoEncrypt.https.createServer()
71
70
  *
72
71
  * @static
@@ -74,7 +73,7 @@ class AutoEncrypt {
74
73
  static get https () { return AutoEncrypt }
75
74
 
76
75
 
77
- static #ocspCache = null
76
+ static ocspCache = null
78
77
 
79
78
  /**
80
79
  * Automatically manages Let’s Encrypt certificate provisioning and renewal for Node.js
@@ -144,12 +143,12 @@ class AutoEncrypt {
144
143
  const configuration = new Configuration({ settingsPath, domains, server: letsEncryptServer})
145
144
  const certificate = new Certificate(configuration)
146
145
 
147
- this.#letsEncryptServer = letsEncryptServer
148
- this.#defaultDomains = defaultDomains
149
- this.#domains = domains
150
- this.#settingsPath = settingsPath
151
- this.#listener = listener
152
- this.#certificate = certificate
146
+ this.letsEncryptServer = letsEncryptServer
147
+ this.defaultDomains = defaultDomains
148
+ this.domains = domains
149
+ this.settingsPath = settingsPath
150
+ this.listener = listener
151
+ this.certificate = certificate
153
152
 
154
153
  function sniError (symbolName, callback, emoji, ...args) {
155
154
  const error = Symbol.for(symbolName)
@@ -227,7 +226,7 @@ class AutoEncrypt {
227
226
  */
228
227
  static shutdown () {
229
228
  this.clearOcspCacheTimers()
230
- this.#certificate.stopCheckingForRenewal()
229
+ this.certificate.stopCheckingForRenewal()
231
230
  }
232
231
 
233
232
  //
@@ -255,7 +254,7 @@ class AutoEncrypt {
255
254
  // By turning on OCSP Stapling, you can improve the performance of your website, provide better privacy protections
256
255
  // … and help Let’s Encrypt efficiently serve as many people as possible.
257
256
  //
258
- // (Source: https://letsencrypt.org/docs/integration-guide/#implement-ocsp-stapling)
257
+ // (Source: https://letsencrypt.org/docs/integration-guide/implement-ocsp-stapling)
259
258
 
260
259
  this.ocspCache = new ocsp.Cache()
261
260
  const cache = this.ocspCache
@@ -295,12 +294,12 @@ class AutoEncrypt {
295
294
  // Custom object description for console output (for debugging).
296
295
  static [util.inspect.custom] () {
297
296
  return `
298
- # AutoEncrypt (static class)
297
+ # AutoEncrypt (static class)
299
298
 
300
- - Using Let’s Encrypt ${this.#letsEncryptServer.name} server.
301
- - Managing TLS for ${this.#domains.toString().replace(',', ', ')}${this.#domains === this.#defaultDomains ? ' (default domains)' : ''}.
302
- - Settings stored at ${this.#settingsPath === null ? 'default settings path' : this.#settingsPath}.
303
- - Listener ${typeof this.#listener === 'function' ? 'is set' : 'not set'}.
299
+ - Using Let’s Encrypt ${this.letsEncryptServer.name} server.
300
+ - Managing TLS for ${this.domains.toString().replace(',', ', ')}${this.domains === this.defaultDomains ? ' (default domains)' : ''}.
301
+ - Settings stored at ${this.settingsPath === null ? 'default settings path' : this.settingsPath}.
302
+ - Listener ${typeof this.listener === 'function' ? 'is set' : 'not set'}.
304
303
  `
305
304
  }
306
305
 
@@ -308,5 +307,3 @@ class AutoEncrypt {
308
307
  throws.error(Symbol.for('StaticClassCannotBeInstantiatedError'))
309
308
  }
310
309
  }
311
-
312
- module.exports = AutoEncrypt
package/lib/Account.js CHANGED
@@ -14,15 +14,15 @@
14
14
  //
15
15
  ////////////////////////////////////////////////////////////////////////////////
16
16
 
17
- const fs = require('fs-extra')
18
- const Throws = require('./util/Throws')
19
- const NewAccountRequest = require('./acme-requests/NewAccountRequest')
17
+ import fs from 'fs'
18
+ import Throws from './util/Throws.js'
19
+ import NewAccountRequest from './acme-requests/NewAccountRequest.js'
20
20
 
21
21
  const throws = new Throws({
22
22
  // No custom errors are thrown by this class.
23
23
  })
24
24
 
25
- class Account {
25
+ export default class Account {
26
26
  //
27
27
  // Async factory method.
28
28
  //
@@ -65,5 +65,3 @@ class Account {
65
65
  get kid () { return this.data.kid }
66
66
  set kid (value) { throws.error(Symbol.for('ReadOnlyAccessorError'), 'kid') }
67
67
  }
68
-
69
- module.exports = Account
@@ -6,12 +6,12 @@
6
6
  * @license AGPLv3 or later.
7
7
  */
8
8
 
9
- const jose = require('jose')
10
- const prepareRequest = require('bent')
11
- const types = require('../typedefs/lib/AcmeRequest')
12
- const Nonce = require('./Nonce')
13
- const Throws = require('./util/Throws')
14
- const log = require('./util/log')
9
+ import jose from 'jose'
10
+ import prepareRequest from 'bent'
11
+ import types from '../typedefs/lib/AcmeRequest.js'
12
+ import Nonce from './Nonce.js'
13
+ import Throws from './util/Throws.js'
14
+ import log from './util/log.js'
15
15
 
16
16
  const throws = new Throws({
17
17
  [Symbol.for('AcmeRequest.classNotInitialisedError')]:
@@ -28,33 +28,33 @@ const throws = new Throws({
28
28
  *
29
29
  * @alias module:lib/AcmeRequest
30
30
  */
31
- class AcmeRequest {
32
- static #initialised = false
33
- static #directory = null
34
- static #accountIdentity = null
35
- static #nonce = null
36
- static #account = null
31
+ export default class AcmeRequest {
32
+ static initialised = false
33
+ static directory = null
34
+ static accountIdentity = null
35
+ static nonce = null
36
+ static __account = null
37
37
 
38
38
  static initialise (directory = throws.ifMissing(), accountIdentity = throws.ifMissing()) {
39
- this.#directory = directory
40
- this.#accountIdentity = accountIdentity
41
- this.#nonce = new Nonce(directory)
42
- this.#initialised = true
39
+ this.directory = directory
40
+ this.accountIdentity = accountIdentity
41
+ this.nonce = new Nonce(directory)
42
+ this.initialised = true
43
43
  }
44
44
 
45
45
  static uninitialise () {
46
- this.#directory = null
47
- this.#accountIdentity = null
48
- this.#nonce = null
49
- this.#account = null
50
- this.#initialised = false
46
+ this.directory = null
47
+ this.accountIdentity = null
48
+ this.nonce = null
49
+ this.__account = null
50
+ this.initialised = false
51
51
  }
52
52
 
53
- static set account (_account = throws.ifMissing()) { this.#account = _account }
54
- static get account () { return this.#account }
53
+ static set account (_account = throws.ifMissing()) { this.__account = _account }
54
+ static get account () { return this.__account }
55
55
 
56
56
  constructor () {
57
- if (!AcmeRequest.#initialised) {
57
+ if (!AcmeRequest.initialised) {
58
58
  throws.error(Symbol.for('AcmeRequest.classNotInitialisedError'))
59
59
  }
60
60
  }
@@ -145,7 +145,7 @@ class AcmeRequest {
145
145
 
146
146
  // Always save the fresh nonce returned from API calls.
147
147
  const freshNonce = response.headers['replay-nonce']
148
- AcmeRequest.#nonce.set(freshNonce)
148
+ AcmeRequest.nonce.set(freshNonce)
149
149
 
150
150
  // The response returned is the raw response object. Let’s consume
151
151
  // it and return a more relevant response.
@@ -208,11 +208,11 @@ class AcmeRequest {
208
208
  // ===== the arguments array as the latter does not reflect default parameters.
209
209
  const originalRequestDetails = [command, payload, useKid, successCodes, url, nonce]
210
210
 
211
- url = url || AcmeRequest.#directory[`${command}Url`]
211
+ url = url || AcmeRequest.directory[`${command}Url`]
212
212
 
213
213
  const protectedHeader = {
214
214
  alg: 'RS256',
215
- nonce: nonce || await AcmeRequest.#nonce.get(),
215
+ nonce: nonce || await AcmeRequest.nonce.get(),
216
216
  url
217
217
  }
218
218
 
@@ -221,10 +221,10 @@ class AcmeRequest {
221
221
  protectedHeader.kid = AcmeRequest.account.kid
222
222
  } else {
223
223
  // If we’re not using the kid, we must use the public JWK (see RFC 8555 § 6.2 Request Authentication)
224
- protectedHeader.jwk = AcmeRequest.#accountIdentity.publicJWK
224
+ protectedHeader.jwk = AcmeRequest.accountIdentity.publicJWK
225
225
  }
226
226
 
227
- const signedRequest = jose.JWS.sign.flattened(payload, AcmeRequest.#accountIdentity.key, protectedHeader)
227
+ const signedRequest = jose.JWS.sign.flattened(payload, AcmeRequest.accountIdentity.key, protectedHeader)
228
228
 
229
229
  const httpsHeaders = {
230
230
  'Content-Type': 'application/jose+json',
@@ -244,6 +244,3 @@ class AcmeRequest {
244
244
  }
245
245
  }
246
246
  }
247
-
248
- module.exports = AcmeRequest
249
-
@@ -13,14 +13,14 @@
13
13
  //
14
14
  ////////////////////////////////////////////////////////////////////////////////
15
15
 
16
- const EventEmitter = require('events')
17
- const log = require('./util/log')
18
- const AuthorisationRequest = require('./acme-requests/AuthorisationRequest')
19
- const ReadyForChallengeValidationRequest = require('./acme-requests/ReadyForChallengeValidationRequest')
20
- const HttpServer = require('./HttpServer')
21
- const waitFor = require('./util/waitFor')
16
+ import EventEmitter from 'events'
17
+ import log from './util/log.js'
18
+ import AuthorisationRequest from './acme-requests/AuthorisationRequest.js'
19
+ import ReadyForChallengeValidationRequest from './acme-requests/ReadyForChallengeValidationRequest.js'
20
+ import HttpServer from './HttpServer.js'
21
+ import waitFor from './util/waitFor.js'
22
22
 
23
- class Authorisation extends EventEmitter {
23
+ export default class Authorisation extends EventEmitter {
24
24
 
25
25
  // Async factory method. Use this to instantiate.
26
26
  // TODO: add check to ensure factory method is used.
@@ -181,5 +181,3 @@ class Authorisation extends EventEmitter {
181
181
  }
182
182
  }
183
183
  }
184
-
185
- module.exports = Authorisation
@@ -6,19 +6,19 @@
6
6
  * @license AGPLv3 or later.
7
7
  */
8
8
 
9
- const fs = require('fs-extra')
10
- const tls = require('tls')
11
- const util = require('util')
12
- const moment = require('moment')
13
- const log = require('./util/log')
14
- const x509 = require('./x.509/rfc5280')
15
- const Account = require('./Account')
16
- const AccountIdentity = require('./identities/AccountIdentity')
17
- const Directory = require('./Directory')
18
- const Order = require('./Order')
19
- const CertificateIdentity = require('./identities/CertificateIdentity')
20
- const AcmeRequest = require('./AcmeRequest')
21
- const Throws = require('./util/Throws')
9
+ import fs from 'fs'
10
+ import tls from 'tls'
11
+ import util from 'util'
12
+ import moment from 'moment'
13
+ import log from './util/log.js'
14
+ import { Certificate as X509Certificate } from './x.509/rfc5280.js'
15
+ import Account from './Account.js'
16
+ import AccountIdentity from './identities/AccountIdentity.js'
17
+ import Directory from './Directory.js'
18
+ import Order from './Order.js'
19
+ import CertificateIdentity from './identities/CertificateIdentity.js'
20
+ import AcmeRequest from './AcmeRequest.js'
21
+ import Throws from './util/Throws.js'
22
22
 
23
23
  const throws = new Throws({
24
24
  // No custom errors are thrown by this class.
@@ -30,7 +30,7 @@ const throws = new Throws({
30
30
  * @alias module:lib/Certificate
31
31
  * @param {String[]} domains List of domains this certificate covers.
32
32
  */
33
- class Certificate {
33
+ export default class Certificate {
34
34
  /**
35
35
  * Get a SecureContext that can be used in an SNICallback.
36
36
  *
@@ -174,13 +174,11 @@ class Certificate {
174
174
  // written but before we had a chance to clean up the old files.)
175
175
  if (fs.existsSync(certificateIdentityPath) && fs.existsSync(certificatePath)) {
176
176
  log(' 🚑 ❨auto-encrypt❩ A new certificate was also found. Going to delete the old one and use that.')
177
- fs.removeSync(oldCertificateIdentityPath)
178
- fs.removeSync(oldCertificatePath)
177
+ fs.rmSync(oldCertificateIdentityPath)
178
+ fs.rmSync(oldCertificatePath)
179
179
  } else {
180
180
  // The renewal process must have failed. Delete any previous state and restore the old certificate.
181
181
  log(' 🚑 ❨auto-encrypt❩ Cleaning up previous state and restoring old certificate…')
182
- fs.removeSync(certificateIdentityPath)
183
- fs.removeSync(certificatePath)
184
182
  fs.renameSync(oldCertificateIdentityPath, certificateIdentityPath)
185
183
  fs.renameSync(oldCertificatePath, certificatePath)
186
184
  }
@@ -278,15 +276,13 @@ class Certificate {
278
276
 
279
277
  //
280
278
  // In case old files were left behind, remove them first and then rename the current files.
281
- // (If the directory doesn’t exist, fs.removeSync() will silently do nothing.)
279
+ // (If the directory doesn’t exist, will silently do nothing.)
282
280
  //
283
281
  const certificateIdentityPath = this.#configuration.certificateIdentityPath
284
282
  const oldCertificateIdentityPath = `${certificateIdentityPath}.old`
285
283
  const certificatePath = this.#configuration.certificatePath
286
284
  const oldCertificatePath = `${certificatePath}.old`
287
285
 
288
- fs.removeSync(oldCertificateIdentityPath)
289
- fs.removeSync(oldCertificatePath)
290
286
  fs.renameSync(certificateIdentityPath, oldCertificateIdentityPath)
291
287
  fs.renameSync(certificatePath, oldCertificatePath)
292
288
 
@@ -296,8 +292,8 @@ class Certificate {
296
292
  await this.createSecureContext(/* renewCertificate = */ true)
297
293
 
298
294
  // Delete the backup of the old certificate.
299
- fs.removeSync(oldCertificateIdentityPath)
300
- fs.removeSync(oldCertificatePath)
295
+ fs.rmSync(oldCertificateIdentityPath)
296
+ fs.rmSync(oldCertificatePath)
301
297
  }
302
298
 
303
299
 
@@ -367,7 +363,7 @@ class Certificate {
367
363
  }
368
364
 
369
365
  parseDetails (certificatePem) {
370
- const certificate = (x509.Certificate.decode(certificatePem, 'pem', {label: 'CERTIFICATE'})).tbsCertificate
366
+ const certificate = (X509Certificate.decode(certificatePem, 'pem', {label: 'CERTIFICATE'})).tbsCertificate
371
367
 
372
368
  const serialNumber = certificate.serialNumber
373
369
  const issuer = certificate.issuer.value[0][0].value.toString('utf-8').slice(2).trim()
@@ -417,5 +413,3 @@ class Certificate {
417
413
  `
418
414
  }
419
415
  }
420
-
421
- module.exports = Certificate
@@ -7,13 +7,13 @@
7
7
  * @license AGPLv3 or later.
8
8
  */
9
9
 
10
- const os = require('os')
11
- const fs = require('fs-extra')
12
- const path = require('path')
13
- const util = require('util')
14
- const crypto = require('crypto')
15
- const log = require('./util/log')
16
- const Throws = require('./util/Throws')
10
+ import os from 'os'
11
+ import fs from 'fs'
12
+ import path from 'path'
13
+ import util from 'util'
14
+ import crypto from 'crypto'
15
+ import log from './util/log.js'
16
+ import Throws from './util/Throws.js'
17
17
 
18
18
  // Custom errors thrown by this class.
19
19
  const throws = new Throws({
@@ -26,11 +26,17 @@ function isAnArrayOfStrings (object) {
26
26
  return Array.isArray(object) && containsOnlyStrings(object)
27
27
  }
28
28
 
29
+ function ensureDirSync (directory) {
30
+ if (!fs.existsSync(directory)) {
31
+ fs.mkdirSync(directory, { recursive: true })
32
+ }
33
+ }
34
+
29
35
  /**
30
36
  * @alias module:lib/Configuration
31
37
  * @hideconstructor
32
38
  */
33
- class Configuration {
39
+ export default class Configuration {
34
40
  #server = null
35
41
  #domains = null
36
42
  #settingsPath = null
@@ -73,7 +79,7 @@ class Configuration {
73
79
  }
74
80
 
75
81
  // And ensure that the settings path exists in the file system.
76
- fs.ensureDirSync(this.#settingsPath)
82
+ ensureDirSync(this.#settingsPath)
77
83
 
78
84
  //
79
85
  // Create account paths.
@@ -106,7 +112,7 @@ class Configuration {
106
112
  this.#certificateDirectoryPath = path.join(this.#settingsPath, certificateDirectoryName)
107
113
 
108
114
  // And ensure that the certificate directory path exists in the file system.
109
- fs.ensureDirSync(this.#certificateDirectoryPath)
115
+ ensureDirSync(this.#certificateDirectoryPath)
110
116
 
111
117
  this.#certificatePath = path.join(this.#certificateDirectoryPath, 'certificate.pem')
112
118
  this.#certificateIdentityPath = path.join(this.#certificateDirectoryPath, 'certificate-identity.pem')
@@ -230,4 +236,3 @@ class Configuration {
230
236
  `
231
237
  }
232
238
  }
233
- module.exports = Configuration
package/lib/Directory.js CHANGED
@@ -11,25 +11,25 @@
11
11
  //
12
12
  ////////////////////////////////////////////////////////////////////////////////
13
13
 
14
- const util = require('util')
15
- const prepareRequest = require('bent')
16
- const log = require('./util/log')
17
- const Throws = require('./util/Throws')
14
+ import util from 'util'
15
+ import prepareRequest from 'bent'
16
+ import log from './util/log.js'
17
+ import Throws from './util/Throws.js'
18
18
 
19
19
  const throws = new Throws()
20
20
 
21
- class Directory {
22
- #directory = null
23
- #letsEncryptServer = null
24
- #directoryRequest = null
21
+ export default class Directory {
22
+ directory = null
23
+ letsEncryptServer = null
24
+ directoryRequest = null
25
25
 
26
26
  //
27
27
  // Factory method access (async).
28
28
  //
29
- static #isBeingInstantiatedViaAsyncFactoryMethod = false
29
+ static isBeingInstantiatedViaAsyncFactoryMethod = false
30
30
 
31
31
  static async getInstanceAsync (configuration = throws.ifMissing()) {
32
- Directory.#isBeingInstantiatedViaAsyncFactoryMethod = true
32
+ Directory.isBeingInstantiatedViaAsyncFactoryMethod = true
33
33
  const directory = new Directory(configuration)
34
34
  await directory.getUrls()
35
35
  return directory
@@ -40,13 +40,13 @@ class Directory {
40
40
  //
41
41
 
42
42
  // Directory URLs.
43
- get keyChangeUrl() { return this.#directory.keyChange }
44
- get newAccountUrl() { return this.#directory.newAccount }
45
- get newNonceUrl() { return this.#directory.newNonce }
46
- get newOrderUrl() { return this.#directory.newOrder }
47
- get revokeCertUrl() { return this.#directory.revokeCert }
48
- get termsOfServiceUrl() { return this.#directory.meta.termsOfService }
49
- get websiteUrl() { return this.#directory.meta.website }
43
+ get keyChangeUrl() { return this.directory.keyChange }
44
+ get newAccountUrl() { return this.directory.newAccount }
45
+ get newNonceUrl() { return this.directory.newNonce }
46
+ get newOrderUrl() { return this.directory.newOrder }
47
+ get revokeCertUrl() { return this.directory.revokeCert }
48
+ get termsOfServiceUrl() { return this.directory.meta.termsOfService }
49
+ get websiteUrl() { return this.directory.meta.website }
50
50
 
51
51
  //
52
52
  // Private.
@@ -54,28 +54,28 @@ class Directory {
54
54
 
55
55
  constructor(configuration) {
56
56
  // Ensure async factory method instantiation.
57
- if (Directory.#isBeingInstantiatedViaAsyncFactoryMethod === false) {
57
+ if (Directory.isBeingInstantiatedViaAsyncFactoryMethod === false) {
58
58
  throws.error(Symbol.for('MustBeInstantiatedViaAsyncFactoryMethodError'), 'Directory')
59
59
  }
60
- Directory.#isBeingInstantiatedViaAsyncFactoryMethod = false
60
+ Directory.isBeingInstantiatedViaAsyncFactoryMethod = false
61
61
 
62
- this.#letsEncryptServer = configuration.server
63
- this.#directoryRequest = prepareRequest('GET', 'json', this.#letsEncryptServer.endpoint)
62
+ this.letsEncryptServer = configuration.server
63
+ this.directoryRequest = prepareRequest('GET', 'json', this.letsEncryptServer.endpoint)
64
64
 
65
- log(` 📕 ❨auto-encrypt❩ Directory is using endpoint ${this.#letsEncryptServer.endpoint}`)
65
+ log(` 📕 ❨auto-encrypt❩ Directory is using endpoint ${this.letsEncryptServer.endpoint}`)
66
66
  }
67
67
 
68
68
  // (Async) Fetches the latest Urls from the Let’s Encrypt ACME endpoint being used.
69
69
  // This will throw if the request fails. Ensure that you catch the error when
70
70
  // using it.
71
- async getUrls() { this.#directory = await this.#directoryRequest() }
71
+ async getUrls() { this.directory = await this.directoryRequest() }
72
72
 
73
73
  // Custom object description for console output (for debugging).
74
74
  [util.inspect.custom] () {
75
75
  return `
76
76
  # Directory
77
77
 
78
- Endpoint: ${this.#letsEncryptServer.endpoint}
78
+ Endpoint: ${this.letsEncryptServer.endpoint}
79
79
 
80
80
  ## URLs:
81
81
 
@@ -89,5 +89,3 @@ class Directory {
89
89
  `
90
90
  }
91
91
  }
92
-
93
- module.exports = Directory