@push.rocks/smartacme 9.5.0 → 9.7.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 +37 -0
- package/dist_ts/classes.exact-certificate-issuer.js +397 -0
- package/dist_ts/handlers/IChallengeHandler.d.ts +8 -3
- package/dist_ts/handlers/index.d.ts +1 -1
- 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 +141 -16
- package/package.json +11 -15
- package/readme.md +90 -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 +408 -0
- package/ts/handlers/IChallengeHandler.ts +10 -4
- package/ts/handlers/index.ts +2 -2
- 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 +151 -15
- package/readme.hints.md +0 -81
- package/readme.plan.md +0 -3
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import type { ICertManager } from './interfaces/certmanager.js';
|
|
3
3
|
import { SmartacmeCert } from './smartacme.classes.cert.js';
|
|
4
|
+
import type { IExactCertificateIdentity, IExactCertificateRequest, IExactIssuanceRecoveryRequest, IExactIssuanceStore, IExactIssuanceInfo, TExactCertificateResult } from './interfaces/exact-issuance.js';
|
|
4
5
|
/**
|
|
5
6
|
* the options for the class @see SmartAcme
|
|
6
7
|
*/
|
|
@@ -12,6 +13,14 @@ export interface ISmartAcmeOptions {
|
|
|
12
13
|
*/
|
|
13
14
|
certManager: ICertManager;
|
|
14
15
|
environment: 'production' | 'integration';
|
|
16
|
+
/** Optional explicit ACME directory, for private CAs and isolated integration. */
|
|
17
|
+
directoryUrl?: string;
|
|
18
|
+
/** Enables isolated explicit-identifier issuance with durable recovery. */
|
|
19
|
+
exactIssuanceStore?: IExactIssuanceStore;
|
|
20
|
+
/** Bounded number of admitted exact-identity operations (default 64). */
|
|
21
|
+
maxPendingExactRequests?: number;
|
|
22
|
+
/** DNS propagation grace period for explicit issuance; defaults to 60 seconds. */
|
|
23
|
+
exactDnsPropagationDelayMs?: number;
|
|
15
24
|
/**
|
|
16
25
|
* Optional retry/backoff configuration for transient failures
|
|
17
26
|
*/
|
|
@@ -66,6 +75,10 @@ export declare class SmartAcme {
|
|
|
66
75
|
private smartdns;
|
|
67
76
|
logger: plugins.smartlog.Smartlog;
|
|
68
77
|
private privateKey;
|
|
78
|
+
private exactIssuer?;
|
|
79
|
+
private exactRequests;
|
|
80
|
+
private lifecycleAbort;
|
|
81
|
+
private started;
|
|
69
82
|
certmanager: ICertManager;
|
|
70
83
|
challengeHandlers: plugins.handlers.IChallengeHandler<any>[];
|
|
71
84
|
private certmatcher;
|
|
@@ -92,6 +105,15 @@ export declare class SmartAcme {
|
|
|
92
105
|
* Stops the SmartAcme instance and closes certificate store connections.
|
|
93
106
|
*/
|
|
94
107
|
stop(): Promise<void>;
|
|
108
|
+
/** Bind durable work to the current account and issuer without creating an order. */
|
|
109
|
+
getCertificateIdentity(request: IExactCertificateRequest): IExactCertificateIdentity;
|
|
110
|
+
/** Ensure a certificate whose SANs exactly match the explicit identifiers. */
|
|
111
|
+
getCertificateForIdentifiers(request: IExactCertificateRequest): Promise<TExactCertificateResult>;
|
|
112
|
+
getCertificateIssuanceStatus(request: IExactCertificateRequest): Promise<IExactIssuanceInfo | null>;
|
|
113
|
+
/** Administrative recovery; embedding services must authorize the caller. */
|
|
114
|
+
recoverCertificateIssuance(request: IExactIssuanceRecoveryRequest): Promise<TExactCertificateResult>;
|
|
115
|
+
private requireExactIssuer;
|
|
116
|
+
private runExact;
|
|
95
117
|
/** Retry helper with exponential backoff and AcmeError awareness */
|
|
96
118
|
private retry;
|
|
97
119
|
/** Clean up pending challenges and shut down */
|
|
@@ -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,9 +71,13 @@ 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;
|
|
69
83
|
if (input.forceRenew)
|
|
@@ -92,6 +106,12 @@ export class SmartAcme {
|
|
|
92
106
|
constraintKeyForExecution: () => 'account',
|
|
93
107
|
});
|
|
94
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
|
+
}));
|
|
95
115
|
this.taskManager.addConstraintGroup(acmeGlobalConcurrency);
|
|
96
116
|
this.taskManager.addConstraintGroup(acmeAccountRateLimit);
|
|
97
117
|
// Create the single reusable certificate issuance task
|
|
@@ -99,6 +119,12 @@ export class SmartAcme {
|
|
|
99
119
|
name: 'cert-issuance',
|
|
100
120
|
steps: CERT_ISSUANCE_STEPS,
|
|
101
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
|
+
}
|
|
102
128
|
return this.performCertificateIssuance(input);
|
|
103
129
|
},
|
|
104
130
|
});
|
|
@@ -111,8 +137,33 @@ export class SmartAcme {
|
|
|
111
137
|
* ```
|
|
112
138
|
*/
|
|
113
139
|
async start() {
|
|
140
|
+
if (this.started)
|
|
141
|
+
throw new Error('SmartAcme is already started');
|
|
142
|
+
this.lifecycleAbort = new AbortController();
|
|
114
143
|
this.privateKey =
|
|
115
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
|
+
}
|
|
116
167
|
// Initialize certificate manager
|
|
117
168
|
if (!this.options.certManager) {
|
|
118
169
|
throw new Error('You must provide a certManager via options.certManager');
|
|
@@ -123,15 +174,9 @@ export class SmartAcme {
|
|
|
123
174
|
this.certmatcher = new SmartacmeCertMatcher();
|
|
124
175
|
// ACME Client
|
|
125
176
|
this.client = new plugins.acme.AcmeClient({
|
|
126
|
-
directoryUrl
|
|
127
|
-
if (this.options.environment === 'production') {
|
|
128
|
-
return plugins.acme.ACME_DIRECTORY_URLS.letsencrypt.production;
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
return plugins.acme.ACME_DIRECTORY_URLS.letsencrypt.staging;
|
|
132
|
-
}
|
|
133
|
-
})(),
|
|
177
|
+
directoryUrl,
|
|
134
178
|
accountKeyPem: this.privateKey,
|
|
179
|
+
signal: this.lifecycleAbort.signal,
|
|
135
180
|
logger: (level, message, data) => {
|
|
136
181
|
this.logger.log(level, message, data);
|
|
137
182
|
},
|
|
@@ -143,6 +188,15 @@ export class SmartAcme {
|
|
|
143
188
|
});
|
|
144
189
|
// Start the task manager
|
|
145
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;
|
|
146
200
|
// Setup graceful shutdown handlers (store references for removal in stop())
|
|
147
201
|
this.boundSigintHandler = () => this.handleSignal('SIGINT');
|
|
148
202
|
this.boundSigtermHandler = () => this.handleSignal('SIGTERM');
|
|
@@ -153,6 +207,8 @@ export class SmartAcme {
|
|
|
153
207
|
* Stops the SmartAcme instance and closes certificate store connections.
|
|
154
208
|
*/
|
|
155
209
|
async stop() {
|
|
210
|
+
this.started = false;
|
|
211
|
+
this.lifecycleAbort.abort();
|
|
156
212
|
// Remove signal handlers so the process can exit cleanly
|
|
157
213
|
if (this.boundSigintHandler) {
|
|
158
214
|
process.removeListener('SIGINT', this.boundSigintHandler);
|
|
@@ -162,8 +218,13 @@ export class SmartAcme {
|
|
|
162
218
|
process.removeListener('SIGTERM', this.boundSigtermHandler);
|
|
163
219
|
this.boundSigtermHandler = null;
|
|
164
220
|
}
|
|
165
|
-
//
|
|
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()]);
|
|
166
224
|
await this.taskManager.stop();
|
|
225
|
+
await pendingExactRequests;
|
|
226
|
+
this.exactRequests.clear();
|
|
227
|
+
this.exactIssuer = undefined;
|
|
167
228
|
// Destroy ACME HTTP transport (closes keep-alive sockets)
|
|
168
229
|
if (this.client) {
|
|
169
230
|
this.client.destroy();
|
|
@@ -176,6 +237,66 @@ export class SmartAcme {
|
|
|
176
237
|
await this.certmanager.close();
|
|
177
238
|
}
|
|
178
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
|
+
}
|
|
179
300
|
/** Retry helper with exponential backoff and AcmeError awareness */
|
|
180
301
|
async retry(operation, operationName = 'operation') {
|
|
181
302
|
let attempt = 0;
|
|
@@ -210,12 +331,12 @@ export class SmartAcme {
|
|
|
210
331
|
}
|
|
211
332
|
/** Clean up pending challenges and shut down */
|
|
212
333
|
async handleShutdown() {
|
|
213
|
-
for (const input of [...this.pendingChallenges]) {
|
|
334
|
+
for (const { input, context } of [...this.pendingChallenges]) {
|
|
214
335
|
const type = input.type;
|
|
215
336
|
const handler = this.challengeHandlers.find((h) => h.getSupportedTypes().includes(type));
|
|
216
337
|
if (handler) {
|
|
217
338
|
try {
|
|
218
|
-
await handler.cleanup(input);
|
|
339
|
+
await handler.cleanup(input, { ...context });
|
|
219
340
|
await this.logger.log('info', `Removed pending ${type} challenge during shutdown`, input);
|
|
220
341
|
}
|
|
221
342
|
catch (err) {
|
|
@@ -329,6 +450,10 @@ export class SmartAcme {
|
|
|
329
450
|
const order = await this.retry(() => this.client.createOrder({
|
|
330
451
|
identifiers,
|
|
331
452
|
}), 'createOrder');
|
|
453
|
+
const challengeContext = {
|
|
454
|
+
operationId: plugins.crypto.createHash('sha256')
|
|
455
|
+
.update(JSON.stringify(['smartacme-legacy-challenge-v1', order.url])).digest('hex'),
|
|
456
|
+
};
|
|
332
457
|
// ── Step: authorize ───────────────────────────────────────────────────
|
|
333
458
|
this.certIssuanceTask.notifyStep('authorize');
|
|
334
459
|
/* Get authorizations and select challenges */
|
|
@@ -371,9 +496,9 @@ export class SmartAcme {
|
|
|
371
496
|
else {
|
|
372
497
|
challengeInput = { type, keyAuthorization: keyAuth, ...selectedChallengeArg };
|
|
373
498
|
}
|
|
374
|
-
this.pendingChallenges.push(challengeInput);
|
|
499
|
+
this.pendingChallenges.push({ input: challengeInput, context: challengeContext });
|
|
375
500
|
try {
|
|
376
|
-
await this.retry(() => handler.prepare(challengeInput), `${type}.prepare`);
|
|
501
|
+
await this.retry(() => handler.prepare(challengeInput, { ...challengeContext }), `${type}.prepare`);
|
|
377
502
|
if (type === 'dns-01') {
|
|
378
503
|
const dnsInput = challengeInput;
|
|
379
504
|
await this.retry(() => this.smartdns.checkUntilAvailable(dnsInput.hostName, 'TXT', dnsInput.challenge, 100, 5000), `${type}.propagation`);
|
|
@@ -390,13 +515,13 @@ export class SmartAcme {
|
|
|
390
515
|
}
|
|
391
516
|
finally {
|
|
392
517
|
try {
|
|
393
|
-
await this.retry(() => handler.cleanup(challengeInput), `${type}.cleanup`);
|
|
518
|
+
await this.retry(() => handler.cleanup(challengeInput, { ...challengeContext }), `${type}.cleanup`);
|
|
394
519
|
}
|
|
395
520
|
catch (err) {
|
|
396
521
|
await this.logger.log('error', `Error during ${type}.cleanup`, err);
|
|
397
522
|
}
|
|
398
523
|
finally {
|
|
399
|
-
this.pendingChallenges = this.pendingChallenges.filter((c) => c !== challengeInput);
|
|
524
|
+
this.pendingChallenges = this.pendingChallenges.filter((c) => c.input !== challengeInput);
|
|
400
525
|
}
|
|
401
526
|
}
|
|
402
527
|
}
|
|
@@ -446,4 +571,4 @@ export class SmartAcme {
|
|
|
446
571
|
return newCertificate ?? certRecord;
|
|
447
572
|
}
|
|
448
573
|
}
|
|
449
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLmNsYXNzZXMuc21hcnRhY21lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvc21hcnRhY21lLmNsYXNzZXMuc21hcnRhY21lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBRXhDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFZNUQsTUFBTSxtQkFBbUIsR0FBRztJQUMxQixFQUFFLElBQUksRUFBRSxTQUFTLEVBQUksV0FBVyxFQUFFLHFCQUFxQixFQUFVLFVBQVUsRUFBRSxFQUFFLEVBQUU7SUFDakYsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSx5QkFBeUIsRUFBTSxVQUFVLEVBQUUsRUFBRSxFQUFFO0lBQ2pGLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRyxXQUFXLEVBQUUsNkJBQTZCLEVBQUUsVUFBVSxFQUFFLEVBQUUsRUFBRTtJQUNqRixFQUFFLElBQUksRUFBRSxPQUFPLEVBQU0sV0FBVyxFQUFFLHFCQUFxQixFQUFVLFVBQVUsRUFBRSxFQUFFLEVBQUU7Q0FDekUsQ0FBQztBQXFEWDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLE9BQU8sU0FBUztJQWlDcEI7O09BRUc7SUFDSCxJQUFXLGtCQUFrQjtRQUMzQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsV0FBVyxDQUFDO0lBQ3RDLENBQUM7SUFFRCxZQUFZLFVBQTZCO1FBbkNqQyxhQUFRLEdBQUcsSUFBSSxPQUFPLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQWdCM0QscURBQXFEO1FBQzdDLHNCQUFpQixHQUE0QyxFQUFFLENBQUM7UUFPeEUseURBQXlEO1FB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
|
|
574
|
+
//# 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.7.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": "^5.0.0",
|
|
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,91 @@ 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
|
+
|
|
172
|
+
Custom challenge handlers receive an optional second `IChallengeContext` argument
|
|
173
|
+
on `prepare`, `verify`, and `cleanup`. SmartAcme always supplies its opaque
|
|
174
|
+
`operationId`: it stays the same for an order's retries, cleanup, and exact
|
|
175
|
+
issuance recovery after restart. Renewal and isolated issuances get separate
|
|
176
|
+
owners. Combine it with the challenge type and input to key durable resource
|
|
177
|
+
intent; do not infer ownership from a hostname or TXT value alone. Existing
|
|
178
|
+
handlers accepting one argument remain supported. Built-in DNS adapters retain
|
|
179
|
+
the ownership semantics of their configured provider.
|
|
180
|
+
|
|
181
|
+
The normal `pnpm test` suite uses isolated protocol fixtures. The live Cloudflare
|
|
182
|
+
test is skipped unless `SMARTACME_LIVE_DNS_TEST=1` is explicitly set. With separate
|
|
183
|
+
authorization for public DNS changes and staging-CA issuance, run
|
|
184
|
+
`SMARTACME_LIVE_DNS_TEST=1 pnpm exec tstest test/test.smartacme.integration.ts --verbose --logfile --timeout 600`.
|
|
185
|
+
That test uses the `CF_TOKEN` credential and issues for `bleu.de` and `*.bleu.de`.
|
|
186
|
+
|
|
98
187
|
### 📦 Certificate Object
|
|
99
188
|
|
|
100
189
|
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
|
*/
|