@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.
Files changed (35) hide show
  1. package/.smartconfig.json +12 -7
  2. package/dist_ts/00_commitinfo_data.js +1 -1
  3. package/dist_ts/acme/acme.classes.client.d.ts +2 -0
  4. package/dist_ts/acme/acme.classes.client.js +5 -2
  5. package/dist_ts/acme/acme.classes.http-client.d.ts +2 -1
  6. package/dist_ts/acme/acme.classes.http-client.js +4 -2
  7. package/dist_ts/acme/acme.classes.order.d.ts +3 -0
  8. package/dist_ts/acme/acme.classes.order.js +11 -2
  9. package/dist_ts/classes.exact-certificate-issuer.d.ts +37 -0
  10. package/dist_ts/classes.exact-certificate-issuer.js +397 -0
  11. package/dist_ts/handlers/IChallengeHandler.d.ts +8 -3
  12. package/dist_ts/handlers/index.d.ts +1 -1
  13. package/dist_ts/index.d.ts +2 -0
  14. package/dist_ts/index.js +2 -1
  15. package/dist_ts/interfaces/exact-issuance.d.ts +79 -0
  16. package/dist_ts/interfaces/exact-issuance.js +2 -0
  17. package/dist_ts/plugins.d.ts +5 -1
  18. package/dist_ts/plugins.js +6 -2
  19. package/dist_ts/smartacme.classes.smartacme.d.ts +22 -0
  20. package/dist_ts/smartacme.classes.smartacme.js +141 -16
  21. package/package.json +11 -15
  22. package/readme.md +90 -1
  23. package/ts/00_commitinfo_data.ts +1 -1
  24. package/ts/acme/acme.classes.client.ts +6 -1
  25. package/ts/acme/acme.classes.http-client.ts +2 -1
  26. package/ts/acme/acme.classes.order.ts +12 -1
  27. package/ts/classes.exact-certificate-issuer.ts +408 -0
  28. package/ts/handlers/IChallengeHandler.ts +10 -4
  29. package/ts/handlers/index.ts +2 -2
  30. package/ts/index.ts +2 -0
  31. package/ts/interfaces/exact-issuance.ts +104 -0
  32. package/ts/plugins.ts +5 -1
  33. package/ts/smartacme.classes.smartacme.ts +151 -15
  34. package/readme.hints.md +0 -81
  35. 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
- // Stop the task manager
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.5.0",
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": "^8.0.2",
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.0",
64
- "@git.zone/tsrun": "^2.0.2",
65
- "@git.zone/tstest": "^3.6.3",
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": "^25.5.0"
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
- "packageManager": "pnpm@10.7.0+sha512.6b865ad4b62a1d9842b61d674a393903b871d9244954f652b8842c2b553c72176b278f64c463e52d40fff8aba385c235c8c9ecf5cc7de4fd78b8bb6d49633ab6",
85
- "pnpm": {
86
- "overrides": {}
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
- console.log(cert.privateKey); // PEM private key
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:
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartacme',
6
- version: '9.5.0',
6
+ version: '9.7.0',
7
7
  description: 'A TypeScript-based ACME client and server for certificate management with built-in CA, supporting LetsEncrypt and custom ACME authorities.'
8
8
  }
@@ -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
  */