@serve.zone/dcrouter 13.5.0 → 13.7.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/dist_serve/bundle.js +1705 -1365
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.dcrouter.d.ts +2 -5
- package/dist_ts/classes.dcrouter.js +41 -10
- package/dist_ts/db/documents/classes.dns-provider.doc.d.ts +22 -0
- package/dist_ts/db/documents/classes.dns-provider.doc.js +134 -0
- package/dist_ts/db/documents/classes.dns-record.doc.d.ts +21 -0
- package/dist_ts/db/documents/classes.dns-record.doc.js +143 -0
- package/dist_ts/db/documents/classes.domain.doc.d.ts +22 -0
- package/dist_ts/db/documents/classes.domain.doc.js +146 -0
- package/dist_ts/db/documents/index.d.ts +3 -0
- package/dist_ts/db/documents/index.js +5 -1
- package/dist_ts/dns/index.d.ts +2 -0
- package/dist_ts/dns/index.js +3 -0
- package/dist_ts/dns/manager.dns.d.ts +227 -0
- package/dist_ts/dns/manager.dns.js +747 -0
- package/dist_ts/dns/providers/cloudflare.provider.d.ts +21 -0
- package/dist_ts/dns/providers/cloudflare.provider.js +106 -0
- package/dist_ts/dns/providers/factory.d.ts +23 -0
- package/dist_ts/dns/providers/factory.js +38 -0
- package/dist_ts/dns/providers/index.d.ts +3 -0
- package/dist_ts/dns/providers/index.js +4 -0
- package/dist_ts/dns/providers/interfaces.d.ts +54 -0
- package/dist_ts/dns/providers/interfaces.js +2 -0
- package/dist_ts/opsserver/classes.opsserver.d.ts +3 -0
- package/dist_ts/opsserver/classes.opsserver.js +7 -1
- package/dist_ts/opsserver/handlers/config.handler.js +11 -2
- package/dist_ts/opsserver/handlers/dns-provider.handler.d.ts +16 -0
- package/dist_ts/opsserver/handlers/dns-provider.handler.js +119 -0
- package/dist_ts/opsserver/handlers/dns-record.handler.d.ts +13 -0
- package/dist_ts/opsserver/handlers/dns-record.handler.js +98 -0
- package/dist_ts/opsserver/handlers/domain.handler.d.ts +13 -0
- package/dist_ts/opsserver/handlers/domain.handler.js +124 -0
- package/dist_ts/opsserver/handlers/index.d.ts +3 -0
- package/dist_ts/opsserver/handlers/index.js +4 -1
- package/dist_ts_interfaces/data/dns-provider.d.ts +112 -0
- package/dist_ts_interfaces/data/dns-provider.js +27 -0
- package/dist_ts_interfaces/data/dns-record.d.ts +40 -0
- package/dist_ts_interfaces/data/dns-record.js +2 -0
- package/dist_ts_interfaces/data/domain.d.ts +34 -0
- package/dist_ts_interfaces/data/domain.js +2 -0
- package/dist_ts_interfaces/data/index.d.ts +3 -0
- package/dist_ts_interfaces/data/index.js +4 -1
- package/dist_ts_interfaces/data/route-management.d.ts +1 -1
- package/dist_ts_interfaces/requests/dns-providers.d.ts +117 -0
- package/dist_ts_interfaces/requests/dns-providers.js +2 -0
- package/dist_ts_interfaces/requests/dns-records.d.ts +89 -0
- package/dist_ts_interfaces/requests/dns-records.js +2 -0
- package/dist_ts_interfaces/requests/domains.d.ts +118 -0
- package/dist_ts_interfaces/requests/domains.js +2 -0
- package/dist_ts_interfaces/requests/index.d.ts +3 -0
- package/dist_ts_interfaces/requests/index.js +4 -1
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/appstate.d.ts +72 -0
- package/dist_ts_web/appstate.js +308 -6
- package/dist_ts_web/elements/access/ops-view-apitokens.js +1 -1
- package/dist_ts_web/elements/access/ops-view-users.js +1 -1
- package/dist_ts_web/elements/domains/dns-provider-form.d.ts +58 -0
- package/dist_ts_web/elements/domains/dns-provider-form.js +268 -0
- package/dist_ts_web/elements/domains/index.d.ts +5 -0
- package/dist_ts_web/elements/domains/index.js +6 -0
- package/dist_ts_web/elements/{ops-view-certificates.d.ts → domains/ops-view-certificates.d.ts} +1 -1
- package/dist_ts_web/elements/{ops-view-certificates.js → domains/ops-view-certificates.js} +5 -5
- package/dist_ts_web/elements/domains/ops-view-dns.d.ts +17 -0
- package/dist_ts_web/elements/domains/ops-view-dns.js +304 -0
- package/dist_ts_web/elements/domains/ops-view-domains.d.ts +18 -0
- package/dist_ts_web/elements/domains/ops-view-domains.js +361 -0
- package/dist_ts_web/elements/domains/ops-view-providers.d.ts +21 -0
- package/dist_ts_web/elements/domains/ops-view-providers.js +316 -0
- package/dist_ts_web/elements/email/ops-view-email-security.js +1 -1
- package/dist_ts_web/elements/email/ops-view-emails.js +1 -1
- package/dist_ts_web/elements/index.d.ts +1 -1
- package/dist_ts_web/elements/index.js +2 -2
- package/dist_ts_web/elements/network/ops-view-network-activity.js +1 -1
- package/dist_ts_web/elements/network/ops-view-networktargets.js +1 -1
- package/dist_ts_web/elements/network/ops-view-remoteingress.js +1 -1
- package/dist_ts_web/elements/network/ops-view-routes.js +1 -1
- package/dist_ts_web/elements/network/ops-view-sourceprofiles.js +1 -1
- package/dist_ts_web/elements/network/ops-view-targetprofiles.js +1 -1
- package/dist_ts_web/elements/network/ops-view-vpn.js +1 -1
- package/dist_ts_web/elements/ops-dashboard.js +14 -5
- package/dist_ts_web/elements/ops-view-logs.js +1 -1
- package/dist_ts_web/elements/overview/ops-view-config.js +3 -3
- package/dist_ts_web/elements/overview/ops-view-overview.js +1 -1
- package/dist_ts_web/elements/security/ops-view-security-authentication.js +1 -1
- package/dist_ts_web/elements/security/ops-view-security-blocked.js +1 -1
- package/dist_ts_web/elements/security/ops-view-security-overview.js +1 -1
- package/dist_ts_web/router.d.ts +1 -1
- package/dist_ts_web/router.js +4 -2
- package/package.json +2 -2
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.dcrouter.ts +46 -17
- package/ts/db/documents/classes.dns-provider.doc.ts +63 -0
- package/ts/db/documents/classes.dns-record.doc.ts +62 -0
- package/ts/db/documents/classes.domain.doc.ts +66 -0
- package/ts/db/documents/index.ts +5 -0
- package/ts/dns/index.ts +2 -0
- package/ts/dns/manager.dns.ts +869 -0
- package/ts/dns/providers/cloudflare.provider.ts +131 -0
- package/ts/dns/providers/factory.ts +48 -0
- package/ts/dns/providers/index.ts +3 -0
- package/ts/dns/providers/interfaces.ts +67 -0
- package/ts/opsserver/classes.opsserver.ts +6 -0
- package/ts/opsserver/handlers/config.handler.ts +10 -1
- package/ts/opsserver/handlers/dns-provider.handler.ts +159 -0
- package/ts/opsserver/handlers/dns-record.handler.ts +127 -0
- package/ts/opsserver/handlers/domain.handler.ts +161 -0
- package/ts/opsserver/handlers/index.ts +4 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/appstate.ts +403 -5
- package/ts_web/elements/access/ops-view-apitokens.ts +1 -1
- package/ts_web/elements/access/ops-view-users.ts +1 -1
- package/ts_web/elements/domains/dns-provider-form.ts +216 -0
- package/ts_web/elements/domains/index.ts +5 -0
- package/ts_web/elements/{ops-view-certificates.ts → domains/ops-view-certificates.ts} +4 -4
- package/ts_web/elements/domains/ops-view-dns.ts +273 -0
- package/ts_web/elements/domains/ops-view-domains.ts +335 -0
- package/ts_web/elements/domains/ops-view-providers.ts +284 -0
- package/ts_web/elements/email/ops-view-email-security.ts +1 -1
- package/ts_web/elements/email/ops-view-emails.ts +1 -1
- package/ts_web/elements/index.ts +1 -1
- package/ts_web/elements/network/ops-view-network-activity.ts +1 -1
- package/ts_web/elements/network/ops-view-networktargets.ts +1 -1
- package/ts_web/elements/network/ops-view-remoteingress.ts +1 -1
- package/ts_web/elements/network/ops-view-routes.ts +1 -1
- package/ts_web/elements/network/ops-view-sourceprofiles.ts +1 -1
- package/ts_web/elements/network/ops-view-targetprofiles.ts +1 -1
- package/ts_web/elements/network/ops-view-vpn.ts +1 -1
- package/ts_web/elements/ops-dashboard.ts +14 -4
- package/ts_web/elements/ops-view-logs.ts +1 -1
- package/ts_web/elements/overview/ops-view-config.ts +2 -2
- package/ts_web/elements/overview/ops-view-overview.ts +1 -1
- package/ts_web/elements/security/ops-view-security-authentication.ts +1 -1
- package/ts_web/elements/security/ops-view-security-blocked.ts +1 -1
- package/ts_web/elements/security/ops-view-security-overview.ts +1 -1
- package/ts_web/router.ts +3 -1
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
import type { OpsServer } from '../classes.opsserver.js';
|
|
3
|
+
import * as interfaces from '../../../ts_interfaces/index.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* CRUD handlers for DomainDoc.
|
|
7
|
+
*/
|
|
8
|
+
export class DomainHandler {
|
|
9
|
+
public typedrouter = new plugins.typedrequest.TypedRouter();
|
|
10
|
+
|
|
11
|
+
constructor(private opsServerRef: OpsServer) {
|
|
12
|
+
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
|
13
|
+
this.registerHandlers();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
private async requireAuth(
|
|
17
|
+
request: { identity?: interfaces.data.IIdentity; apiToken?: string },
|
|
18
|
+
requiredScope?: interfaces.data.TApiTokenScope,
|
|
19
|
+
): Promise<string> {
|
|
20
|
+
if (request.identity?.jwt) {
|
|
21
|
+
try {
|
|
22
|
+
const isAdmin = await this.opsServerRef.adminHandler.adminIdentityGuard.exec({
|
|
23
|
+
identity: request.identity,
|
|
24
|
+
});
|
|
25
|
+
if (isAdmin) return request.identity.userId;
|
|
26
|
+
} catch { /* fall through */ }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (request.apiToken) {
|
|
30
|
+
const tokenManager = this.opsServerRef.dcRouterRef.apiTokenManager;
|
|
31
|
+
if (tokenManager) {
|
|
32
|
+
const token = await tokenManager.validateToken(request.apiToken);
|
|
33
|
+
if (token) {
|
|
34
|
+
if (!requiredScope || tokenManager.hasScope(token, requiredScope)) {
|
|
35
|
+
return token.createdBy;
|
|
36
|
+
}
|
|
37
|
+
throw new plugins.typedrequest.TypedResponseError('insufficient scope');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
throw new plugins.typedrequest.TypedResponseError('unauthorized');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private registerHandlers(): void {
|
|
46
|
+
// Get all domains
|
|
47
|
+
this.typedrouter.addTypedHandler(
|
|
48
|
+
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetDomains>(
|
|
49
|
+
'getDomains',
|
|
50
|
+
async (dataArg) => {
|
|
51
|
+
await this.requireAuth(dataArg, 'domains:read');
|
|
52
|
+
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
|
|
53
|
+
if (!dnsManager) return { domains: [] };
|
|
54
|
+
const docs = await dnsManager.listDomains();
|
|
55
|
+
return { domains: docs.map((d) => dnsManager.toPublicDomain(d)) };
|
|
56
|
+
},
|
|
57
|
+
),
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
// Get single domain
|
|
61
|
+
this.typedrouter.addTypedHandler(
|
|
62
|
+
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_GetDomain>(
|
|
63
|
+
'getDomain',
|
|
64
|
+
async (dataArg) => {
|
|
65
|
+
await this.requireAuth(dataArg, 'domains:read');
|
|
66
|
+
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
|
|
67
|
+
if (!dnsManager) return { domain: null };
|
|
68
|
+
const doc = await dnsManager.getDomain(dataArg.id);
|
|
69
|
+
return { domain: doc ? dnsManager.toPublicDomain(doc) : null };
|
|
70
|
+
},
|
|
71
|
+
),
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
// Create manual domain
|
|
75
|
+
this.typedrouter.addTypedHandler(
|
|
76
|
+
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_CreateDomain>(
|
|
77
|
+
'createDomain',
|
|
78
|
+
async (dataArg) => {
|
|
79
|
+
const userId = await this.requireAuth(dataArg, 'domains:write');
|
|
80
|
+
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
|
|
81
|
+
if (!dnsManager) return { success: false, message: 'DnsManager not initialized' };
|
|
82
|
+
try {
|
|
83
|
+
const id = await dnsManager.createManualDomain({
|
|
84
|
+
name: dataArg.name,
|
|
85
|
+
description: dataArg.description,
|
|
86
|
+
createdBy: userId,
|
|
87
|
+
});
|
|
88
|
+
return { success: true, id };
|
|
89
|
+
} catch (err: unknown) {
|
|
90
|
+
return { success: false, message: (err as Error).message };
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
),
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
// Import domains from a provider
|
|
97
|
+
this.typedrouter.addTypedHandler(
|
|
98
|
+
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_ImportDomain>(
|
|
99
|
+
'importDomain',
|
|
100
|
+
async (dataArg) => {
|
|
101
|
+
const userId = await this.requireAuth(dataArg, 'domains:write');
|
|
102
|
+
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
|
|
103
|
+
if (!dnsManager) return { success: false, message: 'DnsManager not initialized' };
|
|
104
|
+
try {
|
|
105
|
+
const importedIds = await dnsManager.importDomainsFromProvider({
|
|
106
|
+
providerId: dataArg.providerId,
|
|
107
|
+
domainNames: dataArg.domainNames,
|
|
108
|
+
createdBy: userId,
|
|
109
|
+
});
|
|
110
|
+
return { success: true, importedIds };
|
|
111
|
+
} catch (err: unknown) {
|
|
112
|
+
return { success: false, message: (err as Error).message };
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
),
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
// Update domain metadata
|
|
119
|
+
this.typedrouter.addTypedHandler(
|
|
120
|
+
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_UpdateDomain>(
|
|
121
|
+
'updateDomain',
|
|
122
|
+
async (dataArg) => {
|
|
123
|
+
await this.requireAuth(dataArg, 'domains:write');
|
|
124
|
+
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
|
|
125
|
+
if (!dnsManager) return { success: false, message: 'DnsManager not initialized' };
|
|
126
|
+
const ok = await dnsManager.updateDomain(dataArg.id, {
|
|
127
|
+
description: dataArg.description,
|
|
128
|
+
});
|
|
129
|
+
return ok ? { success: true } : { success: false, message: 'Domain not found' };
|
|
130
|
+
},
|
|
131
|
+
),
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// Delete domain
|
|
135
|
+
this.typedrouter.addTypedHandler(
|
|
136
|
+
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_DeleteDomain>(
|
|
137
|
+
'deleteDomain',
|
|
138
|
+
async (dataArg) => {
|
|
139
|
+
await this.requireAuth(dataArg, 'domains:write');
|
|
140
|
+
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
|
|
141
|
+
if (!dnsManager) return { success: false, message: 'DnsManager not initialized' };
|
|
142
|
+
const ok = await dnsManager.deleteDomain(dataArg.id);
|
|
143
|
+
return ok ? { success: true } : { success: false, message: 'Domain not found' };
|
|
144
|
+
},
|
|
145
|
+
),
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
// Force-resync provider domain
|
|
149
|
+
this.typedrouter.addTypedHandler(
|
|
150
|
+
new plugins.typedrequest.TypedHandler<interfaces.requests.IReq_SyncDomain>(
|
|
151
|
+
'syncDomain',
|
|
152
|
+
async (dataArg) => {
|
|
153
|
+
await this.requireAuth(dataArg, 'domains:write');
|
|
154
|
+
const dnsManager = this.opsServerRef.dcRouterRef.dnsManager;
|
|
155
|
+
if (!dnsManager) return { success: false, message: 'DnsManager not initialized' };
|
|
156
|
+
return await dnsManager.syncDomain(dataArg.id);
|
|
157
|
+
},
|
|
158
|
+
),
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -13,4 +13,7 @@ export * from './vpn.handler.js';
|
|
|
13
13
|
export * from './source-profile.handler.js';
|
|
14
14
|
export * from './target-profile.handler.js';
|
|
15
15
|
export * from './network-target.handler.js';
|
|
16
|
-
export * from './users.handler.js';
|
|
16
|
+
export * from './users.handler.js';
|
|
17
|
+
export * from './dns-provider.handler.js';
|
|
18
|
+
export * from './domain.handler.js';
|
|
19
|
+
export * from './dns-record.handler.js';
|
package/ts_web/appstate.ts
CHANGED
|
@@ -117,7 +117,7 @@ export const configStatePart = await appState.getStatePart<IConfigState>(
|
|
|
117
117
|
// Determine initial view from URL path
|
|
118
118
|
const getInitialView = (): string => {
|
|
119
119
|
const path = typeof window !== 'undefined' ? window.location.pathname : '/';
|
|
120
|
-
const validViews = ['overview', 'network', 'email', 'logs', 'access', 'security', '
|
|
120
|
+
const validViews = ['overview', 'network', 'email', 'logs', 'access', 'security', 'domains'];
|
|
121
121
|
const segments = path.split('/').filter(Boolean);
|
|
122
122
|
const view = segments[0];
|
|
123
123
|
return validViews.includes(view) ? view : 'overview';
|
|
@@ -465,8 +465,9 @@ export const setActiveViewAction = uiStatePart.createAction<string>(async (state
|
|
|
465
465
|
}, 100);
|
|
466
466
|
}
|
|
467
467
|
|
|
468
|
-
// If switching to
|
|
469
|
-
|
|
468
|
+
// If switching to the Domains group, ensure we fetch certificate data
|
|
469
|
+
// (Certificates is a subview of Domains).
|
|
470
|
+
if (viewName === 'domains' && currentState.activeView !== 'domains') {
|
|
470
471
|
setTimeout(() => {
|
|
471
472
|
certificateStatePart.dispatchAction(fetchCertificateOverviewAction, null);
|
|
472
473
|
}, 100);
|
|
@@ -1555,6 +1556,403 @@ export const deleteTargetAction = profilesTargetsStatePart.createAction<{
|
|
|
1555
1556
|
}
|
|
1556
1557
|
});
|
|
1557
1558
|
|
|
1559
|
+
// ============================================================================
|
|
1560
|
+
// Domains State (DNS providers + domains + records)
|
|
1561
|
+
// ============================================================================
|
|
1562
|
+
|
|
1563
|
+
export interface IDomainsState {
|
|
1564
|
+
providers: interfaces.data.IDnsProviderPublic[];
|
|
1565
|
+
domains: interfaces.data.IDomain[];
|
|
1566
|
+
records: interfaces.data.IDnsRecord[];
|
|
1567
|
+
/** id of the currently-selected domain in the DNS records subview. */
|
|
1568
|
+
selectedDomainId: string | null;
|
|
1569
|
+
isLoading: boolean;
|
|
1570
|
+
error: string | null;
|
|
1571
|
+
lastUpdated: number;
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
export const domainsStatePart = await appState.getStatePart<IDomainsState>(
|
|
1575
|
+
'domains',
|
|
1576
|
+
{
|
|
1577
|
+
providers: [],
|
|
1578
|
+
domains: [],
|
|
1579
|
+
records: [],
|
|
1580
|
+
selectedDomainId: null,
|
|
1581
|
+
isLoading: false,
|
|
1582
|
+
error: null,
|
|
1583
|
+
lastUpdated: 0,
|
|
1584
|
+
},
|
|
1585
|
+
'soft',
|
|
1586
|
+
);
|
|
1587
|
+
|
|
1588
|
+
export const fetchDomainsAndProvidersAction = domainsStatePart.createAction(
|
|
1589
|
+
async (statePartArg): Promise<IDomainsState> => {
|
|
1590
|
+
const context = getActionContext();
|
|
1591
|
+
const currentState = statePartArg.getState()!;
|
|
1592
|
+
if (!context.identity) return currentState;
|
|
1593
|
+
|
|
1594
|
+
try {
|
|
1595
|
+
const providersRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
1596
|
+
interfaces.requests.IReq_GetDnsProviders
|
|
1597
|
+
>('/typedrequest', 'getDnsProviders');
|
|
1598
|
+
const domainsRequest = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
1599
|
+
interfaces.requests.IReq_GetDomains
|
|
1600
|
+
>('/typedrequest', 'getDomains');
|
|
1601
|
+
|
|
1602
|
+
const [providersResponse, domainsResponse] = await Promise.all([
|
|
1603
|
+
providersRequest.fire({ identity: context.identity }),
|
|
1604
|
+
domainsRequest.fire({ identity: context.identity }),
|
|
1605
|
+
]);
|
|
1606
|
+
|
|
1607
|
+
return {
|
|
1608
|
+
...currentState,
|
|
1609
|
+
providers: providersResponse.providers,
|
|
1610
|
+
domains: domainsResponse.domains,
|
|
1611
|
+
isLoading: false,
|
|
1612
|
+
error: null,
|
|
1613
|
+
lastUpdated: Date.now(),
|
|
1614
|
+
};
|
|
1615
|
+
} catch (error: unknown) {
|
|
1616
|
+
return {
|
|
1617
|
+
...currentState,
|
|
1618
|
+
isLoading: false,
|
|
1619
|
+
error: error instanceof Error ? error.message : 'Failed to fetch domains/providers',
|
|
1620
|
+
};
|
|
1621
|
+
}
|
|
1622
|
+
},
|
|
1623
|
+
);
|
|
1624
|
+
|
|
1625
|
+
export const fetchDnsRecordsForDomainAction = domainsStatePart.createAction<{ domainId: string }>(
|
|
1626
|
+
async (statePartArg, dataArg): Promise<IDomainsState> => {
|
|
1627
|
+
const context = getActionContext();
|
|
1628
|
+
const currentState = statePartArg.getState()!;
|
|
1629
|
+
if (!context.identity) return currentState;
|
|
1630
|
+
|
|
1631
|
+
try {
|
|
1632
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
1633
|
+
interfaces.requests.IReq_GetDnsRecords
|
|
1634
|
+
>('/typedrequest', 'getDnsRecords');
|
|
1635
|
+
const response = await request.fire({
|
|
1636
|
+
identity: context.identity,
|
|
1637
|
+
domainId: dataArg.domainId,
|
|
1638
|
+
});
|
|
1639
|
+
return {
|
|
1640
|
+
...currentState,
|
|
1641
|
+
records: response.records,
|
|
1642
|
+
selectedDomainId: dataArg.domainId,
|
|
1643
|
+
error: null,
|
|
1644
|
+
};
|
|
1645
|
+
} catch (error: unknown) {
|
|
1646
|
+
return {
|
|
1647
|
+
...currentState,
|
|
1648
|
+
error: error instanceof Error ? error.message : 'Failed to fetch DNS records',
|
|
1649
|
+
};
|
|
1650
|
+
}
|
|
1651
|
+
},
|
|
1652
|
+
);
|
|
1653
|
+
|
|
1654
|
+
export const createDnsProviderAction = domainsStatePart.createAction<{
|
|
1655
|
+
name: string;
|
|
1656
|
+
type: interfaces.data.TDnsProviderType;
|
|
1657
|
+
credentials: interfaces.data.TDnsProviderCredentials;
|
|
1658
|
+
}>(async (statePartArg, dataArg, actionContext): Promise<IDomainsState> => {
|
|
1659
|
+
const context = getActionContext();
|
|
1660
|
+
try {
|
|
1661
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
1662
|
+
interfaces.requests.IReq_CreateDnsProvider
|
|
1663
|
+
>('/typedrequest', 'createDnsProvider');
|
|
1664
|
+
const response = await request.fire({
|
|
1665
|
+
identity: context.identity!,
|
|
1666
|
+
name: dataArg.name,
|
|
1667
|
+
type: dataArg.type,
|
|
1668
|
+
credentials: dataArg.credentials,
|
|
1669
|
+
});
|
|
1670
|
+
if (!response.success) {
|
|
1671
|
+
return {
|
|
1672
|
+
...statePartArg.getState()!,
|
|
1673
|
+
error: response.message || 'Failed to create provider',
|
|
1674
|
+
};
|
|
1675
|
+
}
|
|
1676
|
+
return await actionContext!.dispatch(fetchDomainsAndProvidersAction, null);
|
|
1677
|
+
} catch (error: unknown) {
|
|
1678
|
+
return {
|
|
1679
|
+
...statePartArg.getState()!,
|
|
1680
|
+
error: error instanceof Error ? error.message : 'Failed to create provider',
|
|
1681
|
+
};
|
|
1682
|
+
}
|
|
1683
|
+
});
|
|
1684
|
+
|
|
1685
|
+
export const updateDnsProviderAction = domainsStatePart.createAction<{
|
|
1686
|
+
id: string;
|
|
1687
|
+
name?: string;
|
|
1688
|
+
credentials?: interfaces.data.TDnsProviderCredentials;
|
|
1689
|
+
}>(async (statePartArg, dataArg, actionContext): Promise<IDomainsState> => {
|
|
1690
|
+
const context = getActionContext();
|
|
1691
|
+
try {
|
|
1692
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
1693
|
+
interfaces.requests.IReq_UpdateDnsProvider
|
|
1694
|
+
>('/typedrequest', 'updateDnsProvider');
|
|
1695
|
+
const response = await request.fire({
|
|
1696
|
+
identity: context.identity!,
|
|
1697
|
+
id: dataArg.id,
|
|
1698
|
+
name: dataArg.name,
|
|
1699
|
+
credentials: dataArg.credentials,
|
|
1700
|
+
});
|
|
1701
|
+
if (!response.success) {
|
|
1702
|
+
return {
|
|
1703
|
+
...statePartArg.getState()!,
|
|
1704
|
+
error: response.message || 'Failed to update provider',
|
|
1705
|
+
};
|
|
1706
|
+
}
|
|
1707
|
+
return await actionContext!.dispatch(fetchDomainsAndProvidersAction, null);
|
|
1708
|
+
} catch (error: unknown) {
|
|
1709
|
+
return {
|
|
1710
|
+
...statePartArg.getState()!,
|
|
1711
|
+
error: error instanceof Error ? error.message : 'Failed to update provider',
|
|
1712
|
+
};
|
|
1713
|
+
}
|
|
1714
|
+
});
|
|
1715
|
+
|
|
1716
|
+
export const deleteDnsProviderAction = domainsStatePart.createAction<{ id: string; force?: boolean }>(
|
|
1717
|
+
async (statePartArg, dataArg, actionContext): Promise<IDomainsState> => {
|
|
1718
|
+
const context = getActionContext();
|
|
1719
|
+
try {
|
|
1720
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
1721
|
+
interfaces.requests.IReq_DeleteDnsProvider
|
|
1722
|
+
>('/typedrequest', 'deleteDnsProvider');
|
|
1723
|
+
const response = await request.fire({
|
|
1724
|
+
identity: context.identity!,
|
|
1725
|
+
id: dataArg.id,
|
|
1726
|
+
force: dataArg.force,
|
|
1727
|
+
});
|
|
1728
|
+
if (!response.success) {
|
|
1729
|
+
return {
|
|
1730
|
+
...statePartArg.getState()!,
|
|
1731
|
+
error: response.message || 'Failed to delete provider',
|
|
1732
|
+
};
|
|
1733
|
+
}
|
|
1734
|
+
return await actionContext!.dispatch(fetchDomainsAndProvidersAction, null);
|
|
1735
|
+
} catch (error: unknown) {
|
|
1736
|
+
return {
|
|
1737
|
+
...statePartArg.getState()!,
|
|
1738
|
+
error: error instanceof Error ? error.message : 'Failed to delete provider',
|
|
1739
|
+
};
|
|
1740
|
+
}
|
|
1741
|
+
},
|
|
1742
|
+
);
|
|
1743
|
+
|
|
1744
|
+
export const testDnsProviderAction = domainsStatePart.createAction<{ id: string }>(
|
|
1745
|
+
async (statePartArg, dataArg, actionContext): Promise<IDomainsState> => {
|
|
1746
|
+
const context = getActionContext();
|
|
1747
|
+
try {
|
|
1748
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
1749
|
+
interfaces.requests.IReq_TestDnsProvider
|
|
1750
|
+
>('/typedrequest', 'testDnsProvider');
|
|
1751
|
+
await request.fire({ identity: context.identity!, id: dataArg.id });
|
|
1752
|
+
return await actionContext!.dispatch(fetchDomainsAndProvidersAction, null);
|
|
1753
|
+
} catch (error: unknown) {
|
|
1754
|
+
return {
|
|
1755
|
+
...statePartArg.getState()!,
|
|
1756
|
+
error: error instanceof Error ? error.message : 'Failed to test provider',
|
|
1757
|
+
};
|
|
1758
|
+
}
|
|
1759
|
+
},
|
|
1760
|
+
);
|
|
1761
|
+
|
|
1762
|
+
/** One-shot fetch for the import-domain modal. Does NOT modify state. */
|
|
1763
|
+
export async function fetchProviderDomains(
|
|
1764
|
+
providerId: string,
|
|
1765
|
+
): Promise<{ success: boolean; domains?: interfaces.data.IProviderDomainListing[]; message?: string }> {
|
|
1766
|
+
const context = getActionContext();
|
|
1767
|
+
if (!context.identity) return { success: false, message: 'Not authenticated' };
|
|
1768
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
1769
|
+
interfaces.requests.IReq_ListProviderDomains
|
|
1770
|
+
>('/typedrequest', 'listProviderDomains');
|
|
1771
|
+
return await request.fire({ identity: context.identity, providerId });
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
export const createManualDomainAction = domainsStatePart.createAction<{
|
|
1775
|
+
name: string;
|
|
1776
|
+
description?: string;
|
|
1777
|
+
}>(async (statePartArg, dataArg, actionContext): Promise<IDomainsState> => {
|
|
1778
|
+
const context = getActionContext();
|
|
1779
|
+
try {
|
|
1780
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
1781
|
+
interfaces.requests.IReq_CreateDomain
|
|
1782
|
+
>('/typedrequest', 'createDomain');
|
|
1783
|
+
const response = await request.fire({
|
|
1784
|
+
identity: context.identity!,
|
|
1785
|
+
name: dataArg.name,
|
|
1786
|
+
description: dataArg.description,
|
|
1787
|
+
});
|
|
1788
|
+
if (!response.success) {
|
|
1789
|
+
return { ...statePartArg.getState()!, error: response.message || 'Failed to create domain' };
|
|
1790
|
+
}
|
|
1791
|
+
return await actionContext!.dispatch(fetchDomainsAndProvidersAction, null);
|
|
1792
|
+
} catch (error: unknown) {
|
|
1793
|
+
return {
|
|
1794
|
+
...statePartArg.getState()!,
|
|
1795
|
+
error: error instanceof Error ? error.message : 'Failed to create domain',
|
|
1796
|
+
};
|
|
1797
|
+
}
|
|
1798
|
+
});
|
|
1799
|
+
|
|
1800
|
+
export const importDomainsFromProviderAction = domainsStatePart.createAction<{
|
|
1801
|
+
providerId: string;
|
|
1802
|
+
domainNames: string[];
|
|
1803
|
+
}>(async (statePartArg, dataArg, actionContext): Promise<IDomainsState> => {
|
|
1804
|
+
const context = getActionContext();
|
|
1805
|
+
try {
|
|
1806
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
1807
|
+
interfaces.requests.IReq_ImportDomain
|
|
1808
|
+
>('/typedrequest', 'importDomain');
|
|
1809
|
+
const response = await request.fire({
|
|
1810
|
+
identity: context.identity!,
|
|
1811
|
+
providerId: dataArg.providerId,
|
|
1812
|
+
domainNames: dataArg.domainNames,
|
|
1813
|
+
});
|
|
1814
|
+
if (!response.success) {
|
|
1815
|
+
return { ...statePartArg.getState()!, error: response.message || 'Failed to import domains' };
|
|
1816
|
+
}
|
|
1817
|
+
return await actionContext!.dispatch(fetchDomainsAndProvidersAction, null);
|
|
1818
|
+
} catch (error: unknown) {
|
|
1819
|
+
return {
|
|
1820
|
+
...statePartArg.getState()!,
|
|
1821
|
+
error: error instanceof Error ? error.message : 'Failed to import domains',
|
|
1822
|
+
};
|
|
1823
|
+
}
|
|
1824
|
+
});
|
|
1825
|
+
|
|
1826
|
+
export const deleteDomainAction = domainsStatePart.createAction<{ id: string }>(
|
|
1827
|
+
async (statePartArg, dataArg, actionContext): Promise<IDomainsState> => {
|
|
1828
|
+
const context = getActionContext();
|
|
1829
|
+
try {
|
|
1830
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
1831
|
+
interfaces.requests.IReq_DeleteDomain
|
|
1832
|
+
>('/typedrequest', 'deleteDomain');
|
|
1833
|
+
const response = await request.fire({ identity: context.identity!, id: dataArg.id });
|
|
1834
|
+
if (!response.success) {
|
|
1835
|
+
return { ...statePartArg.getState()!, error: response.message || 'Failed to delete domain' };
|
|
1836
|
+
}
|
|
1837
|
+
return await actionContext!.dispatch(fetchDomainsAndProvidersAction, null);
|
|
1838
|
+
} catch (error: unknown) {
|
|
1839
|
+
return {
|
|
1840
|
+
...statePartArg.getState()!,
|
|
1841
|
+
error: error instanceof Error ? error.message : 'Failed to delete domain',
|
|
1842
|
+
};
|
|
1843
|
+
}
|
|
1844
|
+
},
|
|
1845
|
+
);
|
|
1846
|
+
|
|
1847
|
+
export const syncDomainAction = domainsStatePart.createAction<{ id: string }>(
|
|
1848
|
+
async (statePartArg, dataArg, actionContext): Promise<IDomainsState> => {
|
|
1849
|
+
const context = getActionContext();
|
|
1850
|
+
try {
|
|
1851
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
1852
|
+
interfaces.requests.IReq_SyncDomain
|
|
1853
|
+
>('/typedrequest', 'syncDomain');
|
|
1854
|
+
const response = await request.fire({ identity: context.identity!, id: dataArg.id });
|
|
1855
|
+
if (!response.success) {
|
|
1856
|
+
return { ...statePartArg.getState()!, error: response.message || 'Failed to sync domain' };
|
|
1857
|
+
}
|
|
1858
|
+
return await actionContext!.dispatch(fetchDomainsAndProvidersAction, null);
|
|
1859
|
+
} catch (error: unknown) {
|
|
1860
|
+
return {
|
|
1861
|
+
...statePartArg.getState()!,
|
|
1862
|
+
error: error instanceof Error ? error.message : 'Failed to sync domain',
|
|
1863
|
+
};
|
|
1864
|
+
}
|
|
1865
|
+
},
|
|
1866
|
+
);
|
|
1867
|
+
|
|
1868
|
+
export const createDnsRecordAction = domainsStatePart.createAction<{
|
|
1869
|
+
domainId: string;
|
|
1870
|
+
name: string;
|
|
1871
|
+
type: interfaces.data.TDnsRecordType;
|
|
1872
|
+
value: string;
|
|
1873
|
+
ttl?: number;
|
|
1874
|
+
proxied?: boolean;
|
|
1875
|
+
}>(async (statePartArg, dataArg, actionContext): Promise<IDomainsState> => {
|
|
1876
|
+
const context = getActionContext();
|
|
1877
|
+
try {
|
|
1878
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
1879
|
+
interfaces.requests.IReq_CreateDnsRecord
|
|
1880
|
+
>('/typedrequest', 'createDnsRecord');
|
|
1881
|
+
const response = await request.fire({
|
|
1882
|
+
identity: context.identity!,
|
|
1883
|
+
domainId: dataArg.domainId,
|
|
1884
|
+
name: dataArg.name,
|
|
1885
|
+
type: dataArg.type,
|
|
1886
|
+
value: dataArg.value,
|
|
1887
|
+
ttl: dataArg.ttl,
|
|
1888
|
+
proxied: dataArg.proxied,
|
|
1889
|
+
});
|
|
1890
|
+
if (!response.success) {
|
|
1891
|
+
return { ...statePartArg.getState()!, error: response.message || 'Failed to create record' };
|
|
1892
|
+
}
|
|
1893
|
+
return await actionContext!.dispatch(fetchDnsRecordsForDomainAction, { domainId: dataArg.domainId });
|
|
1894
|
+
} catch (error: unknown) {
|
|
1895
|
+
return {
|
|
1896
|
+
...statePartArg.getState()!,
|
|
1897
|
+
error: error instanceof Error ? error.message : 'Failed to create record',
|
|
1898
|
+
};
|
|
1899
|
+
}
|
|
1900
|
+
});
|
|
1901
|
+
|
|
1902
|
+
export const updateDnsRecordAction = domainsStatePart.createAction<{
|
|
1903
|
+
id: string;
|
|
1904
|
+
domainId: string;
|
|
1905
|
+
name?: string;
|
|
1906
|
+
value?: string;
|
|
1907
|
+
ttl?: number;
|
|
1908
|
+
proxied?: boolean;
|
|
1909
|
+
}>(async (statePartArg, dataArg, actionContext): Promise<IDomainsState> => {
|
|
1910
|
+
const context = getActionContext();
|
|
1911
|
+
try {
|
|
1912
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
1913
|
+
interfaces.requests.IReq_UpdateDnsRecord
|
|
1914
|
+
>('/typedrequest', 'updateDnsRecord');
|
|
1915
|
+
const response = await request.fire({
|
|
1916
|
+
identity: context.identity!,
|
|
1917
|
+
id: dataArg.id,
|
|
1918
|
+
name: dataArg.name,
|
|
1919
|
+
value: dataArg.value,
|
|
1920
|
+
ttl: dataArg.ttl,
|
|
1921
|
+
proxied: dataArg.proxied,
|
|
1922
|
+
});
|
|
1923
|
+
if (!response.success) {
|
|
1924
|
+
return { ...statePartArg.getState()!, error: response.message || 'Failed to update record' };
|
|
1925
|
+
}
|
|
1926
|
+
return await actionContext!.dispatch(fetchDnsRecordsForDomainAction, { domainId: dataArg.domainId });
|
|
1927
|
+
} catch (error: unknown) {
|
|
1928
|
+
return {
|
|
1929
|
+
...statePartArg.getState()!,
|
|
1930
|
+
error: error instanceof Error ? error.message : 'Failed to update record',
|
|
1931
|
+
};
|
|
1932
|
+
}
|
|
1933
|
+
});
|
|
1934
|
+
|
|
1935
|
+
export const deleteDnsRecordAction = domainsStatePart.createAction<{ id: string; domainId: string }>(
|
|
1936
|
+
async (statePartArg, dataArg, actionContext): Promise<IDomainsState> => {
|
|
1937
|
+
const context = getActionContext();
|
|
1938
|
+
try {
|
|
1939
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
1940
|
+
interfaces.requests.IReq_DeleteDnsRecord
|
|
1941
|
+
>('/typedrequest', 'deleteDnsRecord');
|
|
1942
|
+
const response = await request.fire({ identity: context.identity!, id: dataArg.id });
|
|
1943
|
+
if (!response.success) {
|
|
1944
|
+
return { ...statePartArg.getState()!, error: response.message || 'Failed to delete record' };
|
|
1945
|
+
}
|
|
1946
|
+
return await actionContext!.dispatch(fetchDnsRecordsForDomainAction, { domainId: dataArg.domainId });
|
|
1947
|
+
} catch (error: unknown) {
|
|
1948
|
+
return {
|
|
1949
|
+
...statePartArg.getState()!,
|
|
1950
|
+
error: error instanceof Error ? error.message : 'Failed to delete record',
|
|
1951
|
+
};
|
|
1952
|
+
}
|
|
1953
|
+
},
|
|
1954
|
+
);
|
|
1955
|
+
|
|
1558
1956
|
// ============================================================================
|
|
1559
1957
|
// Route Management Actions
|
|
1560
1958
|
// ============================================================================
|
|
@@ -2076,8 +2474,8 @@ async function dispatchCombinedRefreshActionInner() {
|
|
|
2076
2474
|
}
|
|
2077
2475
|
}
|
|
2078
2476
|
|
|
2079
|
-
// Refresh certificate data if on
|
|
2080
|
-
if (currentView === 'certificates') {
|
|
2477
|
+
// Refresh certificate data if on Domains > Certificates subview
|
|
2478
|
+
if (currentView === 'domains' && currentSubview === 'certificates') {
|
|
2081
2479
|
try {
|
|
2082
2480
|
await certificateStatePart.dispatchAction(fetchCertificateOverviewAction, null);
|
|
2083
2481
|
} catch (error) {
|
|
@@ -100,7 +100,7 @@ export class OpsViewApiTokens extends DeesElement {
|
|
|
100
100
|
const { apiTokens } = this.routeState;
|
|
101
101
|
|
|
102
102
|
return html`
|
|
103
|
-
<dees-heading level="
|
|
103
|
+
<dees-heading level="3">API Tokens</dees-heading>
|
|
104
104
|
|
|
105
105
|
<div class="apiTokensContainer">
|
|
106
106
|
<dees-table
|
|
@@ -104,7 +104,7 @@ export class OpsViewUsers extends DeesElement {
|
|
|
104
104
|
const currentUserId = this.loginState.identity?.userId;
|
|
105
105
|
|
|
106
106
|
return html`
|
|
107
|
-
<dees-heading level="
|
|
107
|
+
<dees-heading level="3">Users</dees-heading>
|
|
108
108
|
|
|
109
109
|
<div class="usersContainer">
|
|
110
110
|
<dees-table
|