@alchemy.run/acme 0.0.0 → 2.0.0-beta.85
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/LICENSE +201 -0
- package/README.md +48 -4
- package/lib/Account.d.ts +121 -0
- package/lib/Account.d.ts.map +1 -0
- package/lib/Account.js +163 -0
- package/lib/Account.js.map +1 -0
- package/lib/Certificate.d.ts +138 -0
- package/lib/Certificate.d.ts.map +1 -0
- package/lib/Certificate.js +157 -0
- package/lib/Certificate.js.map +1 -0
- package/lib/CertificateAuthority.d.ts +25 -0
- package/lib/CertificateAuthority.d.ts.map +1 -0
- package/lib/CertificateAuthority.js +22 -0
- package/lib/CertificateAuthority.js.map +1 -0
- package/lib/Client.d.ts +89 -0
- package/lib/Client.d.ts.map +1 -0
- package/lib/Client.js +237 -0
- package/lib/Client.js.map +1 -0
- package/lib/Der.d.ts +43 -0
- package/lib/Der.d.ts.map +1 -0
- package/lib/Der.js +138 -0
- package/lib/Der.js.map +1 -0
- package/lib/Dns.d.ts +59 -0
- package/lib/Dns.d.ts.map +1 -0
- package/lib/Dns.js +104 -0
- package/lib/Dns.js.map +1 -0
- package/lib/DnsSolver.d.ts +60 -0
- package/lib/DnsSolver.d.ts.map +1 -0
- package/lib/DnsSolver.js +48 -0
- package/lib/DnsSolver.js.map +1 -0
- package/lib/Errors.d.ts +93 -0
- package/lib/Errors.d.ts.map +1 -0
- package/lib/Errors.js +51 -0
- package/lib/Errors.js.map +1 -0
- package/lib/IssueCertificate.d.ts +76 -0
- package/lib/IssueCertificate.d.ts.map +1 -0
- package/lib/IssueCertificate.js +3 -0
- package/lib/IssueCertificate.js.map +1 -0
- package/lib/IssueCertificateHttp.d.ts +24 -0
- package/lib/IssueCertificateHttp.d.ts.map +1 -0
- package/lib/IssueCertificateHttp.js +56 -0
- package/lib/IssueCertificateHttp.js.map +1 -0
- package/lib/Pki.d.ts +56 -0
- package/lib/Pki.d.ts.map +1 -0
- package/lib/Pki.js +182 -0
- package/lib/Pki.js.map +1 -0
- package/lib/Providers.d.ts +30 -0
- package/lib/Providers.d.ts.map +1 -0
- package/lib/Providers.js +31 -0
- package/lib/Providers.js.map +1 -0
- package/lib/index.d.ts +12 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +12 -0
- package/lib/index.js.map +1 -0
- package/package.json +47 -3
- package/src/Account.ts +254 -0
- package/src/Certificate.ts +272 -0
- package/src/CertificateAuthority.ts +41 -0
- package/src/Client.ts +405 -0
- package/src/Der.ts +157 -0
- package/src/Dns.ts +227 -0
- package/src/DnsSolver.ts +109 -0
- package/src/Errors.ts +90 -0
- package/src/IssueCertificate.ts +89 -0
- package/src/IssueCertificateHttp.ts +67 -0
- package/src/Pki.ts +275 -0
- package/src/Providers.ts +39 -0
- package/src/index.ts +11 -0
package/lib/Client.js
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ACME issuance flow shared by the `Certificate` resource (deploy time)
|
|
3
|
+
* and the `IssueCertificate` binding (runtime):
|
|
4
|
+
*
|
|
5
|
+
* order → DNS-01 per authorization (present → propagated → respond →
|
|
6
|
+
* poll) → finalize with a fresh key's CSR → download → parse.
|
|
7
|
+
*
|
|
8
|
+
* The wire is `@distilled.cloud/acme`; this file only sequences it.
|
|
9
|
+
*/
|
|
10
|
+
import * as Acme from "@distilled.cloud/acme";
|
|
11
|
+
import * as acme from "@distilled.cloud/acme/acme";
|
|
12
|
+
import * as Effect from "effect/Effect";
|
|
13
|
+
import * as FetchHttpClient from "effect/http/FetchHttpClient";
|
|
14
|
+
import * as HttpClient from "effect/http/HttpClient";
|
|
15
|
+
import * as Layer from "effect/Layer";
|
|
16
|
+
import * as Redacted from "effect/Redacted";
|
|
17
|
+
import * as Schedule from "effect/Schedule";
|
|
18
|
+
import { waitForTxt } from "./Dns.js";
|
|
19
|
+
import { ChallengeFailed, ChallengeUnsupported, OrderInvalid, OrderTimeout, PkiError, } from "./Errors.js";
|
|
20
|
+
import { createCsr, csrToBase64Url, fromPem, generateKey, parseCertificate, privateKeyToJwk, splitPemChain, } from "./Pki.js";
|
|
21
|
+
/**
|
|
22
|
+
* The SDK's `Credentials` (+ a CA-trusting `HttpClient` for private CAs)
|
|
23
|
+
* for one account. Provide around any `@distilled.cloud/acme` call.
|
|
24
|
+
*/
|
|
25
|
+
export const accountLayer = (credentials) => {
|
|
26
|
+
const creds = Acme.layer({
|
|
27
|
+
directoryUrl: credentials.ca.directoryUrl,
|
|
28
|
+
accountKey: credentials.accountKey,
|
|
29
|
+
accountUrl: credentials.accountUrl,
|
|
30
|
+
externalAccountBinding: credentials.externalAccountBinding,
|
|
31
|
+
});
|
|
32
|
+
const http = credentials.ca.trustedRoot === undefined
|
|
33
|
+
? FetchHttpClient.layer
|
|
34
|
+
: FetchHttpClient.layer.pipe(Layer.provideMerge(Layer.succeed(FetchHttpClient.RequestInit, {
|
|
35
|
+
// Bun's fetch honours `tls`; the option is ignored elsewhere.
|
|
36
|
+
tls: { ca: credentials.ca.trustedRoot },
|
|
37
|
+
})));
|
|
38
|
+
return Layer.merge(creds, http);
|
|
39
|
+
};
|
|
40
|
+
const PENDING = new Set(["pending", "processing", "ready"]);
|
|
41
|
+
const challengeFqdn = (identifier) => `_acme-challenge.${identifier.replace(/^\*\./, "")}`;
|
|
42
|
+
const problemsOf = (order, authorizations) => {
|
|
43
|
+
const problems = [];
|
|
44
|
+
if (order.error) {
|
|
45
|
+
problems.push({ type: order.error.type, detail: order.error.detail });
|
|
46
|
+
}
|
|
47
|
+
for (const authorization of authorizations) {
|
|
48
|
+
for (const challenge of authorization.challenges) {
|
|
49
|
+
if (challenge.error) {
|
|
50
|
+
problems.push({
|
|
51
|
+
identifier: authorization.identifier.value,
|
|
52
|
+
type: challenge.error.type,
|
|
53
|
+
detail: challenge.error.detail,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return problems;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Complete one DNS-01 authorization and remove its TXT record on every exit.
|
|
62
|
+
*/
|
|
63
|
+
const solveAuthorization = (authorizationUrl, jwk, solver, propagation) => Effect.gen(function* () {
|
|
64
|
+
const authorization = yield* acme.getAuthorization({
|
|
65
|
+
url: authorizationUrl,
|
|
66
|
+
});
|
|
67
|
+
if (authorization.status === "valid")
|
|
68
|
+
return authorization;
|
|
69
|
+
const identifier = authorization.identifier.value;
|
|
70
|
+
const challenge = authorization.challenges.find((c) => c.type === "dns-01");
|
|
71
|
+
if (challenge === undefined || challenge.token === undefined) {
|
|
72
|
+
return yield* new ChallengeUnsupported({
|
|
73
|
+
identifier,
|
|
74
|
+
offered: authorization.challenges.map((c) => c.type),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
const record = {
|
|
78
|
+
fqdn: challengeFqdn(identifier),
|
|
79
|
+
value: yield* Acme.Jose.dnsChallengeValue(challenge.token, jwk),
|
|
80
|
+
};
|
|
81
|
+
return yield* Effect.acquireUseRelease(solver.present(record), () => Effect.gen(function* () {
|
|
82
|
+
yield* solver.propagated === undefined
|
|
83
|
+
? waitForTxt(record.fqdn, record.value, propagation)
|
|
84
|
+
: solver.propagated(record, propagation);
|
|
85
|
+
yield* acme.respondChallenge({ url: challenge.url });
|
|
86
|
+
const settled = yield* acme.getAuthorization({ url: authorizationUrl }).pipe(Effect.repeat({
|
|
87
|
+
schedule: Schedule.spaced("2 seconds"),
|
|
88
|
+
until: (a) => !PENDING.has(a.status),
|
|
89
|
+
times: 8,
|
|
90
|
+
}));
|
|
91
|
+
if (settled.status !== "valid") {
|
|
92
|
+
const failed = settled.challenges.find((c) => c.type === "dns-01");
|
|
93
|
+
return yield* new ChallengeFailed({
|
|
94
|
+
identifier,
|
|
95
|
+
type: failed?.error?.type,
|
|
96
|
+
detail: failed?.error?.detail ?? `authorization is ${settled.status}`,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return settled;
|
|
100
|
+
}), () => solver.cleanup(record));
|
|
101
|
+
});
|
|
102
|
+
const chooseChain = (downloaded, preferredChain) => Effect.gen(function* () {
|
|
103
|
+
const matches = (chain) => Effect.gen(function* () {
|
|
104
|
+
const blocks = splitPemChain(chain);
|
|
105
|
+
const top = blocks[blocks.length - 1];
|
|
106
|
+
if (top === undefined)
|
|
107
|
+
return false;
|
|
108
|
+
const parsed = yield* parseCertificate(top).pipe(Effect.orElseSucceed(() => undefined));
|
|
109
|
+
return parsed?.issuer.includes(preferredChain) === true;
|
|
110
|
+
});
|
|
111
|
+
if (preferredChain === undefined)
|
|
112
|
+
return downloaded.chain;
|
|
113
|
+
if (yield* matches(downloaded.chain))
|
|
114
|
+
return downloaded.chain;
|
|
115
|
+
for (const url of downloaded.alternates ?? []) {
|
|
116
|
+
const alternate = yield* acme.downloadCertificate({ url });
|
|
117
|
+
if (yield* matches(alternate.chain))
|
|
118
|
+
return alternate.chain;
|
|
119
|
+
}
|
|
120
|
+
return downloaded.chain;
|
|
121
|
+
});
|
|
122
|
+
/**
|
|
123
|
+
* Issue a certificate for `identifiers` as the current `Credentials`
|
|
124
|
+
* account. Requires the SDK's `Credentials` and an `HttpClient` (see
|
|
125
|
+
* {@link accountLayer}) plus whatever the solver needs.
|
|
126
|
+
*/
|
|
127
|
+
export const issueCertificate = (request) => Effect.gen(function* () {
|
|
128
|
+
const resolve = yield* Acme.Credentials;
|
|
129
|
+
const config = yield* resolve;
|
|
130
|
+
const jwk = yield* Acme.Jose.parseJwk(config.accountKey);
|
|
131
|
+
const propagation = request.propagation ?? {};
|
|
132
|
+
const order = yield* acme.newOrder({
|
|
133
|
+
identifiers: request.identifiers.map((value) => ({ type: "dns", value })),
|
|
134
|
+
});
|
|
135
|
+
if (order.location === undefined) {
|
|
136
|
+
return yield* new OrderInvalid({
|
|
137
|
+
orderUrl: order.finalize,
|
|
138
|
+
problems: [{ detail: "The CA omitted the order Location header." }],
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
const orderUrl = order.location;
|
|
142
|
+
// Each authorization removes its own TXT record on success or failure.
|
|
143
|
+
const authorizations = yield* Effect.forEach(order.authorizations, (url) => solveAuthorization(url, jwk, request.solver, propagation), { concurrency: 4 });
|
|
144
|
+
const ready = yield* acme.getOrder({ url: orderUrl }).pipe(Effect.repeat({
|
|
145
|
+
schedule: Schedule.spaced("2 seconds"),
|
|
146
|
+
until: (value) => value.status !== "pending",
|
|
147
|
+
times: 8,
|
|
148
|
+
}));
|
|
149
|
+
if (ready.status === "invalid") {
|
|
150
|
+
return yield* new OrderInvalid({
|
|
151
|
+
orderUrl,
|
|
152
|
+
problems: problemsOf(ready, authorizations),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
if (ready.status !== "ready") {
|
|
156
|
+
return yield* new OrderTimeout({ orderUrl, status: ready.status });
|
|
157
|
+
}
|
|
158
|
+
const key = yield* generateKey(request.keyAlgorithm ?? "ES256");
|
|
159
|
+
const csr = yield* createCsr({ key, identifiers: request.identifiers });
|
|
160
|
+
yield* acme.finalizeOrder({ url: order.finalize, csr: csrToBase64Url(csr) }).pipe(Effect.retry({
|
|
161
|
+
while: (error) => error._tag === "AcmeOrderNotReady",
|
|
162
|
+
schedule: Schedule.spaced("1 second"),
|
|
163
|
+
times: 8,
|
|
164
|
+
}));
|
|
165
|
+
const settled = yield* acme.getOrder({ url: orderUrl }).pipe(Effect.repeat({
|
|
166
|
+
schedule: Schedule.spaced("2 seconds"),
|
|
167
|
+
until: (o) => o.status === "valid" || o.status === "invalid",
|
|
168
|
+
times: 8,
|
|
169
|
+
}));
|
|
170
|
+
if (settled.status === "invalid") {
|
|
171
|
+
return yield* new OrderInvalid({
|
|
172
|
+
orderUrl,
|
|
173
|
+
problems: problemsOf(settled, authorizations),
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
if (settled.status !== "valid" || settled.certificate === undefined) {
|
|
177
|
+
return yield* new OrderTimeout({ orderUrl, status: settled.status });
|
|
178
|
+
}
|
|
179
|
+
const downloaded = yield* acme.downloadCertificate({
|
|
180
|
+
url: settled.certificate,
|
|
181
|
+
});
|
|
182
|
+
const chain = yield* chooseChain(downloaded, request.preferredChain);
|
|
183
|
+
const certificate = splitPemChain(chain)[0] ?? chain;
|
|
184
|
+
const parsed = yield* parseCertificate(certificate);
|
|
185
|
+
return toIssued({
|
|
186
|
+
certificate,
|
|
187
|
+
chain,
|
|
188
|
+
privateKey: key.privateKeyPem,
|
|
189
|
+
identifiers: request.identifiers,
|
|
190
|
+
certificateUrl: settled.certificate,
|
|
191
|
+
orderUrl,
|
|
192
|
+
parsed,
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
const toIssued = (input) => ({
|
|
196
|
+
certificate: input.certificate,
|
|
197
|
+
chain: input.chain,
|
|
198
|
+
privateKey: input.privateKey,
|
|
199
|
+
identifiers: input.identifiers,
|
|
200
|
+
serial: input.parsed.serial,
|
|
201
|
+
notBefore: input.parsed.notBefore.toISOString(),
|
|
202
|
+
notAfter: input.parsed.notAfter.toISOString(),
|
|
203
|
+
issuer: input.parsed.issuer,
|
|
204
|
+
certificateUrl: input.certificateUrl,
|
|
205
|
+
orderUrl: input.orderUrl,
|
|
206
|
+
});
|
|
207
|
+
const REASON_CODES = {
|
|
208
|
+
unspecified: 0,
|
|
209
|
+
keyCompromise: 1,
|
|
210
|
+
affiliationChanged: 3,
|
|
211
|
+
superseded: 4,
|
|
212
|
+
cessationOfOperation: 5,
|
|
213
|
+
};
|
|
214
|
+
/** Revoke a certificate. `AcmeAlreadyRevoked` is folded into success. */
|
|
215
|
+
export const revokeCertificate = (request) => Effect.gen(function* () {
|
|
216
|
+
const leaf = splitPemChain(request.certificate)[0] ?? request.certificate;
|
|
217
|
+
const der = yield* Effect.try({
|
|
218
|
+
try: () => fromPem(leaf),
|
|
219
|
+
catch: (cause) => new PkiError({ message: "The certificate is not PEM.", cause }),
|
|
220
|
+
});
|
|
221
|
+
const revoke = acme
|
|
222
|
+
.revokeCertificate({
|
|
223
|
+
certificate: Acme.Jose.base64url(der),
|
|
224
|
+
reason: request.reason === undefined ? undefined : REASON_CODES[request.reason],
|
|
225
|
+
})
|
|
226
|
+
.pipe(Effect.catchTag("AcmeAlreadyRevoked", () => Effect.void));
|
|
227
|
+
if (request.privateKey === undefined) {
|
|
228
|
+
return yield* revoke;
|
|
229
|
+
}
|
|
230
|
+
// Sign with the certificate key (RFC 8555 §7.6): swap the account key
|
|
231
|
+
// and drop the account URL so the protocol embeds the JWK.
|
|
232
|
+
const resolve = yield* Acme.Credentials;
|
|
233
|
+
const config = yield* resolve;
|
|
234
|
+
const jwk = yield* privateKeyToJwk(request.privateKey);
|
|
235
|
+
return yield* revoke.pipe(Effect.provide(Acme.layer({ directoryUrl: config.directoryUrl, accountKey: jwk })));
|
|
236
|
+
});
|
|
237
|
+
//# sourceMappingURL=Client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Client.js","sourceRoot":"","sources":["../src/Client.ts"],"names":[],"mappings":"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"}
|
package/lib/Der.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A minimal DER encoder/decoder — just enough ASN.1 for a PKCS#10
|
|
3
|
+
* certificate request (encode) and reading a certificate's serial,
|
|
4
|
+
* validity, issuer and subject alternative names (decode). Pure
|
|
5
|
+
* TypeScript; no native code, no dependency, works on workerd.
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export declare const concat: (...parts: ReadonlyArray<Uint8Array>) => Uint8Array;
|
|
10
|
+
/** Tag-length-value. */
|
|
11
|
+
export declare const tlv: (tag: number, body: Uint8Array) => Uint8Array;
|
|
12
|
+
export declare const sequence: (...items: ReadonlyArray<Uint8Array>) => Uint8Array<ArrayBufferLike>;
|
|
13
|
+
export declare const set: (...items: ReadonlyArray<Uint8Array>) => Uint8Array<ArrayBufferLike>;
|
|
14
|
+
export declare const octetString: (body: Uint8Array) => Uint8Array<ArrayBufferLike>;
|
|
15
|
+
export declare const bitString: (body: Uint8Array) => Uint8Array<ArrayBufferLike>;
|
|
16
|
+
export declare const nullValue: () => Uint8Array<ArrayBuffer>;
|
|
17
|
+
export declare const ia5String: (text: string) => Uint8Array<ArrayBufferLike>;
|
|
18
|
+
export declare const utf8String: (text: string) => Uint8Array<ArrayBufferLike>;
|
|
19
|
+
/** Context-specific constructed tag `[n]` (implicit or explicit, caller's choice of body). */
|
|
20
|
+
export declare const contextTag: (n: number, body: Uint8Array) => Uint8Array<ArrayBufferLike>;
|
|
21
|
+
/** Context-specific primitive tag `[n]` (e.g. GeneralName dNSName is `[2]`). */
|
|
22
|
+
export declare const contextPrimitive: (n: number, body: Uint8Array) => Uint8Array<ArrayBufferLike>;
|
|
23
|
+
/** INTEGER from a non-negative number or big-endian magnitude bytes. */
|
|
24
|
+
export declare const integer: (value: number | Uint8Array) => Uint8Array;
|
|
25
|
+
/** OBJECT IDENTIFIER from dotted notation. */
|
|
26
|
+
export declare const oid: (dotted: string) => Uint8Array;
|
|
27
|
+
export interface Node {
|
|
28
|
+
readonly tag: number;
|
|
29
|
+
/** Offset of the first content byte. */
|
|
30
|
+
readonly start: number;
|
|
31
|
+
/** Offset one past the last content byte. */
|
|
32
|
+
readonly end: number;
|
|
33
|
+
readonly bytes: Uint8Array;
|
|
34
|
+
}
|
|
35
|
+
export declare const read: (bytes: Uint8Array, offset: number) => Node;
|
|
36
|
+
/** The children of a constructed node, in order. */
|
|
37
|
+
export declare const children: (node: Node) => Node[];
|
|
38
|
+
export declare const content: (node: Node) => Uint8Array;
|
|
39
|
+
export declare const decodeOid: (node: Node) => string;
|
|
40
|
+
/** Parse UTCTime (`YYMMDDHHMMSSZ`) or GeneralizedTime (`YYYYMMDDHHMMSSZ`). */
|
|
41
|
+
export declare const decodeTime: (node: Node) => Date;
|
|
42
|
+
export declare const toHex: (bytes: Uint8Array) => string;
|
|
43
|
+
//# sourceMappingURL=Der.d.ts.map
|
package/lib/Der.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Der.d.ts","sourceRoot":"","sources":["../src/Der.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,MAAM,aAAc,aAAa,CAAC,UAAU,CAAC,KAAG,UAQ5D,CAAC;AASF,wBAAwB;AACxB,eAAO,MAAM,GAAG,QAAS,MAAM,QAAQ,UAAU,KAAG,UACS,CAAC;AAE9D,eAAO,MAAM,QAAQ,aAAc,aAAa,CAAC,UAAU,CAAC,gCAAgC,CAAC;AAC7F,eAAO,MAAM,GAAG,aAAc,aAAa,CAAC,UAAU,CAAC,gCAAgC,CAAC;AACxF,eAAO,MAAM,WAAW,SAAU,UAAU,gCAAoB,CAAC;AACjE,eAAO,MAAM,SAAS,SAAU,UAAU,gCAA8C,CAAC;AACzF,eAAO,MAAM,SAAS,+BAAkC,CAAC;AACzD,eAAO,MAAM,SAAS,SAAU,MAAM,gCAA8C,CAAC;AACrF,eAAO,MAAM,UAAU,SAAU,MAAM,gCAA8C,CAAC;AACtF,8FAA8F;AAC9F,eAAO,MAAM,UAAU,MAAO,MAAM,QAAQ,UAAU,gCAAwB,CAAC;AAC/E,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,MAAO,MAAM,QAAQ,UAAU,gCAAwB,CAAC;AAErF,wEAAwE;AACxE,eAAO,MAAM,OAAO,UAAW,MAAM,GAAG,UAAU,KAAG,UAgBpD,CAAC;AAEF,8CAA8C;AAC9C,eAAO,MAAM,GAAG,WAAY,MAAM,KAAG,UAapC,CAAC;AAMF,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,6CAA6C;IAC7C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED,eAAO,MAAM,IAAI,UAAW,UAAU,UAAU,MAAM,KAAG,IAUxD,CAAC;AAEF,oDAAoD;AACpD,eAAO,MAAM,QAAQ,SAAU,IAAI,KAAG,IAAI,EASzC,CAAC;AAEF,eAAO,MAAM,OAAO,SAAU,IAAI,KAAG,UAAuD,CAAC;AAE7F,eAAO,MAAM,SAAS,SAAU,IAAI,KAAG,MAkBtC,CAAC;AAEF,8EAA8E;AAC9E,eAAO,MAAM,UAAU,SAAU,IAAI,KAAG,IAgBvC,CAAC;AAEF,eAAO,MAAM,KAAK,UAAW,UAAU,KAAG,MAC0B,CAAC"}
|
package/lib/Der.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A minimal DER encoder/decoder — just enough ASN.1 for a PKCS#10
|
|
3
|
+
* certificate request (encode) and reading a certificate's serial,
|
|
4
|
+
* validity, issuer and subject alternative names (decode). Pure
|
|
5
|
+
* TypeScript; no native code, no dependency, works on workerd.
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export const concat = (...parts) => {
|
|
10
|
+
const out = new Uint8Array(parts.reduce((n, p) => n + p.length, 0));
|
|
11
|
+
let offset = 0;
|
|
12
|
+
for (const part of parts) {
|
|
13
|
+
out.set(part, offset);
|
|
14
|
+
offset += part.length;
|
|
15
|
+
}
|
|
16
|
+
return out;
|
|
17
|
+
};
|
|
18
|
+
const encodeLength = (n) => {
|
|
19
|
+
if (n < 0x80)
|
|
20
|
+
return Uint8Array.of(n);
|
|
21
|
+
if (n < 0x100)
|
|
22
|
+
return Uint8Array.of(0x81, n);
|
|
23
|
+
if (n < 0x10000)
|
|
24
|
+
return Uint8Array.of(0x82, n >>> 8, n & 0xff);
|
|
25
|
+
return Uint8Array.of(0x83, n >>> 16, (n >>> 8) & 0xff, n & 0xff);
|
|
26
|
+
};
|
|
27
|
+
/** Tag-length-value. */
|
|
28
|
+
export const tlv = (tag, body) => concat(Uint8Array.of(tag), encodeLength(body.length), body);
|
|
29
|
+
export const sequence = (...items) => tlv(0x30, concat(...items));
|
|
30
|
+
export const set = (...items) => tlv(0x31, concat(...items));
|
|
31
|
+
export const octetString = (body) => tlv(0x04, body);
|
|
32
|
+
export const bitString = (body) => tlv(0x03, concat(Uint8Array.of(0), body));
|
|
33
|
+
export const nullValue = () => Uint8Array.of(0x05, 0x00);
|
|
34
|
+
export const ia5String = (text) => tlv(0x16, new TextEncoder().encode(text));
|
|
35
|
+
export const utf8String = (text) => tlv(0x0c, new TextEncoder().encode(text));
|
|
36
|
+
/** Context-specific constructed tag `[n]` (implicit or explicit, caller's choice of body). */
|
|
37
|
+
export const contextTag = (n, body) => tlv(0xa0 | n, body);
|
|
38
|
+
/** Context-specific primitive tag `[n]` (e.g. GeneralName dNSName is `[2]`). */
|
|
39
|
+
export const contextPrimitive = (n, body) => tlv(0x80 | n, body);
|
|
40
|
+
/** INTEGER from a non-negative number or big-endian magnitude bytes. */
|
|
41
|
+
export const integer = (value) => {
|
|
42
|
+
if (typeof value === "number") {
|
|
43
|
+
if (value === 0)
|
|
44
|
+
return tlv(0x02, Uint8Array.of(0));
|
|
45
|
+
const bytes = [];
|
|
46
|
+
let n = value;
|
|
47
|
+
while (n > 0) {
|
|
48
|
+
bytes.unshift(n & 0xff);
|
|
49
|
+
n = Math.floor(n / 256);
|
|
50
|
+
}
|
|
51
|
+
if (bytes[0] & 0x80)
|
|
52
|
+
bytes.unshift(0);
|
|
53
|
+
return tlv(0x02, Uint8Array.from(bytes));
|
|
54
|
+
}
|
|
55
|
+
let start = 0;
|
|
56
|
+
while (start < value.length - 1 && value[start] === 0)
|
|
57
|
+
start++;
|
|
58
|
+
const magnitude = value.subarray(start);
|
|
59
|
+
return tlv(0x02, magnitude[0] & 0x80 ? concat(Uint8Array.of(0), magnitude) : magnitude);
|
|
60
|
+
};
|
|
61
|
+
/** OBJECT IDENTIFIER from dotted notation. */
|
|
62
|
+
export const oid = (dotted) => {
|
|
63
|
+
const parts = dotted.split(".").map(Number);
|
|
64
|
+
const bytes = [parts[0] * 40 + parts[1]];
|
|
65
|
+
for (const part of parts.slice(2)) {
|
|
66
|
+
const stack = [part & 0x7f];
|
|
67
|
+
let n = Math.floor(part / 128);
|
|
68
|
+
while (n > 0) {
|
|
69
|
+
stack.unshift((n & 0x7f) | 0x80);
|
|
70
|
+
n = Math.floor(n / 128);
|
|
71
|
+
}
|
|
72
|
+
bytes.push(...stack);
|
|
73
|
+
}
|
|
74
|
+
return tlv(0x06, Uint8Array.from(bytes));
|
|
75
|
+
};
|
|
76
|
+
export const read = (bytes, offset) => {
|
|
77
|
+
const tag = bytes[offset];
|
|
78
|
+
let cursor = offset + 1;
|
|
79
|
+
let length = bytes[cursor++];
|
|
80
|
+
if (length & 0x80) {
|
|
81
|
+
const count = length & 0x7f;
|
|
82
|
+
length = 0;
|
|
83
|
+
for (let i = 0; i < count; i++)
|
|
84
|
+
length = length * 256 + bytes[cursor++];
|
|
85
|
+
}
|
|
86
|
+
return { tag, start: cursor, end: cursor + length, bytes };
|
|
87
|
+
};
|
|
88
|
+
/** The children of a constructed node, in order. */
|
|
89
|
+
export const children = (node) => {
|
|
90
|
+
const out = [];
|
|
91
|
+
let cursor = node.start;
|
|
92
|
+
while (cursor < node.end) {
|
|
93
|
+
const child = read(node.bytes, cursor);
|
|
94
|
+
out.push(child);
|
|
95
|
+
cursor = child.end;
|
|
96
|
+
}
|
|
97
|
+
return out;
|
|
98
|
+
};
|
|
99
|
+
export const content = (node) => node.bytes.subarray(node.start, node.end);
|
|
100
|
+
export const decodeOid = (node) => {
|
|
101
|
+
const body = content(node);
|
|
102
|
+
const first = body[0];
|
|
103
|
+
const parts = [Math.floor(first / 40), first % 40];
|
|
104
|
+
let n = 0;
|
|
105
|
+
for (let i = 1; i < body.length; i++) {
|
|
106
|
+
n = n * 128 + (body[i] & 0x7f);
|
|
107
|
+
if ((body[i] & 0x80) === 0) {
|
|
108
|
+
parts.push(n);
|
|
109
|
+
n = 0;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// OIDs under joint-iso-itu-t(2) can have a first arc ≥ 2 with large second arcs.
|
|
113
|
+
if (first >= 80) {
|
|
114
|
+
parts[0] = 2;
|
|
115
|
+
parts[1] = first - 80;
|
|
116
|
+
}
|
|
117
|
+
return parts.join(".");
|
|
118
|
+
};
|
|
119
|
+
/** Parse UTCTime (`YYMMDDHHMMSSZ`) or GeneralizedTime (`YYYYMMDDHHMMSSZ`). */
|
|
120
|
+
export const decodeTime = (node) => {
|
|
121
|
+
const text = new TextDecoder().decode(content(node));
|
|
122
|
+
const generalized = node.tag === 0x18;
|
|
123
|
+
const year = generalized
|
|
124
|
+
? Number(text.slice(0, 4))
|
|
125
|
+
: (() => {
|
|
126
|
+
const yy = Number(text.slice(0, 2));
|
|
127
|
+
return yy < 50 ? 2000 + yy : 1900 + yy;
|
|
128
|
+
})();
|
|
129
|
+
const rest = generalized ? text.slice(4) : text.slice(2);
|
|
130
|
+
const month = Number(rest.slice(0, 2));
|
|
131
|
+
const day = Number(rest.slice(2, 4));
|
|
132
|
+
const hour = Number(rest.slice(4, 6));
|
|
133
|
+
const minute = Number(rest.slice(6, 8));
|
|
134
|
+
const second = Number(rest.slice(8, 10)) || 0;
|
|
135
|
+
return new Date(Date.UTC(year, month - 1, day, hour, minute, second));
|
|
136
|
+
};
|
|
137
|
+
export const toHex = (bytes) => Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
138
|
+
//# sourceMappingURL=Der.js.map
|
package/lib/Der.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Der.js","sourceRoot":"","sources":["../src/Der.ts"],"names":[],"mappings":"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"}
|
package/lib/Dns.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TXT propagation checks.
|
|
3
|
+
*
|
|
4
|
+
* Public recursive resolvers are a poor oracle: they cache negative
|
|
5
|
+
* answers for the zone's SOA minimum (30 minutes is common) and old
|
|
6
|
+
* record sets past their TTL, so a challenge value published a moment ago
|
|
7
|
+
* can stay invisible for far longer than the CA takes to validate. Where
|
|
8
|
+
* `node:dns` is available (deploy time, Fly Machines) the check therefore
|
|
9
|
+
* asks the zone's **authoritative** nameservers directly — the same
|
|
10
|
+
* servers the CA asks. Networks can intercept port 53, so DNS over HTTPS
|
|
11
|
+
* also checks for the exact challenge value. A stale recursive cache must
|
|
12
|
+
* not veto a positive answer; the CA performs its own validation.
|
|
13
|
+
*/
|
|
14
|
+
import * as Duration from "effect/Duration";
|
|
15
|
+
import * as Effect from "effect/Effect";
|
|
16
|
+
import * as HttpClient from "effect/http/HttpClient";
|
|
17
|
+
import { DnsPropagationTimeout } from "./Errors.ts";
|
|
18
|
+
export interface PropagationOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Wait before the first lookup to avoid caching an unpublished record.
|
|
21
|
+
* Outside the polling budget. Cloudflare defaults to 60 seconds.
|
|
22
|
+
* @default "0 seconds"
|
|
23
|
+
*/
|
|
24
|
+
readonly initialDelay?: Duration.Input | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* Extra wait after the record is seen (or, for solvers that skip the
|
|
27
|
+
* check, the whole wait): anycast edges lag the first one that answers.
|
|
28
|
+
* @default "5 seconds"
|
|
29
|
+
*/
|
|
30
|
+
readonly delay?: Duration.Input | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* DNS-over-HTTPS JSON endpoints to use instead of automatic discovery.
|
|
33
|
+
* When supplied, every resolver must return the record. Automatic lookup
|
|
34
|
+
* accepts all discovered nameservers or any default DoH resolver.
|
|
35
|
+
* @default Cloudflare (1.1.1.1) and Google public DNS
|
|
36
|
+
*/
|
|
37
|
+
readonly resolvers?: ReadonlyArray<string> | undefined;
|
|
38
|
+
/** Polling budget. @default "45 seconds" */
|
|
39
|
+
readonly timeout?: Duration.Input | undefined;
|
|
40
|
+
/** Polling interval. @default "3 seconds" */
|
|
41
|
+
readonly interval?: Duration.Input | undefined;
|
|
42
|
+
}
|
|
43
|
+
export declare const DEFAULT_PROPAGATION_DELAY: Duration.Input;
|
|
44
|
+
/** Sleep `options.delay` (default 5 seconds). */
|
|
45
|
+
export declare const propagationDelay: (options?: PropagationOptions) => Effect.Effect<void>;
|
|
46
|
+
export declare const DEFAULT_RESOLVERS: ReadonlyArray<string>;
|
|
47
|
+
/**
|
|
48
|
+
* TXT values for `fqdn` from one DoH resolver. Any transport or parse
|
|
49
|
+
* failure reads as "no records yet".
|
|
50
|
+
*/
|
|
51
|
+
export declare const resolveTxt: (resolver: string, fqdn: string) => Effect.Effect<ReadonlyArray<string>, never, HttpClient.HttpClient>;
|
|
52
|
+
/**
|
|
53
|
+
* Wait `initialDelay`, then poll for the exact challenge value and wait
|
|
54
|
+
* `delay`. Explicit resolvers must all agree; automatic lookup accepts all
|
|
55
|
+
* discovered nameservers or a positive default DoH answer. Discovery and
|
|
56
|
+
* polling share `timeout`; the delays before and after are outside it.
|
|
57
|
+
*/
|
|
58
|
+
export declare const waitForTxt: (fqdn: string, value: string, options?: PropagationOptions) => Effect.Effect<void, DnsPropagationTimeout, HttpClient.HttpClient>;
|
|
59
|
+
//# sourceMappingURL=Dns.d.ts.map
|
package/lib/Dns.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dns.d.ts","sourceRoot":"","sources":["../src/Dns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AAGrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC;IACnD;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC;IAC5C;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACvD,4CAA4C;IAC5C,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC;IAC9C,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAC;CAChD;AAED,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,KAAmB,CAAC;AAErE,iDAAiD;AACjD,eAAO,MAAM,gBAAgB,aAAa,kBAAkB,KAAQ,MAAM,CAAC,MAAM,CAAC,IAAI,CAC5B,CAAC;AA+D3D,eAAO,MAAM,iBAAiB,EAAE,aAAa,CAAC,MAAM,CAGnD,CAAC;AAYF;;;GAGG;AACH,eAAO,MAAM,UAAU,aACX,MAAM,QACV,MAAM,KACX,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAejE,CAAC;AAEJ;;;;;GAKG;AACH,eAAO,MAAM,UAAU,SACf,MAAM,SACL,MAAM,YACJ,kBAAkB,KAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,qBAAqB,EAAE,UAAU,CAAC,UAAU,CAgE/D,CAAC"}
|
package/lib/Dns.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TXT propagation checks.
|
|
3
|
+
*
|
|
4
|
+
* Public recursive resolvers are a poor oracle: they cache negative
|
|
5
|
+
* answers for the zone's SOA minimum (30 minutes is common) and old
|
|
6
|
+
* record sets past their TTL, so a challenge value published a moment ago
|
|
7
|
+
* can stay invisible for far longer than the CA takes to validate. Where
|
|
8
|
+
* `node:dns` is available (deploy time, Fly Machines) the check therefore
|
|
9
|
+
* asks the zone's **authoritative** nameservers directly — the same
|
|
10
|
+
* servers the CA asks. Networks can intercept port 53, so DNS over HTTPS
|
|
11
|
+
* also checks for the exact challenge value. A stale recursive cache must
|
|
12
|
+
* not veto a positive answer; the CA performs its own validation.
|
|
13
|
+
*/
|
|
14
|
+
import * as Duration from "effect/Duration";
|
|
15
|
+
import * as Effect from "effect/Effect";
|
|
16
|
+
import * as HttpClient from "effect/http/HttpClient";
|
|
17
|
+
import * as HttpClientRequest from "effect/http/HttpClientRequest";
|
|
18
|
+
import * as Schedule from "effect/Schedule";
|
|
19
|
+
import { DnsPropagationTimeout } from "./Errors.js";
|
|
20
|
+
export const DEFAULT_PROPAGATION_DELAY = "5 seconds";
|
|
21
|
+
/** Sleep `options.delay` (default 5 seconds). */
|
|
22
|
+
export const propagationDelay = (options = {}) => Effect.sleep(options.delay ?? DEFAULT_PROPAGATION_DELAY);
|
|
23
|
+
const nodeDns = Effect.tryPromise(() => import("node:dns/promises")).pipe(Effect.map((mod) => typeof mod?.Resolver === "function" && typeof mod.resolveNs === "function" ? mod : undefined), Effect.orElseSucceed(() => undefined));
|
|
24
|
+
/** The zone apex's nameserver IPv4s for `fqdn`, or `[]` when unknown. */
|
|
25
|
+
const authoritativeServers = (dns, fqdn) => Effect.gen(function* () {
|
|
26
|
+
const labels = fqdn.replace(/\.$/, "").split(".");
|
|
27
|
+
for (let i = 0; i < labels.length - 1; i++) {
|
|
28
|
+
const candidate = labels.slice(i).join(".");
|
|
29
|
+
const names = yield* Effect.tryPromise(() => dns.resolveNs(candidate)).pipe(Effect.orElseSucceed(() => []));
|
|
30
|
+
if (names.length === 0)
|
|
31
|
+
continue;
|
|
32
|
+
const addresses = yield* Effect.forEach(names, (name) => Effect.tryPromise(() => dns.resolve4(name)).pipe(Effect.orElseSucceed(() => [])), { concurrency: "unbounded" });
|
|
33
|
+
return addresses.flat();
|
|
34
|
+
}
|
|
35
|
+
return [];
|
|
36
|
+
});
|
|
37
|
+
/** TXT values requested from one nameserver (port 53 may be intercepted). */
|
|
38
|
+
const resolveTxtAt = (dns, server, fqdn) => Effect.gen(function* () {
|
|
39
|
+
const resolver = yield* Effect.sync(() => new dns.Resolver());
|
|
40
|
+
yield* Effect.sync(() => resolver.setServers([server]));
|
|
41
|
+
const records = yield* Effect.tryPromise(() => resolver.resolveTxt(fqdn));
|
|
42
|
+
return records.map((chunks) => chunks.join(""));
|
|
43
|
+
}).pipe(Effect.timeout("3 seconds"), Effect.orElseSucceed(() => []));
|
|
44
|
+
export const DEFAULT_RESOLVERS = [
|
|
45
|
+
"https://cloudflare-dns.com/dns-query",
|
|
46
|
+
"https://dns.google/resolve",
|
|
47
|
+
];
|
|
48
|
+
const unquote = (data) => (data.match(/"((?:[^"\\]|\\.)*)"/g) ?? [data])
|
|
49
|
+
.map((part) => part.replace(/^"|"$/g, "").replace(/\\"/g, '"'))
|
|
50
|
+
.join("");
|
|
51
|
+
/**
|
|
52
|
+
* TXT values for `fqdn` from one DoH resolver. Any transport or parse
|
|
53
|
+
* failure reads as "no records yet".
|
|
54
|
+
*/
|
|
55
|
+
export const resolveTxt = (resolver, fqdn) => Effect.gen(function* () {
|
|
56
|
+
const client = yield* HttpClient.HttpClient;
|
|
57
|
+
const request = HttpClientRequest.get(resolver).pipe(HttpClientRequest.setUrlParams({ name: fqdn, type: "TXT" }), HttpClientRequest.setHeader("Accept", "application/dns-json"));
|
|
58
|
+
const response = yield* client.execute(request);
|
|
59
|
+
const body = (yield* response.json);
|
|
60
|
+
return (body.Answer ?? [])
|
|
61
|
+
.filter((answer) => answer.type === 16 && typeof answer.data === "string")
|
|
62
|
+
.map((answer) => unquote(answer.data));
|
|
63
|
+
}).pipe(Effect.timeout("3 seconds"), Effect.orElseSucceed(() => []));
|
|
64
|
+
/**
|
|
65
|
+
* Wait `initialDelay`, then poll for the exact challenge value and wait
|
|
66
|
+
* `delay`. Explicit resolvers must all agree; automatic lookup accepts all
|
|
67
|
+
* discovered nameservers or a positive default DoH answer. Discovery and
|
|
68
|
+
* polling share `timeout`; the delays before and after are outside it.
|
|
69
|
+
*/
|
|
70
|
+
export const waitForTxt = (fqdn, value, options = {}) => Effect.gen(function* () {
|
|
71
|
+
const interval = options.interval ?? "3 seconds";
|
|
72
|
+
const timeout = options.timeout ?? "45 seconds";
|
|
73
|
+
// Bounded by `timeout` below, so poll for the caller's whole budget.
|
|
74
|
+
const attempts = Math.max(1, Math.ceil(Duration.toMillis(timeout) / Duration.toMillis(interval)));
|
|
75
|
+
yield* Effect.sleep(options.initialDelay ?? "0 seconds");
|
|
76
|
+
const propagated = yield* Effect.gen(function* () {
|
|
77
|
+
// Explicit resolvers must work even when node:dns is available.
|
|
78
|
+
const dns = options.resolvers === undefined ? yield* nodeDns : undefined;
|
|
79
|
+
const servers = dns === undefined
|
|
80
|
+
? []
|
|
81
|
+
: yield* authoritativeServers(dns, fqdn).pipe(Effect.timeout("5 seconds"), Effect.orElseSucceed(() => []));
|
|
82
|
+
const check = Effect.all({
|
|
83
|
+
direct: Effect.all(dns === undefined
|
|
84
|
+
? []
|
|
85
|
+
: servers.map((server) => resolveTxtAt(dns, server, fqdn).pipe(Effect.map((values) => values.includes(value)))), { concurrency: "unbounded" }),
|
|
86
|
+
doh: Effect.forEach(options.resolvers ?? DEFAULT_RESOLVERS, (resolver) => resolveTxt(resolver, fqdn).pipe(Effect.map((values) => values.includes(value))), { concurrency: "unbounded" }),
|
|
87
|
+
}, { concurrency: "unbounded" }).pipe(Effect.map(({ direct, doh }) => options.resolvers !== undefined
|
|
88
|
+
? doh.length > 0 && doh.every(Boolean)
|
|
89
|
+
: (direct.length > 0 && direct.every(Boolean)) || doh.some(Boolean)));
|
|
90
|
+
return yield* check.pipe(Effect.repeat({
|
|
91
|
+
schedule: Schedule.spaced(interval),
|
|
92
|
+
until: (seen) => seen,
|
|
93
|
+
times: attempts,
|
|
94
|
+
}));
|
|
95
|
+
}).pipe(Effect.timeoutOrElse({
|
|
96
|
+
duration: timeout,
|
|
97
|
+
orElse: () => Effect.fail(new DnsPropagationTimeout({ fqdn, value })),
|
|
98
|
+
}));
|
|
99
|
+
if (!propagated) {
|
|
100
|
+
return yield* new DnsPropagationTimeout({ fqdn, value });
|
|
101
|
+
}
|
|
102
|
+
yield* propagationDelay(options);
|
|
103
|
+
});
|
|
104
|
+
//# sourceMappingURL=Dns.js.map
|
package/lib/Dns.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dns.js","sourceRoot":"","sources":["../src/Dns.ts"],"names":[],"mappings":"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"}
|