@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
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
export function normalizeCertificateIdentifiers(input) {
|
|
3
|
+
if (!Array.isArray(input) || input.length < 1 || input.length > 100) {
|
|
4
|
+
throw new Error('Between one and 100 explicit DNS identifiers are required');
|
|
5
|
+
}
|
|
6
|
+
return [...new Set(Array.from(input, (value) => {
|
|
7
|
+
if (typeof value !== 'string' || value.length > 1024)
|
|
8
|
+
throw new Error('Invalid DNS identifier');
|
|
9
|
+
const trimmed = value.trim().toLowerCase().replace(/\.$/, '');
|
|
10
|
+
if (/[/\\:@?#%\s]/.test(trimmed))
|
|
11
|
+
throw new Error('Invalid DNS identifier');
|
|
12
|
+
const wildcard = trimmed.startsWith('*.');
|
|
13
|
+
const name = plugins.url.domainToASCII(wildcard ? trimmed.slice(2) : trimmed);
|
|
14
|
+
if (!name || plugins.net.isIP(name) !== 0 || name.length > 253 || name.split('.').length < 2
|
|
15
|
+
|| name.split('.').some((label) => !/^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/.test(label))) {
|
|
16
|
+
throw new Error('Invalid DNS identifier');
|
|
17
|
+
}
|
|
18
|
+
return `${wildcard ? '*.' : ''}${name}`;
|
|
19
|
+
}))].sort();
|
|
20
|
+
}
|
|
21
|
+
/** Owns exact-name issuance and recovery; the embedding service supplies storage. */
|
|
22
|
+
export class ExactCertificateIssuer {
|
|
23
|
+
constructor(options) {
|
|
24
|
+
this.options = options;
|
|
25
|
+
}
|
|
26
|
+
identity(request) {
|
|
27
|
+
if (typeof request.namespace !== 'string' || !/^[\x21-\x7e]{1,200}$/.test(request.namespace)) {
|
|
28
|
+
throw new Error('A nonempty printable isolation namespace of at most 200 characters is required');
|
|
29
|
+
}
|
|
30
|
+
const identifiers = normalizeCertificateIdentifiers(request.identifiers);
|
|
31
|
+
const binding = {
|
|
32
|
+
namespace: request.namespace,
|
|
33
|
+
identifiers,
|
|
34
|
+
directoryUrl: this.options.directoryUrl,
|
|
35
|
+
accountThumbprint: this.options.accountThumbprint,
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
...binding,
|
|
39
|
+
certificateKey: `exact-v1:${plugins.crypto.createHash('sha256').update(JSON.stringify(binding)).digest('hex')}`,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
async status(request) {
|
|
43
|
+
const identity = this.identity(request);
|
|
44
|
+
const record = await this.options.store.getIssuance(identity.certificateKey);
|
|
45
|
+
if (record)
|
|
46
|
+
this.validateRecord(record, identity);
|
|
47
|
+
return record ? this.info(record) : null;
|
|
48
|
+
}
|
|
49
|
+
/** Validate the cache before taking any issuance or CA rate-limit slot. */
|
|
50
|
+
async cached(request) {
|
|
51
|
+
const identity = this.identity(request);
|
|
52
|
+
const certificate = await this.options.store.getCertificate(identity.certificateKey);
|
|
53
|
+
if (!certificate)
|
|
54
|
+
return null;
|
|
55
|
+
this.validateCertificate(certificate, identity);
|
|
56
|
+
const record = await this.options.store.getIssuance(identity.certificateKey);
|
|
57
|
+
if (record?.status !== 'ready' || certificate.id !== record.issuanceId
|
|
58
|
+
|| Date.now() >= certificate.renewAfter || Date.now() >= certificate.validUntil)
|
|
59
|
+
return null;
|
|
60
|
+
this.validateRecord(record, identity);
|
|
61
|
+
return { status: 'ready', certificate, issuance: this.info(record) };
|
|
62
|
+
}
|
|
63
|
+
async run(request) {
|
|
64
|
+
this.options.signal.throwIfAborted();
|
|
65
|
+
const identity = this.identity(request);
|
|
66
|
+
let record = await this.options.store.getIssuance(identity.certificateKey);
|
|
67
|
+
const cached = await this.options.store.getCertificate(identity.certificateKey);
|
|
68
|
+
if (cached) {
|
|
69
|
+
this.validateCertificate(cached, identity);
|
|
70
|
+
if (record?.status === 'ready' && cached.id === record.issuanceId && Date.now() < cached.renewAfter) {
|
|
71
|
+
this.validateRecord(record, identity);
|
|
72
|
+
return { status: 'ready', certificate: cached, issuance: this.info(record) };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (record?.status === 'ready' && !cached) {
|
|
76
|
+
this.validateRecord(record, identity);
|
|
77
|
+
return await this.advance(record, true);
|
|
78
|
+
}
|
|
79
|
+
if (!record || record.status === 'ready') {
|
|
80
|
+
const [privateKey, csr] = await plugins.acme.AcmeCrypto.createCsr({
|
|
81
|
+
commonName: identity.identifiers[0], altNames: identity.identifiers.slice(1),
|
|
82
|
+
});
|
|
83
|
+
const next = {
|
|
84
|
+
...identity, issuanceId: plugins.crypto.randomUUID(), revision: (record?.revision ?? -1) + 1,
|
|
85
|
+
status: 'prepared', createdAt: Date.now(), updatedAt: Date.now(), privateKey, csr,
|
|
86
|
+
pendingChallenges: [],
|
|
87
|
+
};
|
|
88
|
+
this.options.signal.throwIfAborted();
|
|
89
|
+
if (!await this.options.store.compareAndSetIssuance(identity.certificateKey, record?.revision ?? null, next)) {
|
|
90
|
+
const current = await this.requiredRecord(identity.certificateKey);
|
|
91
|
+
return { status: 'pending', issuance: this.info(current) };
|
|
92
|
+
}
|
|
93
|
+
record = next;
|
|
94
|
+
}
|
|
95
|
+
this.validateRecord(record, identity);
|
|
96
|
+
return await this.advance(record, false);
|
|
97
|
+
}
|
|
98
|
+
async recover(request) {
|
|
99
|
+
if (!['recheck', 'retry-proven-unapplied', 'abandon'].includes(request.action)
|
|
100
|
+
|| !Number.isSafeInteger(request.expectedRevision) || request.expectedRevision < 0
|
|
101
|
+
|| typeof request.issuanceId !== 'string' || !request.issuanceId) {
|
|
102
|
+
throw new Error('Invalid issuance recovery request');
|
|
103
|
+
}
|
|
104
|
+
const identity = this.identity(request);
|
|
105
|
+
let record = await this.requiredRecord(identity.certificateKey);
|
|
106
|
+
this.validateRecord(record, identity);
|
|
107
|
+
if (record.issuanceId !== request.issuanceId || record.revision !== request.expectedRevision) {
|
|
108
|
+
throw new Error('Issuance recovery revision conflict');
|
|
109
|
+
}
|
|
110
|
+
if (request.action === 'abandon') {
|
|
111
|
+
if (record.status === 'ready')
|
|
112
|
+
throw new Error('A completed issuance cannot be abandoned');
|
|
113
|
+
record = await this.save(record, { status: 'abandoned_unverified' });
|
|
114
|
+
await this.cleanup(record);
|
|
115
|
+
return { status: 'pending', issuance: this.info(await this.requiredRecord(record.certificateKey)) };
|
|
116
|
+
}
|
|
117
|
+
if (record.status === 'abandoned_unverified') {
|
|
118
|
+
throw new Error('Abandoned issuance requires external resolution; new issuance remains blocked');
|
|
119
|
+
}
|
|
120
|
+
if (request.action === 'retry-proven-unapplied') {
|
|
121
|
+
// Only an acknowledged rejection of newOrder proves no order was created.
|
|
122
|
+
if (record.order || record.status !== 'failed' || record.errorCode !== 'rate_limited') {
|
|
123
|
+
throw new Error('The previous external effect is not proven unapplied');
|
|
124
|
+
}
|
|
125
|
+
if (record.retryAfter && record.retryAfter > Date.now()) {
|
|
126
|
+
return { status: 'pending', issuance: this.info(record) };
|
|
127
|
+
}
|
|
128
|
+
record = await this.save(record, { status: 'prepared', errorCode: undefined, retryAfter: undefined });
|
|
129
|
+
return await this.advance(record, false);
|
|
130
|
+
}
|
|
131
|
+
return await this.advance(record, true);
|
|
132
|
+
}
|
|
133
|
+
async advance(initial, recheckOnly) {
|
|
134
|
+
let record = initial;
|
|
135
|
+
this.options.signal.throwIfAborted();
|
|
136
|
+
if (record.status === 'abandoned_unverified' || record.status === 'failed') {
|
|
137
|
+
return { status: 'pending', issuance: this.info(record) };
|
|
138
|
+
}
|
|
139
|
+
if (record.status === 'creating' || (record.status === 'indeterminate' && !record.order)) {
|
|
140
|
+
record = await this.save(record, { status: 'indeterminate', errorCode: 'order_outcome_unknown' });
|
|
141
|
+
return { status: 'pending', issuance: this.info(record) };
|
|
142
|
+
}
|
|
143
|
+
if (record.status === 'prepared') {
|
|
144
|
+
if (recheckOnly)
|
|
145
|
+
return { status: 'pending', issuance: this.info(record) };
|
|
146
|
+
// Prove challenge support before creating an irreversible CA order.
|
|
147
|
+
await this.handler(record);
|
|
148
|
+
record = await this.save(record, { status: 'creating' });
|
|
149
|
+
let order;
|
|
150
|
+
try {
|
|
151
|
+
this.options.signal.throwIfAborted();
|
|
152
|
+
order = await this.options.client.createOrder({
|
|
153
|
+
identifiers: record.identifiers.map((value) => ({ type: 'dns', value })),
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
const rejected = error instanceof plugins.acme.AcmeError && error.isRateLimited;
|
|
158
|
+
record = await this.save(record, {
|
|
159
|
+
status: rejected ? 'failed' : 'indeterminate',
|
|
160
|
+
errorCode: rejected ? 'rate_limited' : 'order_outcome_unknown',
|
|
161
|
+
retryAfter: rejected ? Date.now() + Math.max(error.retryAfter, 60) * 1000 : undefined,
|
|
162
|
+
});
|
|
163
|
+
return { status: 'pending', issuance: this.info(record) };
|
|
164
|
+
}
|
|
165
|
+
if (!order.url) {
|
|
166
|
+
record = await this.save(record, { status: 'indeterminate', errorCode: 'order_outcome_unknown' });
|
|
167
|
+
return { status: 'pending', issuance: this.info(record) };
|
|
168
|
+
}
|
|
169
|
+
record = await this.save(record, { order, status: 'authorizing' });
|
|
170
|
+
}
|
|
171
|
+
if (!record.order)
|
|
172
|
+
throw new Error('Issuance record has no acknowledged order');
|
|
173
|
+
const observed = await this.options.client.getOrder(record.order.url);
|
|
174
|
+
this.validateOrder(observed, record);
|
|
175
|
+
record = await this.save(record, { order: observed, errorCode: undefined });
|
|
176
|
+
if (observed.status === 'invalid' || observed.status === 'expired' || observed.status === 'revoked') {
|
|
177
|
+
record = await this.save(record, { status: 'failed', errorCode: 'order_invalid' });
|
|
178
|
+
await this.cleanup(record);
|
|
179
|
+
return { status: 'pending', issuance: this.info(await this.requiredRecord(record.certificateKey)) };
|
|
180
|
+
}
|
|
181
|
+
if (observed.status === 'valid')
|
|
182
|
+
return await this.finish(record);
|
|
183
|
+
if (recheckOnly) {
|
|
184
|
+
return { status: 'pending', issuance: this.info(record) };
|
|
185
|
+
}
|
|
186
|
+
if (record.status === 'finalizing' || record.status === 'indeterminate') {
|
|
187
|
+
// Acknowledged processing/ready observations do not prove a previous
|
|
188
|
+
// finalize request was unapplied. Never send a new CSR on uncertainty.
|
|
189
|
+
record = await this.save(record, { status: 'indeterminate', errorCode: 'order_outcome_unknown' });
|
|
190
|
+
return { status: 'pending', issuance: this.info(record) };
|
|
191
|
+
}
|
|
192
|
+
if (observed.status === 'pending') {
|
|
193
|
+
record = await this.authorize(record);
|
|
194
|
+
if (record.status === 'failed')
|
|
195
|
+
return { status: 'pending', issuance: this.info(record) };
|
|
196
|
+
}
|
|
197
|
+
const ready = await this.options.client.getOrder(record.order.url);
|
|
198
|
+
this.validateOrder(ready, record);
|
|
199
|
+
record = await this.save(record, { order: ready });
|
|
200
|
+
if (ready.status === 'valid')
|
|
201
|
+
return await this.finish(record);
|
|
202
|
+
if (ready.status !== 'ready') {
|
|
203
|
+
return { status: 'pending', issuance: this.info(record) };
|
|
204
|
+
}
|
|
205
|
+
record = await this.save(record, { status: 'finalizing' });
|
|
206
|
+
try {
|
|
207
|
+
this.options.signal.throwIfAborted();
|
|
208
|
+
await this.options.client.finalizeOrder(structuredClone(ready), record.csr);
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
// Preserve the acknowledged order and original key/CSR for safe recheck.
|
|
212
|
+
record = await this.save(record, { status: 'indeterminate', errorCode: 'order_outcome_unknown' });
|
|
213
|
+
return { status: 'pending', issuance: this.info(record) };
|
|
214
|
+
}
|
|
215
|
+
const finalized = await this.options.client.getOrder(ready.url);
|
|
216
|
+
this.validateOrder(finalized, record);
|
|
217
|
+
record = await this.save(record, { order: finalized });
|
|
218
|
+
return finalized.status === 'valid'
|
|
219
|
+
? await this.finish(record)
|
|
220
|
+
: { status: 'pending', issuance: this.info(record) };
|
|
221
|
+
}
|
|
222
|
+
async authorize(initial) {
|
|
223
|
+
let record = initial;
|
|
224
|
+
const handler = await this.handler(record);
|
|
225
|
+
const authorizations = await this.options.client.getAuthorizations(record.order);
|
|
226
|
+
for (const authorization of authorizations) {
|
|
227
|
+
this.options.signal.throwIfAborted();
|
|
228
|
+
const identifier = `${authorization.wildcard ? '*.' : ''}${authorization.identifier.value}`;
|
|
229
|
+
if (authorization.identifier.type !== 'dns' || !record.identifiers.includes(identifier)) {
|
|
230
|
+
throw new Error('CA authorization is outside the requested identifiers');
|
|
231
|
+
}
|
|
232
|
+
if (authorization.status === 'valid')
|
|
233
|
+
continue;
|
|
234
|
+
if (authorization.status !== 'pending') {
|
|
235
|
+
return await this.save(record, { status: 'failed', errorCode: 'authorization_failed' });
|
|
236
|
+
}
|
|
237
|
+
const challenge = authorization.challenges.find((value) => value.type === 'dns-01');
|
|
238
|
+
if (!challenge)
|
|
239
|
+
throw new Error('The CA did not offer DNS-01');
|
|
240
|
+
const input = {
|
|
241
|
+
hostName: `_acme-challenge.${authorization.identifier.value}`,
|
|
242
|
+
challenge: this.options.client.getChallengeKeyAuthorization(challenge),
|
|
243
|
+
};
|
|
244
|
+
if (!record.pendingChallenges.some((value) => value.hostName === input.hostName && value.challenge === input.challenge)) {
|
|
245
|
+
record = await this.save(record, { pendingChallenges: [...record.pendingChallenges, input] });
|
|
246
|
+
}
|
|
247
|
+
try {
|
|
248
|
+
await handler.prepare(input, this.challengeContext(record));
|
|
249
|
+
if (handler.verify) {
|
|
250
|
+
await handler.verify(input, this.challengeContext(record));
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
let visible = false;
|
|
254
|
+
for (let attempt = 0; attempt < 100; attempt++) {
|
|
255
|
+
this.options.signal.throwIfAborted();
|
|
256
|
+
const records = await this.options.dns.getRecords(input.hostName, 'TXT', 0);
|
|
257
|
+
if (records.some((value) => value.value === input.challenge)) {
|
|
258
|
+
visible = true;
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
await plugins.timers.setTimeout(1000, undefined, { signal: this.options.signal });
|
|
262
|
+
}
|
|
263
|
+
if (!visible)
|
|
264
|
+
throw new Error('DNS-01 propagation timed out');
|
|
265
|
+
}
|
|
266
|
+
await plugins.timers.setTimeout(this.options.dnsPropagationDelayMs, undefined, { signal: this.options.signal });
|
|
267
|
+
await this.options.client.completeChallenge(challenge);
|
|
268
|
+
await this.options.client.waitForValidStatus(challenge);
|
|
269
|
+
}
|
|
270
|
+
finally {
|
|
271
|
+
// Persist cleanup intent until cleanup actually succeeds, including
|
|
272
|
+
// failure during prepare, process shutdown, or certificate retrieval.
|
|
273
|
+
await handler.cleanup(input, this.challengeContext(record));
|
|
274
|
+
record = await this.save(record, {
|
|
275
|
+
pendingChallenges: record.pendingChallenges.filter((value) => value.hostName !== input.hostName || value.challenge !== input.challenge),
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return record;
|
|
280
|
+
}
|
|
281
|
+
async finish(initial) {
|
|
282
|
+
let record = initial;
|
|
283
|
+
if (!record.order?.certificate)
|
|
284
|
+
throw new Error('Completed order has no certificate URL');
|
|
285
|
+
const pem = await this.options.client.getCertificate(record.order);
|
|
286
|
+
const x509 = new plugins.crypto.X509Certificate(pem);
|
|
287
|
+
const validFrom = new Date(x509.validFrom).getTime();
|
|
288
|
+
const validUntil = new Date(x509.validTo).getTime();
|
|
289
|
+
const certificate = {
|
|
290
|
+
...this.identity(record), id: record.issuanceId, created: Date.now(),
|
|
291
|
+
privateKey: record.privateKey, csr: record.csr, publicKey: pem, validFrom, validUntil,
|
|
292
|
+
renewAfter: validUntil - Math.min(10 * 86400000, (validUntil - validFrom) / 3),
|
|
293
|
+
};
|
|
294
|
+
try {
|
|
295
|
+
this.validateCertificate(certificate, record);
|
|
296
|
+
if (validUntil <= Date.now())
|
|
297
|
+
throw new Error('CA returned an expired certificate');
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
record = await this.save(record, { status: 'failed', errorCode: 'certificate_invalid' });
|
|
301
|
+
return { status: 'pending', issuance: this.info(record) };
|
|
302
|
+
}
|
|
303
|
+
await this.cleanup(record);
|
|
304
|
+
record = await this.requiredRecord(record.certificateKey);
|
|
305
|
+
if (record.status === 'abandoned_unverified') {
|
|
306
|
+
return { status: 'pending', issuance: this.info(record) };
|
|
307
|
+
}
|
|
308
|
+
await this.options.store.storeCertificate(certificate);
|
|
309
|
+
record = await this.save(record, { status: 'ready', errorCode: undefined });
|
|
310
|
+
return { status: 'ready', certificate, issuance: this.info(record) };
|
|
311
|
+
}
|
|
312
|
+
async handler(record) {
|
|
313
|
+
const handler = this.options.handlers.find((value) => value.getSupportedTypes().includes('dns-01'));
|
|
314
|
+
if (!handler)
|
|
315
|
+
throw new Error('Exact issuance requires DNS-01');
|
|
316
|
+
for (const identifier of record.identifiers) {
|
|
317
|
+
if (!await handler.checkWetherDomainIsSupported(identifier.replace(/^\*\./, ''))) {
|
|
318
|
+
throw new Error('DNS-01 ownership is unavailable for a requested identifier');
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return handler;
|
|
322
|
+
}
|
|
323
|
+
async cleanup(initial) {
|
|
324
|
+
let record = initial;
|
|
325
|
+
if (!record.pendingChallenges.length)
|
|
326
|
+
return;
|
|
327
|
+
const handler = this.options.handlers.find((value) => value.getSupportedTypes().includes('dns-01'));
|
|
328
|
+
if (!handler)
|
|
329
|
+
throw new Error('DNS-01 cleanup handler is unavailable');
|
|
330
|
+
for (const input of [...record.pendingChallenges]) {
|
|
331
|
+
await handler.cleanup(input, this.challengeContext(record));
|
|
332
|
+
record = await this.save(record, {
|
|
333
|
+
pendingChallenges: record.pendingChallenges.filter((value) => value.hostName !== input.hostName || value.challenge !== input.challenge),
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
challengeContext(record) {
|
|
338
|
+
return { operationId: plugins.crypto.createHash('sha256')
|
|
339
|
+
.update(JSON.stringify(['smartacme-exact-challenge-v1', record.certificateKey, record.issuanceId])).digest('hex') };
|
|
340
|
+
}
|
|
341
|
+
validateRecord(record, identity) {
|
|
342
|
+
if (record.certificateKey !== identity.certificateKey
|
|
343
|
+
|| this.identity(record).certificateKey !== identity.certificateKey
|
|
344
|
+
|| record.accountThumbprint !== identity.accountThumbprint || record.directoryUrl !== identity.directoryUrl) {
|
|
345
|
+
throw new Error('Issuance storage identity mismatch');
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
validateOrder(order, record) {
|
|
349
|
+
if (!order.url || order.identifiers.some((value) => value.type !== 'dns')
|
|
350
|
+
|| JSON.stringify(normalizeCertificateIdentifiers(order.identifiers.map((value) => value.value))) !== JSON.stringify(record.identifiers)) {
|
|
351
|
+
throw new Error('CA order identifiers do not match the certificate request');
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
validateCertificate(certificate, identity) {
|
|
355
|
+
if (certificate.certificateKey !== identity.certificateKey
|
|
356
|
+
|| this.identity(certificate).certificateKey !== identity.certificateKey
|
|
357
|
+
|| certificate.accountThumbprint !== identity.accountThumbprint || certificate.directoryUrl !== identity.directoryUrl) {
|
|
358
|
+
throw new Error('Certificate storage identity mismatch');
|
|
359
|
+
}
|
|
360
|
+
const parsed = new plugins.x509.X509Certificate(certificate.publicKey);
|
|
361
|
+
const names = parsed.getExtension(plugins.x509.SubjectAlternativeNameExtension)?.names.toJSON();
|
|
362
|
+
if (!names || names.some((value) => value.type !== 'dns')
|
|
363
|
+
|| JSON.stringify(normalizeCertificateIdentifiers(names.map((value) => value.value))) !== JSON.stringify(identity.identifiers)) {
|
|
364
|
+
throw new Error('Certificate identifiers exceed or differ from the requested scope');
|
|
365
|
+
}
|
|
366
|
+
const x509 = new plugins.crypto.X509Certificate(certificate.publicKey);
|
|
367
|
+
if (x509.ca || !x509.checkPrivateKey(plugins.crypto.createPrivateKey(certificate.privateKey))
|
|
368
|
+
|| new Date(x509.validFrom).getTime() !== certificate.validFrom
|
|
369
|
+
|| new Date(x509.validTo).getTime() !== certificate.validUntil
|
|
370
|
+
|| certificate.validFrom > Date.now() + 300000
|
|
371
|
+
|| !Number.isFinite(certificate.renewAfter) || certificate.renewAfter >= certificate.validUntil) {
|
|
372
|
+
throw new Error('Invalid certificate key, lifetime, or constraints');
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
info(record) {
|
|
376
|
+
return {
|
|
377
|
+
certificateKey: record.certificateKey, issuanceId: record.issuanceId,
|
|
378
|
+
identifiers: [...record.identifiers], status: record.status, revision: record.revision,
|
|
379
|
+
createdAt: record.createdAt, updatedAt: record.updatedAt,
|
|
380
|
+
errorCode: record.errorCode, retryAfter: record.retryAfter,
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
async requiredRecord(key) {
|
|
384
|
+
const record = await this.options.store.getIssuance(key);
|
|
385
|
+
if (!record)
|
|
386
|
+
throw new Error('Issuance recovery record is missing');
|
|
387
|
+
return record;
|
|
388
|
+
}
|
|
389
|
+
async save(record, patch) {
|
|
390
|
+
const next = { ...record, ...patch, revision: record.revision + 1, updatedAt: Date.now() };
|
|
391
|
+
if (!await this.options.store.compareAndSetIssuance(record.certificateKey, record.revision, next)) {
|
|
392
|
+
throw new Error('Issuance changed concurrently; reload its durable state before proceeding');
|
|
393
|
+
}
|
|
394
|
+
return next;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5leGFjdC1jZXJ0aWZpY2F0ZS1pc3N1ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9jbGFzc2VzLmV4YWN0LWNlcnRpZmljYXRlLWlzc3Vlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQVl4QyxNQUFNLFVBQVUsK0JBQStCLENBQUMsS0FBd0I7SUFDdEUsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQztRQUNwRSxNQUFNLElBQUksS0FBSyxDQUFDLDJEQUEyRCxDQUFDLENBQUM7SUFDL0UsQ0FBQztJQUNELE9BQU8sQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDN0MsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxJQUFJO2dCQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsd0JBQXdCLENBQUMsQ0FBQztZQUNoRyxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztZQUM5RCxJQUFJLGNBQWMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2dCQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsd0JBQXdCLENBQUMsQ0FBQztZQUM1RSxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzFDLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDOUUsSUFBSSxDQUFDLElBQUksSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQzttQkFDdkYsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsd0NBQXdDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDNUYsTUFBTSxJQUFJLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1lBQzVDLENBQUM7WUFDRCxPQUFPLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxJQUFJLEVBQUUsQ0FBQztRQUMxQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDZCxDQUFDO0FBY0QscUZBQXFGO0FBQ3JGLE1BQU0sT0FBTyxzQkFBc0I7SUFDakMsWUFBb0IsT0FBdUM7UUFBdkMsWUFBTyxHQUFQLE9BQU8sQ0FBZ0M7SUFBRyxDQUFDO0lBRXhELFFBQVEsQ0FBQyxPQUFpQztRQUMvQyxJQUFJLE9BQU8sT0FBTyxDQUFDLFNBQVMsS0FBSyxRQUFRLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDN0YsTUFBTSxJQUFJLEtBQUssQ0FBQyxnRkFBZ0YsQ0FBQyxDQUFDO1FBQ3BHLENBQUM7UUFDRCxNQUFNLFdBQVcsR0FBRywrQkFBK0IsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDekUsTUFBTSxPQUFPLEdBQUc7WUFDZCxTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVM7WUFDNUIsV0FBVztZQUNYLFlBQVksRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVk7WUFDdkMsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUI7U0FDbEQsQ0FBQztRQUNGLE9BQU87WUFDTCxHQUFHLE9BQU87WUFDVixjQUFjLEVBQUUsWUFBWSxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRTtTQUNoSCxDQUFDO0lBQ0osQ0FBQztJQUVNLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBaUM7UUFDbkQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN4QyxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDN0UsSUFBSSxNQUFNO1lBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDbEQsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUMzQyxDQUFDO0lBRUQsMkVBQTJFO0lBQ3BFLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBaUM7UUFDbkQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN4QyxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDckYsSUFBSSxDQUFDLFdBQVc7WUFBRSxPQUFPLElBQUksQ0FBQztRQUM5QixJQUFJLENBQUMsbUJBQW1CLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ2hELE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUM3RSxJQUFJLE1BQU0sRUFBRSxNQUFNLEtBQUssT0FBTyxJQUFJLFdBQVcsQ0FBQyxFQUFFLEtBQUssTUFBTSxDQUFDLFVBQVU7ZUFDakUsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLFdBQVcsQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLFdBQVcsQ0FBQyxVQUFVO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDL0YsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDdEMsT0FBTyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7SUFDdkUsQ0FBQztJQUVNLEtBQUssQ0FBQyxHQUFHLENBQUMsT0FBaUM7UUFDaEQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDckMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN4QyxJQUFJLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDM0UsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2hGLElBQUksTUFBTSxFQUFFLENBQUM7WUFDWCxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQzNDLElBQUksTUFBTSxFQUFFLE1BQU0sS0FBSyxPQUFPLElBQUksTUFBTSxDQUFDLEVBQUUsS0FBSyxNQUFNLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ3BHLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUN0QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDL0UsQ0FBQztRQUNILENBQUM7UUFDRCxJQUFJLE1BQU0sRUFBRSxNQUFNLEtBQUssT0FBTyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDMUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDdEMsT0FBTyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzFDLENBQUM7UUFDRCxJQUFJLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssT0FBTyxFQUFFLENBQUM7WUFDekMsTUFBTSxDQUFDLFVBQVUsRUFBRSxHQUFHLENBQUMsR0FBRyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQztnQkFDaEUsVUFBVSxFQUFFLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQzthQUM3RSxDQUFDLENBQUM7WUFDSCxNQUFNLElBQUksR0FBeUI7Z0JBQ2pDLEdBQUcsUUFBUSxFQUFFLFVBQVUsRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxFQUFFLFFBQVEsRUFBRSxDQUFDLE1BQU0sRUFBRSxRQUFRLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO2dCQUM1RixNQUFNLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsRUFBRSxVQUFVLEVBQUUsR0FBRztnQkFDakYsaUJBQWlCLEVBQUUsRUFBRTthQUN0QixDQUFDO1lBQ0YsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDckMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMscUJBQXFCLENBQUMsUUFBUSxDQUFDLGNBQWMsRUFBRSxNQUFNLEVBQUUsUUFBUSxJQUFJLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUM3RyxNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxDQUFDO2dCQUNuRSxPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQzdELENBQUM7WUFDRCxNQUFNLEdBQUcsSUFBSSxDQUFDO1FBQ2hCLENBQUM7UUFDRCxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN0QyxPQUFPLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVNLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBc0M7UUFDekQsSUFBSSxDQUFDLENBQUMsU0FBUyxFQUFFLHdCQUF3QixFQUFFLFNBQVMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO2VBQ3pFLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxPQUFPLENBQUMsZ0JBQWdCLEdBQUcsQ0FBQztlQUMvRSxPQUFPLE9BQU8sQ0FBQyxVQUFVLEtBQUssUUFBUSxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ25FLE1BQU0sSUFBSSxLQUFLLENBQUMsbUNBQW1DLENBQUMsQ0FBQztRQUN2RCxDQUFDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN4QyxJQUFJLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2hFLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3RDLElBQUksTUFBTSxDQUFDLFVBQVUsS0FBSyxPQUFPLENBQUMsVUFBVSxJQUFJLE1BQU0sQ0FBQyxRQUFRLEtBQUssT0FBTyxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDN0YsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO1FBQ3pELENBQUM7UUFDRCxJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDakMsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLE9BQU87Z0JBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO1lBQzNGLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsTUFBTSxFQUFFLHNCQUFzQixFQUFFLENBQUMsQ0FBQztZQUNyRSxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDM0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDdEcsQ0FBQztRQUNELElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxzQkFBc0IsRUFBRSxDQUFDO1lBQzdDLE1BQU0sSUFBSSxLQUFLLENBQUMsK0VBQStFLENBQUMsQ0FBQztRQUNuRyxDQUFDO1FBQ0QsSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLHdCQUF3QixFQUFFLENBQUM7WUFDaEQsMEVBQTBFO1lBQzFFLElBQUksTUFBTSxDQUFDLEtBQUssSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLFFBQVEsSUFBSSxNQUFNLENBQUMsU0FBUyxLQUFLLGNBQWMsRUFBRSxDQUFDO2dCQUN0RixNQUFNLElBQUksS0FBSyxDQUFDLHNEQUFzRCxDQUFDLENBQUM7WUFDMUUsQ0FBQztZQUNELElBQUksTUFBTSxDQUFDLFVBQVUsSUFBSSxNQUFNLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDO2dCQUN4RCxPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQzVELENBQUM7WUFDRCxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQztZQUN0RyxPQUFPLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDM0MsQ0FBQztRQUNELE9BQU8sTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUE2QixFQUFFLFdBQW9CO1FBQ3ZFLElBQUksTUFBTSxHQUFHLE9BQU8sQ0FBQztRQUNyQixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUNyQyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssc0JBQXNCLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUMzRSxPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQzVELENBQUM7UUFDRCxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssVUFBVSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sS0FBSyxlQUFlLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN6RixNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsU0FBUyxFQUFFLHVCQUF1QixFQUFFLENBQUMsQ0FBQztZQUNsRyxPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQzVELENBQUM7UUFDRCxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDakMsSUFBSSxXQUFXO2dCQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDM0Usb0VBQW9FO1lBQ3BFLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMzQixNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDO1lBQ3pELElBQUksS0FBOEIsQ0FBQztZQUNuQyxJQUFJLENBQUM7Z0JBQ0gsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQ3JDLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQztvQkFDNUMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO2lCQUN6RSxDQUFDLENBQUM7WUFDTCxDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZixNQUFNLFFBQVEsR0FBRyxLQUFLLFlBQVksT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksS0FBSyxDQUFDLGFBQWEsQ0FBQztnQkFDaEYsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7b0JBQy9CLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsZUFBZTtvQkFDN0MsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyx1QkFBdUI7b0JBQzlELFVBQVUsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTO2lCQUN0RixDQUFDLENBQUM7Z0JBQ0gsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUM1RCxDQUFDO1lBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQkFDZixNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsU0FBUyxFQUFFLHVCQUF1QixFQUFFLENBQUMsQ0FBQztnQkFDbEcsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUM1RCxDQUFDO1lBQ0QsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxDQUFDLENBQUM7UUFDckUsQ0FBQztRQUNELElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsMkNBQTJDLENBQUMsQ0FBQztRQUNoRixNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3RFLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUM1RSxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssU0FBUyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssU0FBUyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDcEcsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsQ0FBQyxDQUFDO1lBQ25GLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMzQixPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUN0RyxDQUFDO1FBQ0QsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLE9BQU87WUFBRSxPQUFPLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNsRSxJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQ2hCLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDNUQsQ0FBQztRQUNELElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxZQUFZLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxlQUFlLEVBQUUsQ0FBQztZQUN4RSxxRUFBcUU7WUFDckUsdUVBQXVFO1lBQ3ZFLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsTUFBTSxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsdUJBQXVCLEVBQUUsQ0FBQyxDQUFDO1lBQ2xHLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDNUQsQ0FBQztRQUNELElBQUksUUFBUSxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNsQyxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3RDLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxRQUFRO2dCQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDNUYsQ0FBQztRQUNELE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDcEUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDbEMsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUNuRCxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssT0FBTztZQUFFLE9BQU8sTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9ELElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxPQUFPLEVBQUUsQ0FBQztZQUM3QixPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQzVELENBQUM7UUFDRCxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFDO1FBQzNELElBQUksQ0FBQztZQUNILElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDOUUsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLHlFQUF5RTtZQUN6RSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLE1BQU0sRUFBRSxlQUFlLEVBQUUsU0FBUyxFQUFFLHVCQUF1QixFQUFFLENBQUMsQ0FBQztZQUNsRyxPQUFPLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQzVELENBQUM7UUFDRCxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDaEUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDdEMsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQztRQUN2RCxPQUFPLFNBQVMsQ0FBQyxNQUFNLEtBQUssT0FBTztZQUNqQyxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztZQUMzQixDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7SUFDekQsQ0FBQztJQUVPLEtBQUssQ0FBQyxTQUFTLENBQUMsT0FBNkI7UUFDbkQsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDO1FBQ3JCLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMzQyxNQUFNLGNBQWMsR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxLQUFNLENBQUMsQ0FBQztRQUNsRixLQUFLLE1BQU0sYUFBYSxJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQzNDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sVUFBVSxHQUFHLEdBQUcsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsYUFBYSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUM1RixJQUFJLGFBQWEsQ0FBQyxVQUFVLENBQUMsSUFBSSxLQUFLLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7Z0JBQ3hGLE1BQU0sSUFBSSxLQUFLLENBQUMsdURBQXVELENBQUMsQ0FBQztZQUMzRSxDQUFDO1lBQ0QsSUFBSSxhQUFhLENBQUMsTUFBTSxLQUFLLE9BQU87Z0JBQUUsU0FBUztZQUMvQyxJQUFJLGFBQWEsQ0FBQyxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3ZDLE9BQU8sTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLHNCQUFzQixFQUFFLENBQUMsQ0FBQztZQUMxRixDQUFDO1lBQ0QsTUFBTSxTQUFTLEdBQUcsYUFBYSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssUUFBUSxDQUFDLENBQUM7WUFDcEYsSUFBSSxDQUFDLFNBQVM7Z0JBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO1lBQy9ELE1BQU0sS0FBSyxHQUFHO2dCQUNaLFFBQVEsRUFBRSxtQkFBbUIsYUFBYSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUU7Z0JBQzdELFNBQVMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyw0QkFBNEIsQ0FBQyxTQUFTLENBQUM7YUFDdkUsQ0FBQztZQUNGLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsUUFBUSxLQUFLLEtBQUssQ0FBQyxRQUFRLElBQUksS0FBSyxDQUFDLFNBQVMsS0FBSyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztnQkFDeEgsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxpQkFBaUIsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNoRyxDQUFDO1lBQ0QsSUFBSSxDQUFDO2dCQUNILE1BQU0sT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7Z0JBQzVELElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO29CQUNuQixNQUFNLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO2dCQUM3RCxDQUFDO3FCQUFNLENBQUM7b0JBQ04sSUFBSSxPQUFPLEdBQUcsS0FBSyxDQUFDO29CQUNwQixLQUFLLElBQUksT0FBTyxHQUFHLENBQUMsRUFBRSxPQUFPLEdBQUcsR0FBRyxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUM7d0JBQy9DLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDO3dCQUNyQyxNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQzt3QkFDNUUsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxLQUFLLEtBQUssQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDOzRCQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7NEJBQUMsTUFBTTt3QkFBQyxDQUFDO3dCQUN4RixNQUFNLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO29CQUNwRixDQUFDO29CQUNELElBQUksQ0FBQyxPQUFPO3dCQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQztnQkFDaEUsQ0FBQztnQkFDRCxNQUFNLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMscUJBQXFCLEVBQUUsU0FBUyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztnQkFDaEgsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDdkQsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUMxRCxDQUFDO29CQUFTLENBQUM7Z0JBQ1Qsb0VBQW9FO2dCQUNwRSxzRUFBc0U7Z0JBQ3RFLE1BQU0sT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7Z0JBQzVELE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO29CQUMvQixpQkFBaUIsRUFBRSxNQUFNLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsUUFBUSxLQUFLLEtBQUssQ0FBQyxRQUFRLElBQUksS0FBSyxDQUFDLFNBQVMsS0FBSyxLQUFLLENBQUMsU0FBUyxDQUFDO2lCQUN4SSxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFTyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQTZCO1FBQ2hELElBQUksTUFBTSxHQUFHLE9BQU8sQ0FBQztRQUNyQixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxXQUFXO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1FBQzFGLE1BQU0sR0FBRyxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNuRSxNQUFNLElBQUksR0FBRyxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3JELE1BQU0sU0FBUyxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNyRCxNQUFNLFVBQVUsR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDcEQsTUFBTSxXQUFXLEdBQXNCO1lBQ3JDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsTUFBTSxDQUFDLFVBQVUsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRTtZQUNwRSxVQUFVLEVBQUUsTUFBTSxDQUFDLFVBQVUsRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLEdBQUcsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxVQUFVO1lBQ3JGLFVBQVUsRUFBRSxVQUFVLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsUUFBUSxFQUFFLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUMvRSxDQUFDO1FBQ0YsSUFBSSxDQUFDO1lBQ0gsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM5QyxJQUFJLFVBQVUsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFO2dCQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsb0NBQW9DLENBQUMsQ0FBQztRQUN0RixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxxQkFBcUIsRUFBRSxDQUFDLENBQUM7WUFDekYsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUM1RCxDQUFDO1FBQ0QsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzNCLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzFELElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxzQkFBc0IsRUFBRSxDQUFDO1lBQzdDLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDNUQsQ0FBQztRQUNELE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDdkQsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQzVFLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO0lBQ3ZFLENBQUM7SUFFTyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQWlDO1FBQ3JELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLGlCQUFpQixFQUFFLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDcEcsSUFBSSxDQUFDLE9BQU87WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLGdDQUFnQyxDQUFDLENBQUM7UUFDaEUsS0FBSyxNQUFNLFVBQVUsSUFBSSxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDNUMsSUFBSSxDQUFDLE1BQU0sT0FBTyxDQUFDLDRCQUE0QixDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDakYsTUFBTSxJQUFJLEtBQUssQ0FBQyw0REFBNEQsQ0FBQyxDQUFDO1lBQ2hGLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVPLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBNkI7UUFDakQsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsTUFBTTtZQUFFLE9BQU87UUFDN0MsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUNwRyxJQUFJLENBQUMsT0FBTztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsdUNBQXVDLENBQUMsQ0FBQztRQUN2RSxLQUFLLE1BQU0sS0FBSyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDO1lBQ2xELE1BQU0sT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDNUQsTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7Z0JBQy9CLGlCQUFpQixFQUFFLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxRQUFRLEtBQUssS0FBSyxDQUFDLFFBQVEsSUFBSSxLQUFLLENBQUMsU0FBUyxLQUFLLEtBQUssQ0FBQyxTQUFTLENBQUM7YUFDeEksQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7SUFFTyxnQkFBZ0IsQ0FBQyxNQUE0QjtRQUNuRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQztpQkFDdEQsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyw4QkFBOEIsRUFBRSxNQUFNLENBQUMsY0FBYyxFQUFFLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7SUFDeEgsQ0FBQztJQUVPLGNBQWMsQ0FBQyxNQUE0QixFQUFFLFFBQW1DO1FBQ3RGLElBQUksTUFBTSxDQUFDLGNBQWMsS0FBSyxRQUFRLENBQUMsY0FBYztlQUNoRCxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLGNBQWMsS0FBSyxRQUFRLENBQUMsY0FBYztlQUNoRSxNQUFNLENBQUMsaUJBQWlCLEtBQUssUUFBUSxDQUFDLGlCQUFpQixJQUFJLE1BQU0sQ0FBQyxZQUFZLEtBQUssUUFBUSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQzlHLE1BQU0sSUFBSSxLQUFLLENBQUMsb0NBQW9DLENBQUMsQ0FBQztRQUN4RCxDQUFDO0lBQ0gsQ0FBQztJQUVPLGFBQWEsQ0FBQyxLQUE4QixFQUFFLE1BQTRCO1FBQ2hGLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxJQUFJLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLEtBQUssQ0FBQztlQUNwRSxJQUFJLENBQUMsU0FBUyxDQUFDLCtCQUErQixDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7WUFDM0ksTUFBTSxJQUFJLEtBQUssQ0FBQywyREFBMkQsQ0FBQyxDQUFDO1FBQy9FLENBQUM7SUFDSCxDQUFDO0lBRU8sbUJBQW1CLENBQUMsV0FBOEIsRUFBRSxRQUFtQztRQUM3RixJQUFJLFdBQVcsQ0FBQyxjQUFjLEtBQUssUUFBUSxDQUFDLGNBQWM7ZUFDckQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQyxjQUFjLEtBQUssUUFBUSxDQUFDLGNBQWM7ZUFDckUsV0FBVyxDQUFDLGlCQUFpQixLQUFLLFFBQVEsQ0FBQyxpQkFBaUIsSUFBSSxXQUFXLENBQUMsWUFBWSxLQUFLLFFBQVEsQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN4SCxNQUFNLElBQUksS0FBSyxDQUFDLHVDQUF1QyxDQUFDLENBQUM7UUFDM0QsQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3ZFLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxFQUFFLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNoRyxJQUFJLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssS0FBSyxDQUFDO2VBQ3BELElBQUksQ0FBQyxTQUFTLENBQUMsK0JBQStCLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1lBQ2pJLE1BQU0sSUFBSSxLQUFLLENBQUMsbUVBQW1FLENBQUMsQ0FBQztRQUN2RixDQUFDO1FBQ0QsTUFBTSxJQUFJLEdBQUcsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDdkUsSUFBSSxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQztlQUN4RixJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsT0FBTyxFQUFFLEtBQUssV0FBVyxDQUFDLFNBQVM7ZUFDNUQsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxLQUFLLFdBQVcsQ0FBQyxVQUFVO2VBQzNELFdBQVcsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLE1BQU07ZUFDM0MsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsSUFBSSxXQUFXLENBQUMsVUFBVSxJQUFJLFdBQVcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNsRyxNQUFNLElBQUksS0FBSyxDQUFDLG1EQUFtRCxDQUFDLENBQUM7UUFDdkUsQ0FBQztJQUNILENBQUM7SUFFTyxJQUFJLENBQUMsTUFBNEI7UUFDdkMsT0FBTztZQUNMLGNBQWMsRUFBRSxNQUFNLENBQUMsY0FBYyxFQUFFLFVBQVUsRUFBRSxNQUFNLENBQUMsVUFBVTtZQUNwRSxXQUFXLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVE7WUFDdEYsU0FBUyxFQUFFLE1BQU0sQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxTQUFTO1lBQ3hELFNBQVMsRUFBRSxNQUFNLENBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLENBQUMsVUFBVTtTQUMzRCxDQUFDO0lBQ0osQ0FBQztJQUVPLEtBQUssQ0FBQyxjQUFjLENBQUMsR0FBVztRQUN0QyxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6RCxJQUFJLENBQUMsTUFBTTtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQztRQUNwRSxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRU8sS0FBSyxDQUFDLElBQUksQ0FBQyxNQUE0QixFQUFFLEtBQ3dCO1FBQ3ZFLE1BQU0sSUFBSSxHQUFHLEVBQUUsR0FBRyxNQUFNLEVBQUUsR0FBRyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRLEdBQUcsQ0FBQyxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQztRQUMzRixJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNsRyxNQUFNLElBQUksS0FBSyxDQUFDLDJFQUEyRSxDQUFDLENBQUM7UUFDL0YsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztDQUNGIn0=
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/** Stable resource owner across preparation, retries, cleanup and exact recovery. */
|
|
2
|
+
export interface IChallengeContext {
|
|
3
|
+
/** Opaque identity for one order attempt; never reuse resources across owners. */
|
|
4
|
+
operationId: string;
|
|
5
|
+
}
|
|
1
6
|
/**
|
|
2
7
|
* Pluggable interface for ACME challenge handlers.
|
|
3
8
|
* Supports DNS-01, HTTP-01, TLS-ALPN-01, or custom challenge types.
|
|
@@ -10,14 +15,14 @@ export interface IChallengeHandler<T> {
|
|
|
10
15
|
/**
|
|
11
16
|
* Prepare the challenge: set DNS record, start HTTP/TLS server, etc.
|
|
12
17
|
*/
|
|
13
|
-
prepare(ch: T): Promise<void>;
|
|
18
|
+
prepare(ch: T, context?: IChallengeContext): Promise<void>;
|
|
14
19
|
/**
|
|
15
20
|
* Optional extra verify step (HTTP GET, ALPN handshake).
|
|
16
21
|
*/
|
|
17
|
-
verify?(ch: T): Promise<void>;
|
|
22
|
+
verify?(ch: T, context?: IChallengeContext): Promise<void>;
|
|
18
23
|
/**
|
|
19
24
|
* Clean up resources: remove DNS record, stop server.
|
|
20
25
|
*/
|
|
21
|
-
cleanup(ch: T): Promise<void>;
|
|
26
|
+
cleanup(ch: T, context?: IChallengeContext): Promise<void>;
|
|
22
27
|
checkWetherDomainIsSupported(domainArg: string): Promise<boolean>;
|
|
23
28
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { IChallengeHandler } from './IChallengeHandler.js';
|
|
1
|
+
export type { IChallengeHandler, IChallengeContext } from './IChallengeHandler.js';
|
|
2
2
|
export { Dns01Handler } from './Dns01Handler.js';
|
|
3
3
|
export { Http01Webroot } from './Http01Handler.js';
|
|
4
4
|
export { Http01MemoryHandler } from './Http01MemoryHandler.js';
|
package/dist_ts/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export * from './smartacme.classes.smartacme.js';
|
|
2
2
|
export { SmartacmeCert as Cert } from './smartacme.classes.cert.js';
|
|
3
3
|
export type { ICertManager } from './interfaces/certmanager.js';
|
|
4
|
+
export type * from './interfaces/exact-issuance.js';
|
|
5
|
+
export { normalizeCertificateIdentifiers } from './classes.exact-certificate-issuer.js';
|
|
4
6
|
import * as certmanagers from './certmanagers/index.js';
|
|
5
7
|
export { certmanagers };
|
|
6
8
|
import * as handlers from './handlers/index.js';
|
package/dist_ts/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './smartacme.classes.smartacme.js';
|
|
2
2
|
export { SmartacmeCert as Cert } from './smartacme.classes.cert.js';
|
|
3
|
+
export { normalizeCertificateIdentifiers } from './classes.exact-certificate-issuer.js';
|
|
3
4
|
// certmanagers
|
|
4
5
|
import * as certmanagers from './certmanagers/index.js';
|
|
5
6
|
export { certmanagers };
|
|
@@ -9,4 +10,4 @@ export { handlers };
|
|
|
9
10
|
// server (ACME Directory Server / CA)
|
|
10
11
|
import * as server from '../dist_ts_server/index.js';
|
|
11
12
|
export { server };
|
|
12
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGtDQUFrQyxDQUFDO0FBQ2pELE9BQU8sRUFBRSxhQUFhLElBQUksSUFBSSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFHcEUsT0FBTyxFQUFFLCtCQUErQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFFeEYsZUFBZTtBQUNmLE9BQU8sS0FBSyxZQUFZLE1BQU0seUJBQXlCLENBQUM7QUFDeEQsT0FBTyxFQUFFLFlBQVksRUFBRSxDQUFDO0FBRXhCLFdBQVc7QUFDWCxPQUFPLEtBQUssUUFBUSxNQUFNLHFCQUFxQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxRQUFRLEVBQUUsQ0FBQztBQUVwQixzQ0FBc0M7QUFDdEMsT0FBTyxLQUFLLE1BQU0sTUFBTSx1QkFBdUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsTUFBTSxFQUFFLENBQUMifQ==
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { IAcmeOrder } from '../acme/acme.interfaces.js';
|
|
2
|
+
/** Explicit identifiers never inherit parent or wildcard coverage. */
|
|
3
|
+
export interface IExactCertificateRequest {
|
|
4
|
+
namespace: string;
|
|
5
|
+
identifiers: string[];
|
|
6
|
+
}
|
|
7
|
+
export interface IExactCertificateIdentity extends IExactCertificateRequest {
|
|
8
|
+
certificateKey: string;
|
|
9
|
+
directoryUrl: string;
|
|
10
|
+
accountThumbprint: string;
|
|
11
|
+
}
|
|
12
|
+
export interface IExactCertificate extends IExactCertificateIdentity {
|
|
13
|
+
id: string;
|
|
14
|
+
privateKey: string;
|
|
15
|
+
publicKey: string;
|
|
16
|
+
csr: string;
|
|
17
|
+
created: number;
|
|
18
|
+
validFrom: number;
|
|
19
|
+
validUntil: number;
|
|
20
|
+
renewAfter: number;
|
|
21
|
+
}
|
|
22
|
+
export type TExactIssuanceStatus = 'prepared' | 'creating' | 'authorizing' | 'finalizing' | 'ready' | 'failed' | 'indeterminate' | 'abandoned_unverified';
|
|
23
|
+
export type TExactIssuanceErrorCode = 'order_outcome_unknown' | 'order_invalid' | 'authorization_failed' | 'certificate_invalid' | 'challenge_cleanup_pending' | 'rate_limited' | 'transport_unavailable';
|
|
24
|
+
export interface IExactDnsChallenge {
|
|
25
|
+
hostName: string;
|
|
26
|
+
challenge: string;
|
|
27
|
+
}
|
|
28
|
+
/** Sensitive durable state. Never return this record through a status API. */
|
|
29
|
+
export interface IExactIssuanceRecord extends IExactCertificateIdentity {
|
|
30
|
+
issuanceId: string;
|
|
31
|
+
revision: number;
|
|
32
|
+
status: TExactIssuanceStatus;
|
|
33
|
+
createdAt: number;
|
|
34
|
+
updatedAt: number;
|
|
35
|
+
privateKey: string;
|
|
36
|
+
csr: string;
|
|
37
|
+
order?: IAcmeOrder;
|
|
38
|
+
pendingChallenges: IExactDnsChallenge[];
|
|
39
|
+
errorCode?: TExactIssuanceErrorCode;
|
|
40
|
+
retryAfter?: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Storage must acknowledge durable writes and atomically compare revisions.
|
|
44
|
+
* A null revision means insert only if absent. No filesystem fallback is used.
|
|
45
|
+
* Keep unresolved records until their external outcome has been reconciled.
|
|
46
|
+
*/
|
|
47
|
+
export interface IExactIssuanceStore {
|
|
48
|
+
getAccountKey(accountId: string): Promise<string | null>;
|
|
49
|
+
createAccountKey(accountId: string, privateKey: string): Promise<boolean>;
|
|
50
|
+
getIssuance(certificateKey: string): Promise<IExactIssuanceRecord | null>;
|
|
51
|
+
compareAndSetIssuance(certificateKey: string, expectedRevision: number | null, record: IExactIssuanceRecord): Promise<boolean>;
|
|
52
|
+
getCertificate(certificateKey: string): Promise<IExactCertificate | null>;
|
|
53
|
+
storeCertificate(certificate: IExactCertificate): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
/** Safe status projection; contains neither keys nor challenge material. */
|
|
56
|
+
export interface IExactIssuanceInfo {
|
|
57
|
+
certificateKey: string;
|
|
58
|
+
issuanceId: string;
|
|
59
|
+
identifiers: string[];
|
|
60
|
+
status: TExactIssuanceStatus;
|
|
61
|
+
revision: number;
|
|
62
|
+
createdAt: number;
|
|
63
|
+
updatedAt: number;
|
|
64
|
+
errorCode?: TExactIssuanceErrorCode;
|
|
65
|
+
retryAfter?: number;
|
|
66
|
+
}
|
|
67
|
+
export type TExactCertificateResult = {
|
|
68
|
+
status: 'ready';
|
|
69
|
+
certificate: IExactCertificate;
|
|
70
|
+
issuance: IExactIssuanceInfo;
|
|
71
|
+
} | {
|
|
72
|
+
status: 'pending';
|
|
73
|
+
issuance: IExactIssuanceInfo;
|
|
74
|
+
};
|
|
75
|
+
export interface IExactIssuanceRecoveryRequest extends IExactCertificateRequest {
|
|
76
|
+
issuanceId: string;
|
|
77
|
+
expectedRevision: number;
|
|
78
|
+
action: 'recheck' | 'retry-proven-unapplied' | 'abandon';
|
|
79
|
+
}
|
package/dist_ts/plugins.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
2
|
import * as crypto from 'node:crypto';
|
|
3
|
+
import * as url from 'node:url';
|
|
4
|
+
import * as net from 'node:net';
|
|
5
|
+
import * as timers from 'node:timers/promises';
|
|
6
|
+
import * as x509 from '@peculiar/x509';
|
|
3
7
|
import * as fs from 'fs';
|
|
4
8
|
import * as path from 'path';
|
|
5
|
-
export { crypto, fs, path };
|
|
9
|
+
export { crypto, fs, path, url, net, timers, x509 };
|
|
6
10
|
import * as cloudflare from '@apiclient.xyz/cloudflare';
|
|
7
11
|
export { cloudflare };
|
|
8
12
|
import * as lik from '@push.rocks/lik';
|
package/dist_ts/plugins.js
CHANGED
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
import 'reflect-metadata';
|
|
3
3
|
// node native
|
|
4
4
|
import * as crypto from 'node:crypto';
|
|
5
|
+
import * as url from 'node:url';
|
|
6
|
+
import * as net from 'node:net';
|
|
7
|
+
import * as timers from 'node:timers/promises';
|
|
8
|
+
import * as x509 from '@peculiar/x509';
|
|
5
9
|
import * as fs from 'fs';
|
|
6
10
|
import * as path from 'path';
|
|
7
|
-
export { crypto, fs, path };
|
|
11
|
+
export { crypto, fs, path, url, net, timers, x509 };
|
|
8
12
|
// @apiclient.xyz scope
|
|
9
13
|
import * as cloudflare from '@apiclient.xyz/cloudflare';
|
|
10
14
|
export { cloudflare };
|
|
@@ -29,4 +33,4 @@ export { acme };
|
|
|
29
33
|
// local handlers for challenge types
|
|
30
34
|
import * as handlers from './handlers/index.js';
|
|
31
35
|
export { handlers };
|
|
32
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
36
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEseUVBQXlFO0FBQ3pFLE9BQU8sa0JBQWtCLENBQUM7QUFFMUIsY0FBYztBQUNkLE9BQU8sS0FBSyxNQUFNLE1BQU0sYUFBYSxDQUFDO0FBQ3RDLE9BQU8sS0FBSyxHQUFHLE1BQU0sVUFBVSxDQUFDO0FBQ2hDLE9BQU8sS0FBSyxHQUFHLE1BQU0sVUFBVSxDQUFDO0FBQ2hDLE9BQU8sS0FBSyxNQUFNLE1BQU0sc0JBQXNCLENBQUM7QUFDL0MsT0FBTyxLQUFLLElBQUksTUFBTSxnQkFBZ0IsQ0FBQztBQUN2QyxPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQztBQUN6QixPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUU3QixPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFFcEQsdUJBQXVCO0FBQ3ZCLE9BQU8sS0FBSyxVQUFVLE1BQU0sMkJBQTJCLENBQUM7QUFFeEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxDQUFDO0FBRXRCLG9CQUFvQjtBQUNwQixPQUFPLEtBQUssR0FBRyxNQUFNLGlCQUFpQixDQUFDO0FBQ3ZDLE9BQU8sS0FBSyxTQUFTLE1BQU0sdUJBQXVCLENBQUM7QUFDbkQsT0FBTyxLQUFLLFVBQVUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEtBQUssY0FBYyxNQUFNLDZCQUE2QixDQUFDO0FBQzlELE9BQU8sS0FBSyxRQUFRLE1BQU0sc0JBQXNCLENBQUM7QUFDakQsT0FBTyxLQUFLLFlBQVksTUFBTSwwQkFBMEIsQ0FBQztBQUN6RCxPQUFPLEtBQUssV0FBVyxNQUFNLHlCQUF5QixDQUFDO0FBQ3ZELE9BQU8sS0FBSyxXQUFXLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxLQUFLLFNBQVMsTUFBTSx1QkFBdUIsQ0FBQztBQUNuRCxPQUFPLEtBQUssVUFBVSxNQUFNLHdCQUF3QixDQUFDO0FBRXJELE9BQU8sRUFDTCxHQUFHLEVBQ0gsU0FBUyxFQUNULFVBQVUsRUFDVixjQUFjLEVBQ2QsUUFBUSxFQUNSLFlBQVksRUFDWixXQUFXLEVBQ1gsV0FBVyxFQUNYLFNBQVMsRUFDVCxVQUFVLEdBQ1gsQ0FBQztBQUVGLGlCQUFpQjtBQUNqQixPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBRTVDLE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQztBQUVuQix3Q0FBd0M7QUFDeEMsT0FBTyxLQUFLLElBQUksTUFBTSxpQkFBaUIsQ0FBQztBQUV4QyxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFDaEIscUNBQXFDO0FBQ3JDLE9BQU8sS0FBSyxRQUFRLE1BQU0scUJBQXFCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxDQUFDIn0=
|