@small-tech/auto-encrypt 5.0.1 → 5.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/index.d.ts +3 -0
- package/index.js +50 -32
- package/lib/IPAddresses.js +5 -1
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -20,6 +20,9 @@ import { Server, ServerOptions } from 'node:https'
|
|
|
20
20
|
import { SecureContext } from 'node:tls'
|
|
21
21
|
import { IncomingMessage, ServerResponse } from 'node:http'
|
|
22
22
|
|
|
23
|
+
import IPAddresses from './lib/IPAddresses.js'
|
|
24
|
+
export { IPAddresses }
|
|
25
|
+
|
|
23
26
|
/**
|
|
24
27
|
Options for creating an AutoEncrypt server. Extends Node’s https.ServerOptions.
|
|
25
28
|
*/
|
package/index.js
CHANGED
|
@@ -16,9 +16,10 @@
|
|
|
16
16
|
@license AGPLv3 or later.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import os from 'os'
|
|
20
|
-
import util from 'util'
|
|
21
|
-
import
|
|
19
|
+
import os from 'node:os'
|
|
20
|
+
import util from 'node:util'
|
|
21
|
+
import net from 'node:net'
|
|
22
|
+
import https from 'node:https'
|
|
22
23
|
import monkeyPatchTls from './lib/staging/monkeyPatchTls.js'
|
|
23
24
|
import LetsEncryptServer from './lib/LetsEncryptServer.js'
|
|
24
25
|
import Configuration from './lib/Configuration.js'
|
|
@@ -28,11 +29,9 @@ import Pluralise from './lib/util/Pluralise.js'
|
|
|
28
29
|
import Throws from './lib/util/Throws.js'
|
|
29
30
|
import HttpServer from './lib/HttpServer.js'
|
|
30
31
|
import IPAddresses from './lib/IPAddresses.js'
|
|
32
|
+
export { IPAddresses }
|
|
31
33
|
import log from './lib/util/log.js'
|
|
32
34
|
|
|
33
|
-
// Use module-level await to ensure we have the IP address information we need.
|
|
34
|
-
const ipAddresses = await IPAddresses.getInstanceAsync()
|
|
35
|
-
|
|
36
35
|
// Custom errors thrown by the autoEncrypt function.
|
|
37
36
|
const throws = new Throws({
|
|
38
37
|
[Symbol.for('BusyProvisioningCertificateError')]:
|
|
@@ -152,37 +151,56 @@ export default class AutoEncrypt {
|
|
|
152
151
|
defaultPebbleDomains.push('pebble')
|
|
153
152
|
}
|
|
154
153
|
|
|
155
|
-
if
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
154
|
+
// Check if the passed list of domains contains an IP address. If it does, we can skip our automatic IP address detection and use the provides ones.
|
|
155
|
+
let domainsListContainsAtLeastOneIPAddress = false
|
|
156
|
+
if (options.domains) {
|
|
157
|
+
const ip = options.domains.find(domain => net.isIP(domain) !== 0)
|
|
158
|
+
if (ip !== undefined) {
|
|
159
|
+
domainsListContainsAtLeastOneIPAddress = true
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (!domainsListContainsAtLeastOneIPAddress) {
|
|
164
|
+
// Domains list does not contain any IP addresses, if auto detection is requested, auto detect the requested IP types.
|
|
165
|
+
|
|
166
|
+
/** @type { IPAddresses } */
|
|
167
|
+
let ipAddresses
|
|
168
|
+
if (options.ipv4 === true || options.ipv6 === true) {
|
|
169
|
+
ipAddresses = await IPAddresses.getInstanceAsync()
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (options.ipv4 === true) {
|
|
173
|
+
if (letsEncryptServer.type === LetsEncryptServer.type.PEBBLE) {
|
|
174
|
+
const localIPv4Address = '127.0.0.1'
|
|
175
|
+
defaultPebbleDomains.push(localIPv4Address)
|
|
176
|
+
log(` 📍 ❨auto-encrypt❩ Will provision TLS certificate from Pebble server for local IPv4 address (${localIPv4Address})`)
|
|
165
177
|
} else {
|
|
166
|
-
|
|
178
|
+
if (ipAddresses.hasIPv4Address) {
|
|
179
|
+
const ipv4Address = ipAddresses.ipv4Address
|
|
180
|
+
defaultStagingAndProductionDomains.push(ipv4Address)
|
|
181
|
+
log(` 📍 ❨auto-encrypt❩ Will provision TLS certificate for detected IPv4 address: ${ipv4Address}`)
|
|
182
|
+
} else {
|
|
183
|
+
throws.error(Symbol.for('IPv4AddressNotFound'))
|
|
184
|
+
}
|
|
167
185
|
}
|
|
168
186
|
}
|
|
169
|
-
}
|
|
170
187
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
} else {
|
|
178
|
-
// IPv6: Staging and production.
|
|
179
|
-
const ipv6Addresses = ipAddresses.ipv6Addresses
|
|
180
|
-
if (ipv6Addresses.length > 0) {
|
|
181
|
-
defaultStagingAndProductionDomains = defaultStagingAndProductionDomains.concat(ipv6Addresses)
|
|
182
|
-
ipv6Addresses.forEach(ipv6Address => defaultPebbleDomains.push(ipv6Address))
|
|
183
|
-
log(` 📍 ❨auto-encrypt❩ Will provision TLS certificate for detected stable IPv6 address${ipv6Addresses.length > 1 ? 'es' : ''}: ${ipv6Addresses}`)
|
|
188
|
+
if (options.ipv6 === true) {
|
|
189
|
+
if (letsEncryptServer.type === LetsEncryptServer.type.PEBBLE) {
|
|
190
|
+
// IPv6: Pebble.
|
|
191
|
+
const localIPv6Address = '::1'
|
|
192
|
+
defaultPebbleDomains.push(localIPv6Address)
|
|
193
|
+
log(` 📍 ❨auto-encrypt❩ Will provision TLS certificate from Pebble server for local IPv6 address (${localIPv6Address})`)
|
|
184
194
|
} else {
|
|
185
|
-
|
|
195
|
+
// IPv6: Staging and production.
|
|
196
|
+
const ipv6Addresses = ipAddresses.ipv6Addresses
|
|
197
|
+
if (ipv6Addresses.length > 0) {
|
|
198
|
+
defaultStagingAndProductionDomains = defaultStagingAndProductionDomains.concat(ipv6Addresses)
|
|
199
|
+
ipv6Addresses.forEach(ipv6Address => defaultPebbleDomains.push(ipv6Address))
|
|
200
|
+
log(` 📍 ❨auto-encrypt❩ Will provision TLS certificate for detected stable IPv6 address${ipv6Addresses.length > 1 ? 'es' : ''}: ${ipv6Addresses}`)
|
|
201
|
+
} else {
|
|
202
|
+
throws.error(Symbol.for('IPv6AddressNotFound'))
|
|
203
|
+
}
|
|
186
204
|
}
|
|
187
205
|
}
|
|
188
206
|
}
|
package/lib/IPAddresses.js
CHANGED
|
@@ -11,6 +11,10 @@ import Throws from './util/Throws.js'
|
|
|
11
11
|
|
|
12
12
|
const throws = new Throws()
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
@typedef {{ ip: string }} IpAddressApiResponse
|
|
16
|
+
*/
|
|
17
|
+
|
|
14
18
|
export default class IPAddresses {
|
|
15
19
|
/** @type {IPAddresses} */
|
|
16
20
|
static instance
|
|
@@ -82,7 +86,7 @@ export default class IPAddresses {
|
|
|
82
86
|
try {
|
|
83
87
|
const response = await fetch('https://ip.small-web.org/json/')
|
|
84
88
|
if (response.status === 200) {
|
|
85
|
-
const ip = (await response.json()).ip
|
|
89
|
+
const ip = /** @type { IpAddressApiResponse } */ (await response.json()).ip
|
|
86
90
|
if (ip !== '::1') {
|
|
87
91
|
this.ipv4Address = ip
|
|
88
92
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@small-tech/auto-encrypt",
|
|
3
|
-
"version": "5.0
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "Automatically provisions and renews Let’s Encrypt TLS certificates on Node.js https servers (including Kitten, Polka, Express.js, etc.)",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18.20.0"
|