@push.rocks/smartacme 7.2.1 → 7.2.2
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/dist_ts/00_commitinfo_data.js +1 -1
- package/package.json +1 -1
- package/readme.md +49 -82
- package/ts/00_commitinfo_data.ts +1 -1
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartacme',
|
|
6
|
-
version: '7.2.
|
|
6
|
+
version: '7.2.2',
|
|
7
7
|
description: 'A TypeScript-based ACME client for LetsEncrypt certificate management with a focus on simplicity and power.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx1QkFBdUI7SUFDN0IsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLDZHQUE2RztDQUMzSCxDQUFBIn0=
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -4,19 +4,26 @@ A TypeScript-based ACME client with an easy yet powerful interface for LetsEncry
|
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Using pnpm as the package manager:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
|
|
10
|
+
pnpm add @push.rocks/smartacme
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Ensure your project is set up to use TypeScript and ECMAScript Modules (ESM).
|
|
14
|
+
## Running Tests
|
|
15
|
+
|
|
16
|
+
Tests are written using `@push.rocks/tapbundle` and can be run with:
|
|
14
17
|
|
|
15
18
|
```bash
|
|
16
|
-
|
|
19
|
+
pnpm test
|
|
17
20
|
```
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
To run a specific test file:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
tsx test/<test-file>.ts
|
|
26
|
+
```
|
|
20
27
|
|
|
21
28
|
## Usage
|
|
22
29
|
|
|
@@ -42,28 +49,31 @@ Ensure your project includes the necessary TypeScript configuration and dependen
|
|
|
42
49
|
Start by importing the `SmartAcme` class and any built-in handlers you plan to use. For example, to use DNS-01 via Cloudflare:
|
|
43
50
|
|
|
44
51
|
```typescript
|
|
45
|
-
import { SmartAcme } from '@push.rocks/smartacme';
|
|
52
|
+
import { SmartAcme, MongoCertManager } from '@push.rocks/smartacme';
|
|
46
53
|
import * as cloudflare from '@apiclient.xyz/cloudflare';
|
|
47
54
|
import { Dns01Handler } from '@push.rocks/smartacme/ts/handlers/Dns01Handler.js';
|
|
48
55
|
|
|
49
56
|
// Create a Cloudflare account client with your API token
|
|
50
57
|
const cfAccount = new cloudflare.CloudflareAccount('YOUR_CF_TOKEN');
|
|
51
58
|
|
|
52
|
-
//
|
|
59
|
+
// Initialize a certificate manager (e.g., MongoDB)
|
|
60
|
+
const certManager = new MongoCertManager({
|
|
61
|
+
mongoDbUrl: 'mongodb://yourmongoURL',
|
|
62
|
+
mongoDbName: 'yourDbName',
|
|
63
|
+
mongoDbPass: 'yourDbPassword',
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Instantiate SmartAcme with the certManager and challenge handlers
|
|
53
67
|
const smartAcmeInstance = new SmartAcme({
|
|
54
68
|
accountEmail: 'youremail@example.com',
|
|
55
|
-
|
|
56
|
-
mongoDbUrl: 'mongodb://yourmongoURL',
|
|
57
|
-
mongoDbName: 'yourDbName',
|
|
58
|
-
mongoDbPass: 'yourDbPassword',
|
|
59
|
-
},
|
|
69
|
+
certManager,
|
|
60
70
|
environment: 'integration', // 'production' to request real certificates
|
|
61
|
-
retryOptions: {},
|
|
62
|
-
challengeHandlers: [
|
|
71
|
+
retryOptions: {}, // optional retry/backoff settings
|
|
72
|
+
challengeHandlers: [ // pluggable ACME challenge handlers
|
|
63
73
|
new Dns01Handler(cfAccount),
|
|
64
|
-
//
|
|
74
|
+
// add more handlers as needed (e.g., Http01Webroot, Http01MemoryHandler)
|
|
65
75
|
],
|
|
66
|
-
challengePriority: ['dns-01'], // optional
|
|
76
|
+
challengePriority: ['dns-01'], // optional challenge ordering
|
|
67
77
|
});
|
|
68
78
|
```
|
|
69
79
|
|
|
@@ -91,14 +101,16 @@ SmartAcme uses pluggable ACME challenge handlers (see built-in handlers below) t
|
|
|
91
101
|
|
|
92
102
|
### Managing Certificates
|
|
93
103
|
|
|
94
|
-
The library automatically handles fetching, renewing, and storing your certificates in a MongoDB database specified
|
|
104
|
+
The library automatically handles fetching, renewing, and storing your certificates in a MongoDB database specified via a certificate manager. Ensure your MongoDB instance is accessible and properly configured for use with SmartAcme.
|
|
95
105
|
|
|
96
106
|
```typescript
|
|
97
|
-
|
|
107
|
+
import { MongoCertManager } from '@push.rocks/smartacme';
|
|
108
|
+
|
|
109
|
+
const certManager = new MongoCertManager({
|
|
98
110
|
mongoDbUrl: 'mongodb://yourmongoURL',
|
|
99
111
|
mongoDbName: 'yourDbName',
|
|
100
112
|
mongoDbPass: 'yourDbPassword',
|
|
101
|
-
};
|
|
113
|
+
});
|
|
102
114
|
```
|
|
103
115
|
|
|
104
116
|
### Environmental Considerations
|
|
@@ -110,23 +122,27 @@ When creating an instance of `SmartAcme`, you can specify an `environment` optio
|
|
|
110
122
|
Below is a complete example demonstrating how to use `@push.rocks/smartacme` to obtain and manage an ACME certificate with Let's Encrypt using a DNS-01 handler:
|
|
111
123
|
|
|
112
124
|
```typescript
|
|
113
|
-
import { SmartAcme } from '@push.rocks/smartacme';
|
|
125
|
+
import { SmartAcme, MongoCertManager } from '@push.rocks/smartacme';
|
|
114
126
|
import * as cloudflare from '@apiclient.xyz/cloudflare';
|
|
115
127
|
import { Qenv } from '@push.rocks/qenv';
|
|
128
|
+
import { Dns01Handler } from '@push.rocks/smartacme/ts/handlers/Dns01Handler.js';
|
|
116
129
|
|
|
117
130
|
const qenv = new Qenv('./', './.nogit/');
|
|
118
131
|
const cloudflareAccount = new cloudflare.CloudflareAccount(qenv.getEnvVarOnDemand('CF_TOKEN'));
|
|
119
132
|
|
|
120
133
|
async function main() {
|
|
134
|
+
// Initialize MongoDB certificate manager
|
|
135
|
+
const certManager = new MongoCertManager({
|
|
136
|
+
mongoDbUrl: qenv.getEnvVarRequired('MONGODB_URL'),
|
|
137
|
+
mongoDbName: qenv.getEnvVarRequired('MONGODB_DATABASE'),
|
|
138
|
+
mongoDbPass: qenv.getEnvVarRequired('MONGODB_PASSWORD'),
|
|
139
|
+
});
|
|
140
|
+
|
|
121
141
|
const smartAcmeInstance = new SmartAcme({
|
|
122
142
|
accountEmail: 'youremail@example.com',
|
|
123
|
-
|
|
124
|
-
mongoDbUrl: qenv.getEnvVarRequired('MONGODB_URL'),
|
|
125
|
-
mongoDbName: qenv.getEnvVarRequired('MONGODB_DATABASE'),
|
|
126
|
-
mongoDbPass: qenv.getEnvVarRequired('MONGODB_PASSWORD'),
|
|
127
|
-
},
|
|
143
|
+
certManager,
|
|
128
144
|
environment: 'integration',
|
|
129
|
-
challengeHandlers: [
|
|
145
|
+
challengeHandlers: [new Dns01Handler(cloudflareAccount)],
|
|
130
146
|
});
|
|
131
147
|
|
|
132
148
|
await smartAcmeInstance.start();
|
|
@@ -138,8 +154,8 @@ async function main() {
|
|
|
138
154
|
await smartAcmeInstance.stop();
|
|
139
155
|
}
|
|
140
156
|
|
|
141
|
-
|
|
142
|
-
|
|
157
|
+
main().catch(console.error);
|
|
158
|
+
```
|
|
143
159
|
|
|
144
160
|
## Built-in Challenge Handlers
|
|
145
161
|
|
|
@@ -222,7 +238,7 @@ async function main() {
|
|
|
222
238
|
challengePriority: ['my-01'],
|
|
223
239
|
});
|
|
224
240
|
|
|
225
|
-
In this example, `Qenv` is used to manage environment variables, and
|
|
241
|
+
In this example, `Qenv` is used to manage environment variables, and the Cloudflare library is used to handle DNS challenges through the built-in `Dns01Handler` plugin.
|
|
226
242
|
|
|
227
243
|
## Additional Details
|
|
228
244
|
|
|
@@ -243,8 +259,6 @@ The certificate object obtained from the `getCertificateForDomain` method has th
|
|
|
243
259
|
- **start()**: Initializes the SmartAcme instance, sets up the ACME client, and registers the account with Let's Encrypt.
|
|
244
260
|
- **stop()**: Closes the MongoDB connection and performs any necessary cleanup.
|
|
245
261
|
- **getCertificateForDomain(domainArg: string)**: Retrieves or obtains a certificate for the specified domain name. If a valid certificate exists in the database, it is returned. Otherwise, a new certificate is requested and stored.
|
|
246
|
-
- **setChallenge(dnsChallenge: any)**: Automates the process of setting DNS challenge records.
|
|
247
|
-
- **removeChallenge(dnsChallenge: any)**: Automates the process of removing DNS challenge records.
|
|
248
262
|
|
|
249
263
|
### Handling Domain Matching
|
|
250
264
|
|
|
@@ -260,60 +274,13 @@ console.log('Certificate Domain Name:', certDomainName); // Output: example.com
|
|
|
260
274
|
|
|
261
275
|
### Testing
|
|
262
276
|
|
|
263
|
-
|
|
277
|
+
Sample tests are provided in the `test` directory. They demonstrate core functionality using the `MemoryCertManager` and built-in challenge handlers. To run all tests, use:
|
|
264
278
|
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
import { Qenv } from '@push.rocks/qenv';
|
|
268
|
-
import * as cloudflare from '@apiclient.xyz/cloudflare';
|
|
269
|
-
import * as smartacme from '@push.rocks/smartacme';
|
|
270
|
-
|
|
271
|
-
const testQenv = new Qenv('./', './.nogit/');
|
|
272
|
-
const testCloudflare = new cloudflare.CloudflareAccount(testQenv.getEnvVarOnDemand('CF_TOKEN'));
|
|
273
|
-
|
|
274
|
-
let smartAcmeInstance: smartacme.SmartAcme;
|
|
275
|
-
|
|
276
|
-
tap.test('should create a valid instance of SmartAcme', async () => {
|
|
277
|
-
smartAcmeInstance = new smartacme.SmartAcme({
|
|
278
|
-
accountEmail: 'domains@lossless.org',
|
|
279
|
-
accountPrivateKey: null,
|
|
280
|
-
mongoDescriptor: {
|
|
281
|
-
mongoDbName: testQenv.getEnvVarRequired('MONGODB_DATABASE'),
|
|
282
|
-
mongoDbPass: testQenv.getEnvVarRequired('MONGODB_PASSWORD'),
|
|
283
|
-
mongoDbUrl: testQenv.getEnvVarRequired('MONGODB_URL'),
|
|
284
|
-
},
|
|
285
|
-
setChallenge: async (dnsChallenge) => {
|
|
286
|
-
await testCloudflare.convenience.acmeSetDnsChallenge(dnsChallenge);
|
|
287
|
-
},
|
|
288
|
-
removeChallenge: async (dnsChallenge) => {
|
|
289
|
-
await testCloudflare.convenience.acmeRemoveDnsChallenge(dnsChallenge);
|
|
290
|
-
},
|
|
291
|
-
environment: 'integration',
|
|
292
|
-
});
|
|
293
|
-
await smartAcmeInstance.init();
|
|
294
|
-
expect(smartAcmeInstance).toBeInstanceOf(smartacme.SmartAcme);
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
tap.test('should get a domain certificate', async () => {
|
|
298
|
-
const certificate = await smartAcmeInstance.getCertificateForDomain('example.com');
|
|
299
|
-
console.log('Certificate:', certificate);
|
|
300
|
-
expect(certificate).toHaveProperty('domainName', 'example.com');
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
tap.test('certmatcher should correctly match domains', async () => {
|
|
304
|
-
const certMatcher = new smartacme.SmartacmeCertMatcher();
|
|
305
|
-
const matchedCert = certMatcher.getCertificateDomainNameByDomainName('subdomain.example.com');
|
|
306
|
-
expect(matchedCert).toBe('example.com');
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
tap.test('should stop correctly', async () => {
|
|
310
|
-
await smartAcmeInstance.stop();
|
|
311
|
-
expect(smartAcmeInstance).toHaveProperty('client', null);
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
tap.start();
|
|
279
|
+
```bash
|
|
280
|
+
pnpm test
|
|
315
281
|
```
|
|
316
282
|
|
|
283
|
+
|
|
317
284
|
This comprehensive guide ensures you can set up, manage, and test ACME certificates efficiently and effectively using `@push.rocks/smartacme`.
|
|
318
285
|
|
|
319
286
|
---
|
package/ts/00_commitinfo_data.ts
CHANGED