@serve.zone/dcrouter 13.8.0 → 13.9.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/dist_serve/bundle.js +1622 -1522
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.dcrouter.js +3 -2
- package/dist_ts/dns/manager.dns.d.ts +17 -15
- package/dist_ts/dns/manager.dns.js +33 -27
- package/dist_ts/dns/providers/factory.js +10 -1
- package/dist_ts/opsserver/handlers/dns-provider.handler.js +42 -5
- package/dist_ts/opsserver/handlers/domain.handler.js +3 -3
- package/dist_ts_interfaces/data/dns-provider.d.ts +28 -4
- package/dist_ts_interfaces/data/dns-provider.js +15 -1
- package/dist_ts_interfaces/data/dns-record.d.ts +9 -7
- package/dist_ts_interfaces/data/domain.d.ts +8 -7
- package/dist_ts_interfaces/requests/dns-records.d.ts +1 -1
- package/dist_ts_interfaces/requests/domains.d.ts +3 -3
- package/dist_ts_migrations/index.js +17 -1
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/appstate.d.ts +1 -1
- package/dist_ts_web/appstate.js +2 -2
- package/dist_ts_web/elements/domains/dns-provider-form.d.ts +4 -2
- package/dist_ts_web/elements/domains/dns-provider-form.js +11 -5
- package/dist_ts_web/elements/domains/ops-view-dns.js +3 -3
- package/dist_ts_web/elements/domains/ops-view-domains.d.ts +1 -1
- package/dist_ts_web/elements/domains/ops-view-domains.js +10 -10
- package/dist_ts_web/elements/domains/ops-view-providers.js +19 -5
- package/package.json +3 -3
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.dcrouter.ts +2 -1
- package/ts/dns/manager.dns.ts +38 -27
- package/ts/dns/providers/factory.ts +11 -0
- package/ts/opsserver/handlers/dns-provider.handler.ts +41 -3
- package/ts/opsserver/handlers/domain.handler.ts +2 -2
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/appstate.ts +1 -1
- package/ts_web/elements/domains/dns-provider-form.ts +12 -4
- package/ts_web/elements/domains/ops-view-dns.ts +2 -2
- package/ts_web/elements/domains/ops-view-domains.ts +9 -9
- package/ts_web/elements/domains/ops-view-providers.ts +18 -4
|
@@ -46,15 +46,28 @@ export class DnsProviderHandler {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
private registerHandlers(): void {
|
|
49
|
-
// Get all providers
|
|
49
|
+
// Get all providers — prepends the built-in DcRouter pseudo-provider
|
|
50
|
+
// so operators see a uniform "who serves this?" list that includes the
|
|
51
|
+
// authoritative dcrouter alongside external accounts.
|
|
50
52
|
this.typedrouter.addTypedHandler(
|
|
51
53
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetDnsProviders>(
|
|
52
54
|
'getDnsProviders',
|
|
53
55
|
async (dataArg) => {
|
|
54
56
|
await this.requireAuth(dataArg, 'dns-providers:read');
|
|
55
57
|
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
const synthetic: interfaces.data.IDnsProviderPublic = {
|
|
59
|
+
id: interfaces.data.DCROUTER_BUILTIN_PROVIDER_ID,
|
|
60
|
+
name: 'DcRouter',
|
|
61
|
+
type: 'dcrouter',
|
|
62
|
+
status: 'ok',
|
|
63
|
+
createdAt: 0,
|
|
64
|
+
updatedAt: 0,
|
|
65
|
+
createdBy: 'system',
|
|
66
|
+
hasCredentials: false,
|
|
67
|
+
builtIn: true,
|
|
68
|
+
};
|
|
69
|
+
const real = dnsManager ? await dnsManager.listProviders() : [];
|
|
70
|
+
return { providers: [synthetic, ...real] };
|
|
58
71
|
},
|
|
59
72
|
),
|
|
60
73
|
);
|
|
@@ -78,6 +91,12 @@ export class DnsProviderHandler {
|
|
|
78
91
|
'createDnsProvider',
|
|
79
92
|
async (dataArg) => {
|
|
80
93
|
const userId = await this.requireAuth(dataArg, 'dns-providers:write');
|
|
94
|
+
if (dataArg.type === 'dcrouter') {
|
|
95
|
+
return {
|
|
96
|
+
success: false,
|
|
97
|
+
message: 'cannot create built-in provider',
|
|
98
|
+
};
|
|
99
|
+
}
|
|
81
100
|
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
|
|
82
101
|
if (!dnsManager) {
|
|
83
102
|
return { success: false, message: 'DnsManager not initialized (DB disabled?)' };
|
|
@@ -99,6 +118,9 @@ export class DnsProviderHandler {
|
|
|
99
118
|
'updateDnsProvider',
|
|
100
119
|
async (dataArg) => {
|
|
101
120
|
await this.requireAuth(dataArg, 'dns-providers:write');
|
|
121
|
+
if (dataArg.id === interfaces.data.DCROUTER_BUILTIN_PROVIDER_ID) {
|
|
122
|
+
return { success: false, message: 'cannot edit built-in provider' };
|
|
123
|
+
}
|
|
102
124
|
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
|
|
103
125
|
if (!dnsManager) return { success: false, message: 'DnsManager not initialized' };
|
|
104
126
|
const ok = await dnsManager.updateProvider(dataArg.id, {
|
|
@@ -116,6 +138,9 @@ export class DnsProviderHandler {
|
|
|
116
138
|
'deleteDnsProvider',
|
|
117
139
|
async (dataArg) => {
|
|
118
140
|
await this.requireAuth(dataArg, 'dns-providers:write');
|
|
141
|
+
if (dataArg.id === interfaces.data.DCROUTER_BUILTIN_PROVIDER_ID) {
|
|
142
|
+
return { success: false, message: 'cannot delete built-in provider' };
|
|
143
|
+
}
|
|
119
144
|
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
|
|
120
145
|
if (!dnsManager) return { success: false, message: 'DnsManager not initialized' };
|
|
121
146
|
return await dnsManager.deleteProvider(dataArg.id, dataArg.force ?? false);
|
|
@@ -129,6 +154,13 @@ export class DnsProviderHandler {
|
|
|
129
154
|
'testDnsProvider',
|
|
130
155
|
async (dataArg) => {
|
|
131
156
|
await this.requireAuth(dataArg, 'dns-providers:read');
|
|
157
|
+
if (dataArg.id === interfaces.data.DCROUTER_BUILTIN_PROVIDER_ID) {
|
|
158
|
+
return {
|
|
159
|
+
ok: false,
|
|
160
|
+
error: 'built-in provider has no external connection to test',
|
|
161
|
+
testedAt: Date.now(),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
132
164
|
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
|
|
133
165
|
if (!dnsManager) {
|
|
134
166
|
return { ok: false, error: 'DnsManager not initialized', testedAt: Date.now() };
|
|
@@ -144,6 +176,12 @@ export class DnsProviderHandler {
|
|
|
144
176
|
'listProviderDomains',
|
|
145
177
|
async (dataArg) => {
|
|
146
178
|
await this.requireAuth(dataArg, 'dns-providers:read');
|
|
179
|
+
if (dataArg.providerId === interfaces.data.DCROUTER_BUILTIN_PROVIDER_ID) {
|
|
180
|
+
return {
|
|
181
|
+
success: false,
|
|
182
|
+
message: 'built-in provider has no external domain listing — use "Add DcRouter Domain" instead',
|
|
183
|
+
};
|
|
184
|
+
}
|
|
147
185
|
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
|
|
148
186
|
if (!dnsManager) return { success: false, message: 'DnsManager not initialized' };
|
|
149
187
|
try {
|
|
@@ -71,7 +71,7 @@ export class DomainHandler {
|
|
|
71
71
|
),
|
|
72
72
|
);
|
|
73
73
|
|
|
74
|
-
// Create
|
|
74
|
+
// Create dcrouter-hosted domain
|
|
75
75
|
this.typedrouter.addTypedHandler(
|
|
76
76
|
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateDomain>(
|
|
77
77
|
'createDomain',
|
|
@@ -80,7 +80,7 @@ export class DomainHandler {
|
|
|
80
80
|
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
|
|
81
81
|
if (!dnsManager) return { success: false, message: 'DnsManager not initialized' };
|
|
82
82
|
try {
|
|
83
|
-
const id = await dnsManager.
|
|
83
|
+
const id = await dnsManager.createDcrouterDomain({
|
|
84
84
|
name: dataArg.name,
|
|
85
85
|
description: dataArg.description,
|
|
86
86
|
createdBy: userId,
|
package/ts_web/appstate.ts
CHANGED
|
@@ -1793,7 +1793,7 @@ export async function fetchProviderDomains(
|
|
|
1793
1793
|
return await request.fire({ identity: context.identity, providerId });
|
|
1794
1794
|
}
|
|
1795
1795
|
|
|
1796
|
-
export const
|
|
1796
|
+
export const createDcrouterDomainAction = domainsStatePart.createAction<{
|
|
1797
1797
|
name: string;
|
|
1798
1798
|
description?: string;
|
|
1799
1799
|
}>(async (statePartArg, dataArg, actionContext): Promise<IDomainsState> => {
|
|
@@ -44,12 +44,15 @@ export class DnsProviderForm extends DeesElement {
|
|
|
44
44
|
accessor providerName: string = '';
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
|
-
* Currently selected provider type. Initialized to the first
|
|
48
|
-
* caller can override before mounting (e.g. for edit dialogs).
|
|
47
|
+
* Currently selected provider type. Initialized to the first user-creatable
|
|
48
|
+
* descriptor; caller can override before mounting (e.g. for edit dialogs).
|
|
49
|
+
* The built-in 'dcrouter' pseudo-provider is excluded from the picker —
|
|
50
|
+
* operators cannot create another one.
|
|
49
51
|
*/
|
|
50
52
|
@state()
|
|
51
53
|
accessor selectedType: interfaces.data.TDnsProviderType =
|
|
52
|
-
interfaces.data.dnsProviderTypeDescriptors
|
|
54
|
+
interfaces.data.dnsProviderTypeDescriptors.find((d) => d.type !== 'dcrouter')?.type ??
|
|
55
|
+
'cloudflare';
|
|
53
56
|
|
|
54
57
|
/** When true, hide the type picker — used in edit dialogs. */
|
|
55
58
|
@property({ type: Boolean })
|
|
@@ -102,7 +105,12 @@ export class DnsProviderForm extends DeesElement {
|
|
|
102
105
|
];
|
|
103
106
|
|
|
104
107
|
public render(): TemplateResult {
|
|
105
|
-
|
|
108
|
+
// Exclude the built-in 'dcrouter' pseudo-provider from the type picker —
|
|
109
|
+
// operators cannot create another one, it's surfaced at read time by the
|
|
110
|
+
// backend handler instead.
|
|
111
|
+
const descriptors = interfaces.data.dnsProviderTypeDescriptors.filter(
|
|
112
|
+
(d) => d.type !== 'dcrouter',
|
|
113
|
+
);
|
|
106
114
|
const descriptor = interfaces.data.getDnsProviderTypeDescriptor(this.selectedType);
|
|
107
115
|
|
|
108
116
|
return html`
|
|
@@ -80,7 +80,7 @@ export class OpsViewDns extends DeesElement {
|
|
|
80
80
|
font-weight: 500;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
.sourceBadge.
|
|
83
|
+
.sourceBadge.local {
|
|
84
84
|
background: ${cssManager.bdTheme('#e0e7ff', '#1e1b4b')};
|
|
85
85
|
color: ${cssManager.bdTheme('#3730a3', '#a5b4fc')};
|
|
86
86
|
}
|
|
@@ -184,7 +184,7 @@ export class OpsViewDns extends DeesElement {
|
|
|
184
184
|
private domainHint(domainId: string): string {
|
|
185
185
|
const domain = this.domainsState.domains.find((d) => d.id === domainId);
|
|
186
186
|
if (!domain) return '';
|
|
187
|
-
if (domain.source === '
|
|
187
|
+
if (domain.source === 'dcrouter') {
|
|
188
188
|
return 'Records are served by dcrouter (authoritative).';
|
|
189
189
|
}
|
|
190
190
|
return 'Records are stored at the provider — changes here are pushed via the provider API.';
|
|
@@ -55,7 +55,7 @@ export class OpsViewDomains extends DeesElement {
|
|
|
55
55
|
font-weight: 500;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
.sourceBadge.
|
|
58
|
+
.sourceBadge.dcrouter {
|
|
59
59
|
background: ${cssManager.bdTheme('#e0e7ff', '#1e1b4b')};
|
|
60
60
|
color: ${cssManager.bdTheme('#3730a3', '#a5b4fc')};
|
|
61
61
|
}
|
|
@@ -76,7 +76,7 @@ export class OpsViewDomains extends DeesElement {
|
|
|
76
76
|
<div class="domainsContainer">
|
|
77
77
|
<dees-table
|
|
78
78
|
.heading1=${'Domains'}
|
|
79
|
-
.heading2=${'Domains under management —
|
|
79
|
+
.heading2=${'Domains under management — served by dcrouter (authoritative) or imported from a provider'}
|
|
80
80
|
.data=${domains}
|
|
81
81
|
.showColumnFilters=${true}
|
|
82
82
|
.displayFunction=${(d: interfaces.data.IDomain) => ({
|
|
@@ -90,11 +90,11 @@ export class OpsViewDomains extends DeesElement {
|
|
|
90
90
|
})}
|
|
91
91
|
.dataActions=${[
|
|
92
92
|
{
|
|
93
|
-
name: 'Add
|
|
93
|
+
name: 'Add DcRouter Domain',
|
|
94
94
|
iconName: 'lucide:plus',
|
|
95
95
|
type: ['header' as const],
|
|
96
96
|
actionFunc: async () => {
|
|
97
|
-
await this.
|
|
97
|
+
await this.showCreateDcrouterDialog();
|
|
98
98
|
},
|
|
99
99
|
},
|
|
100
100
|
{
|
|
@@ -168,17 +168,17 @@ export class OpsViewDomains extends DeesElement {
|
|
|
168
168
|
d: interfaces.data.IDomain,
|
|
169
169
|
providersById: Map<string, interfaces.data.IDnsProviderPublic>,
|
|
170
170
|
): TemplateResult {
|
|
171
|
-
if (d.source === '
|
|
172
|
-
return html`<span class="sourceBadge
|
|
171
|
+
if (d.source === 'dcrouter') {
|
|
172
|
+
return html`<span class="sourceBadge dcrouter">DcRouter</span>`;
|
|
173
173
|
}
|
|
174
174
|
const provider = d.providerId ? providersById.get(d.providerId) : undefined;
|
|
175
175
|
return html`<span class="sourceBadge provider">${provider?.name || 'Provider'}</span>`;
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
private async
|
|
178
|
+
private async showCreateDcrouterDialog() {
|
|
179
179
|
const { DeesModal } = await import('@design.estate/dees-catalog');
|
|
180
180
|
DeesModal.createAndShow({
|
|
181
|
-
heading: 'Add
|
|
181
|
+
heading: 'Add DcRouter Domain',
|
|
182
182
|
content: html`
|
|
183
183
|
<dees-form>
|
|
184
184
|
<dees-input-text .key=${'name'} .label=${'FQDN (e.g. example.com)'} .required=${true}></dees-input-text>
|
|
@@ -199,7 +199,7 @@ export class OpsViewDomains extends DeesElement {
|
|
|
199
199
|
?.querySelector('dees-form');
|
|
200
200
|
if (!form) return;
|
|
201
201
|
const data = await form.collectFormData();
|
|
202
|
-
await appstate.domainsStatePart.dispatchAction(appstate.
|
|
202
|
+
await appstate.domainsStatePart.dispatchAction(appstate.createDcrouterDomainAction, {
|
|
203
203
|
name: String(data.name),
|
|
204
204
|
description: data.description ? String(data.description) : undefined,
|
|
205
205
|
});
|
|
@@ -71,6 +71,11 @@ export class OpsViewProviders extends DeesElement {
|
|
|
71
71
|
background: ${cssManager.bdTheme('#f3f4f6', '#1f2937')};
|
|
72
72
|
color: ${cssManager.bdTheme('#4b5563', '#9ca3af')};
|
|
73
73
|
}
|
|
74
|
+
|
|
75
|
+
.statusBadge.builtin {
|
|
76
|
+
background: ${cssManager.bdTheme('#e0e7ff', '#1e1b4b')};
|
|
77
|
+
color: ${cssManager.bdTheme('#3730a3', '#a5b4fc')};
|
|
78
|
+
}
|
|
74
79
|
`,
|
|
75
80
|
];
|
|
76
81
|
|
|
@@ -82,15 +87,21 @@ export class OpsViewProviders extends DeesElement {
|
|
|
82
87
|
<div class="providersContainer">
|
|
83
88
|
<dees-table
|
|
84
89
|
.heading1=${'Providers'}
|
|
85
|
-
.heading2=${'
|
|
90
|
+
.heading2=${'Built-in dcrouter + external DNS provider accounts'}
|
|
86
91
|
.data=${providers}
|
|
87
92
|
.showColumnFilters=${true}
|
|
88
93
|
.displayFunction=${(p: interfaces.data.IDnsProviderPublic) => ({
|
|
89
94
|
Name: p.name,
|
|
90
95
|
Type: this.providerTypeLabel(p.type),
|
|
91
|
-
Status:
|
|
92
|
-
|
|
93
|
-
|
|
96
|
+
Status: p.builtIn
|
|
97
|
+
? html`<span class="statusBadge builtin">built-in</span>`
|
|
98
|
+
: this.renderStatusBadge(p.status),
|
|
99
|
+
'Last Tested': p.builtIn
|
|
100
|
+
? '—'
|
|
101
|
+
: p.lastTestedAt
|
|
102
|
+
? new Date(p.lastTestedAt).toLocaleString()
|
|
103
|
+
: 'never',
|
|
104
|
+
Error: p.builtIn ? '—' : p.lastError || '-',
|
|
94
105
|
})}
|
|
95
106
|
.dataActions=${[
|
|
96
107
|
{
|
|
@@ -116,6 +127,7 @@ export class OpsViewProviders extends DeesElement {
|
|
|
116
127
|
name: 'Test Connection',
|
|
117
128
|
iconName: 'lucide:plug',
|
|
118
129
|
type: ['inRow', 'contextmenu'] as any,
|
|
130
|
+
actionRelevancyCheckFunc: (p: interfaces.data.IDnsProviderPublic) => !p.builtIn,
|
|
119
131
|
actionFunc: async (actionData: any) => {
|
|
120
132
|
const provider = actionData.item as interfaces.data.IDnsProviderPublic;
|
|
121
133
|
await this.testProvider(provider);
|
|
@@ -125,6 +137,7 @@ export class OpsViewProviders extends DeesElement {
|
|
|
125
137
|
name: 'Edit',
|
|
126
138
|
iconName: 'lucide:pencil',
|
|
127
139
|
type: ['inRow', 'contextmenu'] as any,
|
|
140
|
+
actionRelevancyCheckFunc: (p: interfaces.data.IDnsProviderPublic) => !p.builtIn,
|
|
128
141
|
actionFunc: async (actionData: any) => {
|
|
129
142
|
const provider = actionData.item as interfaces.data.IDnsProviderPublic;
|
|
130
143
|
await this.showEditDialog(provider);
|
|
@@ -134,6 +147,7 @@ export class OpsViewProviders extends DeesElement {
|
|
|
134
147
|
name: 'Delete',
|
|
135
148
|
iconName: 'lucide:trash2',
|
|
136
149
|
type: ['inRow', 'contextmenu'] as any,
|
|
150
|
+
actionRelevancyCheckFunc: (p: interfaces.data.IDnsProviderPublic) => !p.builtIn,
|
|
137
151
|
actionFunc: async (actionData: any) => {
|
|
138
152
|
const provider = actionData.item as interfaces.data.IDnsProviderPublic;
|
|
139
153
|
await this.deleteProvider(provider);
|