@viaalink/caddy-api-client 0.0.0-stage → 0.10.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/LICENSE +21 -0
- package/README.md +671 -2
- package/dist/caddy/index.d.ts +5 -0
- package/dist/caddy/index.js +5 -0
- package/dist/caddy-http-DLxwstYo.d.ts +2735 -0
- package/dist/caddy-http.zod-Cx-dcFkE.d.ts +2243 -0
- package/dist/caddy-types.d.ts +941 -0
- package/dist/caddy-types.js +1 -0
- package/dist/client-Bf2QoSWQ.d.ts +6712 -0
- package/dist/generated/extension-assets.d.ts +92 -0
- package/dist/generated/extension-assets.js +302 -0
- package/dist/index-BijF7qR9.d.ts +336 -0
- package/dist/index-BmimANG7.d.ts +1920 -0
- package/dist/index-Q5Jc47QL.d.ts +3025 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.js +6 -0
- package/dist/mitm/index.d.ts +218 -0
- package/dist/mitm/index.js +2 -0
- package/dist/plugins/caddy-dns/index.d.ts +2 -0
- package/dist/plugins/caddy-dns/index.js +1 -0
- package/dist/plugins/caddy-security/index.d.ts +3 -0
- package/dist/plugins/caddy-security/index.js +2 -0
- package/dist/plugins/index.d.ts +4 -0
- package/dist/plugins/index.js +2 -0
- package/dist/types-DIjkvykh.d.ts +1041 -0
- package/package.json +168 -4
|
@@ -0,0 +1,1920 @@
|
|
|
1
|
+
import { a6 as CaddyClient } from './client-Bf2QoSWQ.js';
|
|
2
|
+
import { Q as ServiceRouteOptions$1, k as CaddyRoute, l as HealthCheckRouteOptions, m as HostRouteOptions, P as PathRouteOptions, W as LoadBalancerRouteOptions$1, X as DialAddress, j as CaddyRouteHandler, Y as SecurityHeaders, Z as BasicAuthOptions, _ as AddDomainWithAutoTlsOptions, $ as DomainConfig, a0 as AddDomainWithTlsOptions, a1 as UpdateDomainOptions, a2 as DeleteDomainOptions, a3 as Domain, T as TlsConnectionPolicy } from './types-DIjkvykh.js';
|
|
3
|
+
import { a7 as Config, O as InternalIssuer, z as AutomationPolicy, d as AutoHTTPSConfig } from './caddy-http-DLxwstYo.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Route builder functions for Caddy
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Build routes for a service (host-based and/or path-based)
|
|
11
|
+
* @param options - Service route options
|
|
12
|
+
* @returns Array of Caddy routes
|
|
13
|
+
* @throws {ValidationError} If options fail validation (e.g., invalid dial address)
|
|
14
|
+
*/
|
|
15
|
+
declare function buildServiceRoutes(options: ServiceRouteOptions$1): CaddyRoute[];
|
|
16
|
+
/**
|
|
17
|
+
* Build a health check route
|
|
18
|
+
* @param options - Health check route options
|
|
19
|
+
* @returns Caddy route for health check
|
|
20
|
+
* @throws {ValidationError} If options fail validation
|
|
21
|
+
*/
|
|
22
|
+
declare function buildHealthCheckRoute(options: HealthCheckRouteOptions): CaddyRoute;
|
|
23
|
+
/**
|
|
24
|
+
* Build a host-based route
|
|
25
|
+
* @param options - Host route options
|
|
26
|
+
* @returns Caddy route
|
|
27
|
+
* @throws {ValidationError} If options fail validation (e.g., invalid dial address)
|
|
28
|
+
*/
|
|
29
|
+
declare function buildHostRoute(options: HostRouteOptions): CaddyRoute;
|
|
30
|
+
/**
|
|
31
|
+
* Build a path-based route
|
|
32
|
+
* @param options - Path route options
|
|
33
|
+
* @returns Caddy route
|
|
34
|
+
* @throws {ValidationError} If options fail validation (e.g., invalid dial address)
|
|
35
|
+
*/
|
|
36
|
+
declare function buildPathRoute(options: PathRouteOptions): CaddyRoute;
|
|
37
|
+
/**
|
|
38
|
+
* Build a load balancer route
|
|
39
|
+
* @param options - Load balancer options
|
|
40
|
+
* @returns Caddy route with load balancing
|
|
41
|
+
* @throws {ValidationError} If options fail validation (e.g., invalid upstreams)
|
|
42
|
+
*/
|
|
43
|
+
declare function buildLoadBalancerRoute(options: LoadBalancerRouteOptions$1): CaddyRoute;
|
|
44
|
+
/**
|
|
45
|
+
* Build a reverse proxy handler
|
|
46
|
+
* @param dial - Dial address (host:port or https://host:port)
|
|
47
|
+
* @param options - Optional transport configuration
|
|
48
|
+
* @returns Reverse proxy handler
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* // HTTP backend (default)
|
|
52
|
+
* buildReverseProxyHandler("nginx:80")
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* // HTTPS backend with TLS
|
|
56
|
+
* buildReverseProxyHandler("https://internal-service:443")
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* // HTTPS backend with custom TLS settings
|
|
60
|
+
* buildReverseProxyHandler("internal-service:443", {
|
|
61
|
+
* tls: true,
|
|
62
|
+
* tlsServerName: "internal.example.com",
|
|
63
|
+
* tlsInsecureSkipVerify: false
|
|
64
|
+
* })
|
|
65
|
+
*/
|
|
66
|
+
declare function buildReverseProxyHandler(dial: DialAddress, options?: {
|
|
67
|
+
tls?: boolean;
|
|
68
|
+
tlsServerName?: string;
|
|
69
|
+
tlsInsecureSkipVerify?: boolean;
|
|
70
|
+
tlsTrustedCACerts?: string;
|
|
71
|
+
/** Response headers to delete (e.g., ["Content-Security-Policy"]) */
|
|
72
|
+
deleteResponseHeaders?: string[];
|
|
73
|
+
/** Flush interval for streaming/WebSocket. -1 disables buffering. */
|
|
74
|
+
flushInterval?: number;
|
|
75
|
+
}): CaddyRouteHandler;
|
|
76
|
+
/**
|
|
77
|
+
* Build a security headers handler
|
|
78
|
+
* @param headers - Security headers configuration
|
|
79
|
+
* @returns Headers handler
|
|
80
|
+
*/
|
|
81
|
+
declare function buildSecurityHeadersHandler(headers: SecurityHeaders): CaddyRouteHandler;
|
|
82
|
+
/**
|
|
83
|
+
* Build a basic auth handler
|
|
84
|
+
* Supports both single account (legacy) and multiple accounts
|
|
85
|
+
*
|
|
86
|
+
* @param auth - Basic auth configuration
|
|
87
|
+
* @returns Basic auth handler
|
|
88
|
+
* @throws {Error} If no valid accounts are provided (username + passwordHash or accounts array required)
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* // Single account (legacy)
|
|
92
|
+
* buildBasicAuthHandler({
|
|
93
|
+
* enabled: true,
|
|
94
|
+
* username: "admin",
|
|
95
|
+
* passwordHash: "$2a$10$...",
|
|
96
|
+
* realm: "Admin Area"
|
|
97
|
+
* })
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* // Multiple accounts (recommended)
|
|
101
|
+
* buildBasicAuthHandler({
|
|
102
|
+
* enabled: true,
|
|
103
|
+
* accounts: [
|
|
104
|
+
* { username: "admin", password: "$2a$10$..." },
|
|
105
|
+
* { username: "user", password: "$2a$10$..." }
|
|
106
|
+
* ],
|
|
107
|
+
* realm: "Protected Area",
|
|
108
|
+
* hash: { algorithm: "bcrypt", cost: 10 }
|
|
109
|
+
* })
|
|
110
|
+
*/
|
|
111
|
+
declare function buildBasicAuthHandler(auth: BasicAuthOptions): CaddyRouteHandler;
|
|
112
|
+
/**
|
|
113
|
+
* Build a rewrite handler (strip path prefix)
|
|
114
|
+
* @param prefix - Path prefix to strip
|
|
115
|
+
* @returns Rewrite handler
|
|
116
|
+
*/
|
|
117
|
+
declare function buildRewriteHandler(prefix: string): CaddyRouteHandler;
|
|
118
|
+
/**
|
|
119
|
+
* Build an ingress tag header handler
|
|
120
|
+
* @param tag - Ingress tag value
|
|
121
|
+
* @returns Headers handler
|
|
122
|
+
*/
|
|
123
|
+
declare function buildIngressTagHeadersHandler(tag: string): CaddyRouteHandler;
|
|
124
|
+
/**
|
|
125
|
+
* Build a project identity header handler
|
|
126
|
+
* @param projectId - Project identifier value
|
|
127
|
+
* @returns Headers handler
|
|
128
|
+
*/
|
|
129
|
+
declare function buildProjectIdHeadersHandler(projectId: string): CaddyRouteHandler;
|
|
130
|
+
/**
|
|
131
|
+
* Build CORS/CSP headers for iframe embedding
|
|
132
|
+
*
|
|
133
|
+
* `allowedOrigin` is a CSP `frame-ancestors` source list: one source or
|
|
134
|
+
* several, space-separated, wildcards allowed. CORS headers are added only
|
|
135
|
+
* when it is `*` or one exact origin, because `Access-Control-Allow-Origin`
|
|
136
|
+
* takes nothing else; a list there is invalid, and a browser rejects it.
|
|
137
|
+
* @param allowedOrigin - Allowed origin or frame-ancestors source list (optional, defaults to "*")
|
|
138
|
+
* @returns Headers handler
|
|
139
|
+
*/
|
|
140
|
+
declare function buildIframeHeadersHandler(allowedOrigin?: string): CaddyRouteHandler;
|
|
141
|
+
/**
|
|
142
|
+
* Build a redirect route for domain redirects (www <-> non-www)
|
|
143
|
+
* @param options - Redirect configuration
|
|
144
|
+
* @returns Caddy route for redirect
|
|
145
|
+
*/
|
|
146
|
+
declare function buildRedirectRoute(options: {
|
|
147
|
+
fromHost: string;
|
|
148
|
+
toHost: string;
|
|
149
|
+
permanent?: boolean;
|
|
150
|
+
statusCode?: 301 | 302 | 307 | 308;
|
|
151
|
+
id?: string;
|
|
152
|
+
}): CaddyRoute;
|
|
153
|
+
/**
|
|
154
|
+
* Build a compression (encode) handler
|
|
155
|
+
* Supports gzip, zstd, and brotli compression
|
|
156
|
+
* @param options - Compression options
|
|
157
|
+
* @returns Encode handler
|
|
158
|
+
*/
|
|
159
|
+
declare function buildCompressionHandler(options?: {
|
|
160
|
+
gzip?: boolean;
|
|
161
|
+
zstd?: boolean;
|
|
162
|
+
brotli?: boolean;
|
|
163
|
+
}): CaddyRouteHandler;
|
|
164
|
+
/**
|
|
165
|
+
* Build a WWW redirect route (www.example.com ↔ example.com)
|
|
166
|
+
*
|
|
167
|
+
* Common patterns:
|
|
168
|
+
* - "www-to-domain": www.example.com → example.com
|
|
169
|
+
* - "domain-to-www": example.com → www.example.com
|
|
170
|
+
*
|
|
171
|
+
* @param options - WWW redirect options
|
|
172
|
+
* @returns Caddy route that redirects between www and non-www versions
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* // Redirect www.example.com → example.com
|
|
176
|
+
* const route = buildWwwRedirect({
|
|
177
|
+
* domain: "example.com",
|
|
178
|
+
* mode: "www-to-domain",
|
|
179
|
+
* permanent: true
|
|
180
|
+
* });
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* // Redirect example.com → www.example.com
|
|
184
|
+
* const route = buildWwwRedirect({
|
|
185
|
+
* domain: "example.com",
|
|
186
|
+
* mode: "domain-to-www",
|
|
187
|
+
* permanent: true
|
|
188
|
+
* });
|
|
189
|
+
*/
|
|
190
|
+
declare function buildWwwRedirect(options: {
|
|
191
|
+
domain: string;
|
|
192
|
+
mode: "www-to-domain" | "domain-to-www";
|
|
193
|
+
permanent?: boolean;
|
|
194
|
+
priority?: number;
|
|
195
|
+
}): CaddyRoute;
|
|
196
|
+
/**
|
|
197
|
+
* Build a route that forwards traffic through MITMproxy for inspection
|
|
198
|
+
*
|
|
199
|
+
* This is a convenience function that creates a route pointing to a MITMproxy
|
|
200
|
+
* instance running in reverse proxy mode. Use this to transparently intercept
|
|
201
|
+
* and inspect HTTP traffic for debugging without modifying client or backend code.
|
|
202
|
+
*
|
|
203
|
+
* @param options - MITMproxy route configuration
|
|
204
|
+
* @returns Caddy route configured to forward through MITMproxy
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```typescript
|
|
208
|
+
* // Route traffic for api.example.com through MITMproxy
|
|
209
|
+
* const route = buildMitmproxyRoute({
|
|
210
|
+
* host: "api.example.com",
|
|
211
|
+
* mitmproxyHost: "localhost",
|
|
212
|
+
* mitmproxyPort: 8080,
|
|
213
|
+
* });
|
|
214
|
+
* await client.addRoute("https_server", route, "api_debug");
|
|
215
|
+
* ```
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* ```typescript
|
|
219
|
+
* // Route with custom backend (MITMproxy forwards to this backend)
|
|
220
|
+
* const route = buildMitmproxyRoute({
|
|
221
|
+
* host: "api.example.com",
|
|
222
|
+
* mitmproxyHost: "mitmproxy",
|
|
223
|
+
* mitmproxyPort: 8080,
|
|
224
|
+
* backendHost: "backend-service",
|
|
225
|
+
* backendPort: 3000,
|
|
226
|
+
* });
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
declare function buildMitmproxyRoute(options: {
|
|
230
|
+
/** Host pattern to match (e.g., "api.example.com") */
|
|
231
|
+
host: string;
|
|
232
|
+
/** MITMproxy host (e.g., "localhost" or "mitmproxy-container") */
|
|
233
|
+
mitmproxyHost: string;
|
|
234
|
+
/** MITMproxy proxy port (default: 8080) */
|
|
235
|
+
mitmproxyPort?: number;
|
|
236
|
+
/** Backend host that MITMproxy should forward to (optional, for documentation) */
|
|
237
|
+
backendHost?: string;
|
|
238
|
+
/** Backend port that MITMproxy should forward to (optional, for documentation) */
|
|
239
|
+
backendPort?: number;
|
|
240
|
+
/** Route ID for Caddy (optional) */
|
|
241
|
+
id?: string;
|
|
242
|
+
/** Route priority (optional) */
|
|
243
|
+
priority?: number;
|
|
244
|
+
}): CaddyRoute;
|
|
245
|
+
/**
|
|
246
|
+
* Create a hot-swappable route pair for enabling/disabling MITMproxy interception
|
|
247
|
+
*
|
|
248
|
+
* Returns both a direct route and a MITMproxy-intercepted route with the same ID.
|
|
249
|
+
* Use this to easily toggle between direct and intercepted traffic at runtime.
|
|
250
|
+
*
|
|
251
|
+
* @param options - Configuration for the route pair
|
|
252
|
+
* @returns Object with direct and proxied route configurations
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* ```typescript
|
|
256
|
+
* const routes = buildMitmproxyRoutePair({
|
|
257
|
+
* host: "api.example.com",
|
|
258
|
+
* backendHost: "backend-service",
|
|
259
|
+
* backendPort: 3000,
|
|
260
|
+
* mitmproxyHost: "mitmproxy",
|
|
261
|
+
* routeId: "api_route",
|
|
262
|
+
* });
|
|
263
|
+
*
|
|
264
|
+
* // Start with direct routing
|
|
265
|
+
* await client.addRoute("https_server", routes.direct, routes.direct["@id"]);
|
|
266
|
+
*
|
|
267
|
+
* // Hot-swap to enable interception (no downtime)
|
|
268
|
+
* await client.removeRouteById("https_server", routes.direct["@id"]);
|
|
269
|
+
* await client.addRoute("https_server", routes.proxied, routes.proxied["@id"]);
|
|
270
|
+
*
|
|
271
|
+
* // Hot-swap back to direct (disable interception)
|
|
272
|
+
* await client.removeRouteById("https_server", routes.proxied["@id"]);
|
|
273
|
+
* await client.addRoute("https_server", routes.direct, routes.direct["@id"]);
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
declare function buildMitmproxyRoutePair(options: {
|
|
277
|
+
/** Host pattern to match */
|
|
278
|
+
host: string;
|
|
279
|
+
/** Backend service host */
|
|
280
|
+
backendHost: string;
|
|
281
|
+
/** Backend service port */
|
|
282
|
+
backendPort: number;
|
|
283
|
+
/** MITMproxy host */
|
|
284
|
+
mitmproxyHost: string;
|
|
285
|
+
/** MITMproxy proxy port (default: 8080) */
|
|
286
|
+
mitmproxyPort?: number;
|
|
287
|
+
/** Route ID (used for both routes) */
|
|
288
|
+
routeId: string;
|
|
289
|
+
/** Route priority (optional) */
|
|
290
|
+
priority?: number;
|
|
291
|
+
}): {
|
|
292
|
+
/** Direct route (Client → Caddy → Backend) */
|
|
293
|
+
direct: CaddyRoute;
|
|
294
|
+
/** Proxied route (Client → Caddy → MITMproxy → Backend) */
|
|
295
|
+
proxied: CaddyRoute;
|
|
296
|
+
};
|
|
297
|
+
/**
|
|
298
|
+
* Options for building an iframe-embeddable proxy route
|
|
299
|
+
*/
|
|
300
|
+
interface IframeProxyRouteOptions {
|
|
301
|
+
/** Path prefix for the route (e.g., "/panel") */
|
|
302
|
+
pathPrefix: string;
|
|
303
|
+
/** Upstream host to proxy to */
|
|
304
|
+
upstreamHost: string;
|
|
305
|
+
/** Upstream port to proxy to */
|
|
306
|
+
upstreamPort: number;
|
|
307
|
+
/** Route ID (optional, auto-generated from pathPrefix if not provided) */
|
|
308
|
+
routeId?: string;
|
|
309
|
+
/** Whether to enable iframe embedding headers (default: true) */
|
|
310
|
+
iframeEmbed?: boolean;
|
|
311
|
+
/** Custom Host header to send to upstream (for DNS rebinding bypass) */
|
|
312
|
+
overrideHost?: string;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Build a route for proxying a web UI with iframe embedding support
|
|
316
|
+
*
|
|
317
|
+
* This creates a route that proxies a web interface and optionally adds
|
|
318
|
+
* headers to allow embedding in iframes. Can also override Host/Origin
|
|
319
|
+
* headers for services with DNS rebinding protection.
|
|
320
|
+
*
|
|
321
|
+
* @param options - Iframe proxy route configuration
|
|
322
|
+
* @returns Caddy route for iframe-embeddable proxy
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* ```typescript
|
|
326
|
+
* // Proxy a web panel at /panel/* to panel-service:8080
|
|
327
|
+
* const route = buildIframeProxyRoute({
|
|
328
|
+
* pathPrefix: "/panel",
|
|
329
|
+
* upstreamHost: "panel-service",
|
|
330
|
+
* upstreamPort: 8080,
|
|
331
|
+
* iframeEmbed: true,
|
|
332
|
+
* });
|
|
333
|
+
*
|
|
334
|
+
* // Proxy with DNS rebinding bypass (e.g., for mitmweb)
|
|
335
|
+
* const mitmRoute = buildIframeProxyRoute({
|
|
336
|
+
* pathPrefix: "/mitmproxy",
|
|
337
|
+
* upstreamHost: "mitmproxy",
|
|
338
|
+
* upstreamPort: 8081,
|
|
339
|
+
* overrideHost: "127.0.0.1:8081",
|
|
340
|
+
* });
|
|
341
|
+
* ```
|
|
342
|
+
*/
|
|
343
|
+
declare function buildIframeProxyRoute(options: IframeProxyRouteOptions): CaddyRoute;
|
|
344
|
+
/**
|
|
345
|
+
* @deprecated Use buildIframeProxyRoute instead
|
|
346
|
+
*/
|
|
347
|
+
declare function buildMitmproxyWebUiRoute(options: {
|
|
348
|
+
pathPrefix: string;
|
|
349
|
+
mitmproxyHost: string;
|
|
350
|
+
mitmproxyWebPort?: number;
|
|
351
|
+
routeId?: string;
|
|
352
|
+
iframeEmbed?: boolean;
|
|
353
|
+
}): CaddyRoute;
|
|
354
|
+
/**
|
|
355
|
+
* Options for building a WebSocket proxy route
|
|
356
|
+
*/
|
|
357
|
+
interface WebSocketProxyRouteOptions {
|
|
358
|
+
/** WebSocket path to match (e.g., "/ws", "/updates") */
|
|
359
|
+
path: string;
|
|
360
|
+
/** Upstream host to proxy to */
|
|
361
|
+
upstreamHost: string;
|
|
362
|
+
/** Upstream port to proxy to */
|
|
363
|
+
upstreamPort: number;
|
|
364
|
+
/** Route ID (optional) */
|
|
365
|
+
routeId?: string;
|
|
366
|
+
/** Custom Host header to send to upstream (for DNS rebinding bypass) */
|
|
367
|
+
overrideHost?: string;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Build a route for WebSocket proxy
|
|
371
|
+
*
|
|
372
|
+
* This creates a route that proxies WebSocket connections to an upstream
|
|
373
|
+
* service. Can optionally override Host/Origin headers for services
|
|
374
|
+
* with DNS rebinding protection.
|
|
375
|
+
*
|
|
376
|
+
* @param options - WebSocket route configuration
|
|
377
|
+
* @returns Caddy route for WebSocket proxy
|
|
378
|
+
*
|
|
379
|
+
* @example
|
|
380
|
+
* ```typescript
|
|
381
|
+
* // Simple WebSocket proxy
|
|
382
|
+
* const route = buildWebSocketProxyRoute({
|
|
383
|
+
* path: "/ws",
|
|
384
|
+
* upstreamHost: "ws-server",
|
|
385
|
+
* upstreamPort: 8080,
|
|
386
|
+
* });
|
|
387
|
+
*
|
|
388
|
+
* // WebSocket with DNS rebinding bypass
|
|
389
|
+
* const mitmRoute = buildWebSocketProxyRoute({
|
|
390
|
+
* path: "/updates",
|
|
391
|
+
* upstreamHost: "mitmproxy",
|
|
392
|
+
* upstreamPort: 8081,
|
|
393
|
+
* overrideHost: "127.0.0.1:8081",
|
|
394
|
+
* });
|
|
395
|
+
* ```
|
|
396
|
+
*/
|
|
397
|
+
declare function buildWebSocketProxyRoute(options: WebSocketProxyRouteOptions): CaddyRoute;
|
|
398
|
+
/**
|
|
399
|
+
* @deprecated Use buildWebSocketProxyRoute instead
|
|
400
|
+
*/
|
|
401
|
+
declare function buildMitmproxyWebSocketRoute(options: {
|
|
402
|
+
path?: string;
|
|
403
|
+
mitmproxyHost: string;
|
|
404
|
+
mitmproxyWebPort?: number;
|
|
405
|
+
routeId?: string;
|
|
406
|
+
}): CaddyRoute;
|
|
407
|
+
/**
|
|
408
|
+
* Build a header handler that removes restrictive headers for iframe embedding
|
|
409
|
+
*
|
|
410
|
+
* Removes X-Frame-Options, Content-Security-Policy, and X-Xss-Protection
|
|
411
|
+
* headers while adding permissive CORS and frame-ancestors headers.
|
|
412
|
+
*
|
|
413
|
+
* @param options - Handler options
|
|
414
|
+
* @returns Headers handler for iframe embedding
|
|
415
|
+
*
|
|
416
|
+
* @example
|
|
417
|
+
* ```typescript
|
|
418
|
+
* const handler = buildIframePermissiveHandler();
|
|
419
|
+
* // Use in a route's handle array
|
|
420
|
+
* ```
|
|
421
|
+
*/
|
|
422
|
+
declare function buildIframePermissiveHandler(options?: {
|
|
423
|
+
/** Headers to delete (default: ["X-Frame-Options", "Content-Security-Policy", "X-Xss-Protection"]) */
|
|
424
|
+
deleteHeaders?: string[];
|
|
425
|
+
/** CORS origin (default: "*") */
|
|
426
|
+
corsOrigin?: string;
|
|
427
|
+
}): CaddyRouteHandler;
|
|
428
|
+
/**
|
|
429
|
+
* Build a header handler for DNS rebinding bypass
|
|
430
|
+
*
|
|
431
|
+
* Sets Host and Origin headers to bypass MITMproxy's DNS rebinding protection.
|
|
432
|
+
* Use this when proxying to MITMproxy from a different hostname.
|
|
433
|
+
*
|
|
434
|
+
* @param options - Handler options
|
|
435
|
+
* @returns Headers handler for request modification
|
|
436
|
+
*
|
|
437
|
+
* @example
|
|
438
|
+
* ```typescript
|
|
439
|
+
* const handler = buildDnsRebindingBypassHandler({
|
|
440
|
+
* targetHost: "127.0.0.1:8081",
|
|
441
|
+
* });
|
|
442
|
+
* ```
|
|
443
|
+
*/
|
|
444
|
+
declare function buildDnsRebindingBypassHandler(options: {
|
|
445
|
+
/** Target host:port (e.g., "127.0.0.1:8081") */
|
|
446
|
+
targetHost: string;
|
|
447
|
+
}): CaddyRouteHandler;
|
|
448
|
+
/**
|
|
449
|
+
* Options for building a file server route
|
|
450
|
+
*/
|
|
451
|
+
interface FileServerRouteOptions {
|
|
452
|
+
/** Path prefix to match (e.g., "/static/*") */
|
|
453
|
+
path: string;
|
|
454
|
+
/** Root directory to serve files from */
|
|
455
|
+
root: string;
|
|
456
|
+
/** Enable directory browsing */
|
|
457
|
+
browse?: boolean;
|
|
458
|
+
/** Custom browse template file path */
|
|
459
|
+
browseTemplate?: string;
|
|
460
|
+
/** File patterns to hide (e.g., [".git", ".env"]) */
|
|
461
|
+
hidePatterns?: string[];
|
|
462
|
+
/** Index file names (default: ["index.html"]) */
|
|
463
|
+
indexNames?: string[];
|
|
464
|
+
/** Enable precompressed file support (gzip, brotli) */
|
|
465
|
+
precompressed?: boolean;
|
|
466
|
+
/** Route ID */
|
|
467
|
+
id?: string;
|
|
468
|
+
/** Route priority */
|
|
469
|
+
priority?: number;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Build a file server route for serving static files
|
|
473
|
+
*
|
|
474
|
+
* @param options - File server route configuration
|
|
475
|
+
* @returns Caddy route for static file serving
|
|
476
|
+
*
|
|
477
|
+
* @example
|
|
478
|
+
* ```typescript
|
|
479
|
+
* // Basic static file serving
|
|
480
|
+
* const route = buildFileServerRoute({
|
|
481
|
+
* path: "/static/*",
|
|
482
|
+
* root: "/var/www/static",
|
|
483
|
+
* });
|
|
484
|
+
*
|
|
485
|
+
* // With directory browsing and hidden files
|
|
486
|
+
* const route = buildFileServerRoute({
|
|
487
|
+
* path: "/files/*",
|
|
488
|
+
* root: "/var/www/files",
|
|
489
|
+
* browse: true,
|
|
490
|
+
* hidePatterns: [".git", ".env", "*.secret"],
|
|
491
|
+
* precompressed: true,
|
|
492
|
+
* });
|
|
493
|
+
* ```
|
|
494
|
+
*/
|
|
495
|
+
declare function buildFileServerRoute(options: FileServerRouteOptions): CaddyRoute;
|
|
496
|
+
/**
|
|
497
|
+
* Options for building a templates route
|
|
498
|
+
*/
|
|
499
|
+
interface TemplatesRouteOptions {
|
|
500
|
+
/** Path prefix to match (e.g., "/*.html") */
|
|
501
|
+
path: string;
|
|
502
|
+
/** Root directory for template files */
|
|
503
|
+
fileRoot: string;
|
|
504
|
+
/** MIME types to process as templates */
|
|
505
|
+
mimeTypes?: string[];
|
|
506
|
+
/** Custom delimiters (default: ["{{", "}}"]) */
|
|
507
|
+
delimiters?: [string, string];
|
|
508
|
+
/** Route ID */
|
|
509
|
+
id?: string;
|
|
510
|
+
/** Route priority */
|
|
511
|
+
priority?: number;
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Build a templates route for server-side template rendering
|
|
515
|
+
*
|
|
516
|
+
* @param options - Templates route configuration
|
|
517
|
+
* @returns Caddy route for template processing
|
|
518
|
+
*
|
|
519
|
+
* @example
|
|
520
|
+
* ```typescript
|
|
521
|
+
* // Process HTML files as templates
|
|
522
|
+
* const route = buildTemplatesRoute({
|
|
523
|
+
* path: "/*.html",
|
|
524
|
+
* fileRoot: "/var/www/templates",
|
|
525
|
+
* mimeTypes: ["text/html"],
|
|
526
|
+
* });
|
|
527
|
+
*
|
|
528
|
+
* // With custom delimiters
|
|
529
|
+
* const route = buildTemplatesRoute({
|
|
530
|
+
* path: "/*.tmpl",
|
|
531
|
+
* fileRoot: "/templates",
|
|
532
|
+
* delimiters: ["<%", "%>"],
|
|
533
|
+
* });
|
|
534
|
+
* ```
|
|
535
|
+
*/
|
|
536
|
+
declare function buildTemplatesRoute(options: TemplatesRouteOptions): CaddyRoute;
|
|
537
|
+
/**
|
|
538
|
+
* Options for building an error route
|
|
539
|
+
*/
|
|
540
|
+
interface ErrorRouteOptions {
|
|
541
|
+
/** Route matchers (optional, applies to all requests if not specified) */
|
|
542
|
+
match?: {
|
|
543
|
+
path?: string[];
|
|
544
|
+
host?: string[];
|
|
545
|
+
};
|
|
546
|
+
/** HTTP status code */
|
|
547
|
+
statusCode: number;
|
|
548
|
+
/** Error message body */
|
|
549
|
+
message?: string;
|
|
550
|
+
/** Custom headers to include */
|
|
551
|
+
headers?: Record<string, string[]>;
|
|
552
|
+
/** Route ID */
|
|
553
|
+
id?: string;
|
|
554
|
+
/** Route priority */
|
|
555
|
+
priority?: number;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Build an error route that returns a static error response
|
|
559
|
+
*
|
|
560
|
+
* @param options - Error route configuration
|
|
561
|
+
* @returns Caddy route for error response
|
|
562
|
+
*
|
|
563
|
+
* @example
|
|
564
|
+
* ```typescript
|
|
565
|
+
* // Simple 404 handler
|
|
566
|
+
* const route = buildErrorRoute({
|
|
567
|
+
* statusCode: 404,
|
|
568
|
+
* message: "Page not found",
|
|
569
|
+
* });
|
|
570
|
+
*
|
|
571
|
+
* // JSON error response for API
|
|
572
|
+
* const route = buildErrorRoute({
|
|
573
|
+
* match: { path: ["/api/*"] },
|
|
574
|
+
* statusCode: 500,
|
|
575
|
+
* message: '{"error":"Internal server error"}',
|
|
576
|
+
* headers: { "Content-Type": ["application/json"] },
|
|
577
|
+
* });
|
|
578
|
+
* ```
|
|
579
|
+
*/
|
|
580
|
+
declare function buildErrorRoute(options: ErrorRouteOptions): CaddyRoute;
|
|
581
|
+
/**
|
|
582
|
+
* Options for building a request body handler
|
|
583
|
+
*/
|
|
584
|
+
interface RequestBodyHandlerOptions {
|
|
585
|
+
/** Maximum request body size in bytes */
|
|
586
|
+
maxSize: number;
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Build a request body handler for limiting request body size
|
|
590
|
+
*
|
|
591
|
+
* @param options - Request body handler configuration
|
|
592
|
+
* @returns Request body handler
|
|
593
|
+
*
|
|
594
|
+
* @example
|
|
595
|
+
* ```typescript
|
|
596
|
+
* // Limit request body to 10MB
|
|
597
|
+
* const handler = buildRequestBodyHandler({ maxSize: 10 * 1024 * 1024 });
|
|
598
|
+
* ```
|
|
599
|
+
*/
|
|
600
|
+
declare function buildRequestBodyHandler(options: RequestBodyHandlerOptions): CaddyRouteHandler;
|
|
601
|
+
/**
|
|
602
|
+
* Options for building a vars handler
|
|
603
|
+
*/
|
|
604
|
+
interface VarsHandlerOptions {
|
|
605
|
+
/** Variables to set (key-value pairs) */
|
|
606
|
+
vars: Record<string, string>;
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Build a vars handler for setting request variables
|
|
610
|
+
*
|
|
611
|
+
* @param options - Vars handler configuration
|
|
612
|
+
* @returns Vars handler
|
|
613
|
+
*
|
|
614
|
+
* @example
|
|
615
|
+
* ```typescript
|
|
616
|
+
* // Set custom variables for downstream handlers
|
|
617
|
+
* const handler = buildVarsHandler({
|
|
618
|
+
* vars: {
|
|
619
|
+
* root: "/var/www",
|
|
620
|
+
* backend: "api-server",
|
|
621
|
+
* environment: "production",
|
|
622
|
+
* }
|
|
623
|
+
* });
|
|
624
|
+
* ```
|
|
625
|
+
*/
|
|
626
|
+
declare function buildVarsHandler(options: VarsHandlerOptions): CaddyRouteHandler;
|
|
627
|
+
/**
|
|
628
|
+
* Options for building a tracing handler
|
|
629
|
+
*/
|
|
630
|
+
interface TracingHandlerOptions {
|
|
631
|
+
/** Span name for tracing */
|
|
632
|
+
span?: string;
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Build a tracing handler for distributed tracing
|
|
636
|
+
*
|
|
637
|
+
* @param options - Tracing handler configuration
|
|
638
|
+
* @returns Tracing handler
|
|
639
|
+
*
|
|
640
|
+
* @example
|
|
641
|
+
* ```typescript
|
|
642
|
+
* const handler = buildTracingHandler({ span: "http.request" });
|
|
643
|
+
* ```
|
|
644
|
+
*/
|
|
645
|
+
declare function buildTracingHandler(options?: TracingHandlerOptions): CaddyRouteHandler;
|
|
646
|
+
/**
|
|
647
|
+
* Options for building a map handler
|
|
648
|
+
*/
|
|
649
|
+
interface MapHandlerOptions {
|
|
650
|
+
/** Source placeholder (e.g., "{http.request.uri.path}") */
|
|
651
|
+
source: string;
|
|
652
|
+
/** Destination placeholder names (e.g., ["{my_var}"]) */
|
|
653
|
+
destinations: string[];
|
|
654
|
+
/** Mappings from input patterns to outputs */
|
|
655
|
+
mappings: {
|
|
656
|
+
input: string;
|
|
657
|
+
outputs: string[];
|
|
658
|
+
}[];
|
|
659
|
+
/** Default outputs if no mappings match */
|
|
660
|
+
defaults?: string[];
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Build a map handler for variable mapping
|
|
664
|
+
*
|
|
665
|
+
* @param options - Map handler configuration
|
|
666
|
+
* @returns Map handler
|
|
667
|
+
*
|
|
668
|
+
* @example
|
|
669
|
+
* ```typescript
|
|
670
|
+
* // Map request paths to backend names
|
|
671
|
+
* const handler = buildMapHandler({
|
|
672
|
+
* source: "{http.request.uri.path}",
|
|
673
|
+
* destinations: ["{backend}"],
|
|
674
|
+
* mappings: [
|
|
675
|
+
* { input: "/api/*", outputs: ["api-server"] },
|
|
676
|
+
* { input: "/admin/*", outputs: ["admin-server"] },
|
|
677
|
+
* ],
|
|
678
|
+
* defaults: ["default-server"],
|
|
679
|
+
* });
|
|
680
|
+
* ```
|
|
681
|
+
*/
|
|
682
|
+
declare function buildMapHandler(options: MapHandlerOptions): CaddyRouteHandler;
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Valid Caddy configuration adapters
|
|
686
|
+
*/
|
|
687
|
+
type CaddyAdapter = "caddyfile" | "json" | "yaml" | "nginx" | "apache";
|
|
688
|
+
/**
|
|
689
|
+
* Options for loading configuration files
|
|
690
|
+
*/
|
|
691
|
+
interface LoadConfigOptions {
|
|
692
|
+
/** Caddy Admin API URL (default: http://127.0.0.1:2019) */
|
|
693
|
+
adminUrl?: string;
|
|
694
|
+
/** Request timeout in milliseconds (default: 5000) */
|
|
695
|
+
timeout?: number;
|
|
696
|
+
}
|
|
697
|
+
/**
|
|
698
|
+
* Detect the appropriate adapter based on file extension
|
|
699
|
+
*
|
|
700
|
+
* @param path - Path to the configuration file
|
|
701
|
+
* @returns The detected adapter type
|
|
702
|
+
*
|
|
703
|
+
* @example
|
|
704
|
+
* ```typescript
|
|
705
|
+
* detectAdapter("./config.json"); // "json"
|
|
706
|
+
* detectAdapter("./config.yaml"); // "yaml"
|
|
707
|
+
* detectAdapter("./Caddyfile"); // "caddyfile"
|
|
708
|
+
* detectAdapter("./unknown.txt"); // "caddyfile" (default)
|
|
709
|
+
* ```
|
|
710
|
+
*/
|
|
711
|
+
declare function detectAdapter(path: string): CaddyAdapter;
|
|
712
|
+
/**
|
|
713
|
+
* Load a configuration file and convert it to Caddy JSON format
|
|
714
|
+
*
|
|
715
|
+
* Reads the file from disk, auto-detects the format (or uses the provided adapter),
|
|
716
|
+
* and uses Caddy's /adapt endpoint to convert it to JSON configuration.
|
|
717
|
+
*
|
|
718
|
+
* @param path - Path to the configuration file
|
|
719
|
+
* @param adapter - Adapter to use (auto-detected from extension if not provided)
|
|
720
|
+
* @param options - Loading options (adminUrl, timeout)
|
|
721
|
+
* @returns The parsed Caddy configuration object
|
|
722
|
+
*
|
|
723
|
+
* @throws {ValidationError} If the file content is empty or invalid
|
|
724
|
+
* @throws {CaddyApiError} If Caddy cannot parse the configuration
|
|
725
|
+
* @throws {NetworkError} If unable to connect to Caddy Admin API
|
|
726
|
+
* @throws {TimeoutError} If the request times out
|
|
727
|
+
*
|
|
728
|
+
* @example
|
|
729
|
+
* ```typescript
|
|
730
|
+
* // Auto-detect format from extension
|
|
731
|
+
* const config = await loadConfig("./config.json");
|
|
732
|
+
*
|
|
733
|
+
* // Explicitly specify adapter
|
|
734
|
+
* const config = await loadConfig("./my-config", "caddyfile");
|
|
735
|
+
*
|
|
736
|
+
* // With custom Caddy URL
|
|
737
|
+
* const config = await loadConfig("./Caddyfile", undefined, {
|
|
738
|
+
* adminUrl: "http://caddy:2019"
|
|
739
|
+
* });
|
|
740
|
+
* ```
|
|
741
|
+
*/
|
|
742
|
+
declare function loadConfig(path: string, adapter?: CaddyAdapter, options?: LoadConfigOptions): Promise<Config & Record<string, unknown>>;
|
|
743
|
+
/**
|
|
744
|
+
* Load a Caddyfile and convert it to Caddy JSON format
|
|
745
|
+
*
|
|
746
|
+
* Convenience function for loading Caddyfile-formatted configuration.
|
|
747
|
+
* Equivalent to `loadConfig(path, "caddyfile", options)`.
|
|
748
|
+
*
|
|
749
|
+
* @param path - Path to the Caddyfile
|
|
750
|
+
* @param options - Loading options (adminUrl, timeout)
|
|
751
|
+
* @returns The parsed Caddy configuration object
|
|
752
|
+
*
|
|
753
|
+
* @throws {ValidationError} If the file content is empty or invalid
|
|
754
|
+
* @throws {CaddyApiError} If Caddy cannot parse the Caddyfile
|
|
755
|
+
* @throws {NetworkError} If unable to connect to Caddy Admin API
|
|
756
|
+
* @throws {TimeoutError} If the request times out
|
|
757
|
+
*
|
|
758
|
+
* @example
|
|
759
|
+
* ```typescript
|
|
760
|
+
* const config = await loadCaddyfile("./Caddyfile");
|
|
761
|
+
*
|
|
762
|
+
* // Modify the config
|
|
763
|
+
* config.apps.http.servers.srv0.routes.push(myNewRoute);
|
|
764
|
+
*
|
|
765
|
+
* // Apply to running Caddy
|
|
766
|
+
* await client.applyConfig(config);
|
|
767
|
+
* ```
|
|
768
|
+
*/
|
|
769
|
+
declare function loadCaddyfile(path: string, options?: LoadConfigOptions): Promise<Config & Record<string, unknown>>;
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* Domain management with TLS automation
|
|
773
|
+
*/
|
|
774
|
+
|
|
775
|
+
/**
|
|
776
|
+
* Add a domain with automatic TLS (Let's Encrypt)
|
|
777
|
+
* @param options - Domain configuration
|
|
778
|
+
* @returns Domain configuration
|
|
779
|
+
* @throws {ValidationError} If options fail validation
|
|
780
|
+
* @throws {DomainAlreadyExistsError} If domain already exists
|
|
781
|
+
* @throws {CaddyApiError} If Caddy API returns an error
|
|
782
|
+
*/
|
|
783
|
+
declare function addDomainWithAutoTls(options: AddDomainWithAutoTlsOptions): Promise<DomainConfig>;
|
|
784
|
+
/**
|
|
785
|
+
* Add a domain with custom TLS certificate
|
|
786
|
+
* @param options - Domain configuration with cert files
|
|
787
|
+
* @returns Domain configuration
|
|
788
|
+
* @throws {ValidationError} If options fail validation
|
|
789
|
+
* @throws {DomainAlreadyExistsError} If domain already exists
|
|
790
|
+
* @throws {CaddyApiError} If Caddy API returns an error
|
|
791
|
+
*/
|
|
792
|
+
declare function addDomainWithTls(options: AddDomainWithTlsOptions): Promise<DomainConfig>;
|
|
793
|
+
/**
|
|
794
|
+
* Update an existing domain
|
|
795
|
+
* @param options - Update options
|
|
796
|
+
* @returns Updated domain configuration
|
|
797
|
+
* @throws {ValidationError} If options fail validation
|
|
798
|
+
* @throws {DomainNotFoundError} If domain does not exist
|
|
799
|
+
* @throws {CaddyApiError} If Caddy API returns an error
|
|
800
|
+
*/
|
|
801
|
+
declare function updateDomain(options: UpdateDomainOptions): Promise<DomainConfig>;
|
|
802
|
+
/**
|
|
803
|
+
* Delete a domain and clean up associated certificates
|
|
804
|
+
* @param options - Delete options
|
|
805
|
+
* @throws {ValidationError} If options fail validation
|
|
806
|
+
* @throws {DomainNotFoundError} If domain does not exist
|
|
807
|
+
* @throws {CaddyApiError} If Caddy API returns an error
|
|
808
|
+
*/
|
|
809
|
+
declare function deleteDomain(options: DeleteDomainOptions): Promise<void>;
|
|
810
|
+
/**
|
|
811
|
+
* Get domain configuration
|
|
812
|
+
* @param domain - Domain name
|
|
813
|
+
* @param adminUrl - Caddy Admin API URL
|
|
814
|
+
* @returns Domain configuration or null if not found
|
|
815
|
+
*/
|
|
816
|
+
declare function getDomainConfig(domain: Domain, adminUrl?: string): Promise<DomainConfig | null>;
|
|
817
|
+
/**
|
|
818
|
+
* Rotate TLS certificate for a domain
|
|
819
|
+
* Adds new certificate while keeping the old one temporarily for zero-downtime rotation
|
|
820
|
+
* @param domain - Domain name
|
|
821
|
+
* @param newCertFile - Path to new certificate file
|
|
822
|
+
* @param newKeyFile - Path to new private key file
|
|
823
|
+
* @param adminUrl - Caddy Admin API URL
|
|
824
|
+
* @returns Certificate tag of the newly added certificate
|
|
825
|
+
*/
|
|
826
|
+
declare function rotateCertificate(domain: Domain, newCertFile: string, newKeyFile: string, adminUrl?: string): Promise<string>;
|
|
827
|
+
/**
|
|
828
|
+
* Remove old certificates for a domain after rotation
|
|
829
|
+
* Call this after verifying the new certificate is working
|
|
830
|
+
* @param domain - Domain name
|
|
831
|
+
* @param keepCertTag - Certificate tag to keep (usually the newest)
|
|
832
|
+
* @param adminUrl - Caddy Admin API URL
|
|
833
|
+
* @returns Number of certificates removed
|
|
834
|
+
*/
|
|
835
|
+
declare function removeOldCertificates(domain: Domain, keepCertTag: string, adminUrl?: string): Promise<number>;
|
|
836
|
+
/**
|
|
837
|
+
* List all configured domains across all servers
|
|
838
|
+
* Extracts unique hostnames from all routes in all servers
|
|
839
|
+
*
|
|
840
|
+
* @param adminUrl - Caddy admin API URL (optional, defaults to http://127.0.0.1:2019)
|
|
841
|
+
* @returns Array of unique domain names
|
|
842
|
+
*
|
|
843
|
+
* @example
|
|
844
|
+
* const domains = await listDomains();
|
|
845
|
+
* console.log(domains); // ["example.com", "www.example.com", "api.example.com"]
|
|
846
|
+
*/
|
|
847
|
+
declare function listDomains(adminUrl?: string): Promise<string[]>;
|
|
848
|
+
|
|
849
|
+
/**
|
|
850
|
+
* TLS connection policy builders and utilities
|
|
851
|
+
*/
|
|
852
|
+
|
|
853
|
+
/**
|
|
854
|
+
* Common TLS 1.3 cipher suites (recommended)
|
|
855
|
+
*/
|
|
856
|
+
declare const TLS_1_3_CIPHER_SUITES: readonly ["TLS_AES_128_GCM_SHA256", "TLS_AES_256_GCM_SHA384", "TLS_CHACHA20_POLY1305_SHA256"];
|
|
857
|
+
/**
|
|
858
|
+
* Common TLS 1.2 cipher suites (recommended)
|
|
859
|
+
*/
|
|
860
|
+
declare const TLS_1_2_CIPHER_SUITES: readonly ["TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"];
|
|
861
|
+
/**
|
|
862
|
+
* Modern cipher suites (TLS 1.2 + 1.3, secure)
|
|
863
|
+
*/
|
|
864
|
+
declare const MODERN_CIPHER_SUITES: ("TLS_AES_128_GCM_SHA256" | "TLS_AES_256_GCM_SHA384" | "TLS_CHACHA20_POLY1305_SHA256" | "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" | "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" | "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" | "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" | "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" | "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256")[];
|
|
865
|
+
/**
|
|
866
|
+
* Recommended elliptic curves (in order of preference)
|
|
867
|
+
*/
|
|
868
|
+
declare const RECOMMENDED_CURVES: readonly ["x25519", "secp256r1", "secp384r1"];
|
|
869
|
+
/**
|
|
870
|
+
* ALPN protocols for HTTP/3, HTTP/2, and HTTP/1.1
|
|
871
|
+
*/
|
|
872
|
+
declare const HTTP_ALPN_PROTOCOLS: readonly ["h3", "h2", "http/1.1"];
|
|
873
|
+
/**
|
|
874
|
+
* ALPN protocols for HTTP/2 and HTTP/1.1 (no HTTP/3)
|
|
875
|
+
*/
|
|
876
|
+
declare const HTTP2_ALPN_PROTOCOLS: readonly ["h2", "http/1.1"];
|
|
877
|
+
/**
|
|
878
|
+
* ALPN protocols for HTTP/1.1 only
|
|
879
|
+
*/
|
|
880
|
+
declare const HTTP1_ALPN_PROTOCOLS: readonly ["http/1.1"];
|
|
881
|
+
/**
|
|
882
|
+
* Options for building TLS connection policy
|
|
883
|
+
*/
|
|
884
|
+
interface TlsConnectionPolicyOptions {
|
|
885
|
+
/** SNI hostnames to match (e.g., ["example.com", "*.example.com"]) */
|
|
886
|
+
sni?: string[];
|
|
887
|
+
/** Certificate tags to select (any_tag) */
|
|
888
|
+
certificateTags?: string[];
|
|
889
|
+
/** Certificate tags required (all_tags) */
|
|
890
|
+
requiredCertificateTags?: string[];
|
|
891
|
+
/** Minimum TLS version ("1.2" or "1.3") */
|
|
892
|
+
protocolMin?: "1.2" | "1.3";
|
|
893
|
+
/** Maximum TLS version ("1.2" or "1.3") */
|
|
894
|
+
protocolMax?: "1.2" | "1.3";
|
|
895
|
+
/** Cipher suites to allow (or "modern" for recommended suites) */
|
|
896
|
+
cipherSuites?: string[] | "modern";
|
|
897
|
+
/** Elliptic curves to allow (or "recommended") */
|
|
898
|
+
curves?: string[] | "recommended";
|
|
899
|
+
/** ALPN protocols (or "http3", "http2", "http1") */
|
|
900
|
+
alpn?: string[] | "http3" | "http2" | "http1";
|
|
901
|
+
/** Client authentication mode */
|
|
902
|
+
clientAuthMode?: "request" | "require" | "verify_if_given";
|
|
903
|
+
/** Client CA certificate files */
|
|
904
|
+
clientCaCertFiles?: string[];
|
|
905
|
+
}
|
|
906
|
+
/**
|
|
907
|
+
* Build a TLS connection policy
|
|
908
|
+
*
|
|
909
|
+
* @param options - TLS policy options
|
|
910
|
+
* @returns TLS connection policy object
|
|
911
|
+
*
|
|
912
|
+
* @example
|
|
913
|
+
* ```typescript
|
|
914
|
+
* // Modern TLS 1.3 only with HTTP/3
|
|
915
|
+
* const policy = buildTlsConnectionPolicy({
|
|
916
|
+
* sni: ["example.com"],
|
|
917
|
+
* certificateTags: ["example-cert"],
|
|
918
|
+
* protocolMin: "1.3",
|
|
919
|
+
* cipherSuites: "modern",
|
|
920
|
+
* curves: "recommended",
|
|
921
|
+
* alpn: "http3"
|
|
922
|
+
* });
|
|
923
|
+
* ```
|
|
924
|
+
*/
|
|
925
|
+
declare function buildTlsConnectionPolicy(options: TlsConnectionPolicyOptions): TlsConnectionPolicy;
|
|
926
|
+
/**
|
|
927
|
+
* Build a modern, secure TLS policy (TLS 1.3 with HTTP/3 support)
|
|
928
|
+
*
|
|
929
|
+
* @param options - Basic options (sni, certificateTags)
|
|
930
|
+
* @returns Secure TLS connection policy
|
|
931
|
+
*
|
|
932
|
+
* @example
|
|
933
|
+
* ```typescript
|
|
934
|
+
* const policy = buildModernTlsPolicy({
|
|
935
|
+
* sni: ["example.com"],
|
|
936
|
+
* certificateTags: ["example-cert"]
|
|
937
|
+
* });
|
|
938
|
+
* ```
|
|
939
|
+
*/
|
|
940
|
+
declare function buildModernTlsPolicy(options: {
|
|
941
|
+
sni?: string[];
|
|
942
|
+
certificateTags?: string[];
|
|
943
|
+
}): TlsConnectionPolicy;
|
|
944
|
+
/**
|
|
945
|
+
* Build a compatible TLS policy (TLS 1.2+, HTTP/2 support, broader compatibility)
|
|
946
|
+
*
|
|
947
|
+
* @param options - Basic options (sni, certificateTags)
|
|
948
|
+
* @returns Compatible TLS connection policy
|
|
949
|
+
*
|
|
950
|
+
* @example
|
|
951
|
+
* ```typescript
|
|
952
|
+
* const policy = buildCompatibleTlsPolicy({
|
|
953
|
+
* sni: ["example.com"],
|
|
954
|
+
* certificateTags: ["example-cert"]
|
|
955
|
+
* });
|
|
956
|
+
* ```
|
|
957
|
+
*/
|
|
958
|
+
declare function buildCompatibleTlsPolicy(options: {
|
|
959
|
+
sni?: string[];
|
|
960
|
+
certificateTags?: string[];
|
|
961
|
+
}): TlsConnectionPolicy;
|
|
962
|
+
/**
|
|
963
|
+
* The shape Caddy expects in `policy.issuers[]` for the internal issuer:
|
|
964
|
+
* Caddy's generated {@link InternalIssuer} type (`ca`, `lifetime`,
|
|
965
|
+
* `sign_with_root`) plus the `module: "internal"` discriminator that
|
|
966
|
+
* Caddy's module system adds at the JSON boundary. See:
|
|
967
|
+
* https://caddyserver.com/docs/json/apps/tls/automation/policies/issuers/internal/
|
|
968
|
+
*/
|
|
969
|
+
type InternalIssuerJson = InternalIssuer & {
|
|
970
|
+
module: "internal";
|
|
971
|
+
};
|
|
972
|
+
/**
|
|
973
|
+
* Options for {@link buildAutomationPoliciesWithInternalFallback}.
|
|
974
|
+
*/
|
|
975
|
+
interface InternalFallbackPoliciesOptions {
|
|
976
|
+
/**
|
|
977
|
+
* If `true` (default), prepend an explicit policy scoping the internal
|
|
978
|
+
* issuer to `*.localhost` + `localhost`. The catch-all below would
|
|
979
|
+
* handle these too, but Caddy already treats `.localhost` specially in
|
|
980
|
+
* its built-in auto-HTTPS rules and emitting this policy is documentary.
|
|
981
|
+
*/
|
|
982
|
+
includeLocalhostPolicy?: boolean;
|
|
983
|
+
/**
|
|
984
|
+
* Optional override for the internal issuer used by the localhost
|
|
985
|
+
* policy and the catch-all (e.g. a custom CA id or `lifetime`).
|
|
986
|
+
* Caddy core's {@link InternalIssuer} fields, minus the `module`
|
|
987
|
+
* discriminator (added automatically). Defaults to an empty issuer
|
|
988
|
+
* (i.e. `{ module: "internal" }`).
|
|
989
|
+
*/
|
|
990
|
+
internalIssuer?: InternalIssuer;
|
|
991
|
+
}
|
|
992
|
+
/**
|
|
993
|
+
* Build a TLS `automation.policies` array whose final entry is an
|
|
994
|
+
* unscoped (catch-all) policy that uses Caddy's `internal` issuer.
|
|
995
|
+
*
|
|
996
|
+
* **Why this exists.** Without an unscoped catch-all, any hostname not
|
|
997
|
+
* matched by a more-specific policy hits Caddy's default behavior:
|
|
998
|
+
* obtain a Let's Encrypt cert via HTTP-01 / TLS-ALPN-01. For Caddy
|
|
999
|
+
* instances behind a tunnel/edge that already terminates TLS, or
|
|
1000
|
+
* running on a private network with no inbound port 80/443, that's
|
|
1001
|
+
* always wrong: the ACME challenge can't be solved, every renewal job
|
|
1002
|
+
* fails, and the log fills with `"obtaining certificate: ... context
|
|
1003
|
+
* canceled"` and `"no solvers available for remaining challenges"`.
|
|
1004
|
+
*
|
|
1005
|
+
* The fix is a terminal policy with no `subjects` field that uses the
|
|
1006
|
+
* internal (self-signed) issuer. Caddy's own schema describes
|
|
1007
|
+
* `AutomationPolicy.subjects` as a *filter, not a command*; omitting it
|
|
1008
|
+
* means "match anything not already matched."
|
|
1009
|
+
*
|
|
1010
|
+
* **Adding ACME-DNS or other plugin-backed issuers**: don't pass them
|
|
1011
|
+
* here. Construct a typed plugin policy via the plugin's schema (under
|
|
1012
|
+
* `src/plugins/<plugin-name>/`) and merge it into the policy array
|
|
1013
|
+
* before this catch-all in the calling code. This builder intentionally
|
|
1014
|
+
* exposes no `unknown`-shaped passthrough.
|
|
1015
|
+
*
|
|
1016
|
+
* Policy order produced:
|
|
1017
|
+
* 1. (default) `subjects: ["*.localhost", "localhost"]` → internal
|
|
1018
|
+
* 2. **Catch-all** (no `subjects`) → internal
|
|
1019
|
+
*
|
|
1020
|
+
* @example
|
|
1021
|
+
* ```typescript
|
|
1022
|
+
* const { policies } = buildAutomationPoliciesWithInternalFallback();
|
|
1023
|
+
* // [
|
|
1024
|
+
* // { subjects: ["*.localhost", "localhost"], issuers: [{ module: "internal" }] },
|
|
1025
|
+
* // { issuers: [{ module: "internal" }] },
|
|
1026
|
+
* // ]
|
|
1027
|
+
* ```
|
|
1028
|
+
*
|
|
1029
|
+
* @param options - {@link InternalFallbackPoliciesOptions}
|
|
1030
|
+
* @returns Object shaped for `apps.tls.automation`.
|
|
1031
|
+
*/
|
|
1032
|
+
declare function buildAutomationPoliciesWithInternalFallback(options?: InternalFallbackPoliciesOptions): {
|
|
1033
|
+
policies: AutomationPolicy[];
|
|
1034
|
+
};
|
|
1035
|
+
/**
|
|
1036
|
+
* Walk a Caddy `routes[]` tree (or any nested fragment) and collect every
|
|
1037
|
+
* non-internal hostname referenced in `match[].host[]`.
|
|
1038
|
+
*
|
|
1039
|
+
* Recurses into Caddy's `subroute` handler shape, where nested routes
|
|
1040
|
+
* live at `handle[].routes[]`. Hostnames Caddy already treats as internal
|
|
1041
|
+
* (`localhost`, `*.localhost`, `.localhost` suffixes, literal IPs) are
|
|
1042
|
+
* filtered out — see {@link isInternalHost}.
|
|
1043
|
+
*
|
|
1044
|
+
* Useful as input to {@link buildAutomaticHttpsConfig} when you want
|
|
1045
|
+
* `automatic_https.skip` to mirror the actual route topology rather than
|
|
1046
|
+
* a fixed list maintained somewhere else.
|
|
1047
|
+
*
|
|
1048
|
+
* @param routes - A Caddy `server.routes` array (or any nested fragment).
|
|
1049
|
+
* @returns Sorted, de-duplicated list of non-internal hostnames.
|
|
1050
|
+
*/
|
|
1051
|
+
declare function collectExternalHostsFromRoutes(routes: unknown): string[];
|
|
1052
|
+
/**
|
|
1053
|
+
* Options for {@link buildAutomaticHttpsConfig}. Mirrors Caddy core's
|
|
1054
|
+
* generated {@link AutoHTTPSConfig} (camelCased for the TypeScript API,
|
|
1055
|
+
* but emitted to Caddy's snake_case shape).
|
|
1056
|
+
*/
|
|
1057
|
+
interface AutomaticHttpsConfigOptions {
|
|
1058
|
+
/**
|
|
1059
|
+
* Hostnames to add to `automatic_https.skip` — Caddy disables automatic
|
|
1060
|
+
* HTTPS (cert acquisition AND HTTP→HTTPS redirect) for these.
|
|
1061
|
+
* Internal hosts (see {@link isInternalHost}) are filtered out and
|
|
1062
|
+
* duplicates are de-duplicated.
|
|
1063
|
+
*/
|
|
1064
|
+
skip?: string[];
|
|
1065
|
+
/**
|
|
1066
|
+
* Hostnames to add to `automatic_https.skip_certificates` — Caddy will
|
|
1067
|
+
* not obtain certs for these but will still install the HTTP→HTTPS
|
|
1068
|
+
* redirect. Use when the host is reachable on HTTPS via a manually-
|
|
1069
|
+
* loaded cert.
|
|
1070
|
+
*/
|
|
1071
|
+
skipCerts?: string[];
|
|
1072
|
+
/** Sets `automatic_https.disable_redirects: true`. */
|
|
1073
|
+
disableRedirects?: boolean;
|
|
1074
|
+
/** Sets `automatic_https.disable: true` (entire pipeline off). */
|
|
1075
|
+
disable?: boolean;
|
|
1076
|
+
/** Sets `automatic_https.disable_certificates: true` (cert mgmt off, redirects stay). */
|
|
1077
|
+
disableCertificates?: boolean;
|
|
1078
|
+
/** Sets `automatic_https.ignore_loaded_certificates: true`. */
|
|
1079
|
+
ignoreLoadedCertificates?: boolean;
|
|
1080
|
+
}
|
|
1081
|
+
/**
|
|
1082
|
+
* Build a Caddy `automatic_https` config block.
|
|
1083
|
+
*
|
|
1084
|
+
* Symmetric to {@link collectExternalHostsFromRoutes}: pass the result of
|
|
1085
|
+
* that walker as `skip` to derive the skip list dynamically from the live
|
|
1086
|
+
* routes.
|
|
1087
|
+
*
|
|
1088
|
+
* Returns `undefined` when no field would be set, so the caller can
|
|
1089
|
+
* conditionally assign without polluting the config with empty objects:
|
|
1090
|
+
*
|
|
1091
|
+
* const auto = buildAutomaticHttpsConfig({ skip: hosts, disableRedirects: true });
|
|
1092
|
+
* if (auto) server.automatic_https = auto;
|
|
1093
|
+
*
|
|
1094
|
+
* @see https://caddyserver.com/docs/json/apps/http/servers/automatic_https/
|
|
1095
|
+
*/
|
|
1096
|
+
declare function buildAutomaticHttpsConfig(options?: AutomaticHttpsConfigOptions): AutoHTTPSConfig | undefined;
|
|
1097
|
+
/**
|
|
1098
|
+
* Drop `automatic_https.skip` entries that would shadow an external-
|
|
1099
|
+
* ACME policy (Caddy evaluates skip via the same host-matcher as
|
|
1100
|
+
* routes). Three-way check, case-insensitive: exact match; candidate-
|
|
1101
|
+
* wildcard covers ACME host; ACME-host wildcard covers candidate.
|
|
1102
|
+
* Always returns a fresh array.
|
|
1103
|
+
*
|
|
1104
|
+
* @example
|
|
1105
|
+
* filterAcmeManagedFromSkip(["*.pro.com"], new Set(["app.pro.com"])) // []
|
|
1106
|
+
* filterAcmeManagedFromSkip(["app.pro.com"], new Set(["*.pro.com"])) // []
|
|
1107
|
+
* filterAcmeManagedFromSkip(["*.pro.com"], new Set(["api.other.com"])) // ["*.pro.com"]
|
|
1108
|
+
*/
|
|
1109
|
+
declare function filterAcmeManagedFromSkip(candidates: string[], acmeManagedHosts: Set<string>): string[];
|
|
1110
|
+
/**
|
|
1111
|
+
* Set `apps.pki.certificate_authorities.local.install_trust`.
|
|
1112
|
+
* Idempotent. Mutates in place. Throws when an intermediate node
|
|
1113
|
+
* exists but isn't an object — silent retyping would corrupt unrelated
|
|
1114
|
+
* state.
|
|
1115
|
+
*
|
|
1116
|
+
* Motivating case: on Windows the local CA's first issuance triggers
|
|
1117
|
+
* UAC + `certutil` (5–30 s), blocking the admin API.
|
|
1118
|
+
*
|
|
1119
|
+
* @example
|
|
1120
|
+
* applyLocalCaInstallTrust(cfg, false) // skip trust install
|
|
1121
|
+
*/
|
|
1122
|
+
declare function applyLocalCaInstallTrust(config: Record<string, unknown>, installTrust: boolean): void;
|
|
1123
|
+
|
|
1124
|
+
/**
|
|
1125
|
+
* Caddy host-matcher subset for config builders and diagnostics.
|
|
1126
|
+
* Covers what `automatic_https.skip` and `match.host[]` accept in
|
|
1127
|
+
* practice: exact, leading-wildcard single-label, generic glob.
|
|
1128
|
+
*/
|
|
1129
|
+
/**
|
|
1130
|
+
* True when `host` matches `pattern`:
|
|
1131
|
+
* - Exact: `pattern === host`.
|
|
1132
|
+
* - Single-label `*.tld`: matches one extra label (case-sensitive).
|
|
1133
|
+
* Only fires when the tail is a literal — `*.api-*.tld` is a
|
|
1134
|
+
* generic glob, not a single-label match.
|
|
1135
|
+
* - Generic glob: `*` becomes `.*` (crosses dots intentionally —
|
|
1136
|
+
* only the single-label branch enforces label boundaries).
|
|
1137
|
+
*
|
|
1138
|
+
* Case-sensitive — lowercase both inputs for case-insensitive match.
|
|
1139
|
+
*
|
|
1140
|
+
* @example
|
|
1141
|
+
* hostMatchesPattern("foo.example.com", "*.example.com") // true
|
|
1142
|
+
* hostMatchesPattern("a.b.example.com", "*.example.com") // false
|
|
1143
|
+
* hostMatchesPattern("api-a.b.example.com", "api-*.example.com") // true (glob crosses dots)
|
|
1144
|
+
*/
|
|
1145
|
+
declare function hostMatchesPattern(host: string, pattern: string): boolean;
|
|
1146
|
+
|
|
1147
|
+
/**
|
|
1148
|
+
* ACME-DNS automation policy builder. Emits the wrapper-level shape:
|
|
1149
|
+
* { subjects, issuers: [{ module: "acme", challenges: { dns: { provider: { name } } }, … }] }
|
|
1150
|
+
*
|
|
1151
|
+
* Provider credentials are NOT modelled here — Caddy reads them from
|
|
1152
|
+
* env vars (CLOUDFLARE_API_TOKEN, …). Layer typed `caddy-dns/*` shapes
|
|
1153
|
+
* via `providerConfig` (opaque passthrough).
|
|
1154
|
+
*/
|
|
1155
|
+
|
|
1156
|
+
/** Friendly DNS provider name → Caddy module name. Frozen. */
|
|
1157
|
+
declare const ACME_DNS_PROVIDER_MODULE_MAP: Readonly<Record<string, string>>;
|
|
1158
|
+
/**
|
|
1159
|
+
* Resolve a provider name to its Caddy module name. Trims + lower-cases
|
|
1160
|
+
* (Caddy module identifiers are lower-case). Unknown names pass through
|
|
1161
|
+
* normalised — `"MyProvider"` → `"myprovider"`.
|
|
1162
|
+
*/
|
|
1163
|
+
declare function resolveAcmeDnsProviderModule(name: string): string;
|
|
1164
|
+
/** Options for {@link buildAcmeDnsPolicy}. */
|
|
1165
|
+
interface AcmeDnsPolicyOptions {
|
|
1166
|
+
/** Hostnames the policy applies to. Non-empty; entries are trimmed. */
|
|
1167
|
+
subjects: string[];
|
|
1168
|
+
/** DNS provider name. Trim + lower-case normalised; passes through unknowns. */
|
|
1169
|
+
dnsProvider: string;
|
|
1170
|
+
/** Override ACME directory URL (`ca`). */
|
|
1171
|
+
ca?: string;
|
|
1172
|
+
/** Account email registered with the ACME server. */
|
|
1173
|
+
email?: string;
|
|
1174
|
+
/**
|
|
1175
|
+
* Opaque provider-config passthrough. Reserved keys throw: `name`
|
|
1176
|
+
* (owned by `dnsProvider`) and `module` (issuer-level discriminator,
|
|
1177
|
+
* not a provider field).
|
|
1178
|
+
*/
|
|
1179
|
+
providerConfig?: Record<string, unknown>;
|
|
1180
|
+
}
|
|
1181
|
+
/**
|
|
1182
|
+
* Build an ACME-DNS automation policy. Use with
|
|
1183
|
+
* {@link buildAutomationPoliciesWithInternalFallback} by prepending.
|
|
1184
|
+
*
|
|
1185
|
+
* Provider discriminator is `name`, not `module` — see Caddy core
|
|
1186
|
+
* `caddytls/automation.go`: `caddy:"namespace=dns.providers inline_key=name"`.
|
|
1187
|
+
*
|
|
1188
|
+
* @example
|
|
1189
|
+
* buildAcmeDnsPolicy({ subjects: ["example.com"], dnsProvider: "cloudflare" })
|
|
1190
|
+
*/
|
|
1191
|
+
declare function buildAcmeDnsPolicy(options: AcmeDnsPolicyOptions): AutomationPolicy;
|
|
1192
|
+
|
|
1193
|
+
/**
|
|
1194
|
+
* Route Ordering and Priority System
|
|
1195
|
+
*
|
|
1196
|
+
* Provides explicit route ordering to replace implicit array-based ordering.
|
|
1197
|
+
* Routes are sorted by priority (lower number = higher priority) and then by
|
|
1198
|
+
* path specificity.
|
|
1199
|
+
*
|
|
1200
|
+
* @module caddy/ordering
|
|
1201
|
+
*/
|
|
1202
|
+
|
|
1203
|
+
/**
|
|
1204
|
+
* Standard route priorities for common patterns
|
|
1205
|
+
* Lower numbers are evaluated first
|
|
1206
|
+
*/
|
|
1207
|
+
declare const ROUTE_PRIORITIES: Record<string, number>;
|
|
1208
|
+
/**
|
|
1209
|
+
* Calculate implicit priority from route match patterns
|
|
1210
|
+
* Used when explicit priority is not set
|
|
1211
|
+
*
|
|
1212
|
+
* Priority is calculated based on:
|
|
1213
|
+
* 1. Path specificity (exact > prefix > wildcard)
|
|
1214
|
+
* 2. Host specificity (exact > wildcard)
|
|
1215
|
+
* 3. Number of matchers (more = more specific)
|
|
1216
|
+
*
|
|
1217
|
+
* @param route - Route to analyze
|
|
1218
|
+
* @returns Calculated priority (0-100, lower = higher priority)
|
|
1219
|
+
*
|
|
1220
|
+
* @example
|
|
1221
|
+
* calculateRoutePriority({ match: [{ path: ["/health"] }] }) // Returns ~0 (health check)
|
|
1222
|
+
* calculateRoutePriority({ match: [{ path: ["/api/*"] }] }) // Returns ~30 (specific path)
|
|
1223
|
+
* calculateRoutePriority({ match: [{ path: ["/*"] }] }) // Returns ~90 (wildcard)
|
|
1224
|
+
*/
|
|
1225
|
+
declare function calculateRoutePriority(route: CaddyRoute): number;
|
|
1226
|
+
/**
|
|
1227
|
+
* Sort routes by priority and specificity
|
|
1228
|
+
* Routes with lower priority numbers are placed first
|
|
1229
|
+
* Within same priority, more specific routes come first
|
|
1230
|
+
*
|
|
1231
|
+
* @param routes - Routes to sort
|
|
1232
|
+
* @returns Sorted routes (does not mutate input)
|
|
1233
|
+
*
|
|
1234
|
+
* @example
|
|
1235
|
+
* const routes = [
|
|
1236
|
+
* { match: [{ path: ["/*"] }] }, // Wildcard
|
|
1237
|
+
* { match: [{ path: ["/health"] }] }, // Health
|
|
1238
|
+
* { match: [{ path: ["/api/*"] }] }, // API
|
|
1239
|
+
* ];
|
|
1240
|
+
* const sorted = sortRoutes(routes);
|
|
1241
|
+
* // Order: health, api, wildcard
|
|
1242
|
+
*/
|
|
1243
|
+
declare function sortRoutes(routes: CaddyRoute[]): CaddyRoute[];
|
|
1244
|
+
/**
|
|
1245
|
+
* Validate route ordering against expected rules
|
|
1246
|
+
* Throws if ordering would cause routing issues
|
|
1247
|
+
*
|
|
1248
|
+
* @param routes - Routes to validate (should already be sorted)
|
|
1249
|
+
* @throws {Error} If route ordering violates rules
|
|
1250
|
+
*
|
|
1251
|
+
* @example
|
|
1252
|
+
* const routes = sortRoutes([healthRoute, apiRoute, catchAll]);
|
|
1253
|
+
* validateRouteOrdering(routes); // No error
|
|
1254
|
+
*
|
|
1255
|
+
* validateRouteOrdering([catchAll, healthRoute]); // Throws error
|
|
1256
|
+
*/
|
|
1257
|
+
declare function validateRouteOrdering(routes: CaddyRoute[]): void;
|
|
1258
|
+
/**
|
|
1259
|
+
* Insert route with relative positioning
|
|
1260
|
+
* Allows inserting routes before/after specific route IDs
|
|
1261
|
+
*
|
|
1262
|
+
* @param routes - Existing routes
|
|
1263
|
+
* @param route - Route to insert
|
|
1264
|
+
* @param options - Positioning options
|
|
1265
|
+
* @returns New routes array with route inserted
|
|
1266
|
+
*
|
|
1267
|
+
* @example
|
|
1268
|
+
* // Insert at beginning
|
|
1269
|
+
* insertRouteRelative(routes, newRoute, { position: "beginning" })
|
|
1270
|
+
*
|
|
1271
|
+
* // Insert after health check
|
|
1272
|
+
* insertRouteRelative(routes, newRoute, { afterId: "global-health" })
|
|
1273
|
+
*
|
|
1274
|
+
* // Insert before catch-all
|
|
1275
|
+
* insertRouteRelative(routes, newRoute, { beforeId: "catch-all" })
|
|
1276
|
+
*/
|
|
1277
|
+
declare function insertRouteRelative(routes: CaddyRoute[], route: CaddyRoute, options?: {
|
|
1278
|
+
beforeId?: string;
|
|
1279
|
+
afterId?: string;
|
|
1280
|
+
position?: "beginning" | "end";
|
|
1281
|
+
}): CaddyRoute[];
|
|
1282
|
+
|
|
1283
|
+
/**
|
|
1284
|
+
* High-level helper functions for common Caddy routing patterns
|
|
1285
|
+
*
|
|
1286
|
+
* These helpers encode .asd production patterns and best practices,
|
|
1287
|
+
* hiding Caddy JSON complexity behind clean, semantic APIs.
|
|
1288
|
+
*
|
|
1289
|
+
* @module caddy/helpers
|
|
1290
|
+
*/
|
|
1291
|
+
|
|
1292
|
+
/**
|
|
1293
|
+
* Options for creating a health check route
|
|
1294
|
+
*/
|
|
1295
|
+
interface HealthRouteOptions {
|
|
1296
|
+
/** Instance identifier (e.g., "prod-cluster-1") */
|
|
1297
|
+
instanceId: string;
|
|
1298
|
+
/** Health check path (default: "/health") */
|
|
1299
|
+
path?: string;
|
|
1300
|
+
/** Number of services in this instance */
|
|
1301
|
+
services?: number;
|
|
1302
|
+
/** Instance version */
|
|
1303
|
+
version?: string;
|
|
1304
|
+
/** Project identifier for X-ASD-Project header */
|
|
1305
|
+
projectId?: string;
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* Options for creating service routes
|
|
1309
|
+
*/
|
|
1310
|
+
interface ServiceRouteOptions {
|
|
1311
|
+
/** Route identifier */
|
|
1312
|
+
id: string;
|
|
1313
|
+
/** Host to match (e.g., "api.localhost") */
|
|
1314
|
+
host: string;
|
|
1315
|
+
/** Path to match (default: "/*") */
|
|
1316
|
+
path?: string;
|
|
1317
|
+
/** Upstream backend (dial address or array of upstreams) */
|
|
1318
|
+
upstream: string | {
|
|
1319
|
+
dial: string;
|
|
1320
|
+
}[];
|
|
1321
|
+
/** Service identifier for X-ASD-Service-ID header */
|
|
1322
|
+
serviceId?: string;
|
|
1323
|
+
/** Service type for X-ASD-Service-Type header */
|
|
1324
|
+
serviceType?: string;
|
|
1325
|
+
/** Enable compression (default: true) */
|
|
1326
|
+
enableCompression?: boolean;
|
|
1327
|
+
/** Additional response headers */
|
|
1328
|
+
headers?: Record<string, string[]>;
|
|
1329
|
+
/** Explicit priority (optional) */
|
|
1330
|
+
priority?: number;
|
|
1331
|
+
/** Project identifier for X-ASD-Project header */
|
|
1332
|
+
projectId?: string;
|
|
1333
|
+
}
|
|
1334
|
+
/**
|
|
1335
|
+
* Options for creating basic auth routes
|
|
1336
|
+
*/
|
|
1337
|
+
interface BasicAuthRouteOptions {
|
|
1338
|
+
/** Route identifier */
|
|
1339
|
+
id?: string;
|
|
1340
|
+
/** Host to match */
|
|
1341
|
+
host: string;
|
|
1342
|
+
/** Path to match (omit for domain-level auth) */
|
|
1343
|
+
path?: string;
|
|
1344
|
+
/** User accounts with bcrypt password hashes */
|
|
1345
|
+
accounts: {
|
|
1346
|
+
username: string;
|
|
1347
|
+
password: string;
|
|
1348
|
+
}[];
|
|
1349
|
+
/** Upstream backend */
|
|
1350
|
+
upstream: string | {
|
|
1351
|
+
dial: string;
|
|
1352
|
+
}[];
|
|
1353
|
+
/** Authentication realm */
|
|
1354
|
+
realm?: string;
|
|
1355
|
+
/** Service identifier */
|
|
1356
|
+
serviceId?: string;
|
|
1357
|
+
/** Service type */
|
|
1358
|
+
serviceType?: string;
|
|
1359
|
+
/** Additional response headers */
|
|
1360
|
+
headers?: Record<string, string[]>;
|
|
1361
|
+
/** Explicit priority (optional) */
|
|
1362
|
+
priority?: number;
|
|
1363
|
+
/** Project identifier for X-ASD-Project header */
|
|
1364
|
+
projectId?: string;
|
|
1365
|
+
}
|
|
1366
|
+
/**
|
|
1367
|
+
* Options for creating load balancer routes
|
|
1368
|
+
*/
|
|
1369
|
+
interface LoadBalancerRouteOptions {
|
|
1370
|
+
/** Route identifier */
|
|
1371
|
+
id: string;
|
|
1372
|
+
/** Host to match */
|
|
1373
|
+
host: string;
|
|
1374
|
+
/** Path to match (default: "/*") */
|
|
1375
|
+
path?: string;
|
|
1376
|
+
/** Array of upstream backends */
|
|
1377
|
+
upstreams: string[] | {
|
|
1378
|
+
dial: string;
|
|
1379
|
+
}[];
|
|
1380
|
+
/** Load balancing policy */
|
|
1381
|
+
policy?: "round_robin" | "least_conn" | "ip_hash" | "first" | "random";
|
|
1382
|
+
/** Enable active health checks */
|
|
1383
|
+
healthCheck?: {
|
|
1384
|
+
path?: string;
|
|
1385
|
+
interval?: string;
|
|
1386
|
+
timeout?: string;
|
|
1387
|
+
};
|
|
1388
|
+
/** Service identifier */
|
|
1389
|
+
serviceId?: string;
|
|
1390
|
+
/** Additional response headers */
|
|
1391
|
+
headers?: Record<string, string[]>;
|
|
1392
|
+
}
|
|
1393
|
+
/**
|
|
1394
|
+
* Options for creating path rewrite routes
|
|
1395
|
+
*/
|
|
1396
|
+
interface RewriteRouteOptions {
|
|
1397
|
+
/** Route identifier */
|
|
1398
|
+
id: string;
|
|
1399
|
+
/** Host to match */
|
|
1400
|
+
host: string;
|
|
1401
|
+
/** Path prefix to match and strip */
|
|
1402
|
+
pathPrefix: string;
|
|
1403
|
+
/** Upstream backend */
|
|
1404
|
+
upstream: string | {
|
|
1405
|
+
dial: string;
|
|
1406
|
+
}[];
|
|
1407
|
+
/** Service identifier */
|
|
1408
|
+
serviceId?: string;
|
|
1409
|
+
/** Additional response headers */
|
|
1410
|
+
headers?: Record<string, string[]>;
|
|
1411
|
+
}
|
|
1412
|
+
/**
|
|
1413
|
+
* Create a standardized global health check route
|
|
1414
|
+
* Always evaluated first, accessible from any host
|
|
1415
|
+
*
|
|
1416
|
+
* @param options - Health check configuration
|
|
1417
|
+
* @returns Health check route with priority 0
|
|
1418
|
+
*
|
|
1419
|
+
* @example
|
|
1420
|
+
* const health = createHealthRoute({
|
|
1421
|
+
* instanceId: "prod-cluster-1",
|
|
1422
|
+
* services: 10,
|
|
1423
|
+
* version: "1.0.0",
|
|
1424
|
+
* });
|
|
1425
|
+
*/
|
|
1426
|
+
declare function createHealthRoute(options: HealthRouteOptions): CaddyRoute;
|
|
1427
|
+
/**
|
|
1428
|
+
* Create service routes with standard security headers
|
|
1429
|
+
* Returns single route (no redirect in this version)
|
|
1430
|
+
*
|
|
1431
|
+
* @param options - Service configuration
|
|
1432
|
+
* @returns Service route
|
|
1433
|
+
*
|
|
1434
|
+
* @example
|
|
1435
|
+
* const route = createServiceRoute({
|
|
1436
|
+
* id: "api-service",
|
|
1437
|
+
* host: "api.localhost",
|
|
1438
|
+
* path: "/api/*",
|
|
1439
|
+
* upstream: "backend:8080",
|
|
1440
|
+
* serviceId: "api-backend-v1",
|
|
1441
|
+
* serviceType: "api",
|
|
1442
|
+
* });
|
|
1443
|
+
*/
|
|
1444
|
+
declare function createServiceRoute(options: ServiceRouteOptions): CaddyRoute;
|
|
1445
|
+
/**
|
|
1446
|
+
* Create Basic Auth protected route (domain or path-level)
|
|
1447
|
+
*
|
|
1448
|
+
* @param options - Authentication configuration
|
|
1449
|
+
* @returns Auth-protected route
|
|
1450
|
+
*
|
|
1451
|
+
* @example
|
|
1452
|
+
* // Domain-level auth (entire domain protected)
|
|
1453
|
+
* const route = createBasicAuthRoute({
|
|
1454
|
+
* host: "admin.localhost",
|
|
1455
|
+
* accounts: [
|
|
1456
|
+
* { username: "admin", password: "$2a$14$..." },
|
|
1457
|
+
* { username: "superadmin", password: "$2a$14$..." },
|
|
1458
|
+
* ],
|
|
1459
|
+
* upstream: "admin-backend:8080",
|
|
1460
|
+
* realm: "Admin Dashboard",
|
|
1461
|
+
* });
|
|
1462
|
+
*
|
|
1463
|
+
* @example
|
|
1464
|
+
* // Path-level auth (specific paths protected)
|
|
1465
|
+
* const route = createBasicAuthRoute({
|
|
1466
|
+
* host: "api.localhost",
|
|
1467
|
+
* path: "/admin/*",
|
|
1468
|
+
* accounts: [{ username: "apiuser", password: "$2a$14$..." }],
|
|
1469
|
+
* upstream: "api-backend:8080",
|
|
1470
|
+
* realm: "API Admin",
|
|
1471
|
+
* });
|
|
1472
|
+
*/
|
|
1473
|
+
declare function createBasicAuthRoute(options: BasicAuthRouteOptions): CaddyRoute;
|
|
1474
|
+
/**
|
|
1475
|
+
* Create load-balanced route with health checks
|
|
1476
|
+
*
|
|
1477
|
+
* @param options - Load balancer configuration
|
|
1478
|
+
* @returns Load-balanced route
|
|
1479
|
+
*
|
|
1480
|
+
* @example
|
|
1481
|
+
* const route = createLoadBalancerRoute({
|
|
1482
|
+
* id: "api-lb",
|
|
1483
|
+
* host: "api.localhost",
|
|
1484
|
+
* upstreams: ["backend-1:8080", "backend-2:8080", "backend-3:8080"],
|
|
1485
|
+
* policy: "round_robin",
|
|
1486
|
+
* healthCheck: {
|
|
1487
|
+
* path: "/health",
|
|
1488
|
+
* interval: "10s",
|
|
1489
|
+
* timeout: "2s",
|
|
1490
|
+
* },
|
|
1491
|
+
* });
|
|
1492
|
+
*/
|
|
1493
|
+
declare function createLoadBalancerRoute(options: LoadBalancerRouteOptions): CaddyRoute;
|
|
1494
|
+
/**
|
|
1495
|
+
* Create path rewriting route
|
|
1496
|
+
* Strips path prefix before proxying to backend
|
|
1497
|
+
*
|
|
1498
|
+
* @param options - Rewrite configuration
|
|
1499
|
+
* @returns Route with path rewriting
|
|
1500
|
+
*
|
|
1501
|
+
* @example
|
|
1502
|
+
* const route = createRewriteRoute({
|
|
1503
|
+
* id: "api-rewrite",
|
|
1504
|
+
* host: "app.localhost",
|
|
1505
|
+
* pathPrefix: "/api/v1",
|
|
1506
|
+
* upstream: "backend:3000",
|
|
1507
|
+
* });
|
|
1508
|
+
* // Request to /api/v1/users → backend receives /users
|
|
1509
|
+
*/
|
|
1510
|
+
declare function createRewriteRoute(options: RewriteRouteOptions): CaddyRoute;
|
|
1511
|
+
/**
|
|
1512
|
+
* Create redirect route (www ↔ domain)
|
|
1513
|
+
*
|
|
1514
|
+
* @param options - Redirect configuration
|
|
1515
|
+
* @returns Redirect route
|
|
1516
|
+
*
|
|
1517
|
+
* @example
|
|
1518
|
+
* // Redirect www.example.com → example.com
|
|
1519
|
+
* const route = createRedirectRoute({
|
|
1520
|
+
* from: "www.example.com",
|
|
1521
|
+
* to: "example.com",
|
|
1522
|
+
* });
|
|
1523
|
+
*
|
|
1524
|
+
* @example
|
|
1525
|
+
* // Redirect example.com → www.example.com with custom status code
|
|
1526
|
+
* const route = createRedirectRoute({
|
|
1527
|
+
* from: "example.com",
|
|
1528
|
+
* to: "www.example.com",
|
|
1529
|
+
* statusCode: 301, // Or 302, 307, 308
|
|
1530
|
+
* });
|
|
1531
|
+
*/
|
|
1532
|
+
declare function createRedirectRoute(options: {
|
|
1533
|
+
id?: string;
|
|
1534
|
+
from: string;
|
|
1535
|
+
to: string;
|
|
1536
|
+
permanent?: boolean;
|
|
1537
|
+
statusCode?: 301 | 302 | 307 | 308;
|
|
1538
|
+
}): CaddyRoute;
|
|
1539
|
+
|
|
1540
|
+
interface CertificateInfo {
|
|
1541
|
+
serialNumber: string;
|
|
1542
|
+
subject: string;
|
|
1543
|
+
issuer: string;
|
|
1544
|
+
notBefore: Date;
|
|
1545
|
+
notAfter: Date;
|
|
1546
|
+
}
|
|
1547
|
+
/**
|
|
1548
|
+
* Parse PEM certificate and extract metadata
|
|
1549
|
+
* @param pemCert - PEM-encoded certificate
|
|
1550
|
+
* @returns Certificate metadata
|
|
1551
|
+
*/
|
|
1552
|
+
declare function parseCertificate(pemCert: string): CertificateInfo;
|
|
1553
|
+
/**
|
|
1554
|
+
* Generate unique certificate tag for tracking in Caddy
|
|
1555
|
+
* Format: {domain}-{serial}-{timestamp}
|
|
1556
|
+
* @param domain - Domain name
|
|
1557
|
+
* @param serialNumber - Certificate serial number (hex)
|
|
1558
|
+
* @returns Unique certificate tag
|
|
1559
|
+
*/
|
|
1560
|
+
declare function generateCertTag(domain: string, serialNumber: string): string;
|
|
1561
|
+
/**
|
|
1562
|
+
* Split certificate bundle into individual certificates
|
|
1563
|
+
* Handles multi-certificate PEM files (certificate chains)
|
|
1564
|
+
* @param bundle - PEM bundle containing one or more certificates
|
|
1565
|
+
* @returns Array of individual PEM certificates
|
|
1566
|
+
*/
|
|
1567
|
+
declare function splitCertificateBundle(bundle: string): string[];
|
|
1568
|
+
/**
|
|
1569
|
+
* Extract certificate serial number as hex string
|
|
1570
|
+
* @param pemCert - PEM-encoded certificate
|
|
1571
|
+
* @returns Serial number in hexadecimal format
|
|
1572
|
+
*/
|
|
1573
|
+
declare function extractSerialNumber(pemCert: string): string;
|
|
1574
|
+
/**
|
|
1575
|
+
* Check if certificate is expired
|
|
1576
|
+
* @param pemCert - PEM-encoded certificate
|
|
1577
|
+
* @returns True if certificate is expired
|
|
1578
|
+
*/
|
|
1579
|
+
declare function isCertificateExpired(pemCert: string): boolean;
|
|
1580
|
+
/**
|
|
1581
|
+
* Check if certificate expires within the specified days
|
|
1582
|
+
* @param pemCert - PEM-encoded certificate
|
|
1583
|
+
* @param days - Number of days to check
|
|
1584
|
+
* @returns True if certificate expires within the specified days
|
|
1585
|
+
*/
|
|
1586
|
+
declare function isCertificateExpiringSoon(pemCert: string, days: number): boolean;
|
|
1587
|
+
/**
|
|
1588
|
+
* Get days until certificate expiration
|
|
1589
|
+
* @param pemCert - PEM-encoded certificate
|
|
1590
|
+
* @returns Days until expiration (negative if expired)
|
|
1591
|
+
*/
|
|
1592
|
+
declare function getDaysUntilExpiration(pemCert: string): number;
|
|
1593
|
+
|
|
1594
|
+
/**
|
|
1595
|
+
* Certificate Management Abstraction
|
|
1596
|
+
*
|
|
1597
|
+
* Provides a unified interface for all certificate operations,
|
|
1598
|
+
* bundling certificate utilities and domain TLS management.
|
|
1599
|
+
*
|
|
1600
|
+
* @module caddy/certificates
|
|
1601
|
+
*/
|
|
1602
|
+
|
|
1603
|
+
/**
|
|
1604
|
+
* Certificate metadata with additional context
|
|
1605
|
+
*/
|
|
1606
|
+
interface CertificateWithMetadata extends CertificateInfo {
|
|
1607
|
+
/** Certificate tag in Caddy config */
|
|
1608
|
+
tag: string;
|
|
1609
|
+
/** Whether certificate is expired */
|
|
1610
|
+
isExpired: boolean;
|
|
1611
|
+
/** Whether certificate expires soon (within threshold) */
|
|
1612
|
+
expiringSoon: boolean;
|
|
1613
|
+
/** Days until expiration (negative if expired) */
|
|
1614
|
+
daysUntilExpiration: number;
|
|
1615
|
+
}
|
|
1616
|
+
/**
|
|
1617
|
+
* Options for certificate rotation
|
|
1618
|
+
*/
|
|
1619
|
+
interface RotateCertificateOptions {
|
|
1620
|
+
/** Domain name */
|
|
1621
|
+
domain: string;
|
|
1622
|
+
/** Path to new certificate file */
|
|
1623
|
+
certPath: string;
|
|
1624
|
+
/** Path to new private key file */
|
|
1625
|
+
keyPath: string;
|
|
1626
|
+
/** Caddy admin API URL (optional, defaults to client URL) */
|
|
1627
|
+
adminUrl?: string;
|
|
1628
|
+
/** Whether to remove old certificates after rotation */
|
|
1629
|
+
cleanupOld?: boolean;
|
|
1630
|
+
}
|
|
1631
|
+
/**
|
|
1632
|
+
* Result of certificate rotation operation
|
|
1633
|
+
*/
|
|
1634
|
+
interface RotationResult {
|
|
1635
|
+
/** New certificate tag */
|
|
1636
|
+
tag: string;
|
|
1637
|
+
/** Number of old certificates removed (if cleanup enabled) */
|
|
1638
|
+
removedCount?: number;
|
|
1639
|
+
}
|
|
1640
|
+
/**
|
|
1641
|
+
* Certificate expiration check result
|
|
1642
|
+
*/
|
|
1643
|
+
interface ExpirationCheckResult {
|
|
1644
|
+
/** Whether any certificates are expiring soon */
|
|
1645
|
+
hasExpiring: boolean;
|
|
1646
|
+
/** Certificates that are expiring or expired */
|
|
1647
|
+
expiringCertificates: CertificateWithMetadata[];
|
|
1648
|
+
/** All certificates for the domain */
|
|
1649
|
+
allCertificates: CertificateWithMetadata[];
|
|
1650
|
+
}
|
|
1651
|
+
/**
|
|
1652
|
+
* Certificate Manager
|
|
1653
|
+
*
|
|
1654
|
+
* Unified interface for certificate operations.
|
|
1655
|
+
* Bundles certificate inspection, rotation, cleanup, and monitoring.
|
|
1656
|
+
*
|
|
1657
|
+
* @example
|
|
1658
|
+
* const manager = new CertificateManager(client);
|
|
1659
|
+
*
|
|
1660
|
+
* // Inspect certificate
|
|
1661
|
+
* const info = await manager.inspect(certPem);
|
|
1662
|
+
*
|
|
1663
|
+
* // Rotate certificate
|
|
1664
|
+
* const result = await manager.rotate({
|
|
1665
|
+
* domain: "example.com",
|
|
1666
|
+
* certPath: "/path/to/new-cert.pem",
|
|
1667
|
+
* keyPath: "/path/to/new-key.pem",
|
|
1668
|
+
* cleanupOld: true,
|
|
1669
|
+
* });
|
|
1670
|
+
*
|
|
1671
|
+
* // Check expiration
|
|
1672
|
+
* const check = await manager.checkExpiration("example.com", 30);
|
|
1673
|
+
* if (check.hasExpiring) {
|
|
1674
|
+
* console.log(`${check.expiringCertificates.length} certs expiring soon`);
|
|
1675
|
+
* }
|
|
1676
|
+
*/
|
|
1677
|
+
declare class CertificateManager {
|
|
1678
|
+
private client;
|
|
1679
|
+
constructor(client: CaddyClient);
|
|
1680
|
+
/**
|
|
1681
|
+
* Inspect certificate metadata from PEM string
|
|
1682
|
+
*
|
|
1683
|
+
* @param certPem - PEM-encoded certificate
|
|
1684
|
+
* @returns Certificate information
|
|
1685
|
+
*
|
|
1686
|
+
* @example
|
|
1687
|
+
* const info = await manager.inspect(certPem);
|
|
1688
|
+
* console.log(`Serial: ${info.serialNumber}`);
|
|
1689
|
+
* console.log(`Expires: ${info.notAfter}`);
|
|
1690
|
+
*/
|
|
1691
|
+
inspect(certPem: string): Promise<CertificateInfo>;
|
|
1692
|
+
/**
|
|
1693
|
+
* Rotate certificate with zero downtime
|
|
1694
|
+
*
|
|
1695
|
+
* Process:
|
|
1696
|
+
* 1. Load new certificate and key
|
|
1697
|
+
* 2. Generate unique tag
|
|
1698
|
+
* 3. Add new certificate to Caddy
|
|
1699
|
+
* 4. Update domain's TLS automation to use new certificate
|
|
1700
|
+
* 5. Optionally remove old certificates
|
|
1701
|
+
*
|
|
1702
|
+
* @param options - Rotation options
|
|
1703
|
+
* @returns Rotation result with new tag and cleanup count
|
|
1704
|
+
*
|
|
1705
|
+
* @example
|
|
1706
|
+
* const result = await manager.rotate({
|
|
1707
|
+
* domain: "example.com",
|
|
1708
|
+
* certPath: "/certs/new-cert.pem",
|
|
1709
|
+
* keyPath: "/certs/new-key.pem",
|
|
1710
|
+
* cleanupOld: true,
|
|
1711
|
+
* });
|
|
1712
|
+
* console.log(`New tag: ${result.tag}`);
|
|
1713
|
+
* console.log(`Removed ${result.removedCount} old certificates`);
|
|
1714
|
+
*/
|
|
1715
|
+
rotate(options: RotateCertificateOptions): Promise<RotationResult>;
|
|
1716
|
+
/**
|
|
1717
|
+
* Remove old certificates after rotation
|
|
1718
|
+
*
|
|
1719
|
+
* Removes all certificates for the domain except the one with the specified tag.
|
|
1720
|
+
*
|
|
1721
|
+
* @param domain - Domain name
|
|
1722
|
+
* @param keepTag - Certificate tag to keep
|
|
1723
|
+
* @param adminUrl - Optional Caddy admin URL
|
|
1724
|
+
* @returns Number of certificates removed
|
|
1725
|
+
*
|
|
1726
|
+
* @example
|
|
1727
|
+
* const removed = await manager.cleanupOld("example.com", "example.com-abc123-1234567890");
|
|
1728
|
+
* console.log(`Removed ${removed} old certificates`);
|
|
1729
|
+
*/
|
|
1730
|
+
cleanupOld(domain: string, keepTag: string, adminUrl?: string): Promise<number>;
|
|
1731
|
+
/**
|
|
1732
|
+
* List all certificates for a domain
|
|
1733
|
+
*
|
|
1734
|
+
* Queries Caddy configuration to find all certificates tagged with the domain.
|
|
1735
|
+
*
|
|
1736
|
+
* @param domain - Domain name
|
|
1737
|
+
* @returns Array of certificates with metadata
|
|
1738
|
+
*
|
|
1739
|
+
* @example
|
|
1740
|
+
* const certs = await manager.list("example.com");
|
|
1741
|
+
* for (const cert of certs) {
|
|
1742
|
+
* console.log(`Tag: ${cert.tag}, Expires: ${cert.notAfter}`);
|
|
1743
|
+
* }
|
|
1744
|
+
*/
|
|
1745
|
+
list(domain: string): Promise<CertificateWithMetadata[]>;
|
|
1746
|
+
/**
|
|
1747
|
+
* Check if any certificates are expiring soon
|
|
1748
|
+
*
|
|
1749
|
+
* @param domain - Domain name
|
|
1750
|
+
* @param thresholdDays - Days before expiration to consider "expiring soon" (default: 30)
|
|
1751
|
+
* @returns Expiration check result
|
|
1752
|
+
*
|
|
1753
|
+
* @example
|
|
1754
|
+
* const check = await manager.checkExpiration("example.com", 30);
|
|
1755
|
+
* if (check.hasExpiring) {
|
|
1756
|
+
* for (const cert of check.expiringCertificates) {
|
|
1757
|
+
* console.log(`Certificate ${cert.tag} expires in ${cert.daysUntilExpiration} days`);
|
|
1758
|
+
* }
|
|
1759
|
+
* }
|
|
1760
|
+
*/
|
|
1761
|
+
checkExpiration(domain: string, thresholdDays?: number): Promise<ExpirationCheckResult>;
|
|
1762
|
+
/**
|
|
1763
|
+
* Generate a certificate tag for a domain
|
|
1764
|
+
*
|
|
1765
|
+
* Tags are in format: `{domain}-{serial}-{timestamp}`
|
|
1766
|
+
*
|
|
1767
|
+
* @param domain - Domain name
|
|
1768
|
+
* @param certPem - PEM-encoded certificate
|
|
1769
|
+
* @returns Certificate tag
|
|
1770
|
+
*
|
|
1771
|
+
* @example
|
|
1772
|
+
* const tag = await manager.generateTag("example.com", certPem);
|
|
1773
|
+
* // Returns: "example.com-abc123def456-1234567890"
|
|
1774
|
+
*/
|
|
1775
|
+
generateTag(domain: string, certPem: string): Promise<string>;
|
|
1776
|
+
/**
|
|
1777
|
+
* Check if certificate is expired
|
|
1778
|
+
*
|
|
1779
|
+
* @param certPem - PEM-encoded certificate
|
|
1780
|
+
* @returns True if certificate is expired
|
|
1781
|
+
*
|
|
1782
|
+
* @example
|
|
1783
|
+
* const isExpired = await manager.isExpired(certPem);
|
|
1784
|
+
* if (isExpired) {
|
|
1785
|
+
* console.log("Certificate is expired!");
|
|
1786
|
+
* }
|
|
1787
|
+
*/
|
|
1788
|
+
isExpired(certPem: string): Promise<boolean>;
|
|
1789
|
+
/**
|
|
1790
|
+
* Check if certificate expires soon
|
|
1791
|
+
*
|
|
1792
|
+
* @param certPem - PEM-encoded certificate
|
|
1793
|
+
* @param thresholdDays - Days before expiration (default: 30)
|
|
1794
|
+
* @returns True if certificate expires within threshold
|
|
1795
|
+
*
|
|
1796
|
+
* @example
|
|
1797
|
+
* const expiringSoon = await manager.isExpiringSoon(certPem, 30);
|
|
1798
|
+
* if (expiringSoon) {
|
|
1799
|
+
* console.log("Certificate expires soon!");
|
|
1800
|
+
* }
|
|
1801
|
+
*/
|
|
1802
|
+
isExpiringSoon(certPem: string, thresholdDays?: number): Promise<boolean>;
|
|
1803
|
+
/**
|
|
1804
|
+
* Get days until certificate expiration
|
|
1805
|
+
*
|
|
1806
|
+
* @param certPem - PEM-encoded certificate
|
|
1807
|
+
* @returns Days until expiration (negative if expired)
|
|
1808
|
+
*
|
|
1809
|
+
* @example
|
|
1810
|
+
* const days = await manager.getDaysUntilExpiration(certPem);
|
|
1811
|
+
* console.log(`Certificate expires in ${days} days`);
|
|
1812
|
+
*/
|
|
1813
|
+
getDaysUntilExpiration(certPem: string): Promise<number>;
|
|
1814
|
+
}
|
|
1815
|
+
/**
|
|
1816
|
+
* Create a new CertificateManager instance
|
|
1817
|
+
*
|
|
1818
|
+
* @param client - CaddyClient instance
|
|
1819
|
+
* @returns CertificateManager
|
|
1820
|
+
*
|
|
1821
|
+
* @example
|
|
1822
|
+
* import { CaddyClient, createCertificateManager } from "caddy-api-client";
|
|
1823
|
+
*
|
|
1824
|
+
* const client = new CaddyClient();
|
|
1825
|
+
* const manager = createCertificateManager(client);
|
|
1826
|
+
*
|
|
1827
|
+
* const result = await manager.rotate({
|
|
1828
|
+
* domain: "example.com",
|
|
1829
|
+
* certPath: "/certs/cert.pem",
|
|
1830
|
+
* keyPath: "/certs/key.pem",
|
|
1831
|
+
* });
|
|
1832
|
+
*/
|
|
1833
|
+
declare function createCertificateManager(client: CaddyClient): CertificateManager;
|
|
1834
|
+
|
|
1835
|
+
/**
|
|
1836
|
+
* Authentication utilities for Caddy
|
|
1837
|
+
* Provides bcrypt password hashing for HTTP Basic Auth
|
|
1838
|
+
*/
|
|
1839
|
+
/**
|
|
1840
|
+
* Hash a password using bcrypt
|
|
1841
|
+
* This uses Node.js crypto module to generate bcrypt hashes
|
|
1842
|
+
* compatible with Caddy's basic_auth handler.
|
|
1843
|
+
*
|
|
1844
|
+
* @param password - Plain text password
|
|
1845
|
+
* @param rounds - Bcrypt cost factor (default: 10, range: 4-31)
|
|
1846
|
+
* @returns Promise resolving to bcrypt hash string
|
|
1847
|
+
* @throws Error if rounds is outside valid range (4-31) or bcrypt module is not installed
|
|
1848
|
+
*
|
|
1849
|
+
* @example
|
|
1850
|
+
* const hash = await hashPassword("my-secret-password");
|
|
1851
|
+
* // Returns: $2a$10$... (bcrypt hash)
|
|
1852
|
+
*/
|
|
1853
|
+
declare function hashPassword(password: string, rounds?: number): Promise<string>;
|
|
1854
|
+
/**
|
|
1855
|
+
* Verify a password against a bcrypt hash
|
|
1856
|
+
* Useful for testing authentication configurations
|
|
1857
|
+
*
|
|
1858
|
+
* @param password - Plain text password
|
|
1859
|
+
* @param hash - Bcrypt hash to verify against
|
|
1860
|
+
* @returns Promise resolving to true if password matches
|
|
1861
|
+
*
|
|
1862
|
+
* @example
|
|
1863
|
+
* const isValid = await verifyPassword("my-password", hash);
|
|
1864
|
+
*/
|
|
1865
|
+
declare function verifyPassword(password: string, hash: string): Promise<boolean>;
|
|
1866
|
+
/**
|
|
1867
|
+
* Generate a bcrypt hash synchronously using Caddy's caddy hash-password command
|
|
1868
|
+
* This is useful for generating hashes without the bcrypt npm module
|
|
1869
|
+
*
|
|
1870
|
+
* @param password - Plain text password
|
|
1871
|
+
* @returns Promise resolving to bcrypt hash or instructions
|
|
1872
|
+
*
|
|
1873
|
+
* @example
|
|
1874
|
+
* const hash = await hashPasswordWithCaddy("my-password");
|
|
1875
|
+
*/
|
|
1876
|
+
declare function hashPasswordWithCaddy(password: string): Promise<string>;
|
|
1877
|
+
/**
|
|
1878
|
+
* Create basic auth account configuration for Caddy
|
|
1879
|
+
*
|
|
1880
|
+
* @param username - Username for authentication
|
|
1881
|
+
* @param password - Plain text password (will be hashed with bcrypt)
|
|
1882
|
+
* @param options - Optional configuration
|
|
1883
|
+
* @returns Promise resolving to account object with hashed password
|
|
1884
|
+
*
|
|
1885
|
+
* @example
|
|
1886
|
+
* const account = await createBasicAuthAccount("admin", "secret123");
|
|
1887
|
+
* // Returns: { username: "admin", password: "$2a$10$..." }
|
|
1888
|
+
*/
|
|
1889
|
+
declare function createBasicAuthAccount(username: string, password: string, options?: {
|
|
1890
|
+
rounds?: number;
|
|
1891
|
+
useCaddyCLI?: boolean;
|
|
1892
|
+
}): Promise<{
|
|
1893
|
+
username: string;
|
|
1894
|
+
password: string;
|
|
1895
|
+
}>;
|
|
1896
|
+
/**
|
|
1897
|
+
* Create multiple basic auth accounts at once
|
|
1898
|
+
*
|
|
1899
|
+
* @param users - Array of {username, password} pairs
|
|
1900
|
+
* @param options - Optional configuration
|
|
1901
|
+
* @returns Promise resolving to array of account objects with hashed passwords
|
|
1902
|
+
*
|
|
1903
|
+
* @example
|
|
1904
|
+
* const accounts = await createBasicAuthAccounts([
|
|
1905
|
+
* { username: "admin", password: "admin-pass" },
|
|
1906
|
+
* { username: "user", password: "user-pass" }
|
|
1907
|
+
* ]);
|
|
1908
|
+
*/
|
|
1909
|
+
declare function createBasicAuthAccounts(users: {
|
|
1910
|
+
username: string;
|
|
1911
|
+
password: string;
|
|
1912
|
+
}[], options?: {
|
|
1913
|
+
rounds?: number;
|
|
1914
|
+
useCaddyCLI?: boolean;
|
|
1915
|
+
}): Promise<{
|
|
1916
|
+
username: string;
|
|
1917
|
+
password: string;
|
|
1918
|
+
}[]>;
|
|
1919
|
+
|
|
1920
|
+
export { buildCompressionHandler as $, type RotateCertificateOptions as A, type BasicAuthRouteOptions as B, type CaddyAdapter as C, type RotationResult as D, type ExpirationCheckResult as E, hashPassword as F, verifyPassword as G, type HealthRouteOptions as H, hashPasswordWithCaddy as I, createBasicAuthAccount as J, createBasicAuthAccounts as K, type LoadConfigOptions as L, buildServiceRoutes as M, buildHealthCheckRoute as N, buildHostRoute as O, buildPathRoute as P, buildLoadBalancerRoute as Q, ROUTE_PRIORITIES as R, type ServiceRouteOptions as S, buildReverseProxyHandler as T, buildSecurityHeadersHandler as U, buildBasicAuthHandler as V, buildRewriteHandler as W, buildIngressTagHeadersHandler as X, buildProjectIdHeadersHandler as Y, buildIframeHeadersHandler as Z, buildRedirectRoute as _, loadCaddyfile as a, buildWwwRedirect as a0, buildMitmproxyRoute as a1, buildMitmproxyRoutePair as a2, type IframeProxyRouteOptions as a3, buildIframeProxyRoute as a4, buildMitmproxyWebUiRoute as a5, type WebSocketProxyRouteOptions as a6, buildWebSocketProxyRoute as a7, buildMitmproxyWebSocketRoute as a8, buildIframePermissiveHandler as a9, type InternalIssuerJson as aA, type InternalFallbackPoliciesOptions as aB, buildAutomationPoliciesWithInternalFallback as aC, collectExternalHostsFromRoutes as aD, type AutomaticHttpsConfigOptions as aE, buildAutomaticHttpsConfig as aF, filterAcmeManagedFromSkip as aG, applyLocalCaInstallTrust as aH, hostMatchesPattern as aI, ACME_DNS_PROVIDER_MODULE_MAP as aJ, resolveAcmeDnsProviderModule as aK, type AcmeDnsPolicyOptions as aL, buildAcmeDnsPolicy as aM, type CertificateInfo as aN, parseCertificate as aO, generateCertTag as aP, splitCertificateBundle as aQ, extractSerialNumber as aR, isCertificateExpired as aS, isCertificateExpiringSoon as aT, getDaysUntilExpiration as aU, buildDnsRebindingBypassHandler as aa, type FileServerRouteOptions as ab, buildFileServerRoute as ac, type TemplatesRouteOptions as ad, buildTemplatesRoute as ae, type ErrorRouteOptions as af, buildErrorRoute as ag, type RequestBodyHandlerOptions as ah, buildRequestBodyHandler as ai, type VarsHandlerOptions as aj, buildVarsHandler as ak, type TracingHandlerOptions as al, buildTracingHandler as am, type MapHandlerOptions as an, buildMapHandler as ao, TLS_1_3_CIPHER_SUITES as ap, TLS_1_2_CIPHER_SUITES as aq, MODERN_CIPHER_SUITES as ar, RECOMMENDED_CURVES as as, HTTP_ALPN_PROTOCOLS as at, HTTP2_ALPN_PROTOCOLS as au, HTTP1_ALPN_PROTOCOLS as av, type TlsConnectionPolicyOptions as aw, buildTlsConnectionPolicy as ax, buildModernTlsPolicy as ay, buildCompatibleTlsPolicy as az, addDomainWithAutoTls as b, addDomainWithTls as c, detectAdapter as d, deleteDomain as e, listDomains as f, getDomainConfig as g, removeOldCertificates as h, calculateRoutePriority as i, insertRouteRelative as j, createHealthRoute as k, loadConfig as l, createServiceRoute as m, createBasicAuthRoute as n, createLoadBalancerRoute as o, createRewriteRoute as p, createRedirectRoute as q, rotateCertificate as r, sortRoutes as s, type LoadBalancerRouteOptions as t, updateDomain as u, validateRouteOrdering as v, type RewriteRouteOptions as w, CertificateManager as x, createCertificateManager as y, type CertificateWithMetadata as z };
|