@serve.zone/dcrouter 17.10.2 → 18.0.1
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/deno.json +1 -1
- package/dist_serve/bundle.js +360 -360
- package/dist_ts/00_commitinfo_data.js +2 -2
- package/dist_ts/acme/acme-failure-classification.d.ts +64 -0
- package/dist_ts/acme/acme-failure-classification.js +114 -0
- package/dist_ts/acme/classes.smartacme-lifecycle.d.ts +42 -0
- package/dist_ts/acme/classes.smartacme-lifecycle.js +75 -4
- package/dist_ts/acme/index.d.ts +1 -0
- package/dist_ts/acme/index.js +2 -1
- package/dist_ts/classes.dcrouter.d.ts +33 -9
- package/dist_ts/classes.dcrouter.js +145 -11
- package/dist_ts/config/classes.route-config-manager.d.ts +56 -0
- package/dist_ts/config/classes.route-config-manager.js +161 -1
- package/dist_ts/db/documents/classes.dns-authority.doc.d.ts +30 -0
- package/dist_ts/db/documents/classes.dns-authority.doc.js +108 -0
- package/dist_ts/db/documents/index.d.ts +1 -0
- package/dist_ts/db/documents/index.js +2 -1
- package/dist_ts/dns/classes.dns-server-runtime.d.ts +109 -1
- package/dist_ts/dns/classes.dns-server-runtime.js +212 -34
- package/dist_ts/dns/domain-ownership.d.ts +111 -0
- package/dist_ts/dns/domain-ownership.js +152 -0
- package/dist_ts/dns/index.d.ts +2 -0
- package/dist_ts/dns/index.js +3 -1
- package/dist_ts/dns/manager.dns-authority.d.ts +143 -0
- package/dist_ts/dns/manager.dns-authority.js +481 -0
- package/dist_ts/dns/manager.dns.d.ts +121 -12
- package/dist_ts/dns/manager.dns.js +298 -28
- package/dist_ts/email/classes.accepted-email-spool.d.ts +15 -0
- package/dist_ts/email/classes.accepted-email-spool.js +102 -23
- package/dist_ts/email/classes.smartmta-blob-storage-manager.js +12 -3
- package/dist_ts/errors/error.codes.d.ts +4 -0
- package/dist_ts/errors/error.codes.js +5 -1
- package/dist_ts/opsserver/classes.opsserver.d.ts +1 -0
- package/dist_ts/opsserver/classes.opsserver.js +3 -1
- package/dist_ts/opsserver/handlers/acme-config.handler.js +6 -1
- package/dist_ts/opsserver/handlers/certificate.handler.d.ts +16 -0
- package/dist_ts/opsserver/handlers/certificate.handler.js +96 -10
- package/dist_ts/opsserver/handlers/config.handler.js +4 -2
- package/dist_ts/opsserver/handlers/dns-authority.handler.d.ts +20 -0
- package/dist_ts/opsserver/handlers/dns-authority.handler.js +108 -0
- package/dist_ts/opsserver/handlers/dns-provider.handler.js +5 -1
- package/dist_ts/opsserver/handlers/domain.handler.js +9 -1
- package/dist_ts/opsserver/handlers/gatewayclient.handler.js +2 -2
- package/dist_ts/opsserver/handlers/index.d.ts +1 -0
- package/dist_ts/opsserver/handlers/index.js +2 -1
- package/dist_ts_interfaces/data/dns-authority.d.ts +98 -0
- package/dist_ts_interfaces/data/dns-authority.js +26 -0
- package/dist_ts_interfaces/data/index.d.ts +1 -0
- package/dist_ts_interfaces/data/index.js +2 -1
- package/dist_ts_interfaces/data/route-management.d.ts +9 -2
- package/dist_ts_interfaces/data/route-management.js +3 -1
- package/dist_ts_interfaces/requests/certificate.d.ts +23 -0
- package/dist_ts_interfaces/requests/certificate.js +1 -1
- package/dist_ts_interfaces/requests/dns-authority.d.ts +80 -0
- package/dist_ts_interfaces/requests/dns-authority.js +3 -0
- package/dist_ts_interfaces/requests/index.d.ts +1 -0
- package/dist_ts_interfaces/requests/index.js +2 -1
- package/dist_ts_oci_container/index.js +9 -4
- package/dist_ts_web/00_commitinfo_data.js +2 -2
- package/package.json +1 -1
- package/readme.hints.md +412 -0
- package/readme.md +48 -6
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/acme/acme-failure-classification.ts +201 -0
- package/ts/acme/classes.smartacme-lifecycle.ts +104 -3
- package/ts/acme/index.ts +1 -0
- package/ts/classes.dcrouter.ts +193 -23
- package/ts/config/classes.route-config-manager.ts +197 -0
- package/ts/db/documents/classes.dns-authority.doc.ts +49 -0
- package/ts/db/documents/index.ts +1 -0
- package/ts/dns/classes.dns-server-runtime.ts +257 -38
- package/ts/dns/domain-ownership.ts +272 -0
- package/ts/dns/index.ts +2 -0
- package/ts/dns/manager.dns-authority.ts +558 -0
- package/ts/dns/manager.dns.ts +373 -27
- package/ts/email/classes.accepted-email-spool.ts +98 -21
- package/ts/email/classes.smartmta-blob-storage-manager.ts +10 -2
- package/ts/errors/error.codes.ts +4 -0
- package/ts/opsserver/classes.opsserver.ts +2 -0
- package/ts/opsserver/handlers/acme-config.handler.ts +7 -0
- package/ts/opsserver/handlers/certificate.handler.ts +103 -8
- package/ts/opsserver/handlers/config.handler.ts +3 -1
- package/ts/opsserver/handlers/dns-authority.handler.ts +142 -0
- package/ts/opsserver/handlers/dns-provider.handler.ts +6 -0
- package/ts/opsserver/handlers/domain.handler.ts +12 -0
- package/ts/opsserver/handlers/gatewayclient.handler.ts +1 -1
- package/ts/opsserver/handlers/index.ts +1 -0
- package/ts/readme.md +1 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DNS authority — which zones dcrouter may answer for authoritatively.
|
|
3
|
+
*
|
|
4
|
+
* dcrouter used to derive this from exactly one place: the `dnsScopes` bootstrap
|
|
5
|
+
* option, read once at startup from the OCI container config and never
|
|
6
|
+
* reconciled against anything. That produced two independent representations of
|
|
7
|
+
* the same fact — *declared* authority in bootstrap config and *real* delegation
|
|
8
|
+
* in public DNS — with nothing comparing them. In production one zone was
|
|
9
|
+
* declared while four others were live and delegated to our nameservers, so the
|
|
10
|
+
* server answered `A` with the `aa` bit for those four while REFUSING every
|
|
11
|
+
* other qtype for the same name, which public recursives turn into SERVFAIL.
|
|
12
|
+
*
|
|
13
|
+
* The fix is not to make the declared list editable. A list an operator can
|
|
14
|
+
* simply append to is self-assertion, which is precisely the failure mode that
|
|
15
|
+
* let routes claim domains nobody verified we own. Instead a zone earns
|
|
16
|
+
* authority by *proof*: its public delegation must name our nameservers. That
|
|
17
|
+
* proof is unforgeable by an ops-API caller — you cannot point `example.com`'s
|
|
18
|
+
* NS records at our nameservers unless you actually control the domain — and it
|
|
19
|
+
* is the missing comparison between the two representations.
|
|
20
|
+
*
|
|
21
|
+
* `dnsScopes` is gone entirely. There is exactly one representation of DNS
|
|
22
|
+
* authority now, it lives in the database, and it is the one that carries its
|
|
23
|
+
* own evidence.
|
|
24
|
+
*/
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG5zLWF1dGhvcml0eS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX2ludGVyZmFjZXMvZGF0YS9kbnMtYXV0aG9yaXR5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXVCRyJ9
|
|
@@ -6,6 +6,7 @@ export * from './target-profile.js';
|
|
|
6
6
|
export * from './vpn.js';
|
|
7
7
|
export * from './dns-provider.js';
|
|
8
8
|
export * from './domain.js';
|
|
9
|
+
export * from './dns-authority.js';
|
|
9
10
|
export * from './workhoster.js';
|
|
10
11
|
export * from './dns-record.js';
|
|
11
12
|
export * from './acme-config.js';
|
|
@@ -6,6 +6,7 @@ export * from './target-profile.js';
|
|
|
6
6
|
export * from './vpn.js';
|
|
7
7
|
export * from './dns-provider.js';
|
|
8
8
|
export * from './domain.js';
|
|
9
|
+
export * from './dns-authority.js';
|
|
9
10
|
export * from './workhoster.js';
|
|
10
11
|
export * from './dns-record.js';
|
|
11
12
|
export * from './acme-config.js';
|
|
@@ -13,4 +14,4 @@ export * from './email-domain.js';
|
|
|
13
14
|
export * from './email-settings.js';
|
|
14
15
|
export * from './security-policy.js';
|
|
15
16
|
export * from './config-events.js';
|
|
16
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
17
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c19pbnRlcmZhY2VzL2RhdGEvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxXQUFXLENBQUM7QUFDMUIsY0FBYyxZQUFZLENBQUM7QUFDM0IsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLHVCQUF1QixDQUFDO0FBQ3RDLGNBQWMscUJBQXFCLENBQUM7QUFDcEMsY0FBYyxVQUFVLENBQUM7QUFDekIsY0FBYyxtQkFBbUIsQ0FBQztBQUNsQyxjQUFjLGFBQWEsQ0FBQztBQUM1QixjQUFjLG9CQUFvQixDQUFDO0FBQ25DLGNBQWMsaUJBQWlCLENBQUM7QUFDaEMsY0FBYyxpQkFBaUIsQ0FBQztBQUNoQyxjQUFjLGtCQUFrQixDQUFDO0FBQ2pDLGNBQWMsbUJBQW1CLENBQUM7QUFDbEMsY0FBYyxxQkFBcUIsQ0FBQztBQUNwQyxjQUFjLHNCQUFzQixDQUFDO0FBQ3JDLGNBQWMsb0JBQW9CLENBQUMifQ==
|
|
@@ -12,7 +12,7 @@ export interface IRouteSecurity extends TSmartProxyRouteSecurityBase {
|
|
|
12
12
|
rateLimit?: IRouteRateLimit | null;
|
|
13
13
|
challenge?: IRouteChallengeConfig | null;
|
|
14
14
|
}
|
|
15
|
-
export declare const apiTokenScopes: readonly ["*", "routes:read", "routes:write", "config:read", "stats:read", "logs:read", "config-events:read", "config-events:write", "security:read", "security:write", "emails:read", "emails:write", "certificates:read", "certificates:write", "tokens:read", "tokens:manage", "users:read", "users:manage", "source-profiles:read", "source-profiles:write", "target-profiles:read", "target-profiles:write", "targets:read", "targets:write", "dns-providers:read", "dns-providers:write", "domains:read", "domains:write", "dns-records:read", "dns-records:write", "acme-config:read", "acme-config:write", "email-domains:read", "email-domains:write", "remote-ingress:read", "remote-ingress:write", "vpn:read", "vpn:write", "radius:read", "radius:write", "gateway-clients:read", "gateway-clients:write", "workhosters:read", "workhosters:write"];
|
|
15
|
+
export declare const apiTokenScopes: readonly ["*", "routes:read", "routes:write", "config:read", "stats:read", "logs:read", "config-events:read", "config-events:write", "security:read", "security:write", "emails:read", "emails:write", "certificates:read", "certificates:write", "tokens:read", "tokens:manage", "users:read", "users:manage", "source-profiles:read", "source-profiles:write", "target-profiles:read", "target-profiles:write", "targets:read", "targets:write", "dns-providers:read", "dns-providers:write", "domains:read", "domains:write", "dns-authority:read", "dns-authority:write", "dns-records:read", "dns-records:write", "acme-config:read", "acme-config:write", "email-domains:read", "email-domains:write", "remote-ingress:read", "remote-ingress:write", "vpn:read", "vpn:write", "radius:read", "radius:write", "gateway-clients:read", "gateway-clients:write", "workhosters:read", "workhosters:write"];
|
|
16
16
|
export type TApiTokenScope = typeof apiTokenScopes[number];
|
|
17
17
|
export type TGatewayClientType = 'onebox' | 'cloudly' | 'custom';
|
|
18
18
|
export interface IApiTokenPolicy {
|
|
@@ -186,7 +186,14 @@ export interface IMergedRoute {
|
|
|
186
186
|
* A warning generated during route startup/apply.
|
|
187
187
|
*/
|
|
188
188
|
export interface IRouteWarning {
|
|
189
|
-
|
|
189
|
+
/**
|
|
190
|
+
* - 'disabled-route' → the route exists but is switched off.
|
|
191
|
+
* - 'unverified-domain-ownership' → the route requests an automatic
|
|
192
|
+
* certificate for a domain whose ownership dcrouter cannot prove, so ACME
|
|
193
|
+
* can never succeed for it. Surfaced rather than refused for already-stored
|
|
194
|
+
* routes; new and updated routes are refused outright.
|
|
195
|
+
*/
|
|
196
|
+
type: 'disabled-route' | 'unverified-domain-ownership';
|
|
190
197
|
routeName: string;
|
|
191
198
|
message: string;
|
|
192
199
|
}
|
|
@@ -30,6 +30,8 @@ export const apiTokenScopes = [
|
|
|
30
30
|
'dns-providers:write',
|
|
31
31
|
'domains:read',
|
|
32
32
|
'domains:write',
|
|
33
|
+
'dns-authority:read',
|
|
34
|
+
'dns-authority:write',
|
|
33
35
|
'dns-records:read',
|
|
34
36
|
'dns-records:write',
|
|
35
37
|
'acme-config:read',
|
|
@@ -120,4 +122,4 @@ export function canonicalizeSourceRouteId(routeId) {
|
|
|
120
122
|
const sourceVariantIndex = routeId.indexOf(':source:');
|
|
121
123
|
return sourceVariantIndex === -1 ? routeId : routeId.slice(0, sourceVariantIndex);
|
|
122
124
|
}
|
|
123
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
125
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUtbWFuYWdlbWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX2ludGVyZmFjZXMvZGF0YS9yb3V0ZS1tYW5hZ2VtZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXFCQSwrRUFBK0U7QUFDL0UsOEJBQThCO0FBQzlCLCtFQUErRTtBQUUvRSxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUc7SUFDNUIsR0FBRztJQUNILGFBQWE7SUFDYixjQUFjO0lBQ2QsYUFBYTtJQUNiLFlBQVk7SUFDWixXQUFXO0lBQ1gsb0JBQW9CO0lBQ3BCLHFCQUFxQjtJQUNyQixlQUFlO0lBQ2YsZ0JBQWdCO0lBQ2hCLGFBQWE7SUFDYixjQUFjO0lBQ2QsbUJBQW1CO0lBQ25CLG9CQUFvQjtJQUNwQixhQUFhO0lBQ2IsZUFBZTtJQUNmLFlBQVk7SUFDWixjQUFjO0lBQ2Qsc0JBQXNCO0lBQ3RCLHVCQUF1QjtJQUN2QixzQkFBc0I7SUFDdEIsdUJBQXVCO0lBQ3ZCLGNBQWM7SUFDZCxlQUFlO0lBQ2Ysb0JBQW9CO0lBQ3BCLHFCQUFxQjtJQUNyQixjQUFjO0lBQ2QsZUFBZTtJQUNmLG9CQUFvQjtJQUNwQixxQkFBcUI7SUFDckIsa0JBQWtCO0lBQ2xCLG1CQUFtQjtJQUNuQixrQkFBa0I7SUFDbEIsbUJBQW1CO0lBQ25CLG9CQUFvQjtJQUNwQixxQkFBcUI7SUFDckIscUJBQXFCO0lBQ3JCLHNCQUFzQjtJQUN0QixVQUFVO0lBQ1YsV0FBVztJQUNYLGFBQWE7SUFDYixjQUFjO0lBQ2Qsc0JBQXNCO0lBQ3RCLHVCQUF1QjtJQUN2QixrQkFBa0I7SUFDbEIsbUJBQW1CO0NBQ1gsQ0FBQztBQWlGWCxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRztJQUM5QixnQkFBZ0I7SUFDaEIsUUFBUTtJQUNSLGFBQWE7SUFDYixnQkFBZ0I7SUFDaEIsS0FBSztJQUNMLFNBQVM7Q0FDRCxDQUFDO0FBSVgsTUFBTSxDQUFDLE1BQU0seUJBQXlCLEdBQW9DO0lBQ3hFLGdCQUFnQixFQUFFLGdCQUFnQjtJQUNsQyxNQUFNLEVBQUUsZUFBZTtJQUN2QixhQUFhLEVBQUUsYUFBYTtJQUM1QixnQkFBZ0IsRUFBRSxnQkFBZ0I7SUFDbEMsR0FBRyxFQUFFLFdBQVc7SUFDaEIsT0FBTyxFQUFFLFVBQVU7Q0FDcEIsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLDJCQUEyQixHQUFzQztJQUM1RSxnQkFBZ0IsRUFBRTtRQUNoQixvQkFBb0I7UUFDcEIsMEJBQTBCO1FBQzFCLDJCQUEyQjtRQUMzQixtQkFBbUI7UUFDbkIscUJBQXFCO0tBQ3RCO0lBQ0QsTUFBTSxFQUFFO1FBQ04sV0FBVztRQUNYLFlBQVk7UUFDWixpQkFBaUI7UUFDakIsZ0JBQWdCO1FBQ2hCLFFBQVE7UUFDUixRQUFRO1FBQ1IsT0FBTztRQUNQLFVBQVU7UUFDVixjQUFjO0tBQ2Y7SUFDRCxhQUFhLEVBQUUsRUFBRTtJQUNqQixnQkFBZ0IsRUFBRTtRQUNoQixZQUFZO1FBQ1osU0FBUztRQUNULFdBQVc7UUFDWCxRQUFRO1FBQ1IsVUFBVTtRQUNWLFNBQVM7UUFDVCxnQkFBZ0I7UUFDaEIsWUFBWTtRQUNaLGVBQWU7UUFDZixZQUFZO1FBQ1osWUFBWTtRQUNaLGVBQWU7UUFDZixhQUFhO1FBQ2IsWUFBWTtRQUNaLGVBQWU7UUFDZixjQUFjO1FBQ2QsZUFBZTtLQUNoQjtJQUNELEdBQUcsRUFBRTtRQUNILFlBQVk7UUFDWixZQUFZO0tBQ2I7SUFDRCxPQUFPLEVBQUU7UUFDUCxnQkFBZ0I7UUFDaEIsMEJBQTBCO0tBQzNCO0NBQ0YsQ0FBQztBQW1ERiwrRUFBK0U7QUFDL0UsdUJBQXVCO0FBQ3ZCLCtFQUErRTtBQUUvRSxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLDRCQUE0QixDQUFVLENBQUM7QUFnR3pFLGdGQUFnRjtBQUNoRixNQUFNLFVBQVUseUJBQXlCLENBQUMsT0FBZTtJQUN2RCxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDdkQsT0FBTyxrQkFBa0IsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO0FBQ3BGLENBQUMifQ==
|
|
@@ -2,17 +2,40 @@ import * as plugins from '../plugins.js';
|
|
|
2
2
|
import * as authInterfaces from '../data/auth.js';
|
|
3
3
|
export type TCertificateStatus = 'valid' | 'expiring' | 'expired' | 'provisioning' | 'failed' | 'unknown';
|
|
4
4
|
export type TCertificateSource = 'acme' | 'provision-function' | 'static' | 'none';
|
|
5
|
+
/**
|
|
6
|
+
* What the running proxy is actually presenting on the wire for a domain, as
|
|
7
|
+
* reported by the Rust engine.
|
|
8
|
+
*
|
|
9
|
+
* This is deliberately separate from the issued/stored view: a certificate can be
|
|
10
|
+
* valid in storage while the engine still serves an older, expired one, and
|
|
11
|
+
* reporting only the stored view is how a 21-day outage went unnoticed. Absent
|
|
12
|
+
* when the engine cannot be queried — absence means "unknown", never "fine".
|
|
13
|
+
*/
|
|
14
|
+
export interface ICertificateServedState {
|
|
15
|
+
expiryDate?: string;
|
|
16
|
+
isValid: boolean;
|
|
17
|
+
source?: string;
|
|
18
|
+
}
|
|
5
19
|
export interface ICertificateInfo {
|
|
6
20
|
domain: string;
|
|
7
21
|
routeNames: string[];
|
|
22
|
+
/** Combined verdict. Downgraded to 'failed' whenever `servedMismatch` is true. */
|
|
8
23
|
status: TCertificateStatus;
|
|
9
24
|
source: TCertificateSource;
|
|
10
25
|
tlsMode: 'terminate' | 'terminate-and-reencrypt' | 'passthrough';
|
|
26
|
+
/** Expiry of the issued/stored certificate. */
|
|
11
27
|
expiryDate?: string;
|
|
12
28
|
issuer?: string;
|
|
13
29
|
issuedAt?: string;
|
|
14
30
|
error?: string;
|
|
15
31
|
canReprovision: boolean;
|
|
32
|
+
/** What the running proxy serves, when determinable. */
|
|
33
|
+
served?: ICertificateServedState;
|
|
34
|
+
/**
|
|
35
|
+
* True when a valid certificate is issued/stored but the proxy is still serving
|
|
36
|
+
* an invalid or expired one. An issuance success must never mask this.
|
|
37
|
+
*/
|
|
38
|
+
servedMismatch?: boolean;
|
|
16
39
|
backoffInfo?: {
|
|
17
40
|
failures: number;
|
|
18
41
|
retryAfter?: string;
|
|
@@ -2,4 +2,4 @@ import * as plugins from '../plugins.js';
|
|
|
2
2
|
import * as authInterfaces from '../data/auth.js';
|
|
3
3
|
// The certificate import/export contracts live in @serve.zone/interfaces
|
|
4
4
|
// (requests/gateway.ts).
|
|
5
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydGlmaWNhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c19pbnRlcmZhY2VzL3JlcXVlc3RzL2NlcnRpZmljYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sS0FBSyxjQUFjLE1BQU0saUJBQWlCLENBQUM7QUF1R2xELHlFQUF5RTtBQUN6RSx5QkFBeUIifQ==
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import * as authInterfaces from '../data/auth.js';
|
|
3
|
+
import type { IDnsAuthorityDrift, IDnsAuthoritySettings, IDnsDelegationProbe } from '../data/dns-authority.js';
|
|
4
|
+
export interface IReq_GetDnsAuthority extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_GetDnsAuthority> {
|
|
5
|
+
method: 'getDnsAuthority';
|
|
6
|
+
request: {
|
|
7
|
+
identity?: authInterfaces.IIdentity;
|
|
8
|
+
apiToken?: string;
|
|
9
|
+
};
|
|
10
|
+
response: {
|
|
11
|
+
settings: IDnsAuthoritySettings;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Probe a zone's public delegation without changing anything. Lets an operator
|
|
16
|
+
* see the evidence before claiming authority.
|
|
17
|
+
*/
|
|
18
|
+
export interface IReq_ProbeDnsAuthorityZone extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_ProbeDnsAuthorityZone> {
|
|
19
|
+
method: 'probeDnsAuthorityZone';
|
|
20
|
+
request: {
|
|
21
|
+
identity?: authInterfaces.IIdentity;
|
|
22
|
+
apiToken?: string;
|
|
23
|
+
zone: string;
|
|
24
|
+
};
|
|
25
|
+
response: {
|
|
26
|
+
probe: IDnsDelegationProbe;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Claim authority over a zone. Succeeds only when the zone's public delegation
|
|
31
|
+
* names our nameservers; the claim is then persisted and reconciled in-process,
|
|
32
|
+
* with no restart.
|
|
33
|
+
*/
|
|
34
|
+
export interface IReq_VerifyDnsAuthorityZone extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_VerifyDnsAuthorityZone> {
|
|
35
|
+
method: 'verifyDnsAuthorityZone';
|
|
36
|
+
request: {
|
|
37
|
+
identity?: authInterfaces.IIdentity;
|
|
38
|
+
apiToken?: string;
|
|
39
|
+
zone: string;
|
|
40
|
+
};
|
|
41
|
+
response: {
|
|
42
|
+
success: boolean;
|
|
43
|
+
message?: string;
|
|
44
|
+
probe?: IDnsDelegationProbe;
|
|
45
|
+
settings?: IDnsAuthoritySettings;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Drop a previously verified zone. Every zone in the authority set is revocable
|
|
50
|
+
* through this call: there is no deployment-declared floor left that would need
|
|
51
|
+
* a redeploy to withdraw.
|
|
52
|
+
*/
|
|
53
|
+
export interface IReq_RevokeDnsAuthorityZone extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_RevokeDnsAuthorityZone> {
|
|
54
|
+
method: 'revokeDnsAuthorityZone';
|
|
55
|
+
request: {
|
|
56
|
+
identity?: authInterfaces.IIdentity;
|
|
57
|
+
apiToken?: string;
|
|
58
|
+
zone: string;
|
|
59
|
+
};
|
|
60
|
+
response: {
|
|
61
|
+
success: boolean;
|
|
62
|
+
message?: string;
|
|
63
|
+
settings?: IDnsAuthoritySettings;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Compare declared authority against observed delegation in both directions.
|
|
68
|
+
* This is the check whose absence let one zone sit declared while four live
|
|
69
|
+
* zones were delegated to us and unclaimed.
|
|
70
|
+
*/
|
|
71
|
+
export interface IReq_GetDnsAuthorityDrift extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_GetDnsAuthorityDrift> {
|
|
72
|
+
method: 'getDnsAuthorityDrift';
|
|
73
|
+
request: {
|
|
74
|
+
identity?: authInterfaces.IIdentity;
|
|
75
|
+
apiToken?: string;
|
|
76
|
+
};
|
|
77
|
+
response: {
|
|
78
|
+
drift: IDnsAuthorityDrift[];
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import * as authInterfaces from '../data/auth.js';
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG5zLWF1dGhvcml0eS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzX2ludGVyZmFjZXMvcmVxdWVzdHMvZG5zLWF1dGhvcml0eS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGVBQWUsQ0FBQztBQUN6QyxPQUFPLEtBQUssY0FBYyxNQUFNLGlCQUFpQixDQUFDIn0=
|
|
@@ -16,6 +16,7 @@ export * from './network-targets.js';
|
|
|
16
16
|
export * from './users.js';
|
|
17
17
|
export * from './dns-providers.js';
|
|
18
18
|
export * from './domains.js';
|
|
19
|
+
export * from './dns-authority.js';
|
|
19
20
|
export * from './dns-records.js';
|
|
20
21
|
export * from './acme-config.js';
|
|
21
22
|
export * from './email-domains.js';
|
|
@@ -16,6 +16,7 @@ export * from './network-targets.js';
|
|
|
16
16
|
export * from './users.js';
|
|
17
17
|
export * from './dns-providers.js';
|
|
18
18
|
export * from './domains.js';
|
|
19
|
+
export * from './dns-authority.js';
|
|
19
20
|
export * from './dns-records.js';
|
|
20
21
|
export * from './acme-config.js';
|
|
21
22
|
export * from './email-domains.js';
|
|
@@ -24,4 +25,4 @@ export * from './realtime.js';
|
|
|
24
25
|
export * from './workhoster.js';
|
|
25
26
|
export * from './security-policy.js';
|
|
26
27
|
export * from './config-events.js';
|
|
27
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
28
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c19pbnRlcmZhY2VzL3JlcXVlc3RzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsWUFBWSxDQUFDO0FBQzNCLGNBQWMsYUFBYSxDQUFDO0FBQzVCLGNBQWMsV0FBVyxDQUFDO0FBQzFCLGNBQWMsWUFBWSxDQUFDO0FBQzNCLGNBQWMscUJBQXFCLENBQUM7QUFDcEMsY0FBYyxhQUFhLENBQUM7QUFDNUIsY0FBYyxnQkFBZ0IsQ0FBQztBQUMvQixjQUFjLGtCQUFrQixDQUFDO0FBQ2pDLGNBQWMsb0JBQW9CLENBQUM7QUFDbkMsY0FBYyx1QkFBdUIsQ0FBQztBQUN0QyxjQUFjLGlCQUFpQixDQUFDO0FBQ2hDLGNBQWMsVUFBVSxDQUFDO0FBQ3pCLGNBQWMsc0JBQXNCLENBQUM7QUFDckMsY0FBYyxzQkFBc0IsQ0FBQztBQUNyQyxjQUFjLHNCQUFzQixDQUFDO0FBQ3JDLGNBQWMsWUFBWSxDQUFDO0FBQzNCLGNBQWMsb0JBQW9CLENBQUM7QUFDbkMsY0FBYyxjQUFjLENBQUM7QUFDN0IsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLGtCQUFrQixDQUFDO0FBQ2pDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLHFCQUFxQixDQUFDO0FBQ3BDLGNBQWMsZUFBZSxDQUFDO0FBQzlCLGNBQWMsaUJBQWlCLENBQUM7QUFDaEMsY0FBYyxzQkFBc0IsQ0FBQztBQUNyQyxjQUFjLG9CQUFvQixDQUFDIn0=
|
|
@@ -60,9 +60,14 @@ export function getOciContainerConfig() {
|
|
|
60
60
|
if (nsDomains) {
|
|
61
61
|
options.dnsNsDomains = nsDomains;
|
|
62
62
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
// DCROUTER_DNS_SCOPES is intentionally not read. DNS authority is
|
|
64
|
+
// delegation-verified state in the database, not deployment configuration.
|
|
65
|
+
// Called out rather than dropped silently, because a container still setting
|
|
66
|
+
// it would otherwise look configured and answer for nothing.
|
|
67
|
+
if (process.env.DCROUTER_DNS_SCOPES) {
|
|
68
|
+
console.warn('[OCI Container] DCROUTER_DNS_SCOPES is set but no longer honored: dcrouter derives DNS authority from the database, '
|
|
69
|
+
+ 'where a zone is admitted by having its public NS records observed naming DCROUTER_DNS_NS_DOMAINS. '
|
|
70
|
+
+ 'Verify each zone through the ops API (dns-authority:write) instead.');
|
|
66
71
|
}
|
|
67
72
|
if (process.env.DCROUTER_DNS_BIND_INTERFACE) {
|
|
68
73
|
options.dnsBindInterface = process.env.DCROUTER_DNS_BIND_INTERFACE;
|
|
@@ -111,4 +116,4 @@ export function getOciContainerConfig() {
|
|
|
111
116
|
}
|
|
112
117
|
return options;
|
|
113
118
|
}
|
|
114
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
119
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c19vY2lfY29udGFpbmVyL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBR3hDOzs7R0FHRztBQUNILFNBQVMsbUJBQW1CLENBQUMsTUFBMEI7SUFDckQsSUFBSSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQ3RELE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUNoRSxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUywwQkFBMEIsQ0FBQyxNQUEwQjtJQUM1RCxNQUFNLEtBQUssR0FBRyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxQyxJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQzdCLE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNwRSxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUscUJBQXFCO0lBQ25DLElBQUksT0FBTyxHQUFxQixFQUFFLENBQUM7SUFFbkMscUNBQXFDO0lBQ3JDLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUM7SUFDcEQsSUFBSSxVQUFVLElBQUksT0FBTyxDQUFDLEVBQUUsQ0FBQyxVQUFV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
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@serve.zone/dcrouter',
|
|
6
|
-
version: '
|
|
6
|
+
version: '18.0.1',
|
|
7
7
|
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
|
8
8
|
};
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfd2ViLzAwX2NvbW1pdGluZm9fZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRztJQUN4QixJQUFJLEVBQUUsc0JBQXNCO0lBQzVCLE9BQU8sRUFBRSxRQUFRO0lBQ2pCLFdBQVcsRUFBRSwwRUFBMEU7Q0FDeEYsQ0FBQSJ9
|