@push.rocks/smartacme 9.4.0 → 9.6.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/.smartconfig.json +12 -7
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/acme/acme.classes.client.d.ts +2 -0
- package/dist_ts/acme/acme.classes.client.js +5 -2
- package/dist_ts/acme/acme.classes.http-client.d.ts +2 -1
- package/dist_ts/acme/acme.classes.http-client.js +4 -2
- package/dist_ts/acme/acme.classes.order.d.ts +3 -0
- package/dist_ts/acme/acme.classes.order.js +11 -2
- package/dist_ts/classes.exact-certificate-issuer.d.ts +36 -0
- package/dist_ts/classes.exact-certificate-issuer.js +393 -0
- package/dist_ts/index.d.ts +2 -0
- package/dist_ts/index.js +2 -1
- package/dist_ts/interfaces/exact-issuance.d.ts +79 -0
- package/dist_ts/interfaces/exact-issuance.js +2 -0
- package/dist_ts/plugins.d.ts +5 -1
- package/dist_ts/plugins.js +6 -2
- package/dist_ts/smartacme.classes.smartacme.d.ts +22 -0
- package/dist_ts/smartacme.classes.smartacme.js +134 -10
- package/package.json +11 -15
- package/readme.md +75 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/acme/acme.classes.client.ts +6 -1
- package/ts/acme/acme.classes.http-client.ts +2 -1
- package/ts/acme/acme.classes.order.ts +12 -1
- package/ts/classes.exact-certificate-issuer.ts +403 -0
- package/ts/index.ts +2 -0
- package/ts/interfaces/exact-issuance.ts +104 -0
- package/ts/plugins.ts +5 -1
- package/ts/smartacme.classes.smartacme.ts +142 -8
- package/readme.hints.md +0 -81
- package/readme.plan.md +0 -3
|
@@ -2,6 +2,7 @@ import * as plugins from './plugins.js';
|
|
|
2
2
|
import { SmartacmeCertMatcher } from './smartacme.classes.certmatcher.js';
|
|
3
3
|
import { commitinfo } from './00_commitinfo_data.js';
|
|
4
4
|
import { SmartacmeCert } from './smartacme.classes.cert.js';
|
|
5
|
+
import { ExactCertificateIssuer } from './classes.exact-certificate-issuer.js';
|
|
5
6
|
const CERT_ISSUANCE_STEPS = [
|
|
6
7
|
{ name: 'prepare', description: 'Creating ACME order', percentage: 10 },
|
|
7
8
|
{ name: 'authorize', description: 'Solving ACME challenges', percentage: 40 },
|
|
@@ -27,12 +28,21 @@ export class SmartAcme {
|
|
|
27
28
|
}
|
|
28
29
|
constructor(optionsArg) {
|
|
29
30
|
this.smartdns = new plugins.smartdnsClient.Smartdns({});
|
|
31
|
+
this.exactRequests = new Map();
|
|
32
|
+
this.lifecycleAbort = new AbortController();
|
|
33
|
+
this.started = false;
|
|
30
34
|
// track pending DNS challenges for graceful shutdown
|
|
31
35
|
this.pendingChallenges = [];
|
|
32
36
|
// bound signal handlers so they can be removed on stop()
|
|
33
37
|
this.boundSigintHandler = null;
|
|
34
38
|
this.boundSigtermHandler = null;
|
|
35
39
|
this.options = optionsArg;
|
|
40
|
+
if (!Number.isSafeInteger(optionsArg.maxPendingExactRequests ?? 64)
|
|
41
|
+
|| (optionsArg.maxPendingExactRequests ?? 64) < 1
|
|
42
|
+
|| !Number.isSafeInteger(optionsArg.exactDnsPropagationDelayMs ?? 60000)
|
|
43
|
+
|| (optionsArg.exactDnsPropagationDelayMs ?? 60000) < 0) {
|
|
44
|
+
throw new Error('Invalid explicit issuance admission or propagation limits');
|
|
45
|
+
}
|
|
36
46
|
this.logger = plugins.smartlog.Smartlog.createForCommitinfo(commitinfo);
|
|
37
47
|
// enable console output for structured logging
|
|
38
48
|
this.logger.enableConsole();
|
|
@@ -61,11 +71,17 @@ export class SmartAcme {
|
|
|
61
71
|
maxConcurrent: 1,
|
|
62
72
|
resultSharingMode: 'share-latest',
|
|
63
73
|
constraintKeyForExecution: (_task, input) => {
|
|
74
|
+
if (input?.exact)
|
|
75
|
+
return null;
|
|
64
76
|
return input?.certDomainName ?? null;
|
|
65
77
|
},
|
|
66
78
|
shouldExecute: async (_task, input) => {
|
|
79
|
+
if (input?.exact)
|
|
80
|
+
return true;
|
|
67
81
|
if (!input?.certDomainName || !this.certmanager)
|
|
68
82
|
return true;
|
|
83
|
+
if (input.forceRenew)
|
|
84
|
+
return true;
|
|
69
85
|
// Safety net: if a valid cert is already cached, skip re-issuance
|
|
70
86
|
const existing = await this.certmanager.retrieveCertificate(input.certDomainName);
|
|
71
87
|
if (existing && !existing.shouldBeRenewed()) {
|
|
@@ -90,6 +106,12 @@ export class SmartAcme {
|
|
|
90
106
|
constraintKeyForExecution: () => 'account',
|
|
91
107
|
});
|
|
92
108
|
this.taskManager.addConstraintGroup(certDomainMutex);
|
|
109
|
+
// One fixed key reserves a bounded share of global capacity for testing.
|
|
110
|
+
// Exact results contain private keys and must never enter result-sharing caches.
|
|
111
|
+
this.taskManager.addConstraintGroup(new plugins.taskbuffer.TaskConstraintGroup({
|
|
112
|
+
name: 'exact-issuance-concurrency', maxConcurrent: 2,
|
|
113
|
+
constraintKeyForExecution: (_task, input) => input?.exact ? 'exact' : null,
|
|
114
|
+
}));
|
|
93
115
|
this.taskManager.addConstraintGroup(acmeGlobalConcurrency);
|
|
94
116
|
this.taskManager.addConstraintGroup(acmeAccountRateLimit);
|
|
95
117
|
// Create the single reusable certificate issuance task
|
|
@@ -97,6 +119,12 @@ export class SmartAcme {
|
|
|
97
119
|
name: 'cert-issuance',
|
|
98
120
|
steps: CERT_ISSUANCE_STEPS,
|
|
99
121
|
taskFunction: async (input) => {
|
|
122
|
+
if (input.exact) {
|
|
123
|
+
const issuer = this.requireExactIssuer();
|
|
124
|
+
return input.exact.recovery
|
|
125
|
+
? issuer.recover(input.exact.recovery)
|
|
126
|
+
: issuer.run(input.exact.request);
|
|
127
|
+
}
|
|
100
128
|
return this.performCertificateIssuance(input);
|
|
101
129
|
},
|
|
102
130
|
});
|
|
@@ -109,8 +137,33 @@ export class SmartAcme {
|
|
|
109
137
|
* ```
|
|
110
138
|
*/
|
|
111
139
|
async start() {
|
|
140
|
+
if (this.started)
|
|
141
|
+
throw new Error('SmartAcme is already started');
|
|
142
|
+
this.lifecycleAbort = new AbortController();
|
|
112
143
|
this.privateKey =
|
|
113
144
|
this.options.accountPrivateKey || plugins.acme.AcmeCrypto.createRsaPrivateKey();
|
|
145
|
+
const directoryUrl = this.options.directoryUrl ?? (this.options.environment === 'production'
|
|
146
|
+
? plugins.acme.ACME_DIRECTORY_URLS.letsencrypt.production
|
|
147
|
+
: plugins.acme.ACME_DIRECTORY_URLS.letsencrypt.staging);
|
|
148
|
+
const directory = new URL(directoryUrl);
|
|
149
|
+
if (directory.username || directory.password || directory.hash
|
|
150
|
+
|| (directory.protocol !== 'https:' && !(directory.protocol === 'http:'
|
|
151
|
+
&& ['localhost', '127.0.0.1', '[::1]'].includes(directory.hostname)))) {
|
|
152
|
+
throw new Error('An HTTPS ACME directory or an explicit loopback test directory is required');
|
|
153
|
+
}
|
|
154
|
+
if (this.options.exactIssuanceStore && !this.options.accountPrivateKey) {
|
|
155
|
+
const accountId = plugins.crypto.createHash('sha256')
|
|
156
|
+
.update(JSON.stringify([directoryUrl, this.options.accountEmail.trim().toLowerCase()])).digest('hex');
|
|
157
|
+
const store = this.options.exactIssuanceStore;
|
|
158
|
+
let storedKey = await store.getAccountKey(accountId);
|
|
159
|
+
if (!storedKey) {
|
|
160
|
+
await store.createAccountKey(accountId, this.privateKey);
|
|
161
|
+
storedKey = await store.getAccountKey(accountId);
|
|
162
|
+
}
|
|
163
|
+
if (!storedKey)
|
|
164
|
+
throw new Error('ACME account key could not be retained durably');
|
|
165
|
+
this.privateKey = storedKey;
|
|
166
|
+
}
|
|
114
167
|
// Initialize certificate manager
|
|
115
168
|
if (!this.options.certManager) {
|
|
116
169
|
throw new Error('You must provide a certManager via options.certManager');
|
|
@@ -121,15 +174,9 @@ export class SmartAcme {
|
|
|
121
174
|
this.certmatcher = new SmartacmeCertMatcher();
|
|
122
175
|
// ACME Client
|
|
123
176
|
this.client = new plugins.acme.AcmeClient({
|
|
124
|
-
directoryUrl
|
|
125
|
-
if (this.options.environment === 'production') {
|
|
126
|
-
return plugins.acme.ACME_DIRECTORY_URLS.letsencrypt.production;
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
return plugins.acme.ACME_DIRECTORY_URLS.letsencrypt.staging;
|
|
130
|
-
}
|
|
131
|
-
})(),
|
|
177
|
+
directoryUrl,
|
|
132
178
|
accountKeyPem: this.privateKey,
|
|
179
|
+
signal: this.lifecycleAbort.signal,
|
|
133
180
|
logger: (level, message, data) => {
|
|
134
181
|
this.logger.log(level, message, data);
|
|
135
182
|
},
|
|
@@ -141,6 +188,15 @@ export class SmartAcme {
|
|
|
141
188
|
});
|
|
142
189
|
// Start the task manager
|
|
143
190
|
await this.taskManager.start();
|
|
191
|
+
if (this.options.exactIssuanceStore) {
|
|
192
|
+
this.exactIssuer = new ExactCertificateIssuer({
|
|
193
|
+
store: this.options.exactIssuanceStore, client: this.client, directoryUrl,
|
|
194
|
+
accountThumbprint: plugins.acme.AcmeCrypto.getJwkThumbprint(plugins.acme.AcmeCrypto.getJwk(this.privateKey)),
|
|
195
|
+
dns: this.smartdns, handlers: this.challengeHandlers, signal: this.lifecycleAbort.signal,
|
|
196
|
+
dnsPropagationDelayMs: this.options.exactDnsPropagationDelayMs ?? 60000,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
this.started = true;
|
|
144
200
|
// Setup graceful shutdown handlers (store references for removal in stop())
|
|
145
201
|
this.boundSigintHandler = () => this.handleSignal('SIGINT');
|
|
146
202
|
this.boundSigtermHandler = () => this.handleSignal('SIGTERM');
|
|
@@ -151,6 +207,8 @@ export class SmartAcme {
|
|
|
151
207
|
* Stops the SmartAcme instance and closes certificate store connections.
|
|
152
208
|
*/
|
|
153
209
|
async stop() {
|
|
210
|
+
this.started = false;
|
|
211
|
+
this.lifecycleAbort.abort();
|
|
154
212
|
// Remove signal handlers so the process can exit cleanly
|
|
155
213
|
if (this.boundSigintHandler) {
|
|
156
214
|
process.removeListener('SIGINT', this.boundSigintHandler);
|
|
@@ -160,8 +218,13 @@ export class SmartAcme {
|
|
|
160
218
|
process.removeListener('SIGTERM', this.boundSigtermHandler);
|
|
161
219
|
this.boundSigtermHandler = null;
|
|
162
220
|
}
|
|
163
|
-
//
|
|
221
|
+
// Observe active requests before rejecting queued work. The task manager
|
|
222
|
+
// must close its queue before we drain callers waiting on that queue.
|
|
223
|
+
const pendingExactRequests = Promise.allSettled([...this.exactRequests.values()]);
|
|
164
224
|
await this.taskManager.stop();
|
|
225
|
+
await pendingExactRequests;
|
|
226
|
+
this.exactRequests.clear();
|
|
227
|
+
this.exactIssuer = undefined;
|
|
165
228
|
// Destroy ACME HTTP transport (closes keep-alive sockets)
|
|
166
229
|
if (this.client) {
|
|
167
230
|
this.client.destroy();
|
|
@@ -174,6 +237,66 @@ export class SmartAcme {
|
|
|
174
237
|
await this.certmanager.close();
|
|
175
238
|
}
|
|
176
239
|
}
|
|
240
|
+
/** Bind durable work to the current account and issuer without creating an order. */
|
|
241
|
+
getCertificateIdentity(request) {
|
|
242
|
+
return this.requireExactIssuer().identity(request);
|
|
243
|
+
}
|
|
244
|
+
/** Ensure a certificate whose SANs exactly match the explicit identifiers. */
|
|
245
|
+
async getCertificateForIdentifiers(request) {
|
|
246
|
+
return await this.runExact(request);
|
|
247
|
+
}
|
|
248
|
+
async getCertificateIssuanceStatus(request) {
|
|
249
|
+
return await this.requireExactIssuer().status(request);
|
|
250
|
+
}
|
|
251
|
+
/** Administrative recovery; embedding services must authorize the caller. */
|
|
252
|
+
async recoverCertificateIssuance(request) {
|
|
253
|
+
return await this.runExact(request, request);
|
|
254
|
+
}
|
|
255
|
+
requireExactIssuer() {
|
|
256
|
+
if (!this.started || !this.exactIssuer)
|
|
257
|
+
throw new Error('SmartAcme explicit issuance is not running or configured');
|
|
258
|
+
return this.exactIssuer;
|
|
259
|
+
}
|
|
260
|
+
async runExact(request, recovery) {
|
|
261
|
+
const issuer = this.requireExactIssuer();
|
|
262
|
+
const identity = issuer.identity(request);
|
|
263
|
+
const recoverySnapshot = recovery ? {
|
|
264
|
+
namespace: identity.namespace, identifiers: [...identity.identifiers],
|
|
265
|
+
issuanceId: recovery.issuanceId, expectedRevision: recovery.expectedRevision, action: recovery.action,
|
|
266
|
+
} : undefined;
|
|
267
|
+
const existing = this.exactRequests.get(identity.certificateKey);
|
|
268
|
+
if (existing) {
|
|
269
|
+
if (recovery)
|
|
270
|
+
throw new Error('Issuance is running; recover after its current operation completes');
|
|
271
|
+
return await existing;
|
|
272
|
+
}
|
|
273
|
+
if (this.exactRequests.size >= (this.options.maxPendingExactRequests ?? 64)) {
|
|
274
|
+
throw new Error('Explicit issuance admission limit reached');
|
|
275
|
+
}
|
|
276
|
+
const operation = (async () => {
|
|
277
|
+
if (!recovery) {
|
|
278
|
+
const cached = await issuer.cached(identity);
|
|
279
|
+
if (cached)
|
|
280
|
+
return cached;
|
|
281
|
+
}
|
|
282
|
+
this.lifecycleAbort.signal.throwIfAborted();
|
|
283
|
+
const result = await this.taskManager.triggerTaskConstrained(this.certIssuanceTask, {
|
|
284
|
+
certDomainName: identity.certificateKey, domainArg: identity.identifiers[0],
|
|
285
|
+
isWildcardRequest: false, includeWildcard: false, forceRenew: false,
|
|
286
|
+
exact: { request: { namespace: identity.namespace, identifiers: identity.identifiers }, recovery: recoverySnapshot },
|
|
287
|
+
});
|
|
288
|
+
if (!result)
|
|
289
|
+
throw new Error('Explicit issuance completed without a result');
|
|
290
|
+
return result;
|
|
291
|
+
})();
|
|
292
|
+
this.exactRequests.set(identity.certificateKey, operation);
|
|
293
|
+
try {
|
|
294
|
+
return await operation;
|
|
295
|
+
}
|
|
296
|
+
finally {
|
|
297
|
+
this.exactRequests.delete(identity.certificateKey);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
177
300
|
/** Retry helper with exponential backoff and AcmeError awareness */
|
|
178
301
|
async retry(operation, operationName = 'operation') {
|
|
179
302
|
let attempt = 0;
|
|
@@ -283,6 +406,7 @@ export class SmartAcme {
|
|
|
283
406
|
domainArg,
|
|
284
407
|
isWildcardRequest,
|
|
285
408
|
includeWildcard: options?.includeWildcard ?? false,
|
|
409
|
+
forceRenew,
|
|
286
410
|
};
|
|
287
411
|
const result = await this.taskManager.triggerTaskConstrained(this.certIssuanceTask, issuanceInput);
|
|
288
412
|
// If we got a cert directly (either from execution or result sharing), return it
|
|
@@ -443,4 +567,4 @@ export class SmartAcme {
|
|
|
443
567
|
return newCertificate ?? certRecord;
|
|
444
568
|
}
|
|
445
569
|
}
|
|
446
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLmNsYXNzZXMuc21hcnRhY21lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvc21hcnRhY21lLmNsYXNzZXMuc21hcnRhY21lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBRXhDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFXNUQsTUFBTSxtQkFBbUIsR0FBRztJQUMxQixFQUFFLElBQUksRUFBRSxTQUFTLEVBQUksV0FBVyxFQUFFLHFCQUFxQixFQUFVLFVBQVUsRUFBRSxFQUFFLEVBQUU7SUFDakYsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSx5QkFBeUIsRUFBTSxVQUFVLEVBQUUsRUFBRSxFQUFFO0lBQ2pGLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRyxXQUFXLEVBQUUsNkJBQTZCLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBRTtJQUNqRixFQUFFLElBQUksRUFBRSxPQUFPLEVBQU0sV0FBVyxFQUFFLHFCQUFxQixFQUFVLFVBQVUsRUFBRSxFQUFFLEVBQUU7Q0FDekUsQ0FBQztBQXFEWDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLE9BQU8sU0FBUztJQWlDcEI7O09BRUc7SUFDSCxJQUFXLGtCQUFrQjtRQUMzQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDO0lBQ3RDLENBQUM7SUFFRCxZQUFZLFVBQTZCO1FBbkNqQyxhQUFRLEdBQUcsSUFBSSxPQUFPLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQWdCM0QscURBQXFEO1FBQzdDLHNCQUFpQixHQUE0QyxFQUFFLENBQUM7UUFPeEUseURBQXlEO1FB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
|
|
570
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLmNsYXNzZXMuc21hcnRhY21lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvc21hcnRhY21lLmNsYXNzZXMuc21hcnRhY21lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBRXhDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDNUQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFrQi9FLE1BQU0sbUJBQW1CLEdBQUc7SUFDMUIsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFJLFdBQVcsRUFBRSxxQkFBcUIsRUFBVSxVQUFVLEVBQUUsRUFBRSxFQUFFO0lBQ2pGLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUseUJBQXlCLEVBQU0sVUFBVSxFQUFFLEVBQUUsRUFBRTtJQUNqRixFQUFFLElBQUksRUFBRSxVQUFVLEVBQUcsV0FBVyxFQUFFLDZCQUE2QixFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUU7SUFDakYsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFNLFdBQVcsRUFBRSxxQkFBcUIsRUFBVSxVQUFVLEVBQUUsRUFBRSxFQUFFO0NBQ3pFLENBQUM7QUE2RFg7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxPQUFPLFNBQVM7SUFxQ3BCOztPQUVHO0lBQ0gsSUFBVyxrQkFBa0I7UUFDM0IsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQztJQUN0QyxDQUFDO0lBRUQsWUFBWSxVQUE2QjtRQXZDakMsYUFBUSxHQUFHLElBQUksT0FBTyxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7UUFNbkQsa0JBQWEs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
|
package/package.json
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@push.rocks/smartacme",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.6.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A TypeScript-based ACME client and server for certificate management with built-in CA, supporting LetsEncrypt and custom ACME authorities.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
7
7
|
"typings": "dist_ts/index.d.ts",
|
|
8
8
|
"type": "module",
|
|
9
|
-
"scripts": {
|
|
10
|
-
"test": "(tstest test/ --verbose --logfile --timeout 600)",
|
|
11
|
-
"build": "(tsbuild tsfolders)",
|
|
12
|
-
"buildDocs": "tsdoc"
|
|
13
|
-
},
|
|
14
9
|
"repository": {
|
|
15
10
|
"type": "git",
|
|
16
11
|
"url": "https://code.foss.global/push.rocks/smartacme.git"
|
|
@@ -55,16 +50,16 @@
|
|
|
55
50
|
"@push.rocks/smartstring": "^4.1.0",
|
|
56
51
|
"@push.rocks/smarttime": "^4.2.3",
|
|
57
52
|
"@push.rocks/smartunique": "^3.0.9",
|
|
58
|
-
"@push.rocks/taskbuffer": "^
|
|
53
|
+
"@push.rocks/taskbuffer": "^9.0.2",
|
|
59
54
|
"@tsclass/tsclass": "^9.5.0",
|
|
60
55
|
"reflect-metadata": "^0.2.2"
|
|
61
56
|
},
|
|
62
57
|
"devDependencies": {
|
|
63
|
-
"@git.zone/tsbuild": "^4.4.
|
|
64
|
-
"@git.zone/tsrun": "^2.0.
|
|
65
|
-
"@git.zone/tstest": "^
|
|
58
|
+
"@git.zone/tsbuild": "^4.4.2",
|
|
59
|
+
"@git.zone/tsrun": "^2.0.6",
|
|
60
|
+
"@git.zone/tstest": "^4.1.1",
|
|
66
61
|
"@push.rocks/qenv": "^6.1.3",
|
|
67
|
-
"@types/node": "
|
|
62
|
+
"@types/node": "26.4.1"
|
|
68
63
|
},
|
|
69
64
|
"files": [
|
|
70
65
|
"ts/**/*",
|
|
@@ -81,8 +76,9 @@
|
|
|
81
76
|
"browserslist": [
|
|
82
77
|
"last 1 chrome versions"
|
|
83
78
|
],
|
|
84
|
-
"
|
|
85
|
-
|
|
86
|
-
"
|
|
79
|
+
"scripts": {
|
|
80
|
+
"test": "(tstest test/ --verbose --logfile --timeout 600)",
|
|
81
|
+
"build": "(tsbuild tsfolders)",
|
|
82
|
+
"buildDocs": "tsdoc"
|
|
87
83
|
}
|
|
88
|
-
}
|
|
84
|
+
}
|
package/readme.md
CHANGED
|
@@ -48,7 +48,7 @@ await smartAcme.start();
|
|
|
48
48
|
// 4. Get a certificate
|
|
49
49
|
const cert = await smartAcme.getCertificateForDomain('example.com');
|
|
50
50
|
console.log(cert.publicKey); // PEM certificate chain
|
|
51
|
-
|
|
51
|
+
// Supply cert.privateKey directly to your TLS consumer; never log it.
|
|
52
52
|
|
|
53
53
|
// 5. Clean up
|
|
54
54
|
await smartAcme.stop();
|
|
@@ -74,6 +74,10 @@ interface ISmartAcmeOptions {
|
|
|
74
74
|
maxConcurrentIssuances?: number; // Global cap on parallel ACME ops (default: 5)
|
|
75
75
|
maxOrdersPerWindow?: number; // Max orders in sliding window (default: 250)
|
|
76
76
|
orderWindowMs?: number; // Sliding window duration in ms (default: 3 hours)
|
|
77
|
+
directoryUrl?: string; // Explicit HTTPS CA directory; loopback HTTP for tests
|
|
78
|
+
exactIssuanceStore?: IExactIssuanceStore; // Durable exact-name account/order/certificate adapter
|
|
79
|
+
maxPendingExactRequests?: number; // Bounded in-flight exact identities (default: 64)
|
|
80
|
+
exactDnsPropagationDelayMs?: number; // DNS propagation grace period (default: 60000)
|
|
77
81
|
}
|
|
78
82
|
```
|
|
79
83
|
|
|
@@ -95,6 +99,76 @@ const wildcardCert = await smartAcme.getCertificateForDomain('*.example.com');
|
|
|
95
99
|
|
|
96
100
|
Certificates are automatically cached and reused when still valid. Renewal happens automatically when a certificate is within 10 days of expiration. The actual X.509 expiry date is parsed from the issued certificate, ensuring renewal timing is precise.
|
|
97
101
|
|
|
102
|
+
### Exact identifiers and durable order recovery
|
|
103
|
+
|
|
104
|
+
Use `getCertificateForIdentifiers()` for independently authorized hostnames. It
|
|
105
|
+
supports nested names such as `alice.dev.example.com`, canonicalizes IDNA, case,
|
|
106
|
+
and trailing dots, and never adds a parent or wildcard identifier. Explicit
|
|
107
|
+
wildcards remain supported when deliberately included by the caller. The
|
|
108
|
+
embedding application must authorize the entire requested identifier set.
|
|
109
|
+
|
|
110
|
+
Configure `exactIssuanceStore` before `start()`. Its public `IExactIssuanceStore`
|
|
111
|
+
interface owns durable account keys, revision-checked issuance records, and
|
|
112
|
+
completed certificates. `createAccountKey()` must insert only if absent;
|
|
113
|
+
`compareAndSetIssuance()` must atomically insert on a null revision or replace
|
|
114
|
+
only the expected revision. Acknowledgement means the write is durable. No
|
|
115
|
+
filesystem or implicit in-memory persistence fallback is provided.
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
// smartAcme has been started with your durable exactIssuanceStore adapter.
|
|
119
|
+
const request = {
|
|
120
|
+
namespace: 'testing-grant:stable-grant-id',
|
|
121
|
+
identifiers: ['alice.dev.example.com'],
|
|
122
|
+
};
|
|
123
|
+
const result = await smartAcme.getCertificateForIdentifiers(request);
|
|
124
|
+
if (result.status === 'ready') {
|
|
125
|
+
// Pass result.certificate.publicKey and .privateKey to the authorized TLS consumer.
|
|
126
|
+
// Metadata includes validFrom, validUntil, and renewAfter in milliseconds.
|
|
127
|
+
} else {
|
|
128
|
+
// Persist a job reference and poll according to your worker policy.
|
|
129
|
+
console.log(result.issuance.status); // Safe projection; contains no secret material.
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Certificate identity binds the namespace, sorted exact identifiers, directory
|
|
134
|
+
URL, and account thumbprint. Different namespaces never reuse private keys.
|
|
135
|
+
Cached material is checked for the exact SAN set, matching private key, and
|
|
136
|
+
validity before delivery. Valid cache reads consume no issuance slot. Renewal
|
|
137
|
+
is on demand at `renewAfter`, with a new key and order; there is no background
|
|
138
|
+
renewal timer. The renewal margin is the smaller of ten days or one third of
|
|
139
|
+
the certificate lifetime.
|
|
140
|
+
|
|
141
|
+
The exact path requires DNS-01 and verifies handler support before creating an
|
|
142
|
+
order. Handler prepare/cleanup must be idempotent and cleanup must remove only
|
|
143
|
+
the supplied TXT value. Cleanup intent is retained until cleanup succeeds.
|
|
144
|
+
Exact work has two concurrent slots within the configured global capacity,
|
|
145
|
+
bounded admission, and an in-flight map that releases entries on completion.
|
|
146
|
+
Secret-bearing results do not enter Taskbuffer's result-sharing cache.
|
|
147
|
+
For exact issuance, `stop()` closes admission, rejects queued callers, aborts active protocol
|
|
148
|
+
requests and propagation waits, and drains their cleanup before closing the
|
|
149
|
+
transport and storage. Custom challenge callbacks must settle for shutdown to
|
|
150
|
+
finish; their external effects remain the callback owner's responsibility.
|
|
151
|
+
|
|
152
|
+
`getCertificateIdentity(request)` binds a durable job to the current namespace,
|
|
153
|
+
identifiers, issuer, and account without placing an order.
|
|
154
|
+
`getCertificateIssuanceStatus(request)` returns only safe status metadata.
|
|
155
|
+
`recoverCertificateIssuance({ ...request, issuanceId, expectedRevision, action })`
|
|
156
|
+
accepts `recheck`, `retry-proven-unapplied`, or `abandon`; the embedding service
|
|
157
|
+
must authorize administrative recovery. An acknowledged order retains its
|
|
158
|
+
original key, CSR, and order handle through restarts. Lost order-creation or
|
|
159
|
+
finalization responses produce `indeterminate` rather than automatically
|
|
160
|
+
placing another order. `recheck` reads the acknowledged order and can recover
|
|
161
|
+
an issued certificate. A rate-limit rejection of order creation is the only
|
|
162
|
+
currently supported proof permitting `retry-proven-unapplied`; its retry time
|
|
163
|
+
must first elapse. `abandon` retains `abandoned_unverified` evidence and does
|
|
164
|
+
not authorize a replacement order or claim CA rollback.
|
|
165
|
+
|
|
166
|
+
Store adapters must keep unresolved issuance evidence and enforce retention
|
|
167
|
+
and admission quotas at their application boundary. Issuance records contain
|
|
168
|
+
private keys, CSRs, and challenge values: do not serialize them into status
|
|
169
|
+
APIs or logs. Credential/grant revocation belongs to the embedding application;
|
|
170
|
+
it cannot erase material previously delivered to a client.
|
|
171
|
+
|
|
98
172
|
### 📦 Certificate Object
|
|
99
173
|
|
|
100
174
|
The returned `SmartacmeCert` (also exported as `Cert`) object has these properties:
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -17,6 +17,7 @@ export interface IAcmeClientOptions {
|
|
|
17
17
|
directoryUrl: string;
|
|
18
18
|
accountKeyPem: string;
|
|
19
19
|
logger?: TAcmeLogger;
|
|
20
|
+
signal?: AbortSignal;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
/**
|
|
@@ -35,7 +36,7 @@ export class AcmeClient {
|
|
|
35
36
|
static crypto = AcmeCrypto;
|
|
36
37
|
|
|
37
38
|
constructor(options: IAcmeClientOptions) {
|
|
38
|
-
this.httpClient = new AcmeHttpClient(options.directoryUrl, options.accountKeyPem, options.logger);
|
|
39
|
+
this.httpClient = new AcmeHttpClient(options.directoryUrl, options.accountKeyPem, options.logger, options.signal);
|
|
39
40
|
this.account = new AcmeAccount(this.httpClient);
|
|
40
41
|
this.orderManager = new AcmeOrderManager(this.httpClient);
|
|
41
42
|
this.challengeManager = new AcmeChallengeManager(this.httpClient, options.accountKeyPem);
|
|
@@ -55,6 +56,10 @@ export class AcmeClient {
|
|
|
55
56
|
return this.orderManager.create(opts);
|
|
56
57
|
}
|
|
57
58
|
|
|
59
|
+
async getOrder(url: string): Promise<IAcmeOrder> {
|
|
60
|
+
return this.orderManager.get(url);
|
|
61
|
+
}
|
|
62
|
+
|
|
58
63
|
/**
|
|
59
64
|
* Get all authorizations for an order
|
|
60
65
|
*/
|
|
@@ -20,7 +20,7 @@ export class AcmeHttpClient {
|
|
|
20
20
|
private httpsAgent: https.Agent;
|
|
21
21
|
private httpAgent: http.Agent;
|
|
22
22
|
|
|
23
|
-
constructor(directoryUrl: string, accountKeyPem: string, logger?: TAcmeLogger) {
|
|
23
|
+
constructor(directoryUrl: string, accountKeyPem: string, logger?: TAcmeLogger, public readonly signal?: AbortSignal) {
|
|
24
24
|
this.directoryUrl = directoryUrl;
|
|
25
25
|
this.accountKeyPem = accountKeyPem;
|
|
26
26
|
this.logger = logger;
|
|
@@ -199,6 +199,7 @@ export class AcmeHttpClient {
|
|
|
199
199
|
method,
|
|
200
200
|
headers: requestHeaders,
|
|
201
201
|
agent: isHttps ? this.httpsAgent : this.httpAgent,
|
|
202
|
+
signal: this.signal,
|
|
202
203
|
};
|
|
203
204
|
|
|
204
205
|
const req = lib.request(options, (res) => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AcmeCrypto } from './acme.classes.crypto.js';
|
|
2
2
|
import { AcmeError } from './acme.classes.error.js';
|
|
3
|
+
import { setTimeout as delay } from 'node:timers/promises';
|
|
3
4
|
import type { AcmeHttpClient } from './acme.classes.http-client.js';
|
|
4
5
|
import type {
|
|
5
6
|
IAcmeAuthorization,
|
|
@@ -33,6 +34,12 @@ export class AcmeOrderManager {
|
|
|
33
34
|
return order;
|
|
34
35
|
}
|
|
35
36
|
|
|
37
|
+
/** Read an acknowledged order without creating or finalizing another one. */
|
|
38
|
+
async get(url: string): Promise<IAcmeOrder> {
|
|
39
|
+
const response = await this.httpClient.signedRequest(url, null);
|
|
40
|
+
return { ...response.data as IAcmeOrder, url };
|
|
41
|
+
}
|
|
42
|
+
|
|
36
43
|
/**
|
|
37
44
|
* Retrieve all authorizations for an order (POST-as-GET each authorization URL)
|
|
38
45
|
*/
|
|
@@ -117,9 +124,13 @@ export class AcmeOrderManager {
|
|
|
117
124
|
const retryAfter = parseInt(response.headers['retry-after'] || '0', 10);
|
|
118
125
|
const delay =
|
|
119
126
|
retryAfter > 0 ? retryAfter * 1000 : Math.min(initialDelay * Math.pow(2, i), 30000);
|
|
120
|
-
await
|
|
127
|
+
await this.wait(delay);
|
|
121
128
|
}
|
|
122
129
|
|
|
123
130
|
throw new Error(`Timeout waiting for valid status after ${maxAttempts} attempts`);
|
|
124
131
|
}
|
|
132
|
+
|
|
133
|
+
private async wait(milliseconds: number): Promise<void> {
|
|
134
|
+
await delay(milliseconds, undefined, { signal: this.httpClient.signal });
|
|
135
|
+
}
|
|
125
136
|
}
|