@serve.zone/dcrouter 7.4.3 → 8.1.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 +11567 -3516
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.dcrouter.d.ts +9 -0
- package/dist_ts/classes.dcrouter.js +27 -1
- package/dist_ts/config/classes.api-token-manager.d.ts +38 -0
- package/dist_ts/config/classes.api-token-manager.js +134 -0
- package/dist_ts/config/classes.route-config-manager.d.ts +35 -0
- package/dist_ts/config/classes.route-config-manager.js +231 -0
- package/dist_ts/config/index.d.ts +2 -0
- package/dist_ts/config/index.js +3 -1
- package/dist_ts/opsserver/classes.opsserver.d.ts +2 -0
- package/dist_ts/opsserver/classes.opsserver.js +5 -1
- package/dist_ts/opsserver/handlers/{email-ops.handler.d.ts → api-token.handler.d.ts} +4 -4
- package/dist_ts/opsserver/handlers/api-token.handler.js +66 -0
- package/dist_ts/opsserver/handlers/index.d.ts +2 -0
- package/dist_ts/opsserver/handlers/index.js +3 -1
- package/dist_ts/opsserver/handlers/{radius.handler.d.ts → route-management.handler.d.ts} +6 -1
- package/dist_ts/opsserver/handlers/route-management.handler.js +117 -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 +68 -0
- package/dist_ts_interfaces/data/route-management.js +2 -0
- package/dist_ts_interfaces/requests/api-tokens.d.ts +63 -0
- package/dist_ts_interfaces/requests/api-tokens.js +2 -0
- package/dist_ts_interfaces/requests/email-ops.d.ts +51 -108
- package/dist_ts_interfaces/requests/index.d.ts +2 -0
- package/dist_ts_interfaces/requests/index.js +3 -1
- package/dist_ts_interfaces/requests/route-management.d.ts +114 -0
- package/dist_ts_interfaces/requests/route-management.js +2 -0
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/appstate.d.ts +38 -16
- package/dist_ts_web/appstate.js +226 -177
- package/dist_ts_web/elements/index.d.ts +2 -0
- package/dist_ts_web/elements/index.js +3 -1
- package/dist_ts_web/elements/ops-dashboard.js +11 -1
- package/dist_ts_web/elements/ops-view-apitokens.d.ts +12 -0
- package/dist_ts_web/elements/ops-view-apitokens.js +306 -0
- package/dist_ts_web/elements/ops-view-emails.d.ts +8 -31
- package/dist_ts_web/elements/ops-view-emails.js +54 -769
- package/dist_ts_web/elements/ops-view-logs.d.ts +2 -8
- package/dist_ts_web/elements/ops-view-logs.js +4 -101
- package/dist_ts_web/elements/ops-view-routes.d.ts +12 -0
- package/dist_ts_web/elements/ops-view-routes.js +404 -0
- package/dist_ts_web/plugins.d.ts +2 -1
- package/dist_ts_web/plugins.js +4 -2
- package/dist_ts_web/router.d.ts +1 -7
- package/dist_ts_web/router.js +8 -82
- package/package.json +2 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.dcrouter.ts +37 -1
- package/ts/config/classes.api-token-manager.ts +155 -0
- package/ts/config/classes.route-config-manager.ts +271 -0
- package/ts/config/index.ts +3 -1
- package/ts/opsserver/classes.opsserver.ts +4 -0
- package/ts/opsserver/handlers/api-token.handler.ts +96 -0
- package/ts/opsserver/handlers/email-ops.handler.ts +177 -225
- package/ts/opsserver/handlers/index.ts +3 -1
- package/ts/opsserver/handlers/route-management.handler.ts +163 -0
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/appstate.ts +316 -222
- package/ts_web/elements/index.ts +2 -0
- package/ts_web/elements/ops-dashboard.ts +10 -0
- package/ts_web/elements/ops-view-apitokens.ts +281 -0
- package/ts_web/elements/ops-view-emails.ts +40 -749
- package/ts_web/elements/ops-view-logs.ts +2 -87
- package/ts_web/elements/ops-view-routes.ts +389 -0
- package/ts_web/plugins.ts +4 -0
- package/ts_web/router.ts +7 -82
- package/dist_ts/cache/classes.cache.cleaner.d.ts +0 -47
- package/dist_ts/cache/classes.cache.cleaner.js +0 -130
- package/dist_ts/cache/classes.cached.document.d.ts +0 -76
- package/dist_ts/cache/classes.cached.document.js +0 -100
- package/dist_ts/cache/classes.cachedb.d.ts +0 -60
- package/dist_ts/cache/classes.cachedb.js +0 -126
- package/dist_ts/cache/documents/classes.cached.email.d.ts +0 -125
- package/dist_ts/cache/documents/classes.cached.email.js +0 -337
- package/dist_ts/cache/documents/classes.cached.ip.reputation.d.ts +0 -119
- package/dist_ts/cache/documents/classes.cached.ip.reputation.js +0 -323
- package/dist_ts/cache/documents/index.d.ts +0 -2
- package/dist_ts/cache/documents/index.js +0 -3
- package/dist_ts/cache/index.d.ts +0 -4
- package/dist_ts/cache/index.js +0 -7
- package/dist_ts/monitoring/classes.metricscache.d.ts +0 -32
- package/dist_ts/monitoring/classes.metricscache.js +0 -63
- package/dist_ts/monitoring/classes.metricsmanager.d.ts +0 -169
- package/dist_ts/monitoring/classes.metricsmanager.js +0 -591
- package/dist_ts/monitoring/index.d.ts +0 -1
- package/dist_ts/monitoring/index.js +0 -2
- package/dist_ts/opsserver/handlers/admin.handler.d.ts +0 -31
- package/dist_ts/opsserver/handlers/admin.handler.js +0 -180
- package/dist_ts/opsserver/handlers/certificate.handler.d.ts +0 -34
- package/dist_ts/opsserver/handlers/certificate.handler.js +0 -419
- package/dist_ts/opsserver/handlers/config.handler.d.ts +0 -9
- package/dist_ts/opsserver/handlers/config.handler.js +0 -67
- package/dist_ts/opsserver/handlers/email-ops.handler.js +0 -219
- package/dist_ts/opsserver/handlers/logs.handler.d.ts +0 -17
- package/dist_ts/opsserver/handlers/logs.handler.js +0 -215
- package/dist_ts/opsserver/handlers/radius.handler.js +0 -296
- package/dist_ts/opsserver/handlers/remoteingress.handler.d.ts +0 -8
- package/dist_ts/opsserver/handlers/remoteingress.handler.js +0 -154
- package/dist_ts/opsserver/handlers/security.handler.d.ts +0 -11
- package/dist_ts/opsserver/handlers/security.handler.js +0 -232
- package/dist_ts/opsserver/handlers/stats.handler.d.ts +0 -13
- package/dist_ts/opsserver/handlers/stats.handler.js +0 -400
- package/dist_ts/security/classes.securitylogger.d.ts +0 -140
- package/dist_ts/security/classes.securitylogger.js +0 -235
- package/dist_ts/storage/classes.storagemanager.d.ts +0 -82
- package/dist_ts/storage/classes.storagemanager.js +0 -344
- package/dist_ts/storage/index.d.ts +0 -1
- package/dist_ts/storage/index.js +0 -3
|
@@ -1,419 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../../plugins.js';
|
|
2
|
-
import * as interfaces from '../../../dist_ts_interfaces/index.js';
|
|
3
|
-
export class CertificateHandler {
|
|
4
|
-
opsServerRef;
|
|
5
|
-
typedrouter = new plugins.typedrequest.TypedRouter();
|
|
6
|
-
constructor(opsServerRef) {
|
|
7
|
-
this.opsServerRef = opsServerRef;
|
|
8
|
-
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
|
9
|
-
this.registerHandlers();
|
|
10
|
-
}
|
|
11
|
-
registerHandlers() {
|
|
12
|
-
// Get Certificate Overview
|
|
13
|
-
this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('getCertificateOverview', async (dataArg) => {
|
|
14
|
-
const certificates = await this.buildCertificateOverview();
|
|
15
|
-
const summary = this.buildSummary(certificates);
|
|
16
|
-
return { certificates, summary };
|
|
17
|
-
}));
|
|
18
|
-
// Legacy route-based reprovision (backward compat)
|
|
19
|
-
this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('reprovisionCertificate', async (dataArg) => {
|
|
20
|
-
return this.reprovisionCertificateByRoute(dataArg.routeName);
|
|
21
|
-
}));
|
|
22
|
-
// Domain-based reprovision (preferred)
|
|
23
|
-
this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('reprovisionCertificateDomain', async (dataArg) => {
|
|
24
|
-
return this.reprovisionCertificateDomain(dataArg.domain);
|
|
25
|
-
}));
|
|
26
|
-
// Delete certificate
|
|
27
|
-
this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('deleteCertificate', async (dataArg) => {
|
|
28
|
-
return this.deleteCertificate(dataArg.domain);
|
|
29
|
-
}));
|
|
30
|
-
// Export certificate
|
|
31
|
-
this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('exportCertificate', async (dataArg) => {
|
|
32
|
-
return this.exportCertificate(dataArg.domain);
|
|
33
|
-
}));
|
|
34
|
-
// Import certificate
|
|
35
|
-
this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('importCertificate', async (dataArg) => {
|
|
36
|
-
return this.importCertificate(dataArg.cert);
|
|
37
|
-
}));
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Build domain-centric certificate overview.
|
|
41
|
-
* Instead of one row per route, we produce one row per unique domain.
|
|
42
|
-
*/
|
|
43
|
-
async buildCertificateOverview() {
|
|
44
|
-
const dcRouter = this.opsServerRef.dcRouterRef;
|
|
45
|
-
const smartProxy = dcRouter.smartProxy;
|
|
46
|
-
if (!smartProxy)
|
|
47
|
-
return [];
|
|
48
|
-
const routes = smartProxy.routeManager.getRoutes();
|
|
49
|
-
// Phase 1: Collect unique domains with their associated route info
|
|
50
|
-
const domainMap = new Map();
|
|
51
|
-
for (const route of routes) {
|
|
52
|
-
if (!route.name)
|
|
53
|
-
continue;
|
|
54
|
-
const tls = route.action?.tls;
|
|
55
|
-
if (!tls)
|
|
56
|
-
continue;
|
|
57
|
-
// Skip passthrough routes - they don't manage certificates
|
|
58
|
-
if (tls.mode === 'passthrough')
|
|
59
|
-
continue;
|
|
60
|
-
const routeDomains = route.match.domains
|
|
61
|
-
? (Array.isArray(route.match.domains) ? route.match.domains : [route.match.domains])
|
|
62
|
-
: [];
|
|
63
|
-
// Determine source
|
|
64
|
-
let source = 'none';
|
|
65
|
-
if (tls.certificate === 'auto') {
|
|
66
|
-
if (smartProxy.settings.certProvisionFunction) {
|
|
67
|
-
source = 'provision-function';
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
source = 'acme';
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
else if (tls.certificate && typeof tls.certificate === 'object') {
|
|
74
|
-
source = 'static';
|
|
75
|
-
}
|
|
76
|
-
const canReprovision = source === 'acme' || source === 'provision-function';
|
|
77
|
-
const tlsMode = tls.mode;
|
|
78
|
-
for (const domain of routeDomains) {
|
|
79
|
-
const existing = domainMap.get(domain);
|
|
80
|
-
if (existing) {
|
|
81
|
-
// Add this route name to the existing domain entry
|
|
82
|
-
if (!existing.routeNames.includes(route.name)) {
|
|
83
|
-
existing.routeNames.push(route.name);
|
|
84
|
-
}
|
|
85
|
-
// Upgrade source if more specific
|
|
86
|
-
if (existing.source === 'none' && source !== 'none') {
|
|
87
|
-
existing.source = source;
|
|
88
|
-
existing.canReprovision = canReprovision;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
domainMap.set(domain, {
|
|
93
|
-
routeNames: [route.name],
|
|
94
|
-
source,
|
|
95
|
-
tlsMode,
|
|
96
|
-
canReprovision,
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
// Phase 2: Resolve status for each unique domain
|
|
102
|
-
const certificates = [];
|
|
103
|
-
for (const [domain, info] of domainMap) {
|
|
104
|
-
let status = 'unknown';
|
|
105
|
-
let expiryDate;
|
|
106
|
-
let issuedAt;
|
|
107
|
-
let issuer;
|
|
108
|
-
let error;
|
|
109
|
-
// Check event-based status from certificateStatusMap (now keyed by domain)
|
|
110
|
-
const eventStatus = dcRouter.certificateStatusMap.get(domain);
|
|
111
|
-
if (eventStatus) {
|
|
112
|
-
status = eventStatus.status;
|
|
113
|
-
expiryDate = eventStatus.expiryDate;
|
|
114
|
-
issuedAt = eventStatus.issuedAt;
|
|
115
|
-
error = eventStatus.error;
|
|
116
|
-
if (eventStatus.source) {
|
|
117
|
-
issuer = eventStatus.source;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
// Try SmartProxy certificate status if no event data
|
|
121
|
-
if (status === 'unknown' && info.routeNames.length > 0) {
|
|
122
|
-
try {
|
|
123
|
-
const rustStatus = await smartProxy.getCertificateStatus(info.routeNames[0]);
|
|
124
|
-
if (rustStatus) {
|
|
125
|
-
if (rustStatus.expiryDate)
|
|
126
|
-
expiryDate = rustStatus.expiryDate;
|
|
127
|
-
if (rustStatus.issuer)
|
|
128
|
-
issuer = rustStatus.issuer;
|
|
129
|
-
if (rustStatus.issuedAt)
|
|
130
|
-
issuedAt = rustStatus.issuedAt;
|
|
131
|
-
if (rustStatus.status === 'valid' || rustStatus.status === 'expired') {
|
|
132
|
-
status = rustStatus.status;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
catch {
|
|
137
|
-
// Rust bridge may not support this command yet — ignore
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
// Check persisted cert data from StorageManager
|
|
141
|
-
if (status === 'unknown') {
|
|
142
|
-
const cleanDomain = domain.replace(/^\*\.?/, '');
|
|
143
|
-
let certData = await dcRouter.storageManager.getJSON(`/certs/${cleanDomain}`);
|
|
144
|
-
if (!certData) {
|
|
145
|
-
// Also check certStore path (proxy-certs)
|
|
146
|
-
certData = await dcRouter.storageManager.getJSON(`/proxy-certs/${domain}`);
|
|
147
|
-
}
|
|
148
|
-
if (certData?.validUntil) {
|
|
149
|
-
expiryDate = new Date(certData.validUntil).toISOString();
|
|
150
|
-
if (certData.created) {
|
|
151
|
-
issuedAt = new Date(certData.created).toISOString();
|
|
152
|
-
}
|
|
153
|
-
issuer = 'smartacme-dns-01';
|
|
154
|
-
}
|
|
155
|
-
else if (certData?.publicKey) {
|
|
156
|
-
// certStore has the cert — parse PEM for expiry
|
|
157
|
-
try {
|
|
158
|
-
const x509 = new plugins.crypto.X509Certificate(certData.publicKey);
|
|
159
|
-
expiryDate = new Date(x509.validTo).toISOString();
|
|
160
|
-
issuedAt = new Date(x509.validFrom).toISOString();
|
|
161
|
-
}
|
|
162
|
-
catch { /* PEM parsing failed */ }
|
|
163
|
-
status = 'valid';
|
|
164
|
-
issuer = 'cert-store';
|
|
165
|
-
}
|
|
166
|
-
else if (certData) {
|
|
167
|
-
status = 'valid';
|
|
168
|
-
issuer = 'cert-store';
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
// Compute status from expiry date
|
|
172
|
-
if (expiryDate && (status === 'valid' || status === 'unknown')) {
|
|
173
|
-
const expiry = new Date(expiryDate);
|
|
174
|
-
const now = new Date();
|
|
175
|
-
const daysUntilExpiry = (expiry.getTime() - now.getTime()) / (1000 * 60 * 60 * 24);
|
|
176
|
-
if (daysUntilExpiry < 0) {
|
|
177
|
-
status = 'expired';
|
|
178
|
-
}
|
|
179
|
-
else if (daysUntilExpiry < 30) {
|
|
180
|
-
status = 'expiring';
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
status = 'valid';
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
// Static certs with no other info default to 'valid'
|
|
187
|
-
if (info.source === 'static' && status === 'unknown') {
|
|
188
|
-
status = 'valid';
|
|
189
|
-
}
|
|
190
|
-
// ACME/provision-function routes with no cert data are still provisioning
|
|
191
|
-
if (status === 'unknown' && (info.source === 'acme' || info.source === 'provision-function')) {
|
|
192
|
-
status = 'provisioning';
|
|
193
|
-
}
|
|
194
|
-
// Phase 3: Attach backoff info
|
|
195
|
-
let backoffInfo;
|
|
196
|
-
if (dcRouter.certProvisionScheduler) {
|
|
197
|
-
const bi = await dcRouter.certProvisionScheduler.getBackoffInfo(domain);
|
|
198
|
-
if (bi) {
|
|
199
|
-
backoffInfo = bi;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
certificates.push({
|
|
203
|
-
domain,
|
|
204
|
-
routeNames: info.routeNames,
|
|
205
|
-
status,
|
|
206
|
-
source: info.source,
|
|
207
|
-
tlsMode: info.tlsMode,
|
|
208
|
-
expiryDate,
|
|
209
|
-
issuer,
|
|
210
|
-
issuedAt,
|
|
211
|
-
error,
|
|
212
|
-
canReprovision: info.canReprovision,
|
|
213
|
-
backoffInfo,
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
return certificates;
|
|
217
|
-
}
|
|
218
|
-
buildSummary(certificates) {
|
|
219
|
-
const summary = { total: 0, valid: 0, expiring: 0, expired: 0, failed: 0, unknown: 0 };
|
|
220
|
-
summary.total = certificates.length;
|
|
221
|
-
for (const cert of certificates) {
|
|
222
|
-
switch (cert.status) {
|
|
223
|
-
case 'valid':
|
|
224
|
-
summary.valid++;
|
|
225
|
-
break;
|
|
226
|
-
case 'expiring':
|
|
227
|
-
summary.expiring++;
|
|
228
|
-
break;
|
|
229
|
-
case 'expired':
|
|
230
|
-
summary.expired++;
|
|
231
|
-
break;
|
|
232
|
-
case 'failed':
|
|
233
|
-
summary.failed++;
|
|
234
|
-
break;
|
|
235
|
-
case 'provisioning': // count as unknown
|
|
236
|
-
case 'unknown':
|
|
237
|
-
summary.unknown++;
|
|
238
|
-
break;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
return summary;
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Legacy route-based reprovisioning
|
|
245
|
-
*/
|
|
246
|
-
async reprovisionCertificateByRoute(routeName) {
|
|
247
|
-
const dcRouter = this.opsServerRef.dcRouterRef;
|
|
248
|
-
const smartProxy = dcRouter.smartProxy;
|
|
249
|
-
if (!smartProxy) {
|
|
250
|
-
return { success: false, message: 'SmartProxy is not running' };
|
|
251
|
-
}
|
|
252
|
-
try {
|
|
253
|
-
await smartProxy.provisionCertificate(routeName);
|
|
254
|
-
// Clear event-based status for domains in this route
|
|
255
|
-
for (const [domain, entry] of dcRouter.certificateStatusMap) {
|
|
256
|
-
if (entry.routeNames.includes(routeName)) {
|
|
257
|
-
dcRouter.certificateStatusMap.delete(domain);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
return { success: true, message: `Certificate reprovisioning triggered for route '${routeName}'` };
|
|
261
|
-
}
|
|
262
|
-
catch (err) {
|
|
263
|
-
return { success: false, message: err.message || 'Failed to reprovision certificate' };
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Domain-based reprovisioning — clears backoff first, then triggers provision
|
|
268
|
-
*/
|
|
269
|
-
async reprovisionCertificateDomain(domain) {
|
|
270
|
-
const dcRouter = this.opsServerRef.dcRouterRef;
|
|
271
|
-
const smartProxy = dcRouter.smartProxy;
|
|
272
|
-
if (!smartProxy) {
|
|
273
|
-
return { success: false, message: 'SmartProxy is not running' };
|
|
274
|
-
}
|
|
275
|
-
// Clear backoff for this domain (user override)
|
|
276
|
-
if (dcRouter.certProvisionScheduler) {
|
|
277
|
-
await dcRouter.certProvisionScheduler.clearBackoff(domain);
|
|
278
|
-
}
|
|
279
|
-
// Clear status map entry so it gets refreshed
|
|
280
|
-
dcRouter.certificateStatusMap.delete(domain);
|
|
281
|
-
// Try to provision via SmartAcme directly
|
|
282
|
-
if (dcRouter.smartAcme) {
|
|
283
|
-
try {
|
|
284
|
-
await dcRouter.smartAcme.getCertificateForDomain(domain);
|
|
285
|
-
return { success: true, message: `Certificate reprovisioning triggered for domain '${domain}'` };
|
|
286
|
-
}
|
|
287
|
-
catch (err) {
|
|
288
|
-
return { success: false, message: err.message || `Failed to reprovision certificate for ${domain}` };
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
// Fallback: try provisioning via the first matching route
|
|
292
|
-
const routeNames = dcRouter.findRouteNamesForDomain(domain);
|
|
293
|
-
if (routeNames.length > 0) {
|
|
294
|
-
try {
|
|
295
|
-
await smartProxy.provisionCertificate(routeNames[0]);
|
|
296
|
-
return { success: true, message: `Certificate reprovisioning triggered for domain '${domain}' via route '${routeNames[0]}'` };
|
|
297
|
-
}
|
|
298
|
-
catch (err) {
|
|
299
|
-
return { success: false, message: err.message || `Failed to reprovision certificate for ${domain}` };
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
return { success: false, message: `No routes found for domain '${domain}'` };
|
|
303
|
-
}
|
|
304
|
-
/**
|
|
305
|
-
* Delete certificate data for a domain from storage
|
|
306
|
-
*/
|
|
307
|
-
async deleteCertificate(domain) {
|
|
308
|
-
const dcRouter = this.opsServerRef.dcRouterRef;
|
|
309
|
-
const cleanDomain = domain.replace(/^\*\.?/, '');
|
|
310
|
-
// Delete from all known storage paths
|
|
311
|
-
const paths = [
|
|
312
|
-
`/proxy-certs/${domain}`,
|
|
313
|
-
`/proxy-certs/${cleanDomain}`,
|
|
314
|
-
`/certs/${cleanDomain}`,
|
|
315
|
-
];
|
|
316
|
-
for (const path of paths) {
|
|
317
|
-
try {
|
|
318
|
-
await dcRouter.storageManager.delete(path);
|
|
319
|
-
}
|
|
320
|
-
catch {
|
|
321
|
-
// Path may not exist — ignore
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
// Clear from in-memory status map
|
|
325
|
-
dcRouter.certificateStatusMap.delete(domain);
|
|
326
|
-
// Clear backoff info
|
|
327
|
-
if (dcRouter.certProvisionScheduler) {
|
|
328
|
-
await dcRouter.certProvisionScheduler.clearBackoff(domain);
|
|
329
|
-
}
|
|
330
|
-
return { success: true, message: `Certificate data deleted for '${domain}'` };
|
|
331
|
-
}
|
|
332
|
-
/**
|
|
333
|
-
* Export certificate data for a domain as ICert-shaped JSON
|
|
334
|
-
*/
|
|
335
|
-
async exportCertificate(domain) {
|
|
336
|
-
const dcRouter = this.opsServerRef.dcRouterRef;
|
|
337
|
-
const cleanDomain = domain.replace(/^\*\.?/, '');
|
|
338
|
-
// Try SmartAcme /certs/ path first (has full ICert fields)
|
|
339
|
-
let certData = await dcRouter.storageManager.getJSON(`/certs/${cleanDomain}`);
|
|
340
|
-
if (certData && certData.publicKey && certData.privateKey) {
|
|
341
|
-
return {
|
|
342
|
-
success: true,
|
|
343
|
-
cert: {
|
|
344
|
-
id: certData.id || plugins.crypto.randomUUID(),
|
|
345
|
-
domainName: certData.domainName || domain,
|
|
346
|
-
created: certData.created || Date.now(),
|
|
347
|
-
validUntil: certData.validUntil || 0,
|
|
348
|
-
privateKey: certData.privateKey,
|
|
349
|
-
publicKey: certData.publicKey,
|
|
350
|
-
csr: certData.csr || '',
|
|
351
|
-
},
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
// Fallback: try /proxy-certs/ with original domain
|
|
355
|
-
certData = await dcRouter.storageManager.getJSON(`/proxy-certs/${domain}`);
|
|
356
|
-
if (!certData || !certData.publicKey) {
|
|
357
|
-
// Try with clean domain
|
|
358
|
-
certData = await dcRouter.storageManager.getJSON(`/proxy-certs/${cleanDomain}`);
|
|
359
|
-
}
|
|
360
|
-
if (certData && certData.publicKey && certData.privateKey) {
|
|
361
|
-
return {
|
|
362
|
-
success: true,
|
|
363
|
-
cert: {
|
|
364
|
-
id: plugins.crypto.randomUUID(),
|
|
365
|
-
domainName: domain,
|
|
366
|
-
created: certData.validFrom || Date.now(),
|
|
367
|
-
validUntil: certData.validUntil || 0,
|
|
368
|
-
privateKey: certData.privateKey,
|
|
369
|
-
publicKey: certData.publicKey,
|
|
370
|
-
csr: '',
|
|
371
|
-
},
|
|
372
|
-
};
|
|
373
|
-
}
|
|
374
|
-
return { success: false, message: `No certificate data found for '${domain}'` };
|
|
375
|
-
}
|
|
376
|
-
/**
|
|
377
|
-
* Import a certificate from ICert-shaped JSON
|
|
378
|
-
*/
|
|
379
|
-
async importCertificate(cert) {
|
|
380
|
-
// Validate PEM content
|
|
381
|
-
if (!cert.publicKey || !cert.publicKey.includes('-----BEGIN CERTIFICATE-----')) {
|
|
382
|
-
return { success: false, message: 'Invalid publicKey: must contain a PEM-encoded certificate' };
|
|
383
|
-
}
|
|
384
|
-
if (!cert.privateKey || !cert.privateKey.includes('-----BEGIN')) {
|
|
385
|
-
return { success: false, message: 'Invalid privateKey: must contain a PEM-encoded key' };
|
|
386
|
-
}
|
|
387
|
-
const dcRouter = this.opsServerRef.dcRouterRef;
|
|
388
|
-
const cleanDomain = cert.domainName.replace(/^\*\.?/, '');
|
|
389
|
-
// Save to /certs/ (SmartAcme-compatible path)
|
|
390
|
-
await dcRouter.storageManager.setJSON(`/certs/${cleanDomain}`, {
|
|
391
|
-
id: cert.id,
|
|
392
|
-
domainName: cert.domainName,
|
|
393
|
-
created: cert.created,
|
|
394
|
-
validUntil: cert.validUntil,
|
|
395
|
-
privateKey: cert.privateKey,
|
|
396
|
-
publicKey: cert.publicKey,
|
|
397
|
-
csr: cert.csr || '',
|
|
398
|
-
});
|
|
399
|
-
// Also save to /proxy-certs/ (proxy-cert format)
|
|
400
|
-
await dcRouter.storageManager.setJSON(`/proxy-certs/${cert.domainName}`, {
|
|
401
|
-
domain: cert.domainName,
|
|
402
|
-
publicKey: cert.publicKey,
|
|
403
|
-
privateKey: cert.privateKey,
|
|
404
|
-
ca: undefined,
|
|
405
|
-
validUntil: cert.validUntil,
|
|
406
|
-
validFrom: cert.created,
|
|
407
|
-
});
|
|
408
|
-
// Update in-memory status map
|
|
409
|
-
dcRouter.certificateStatusMap.set(cert.domainName, {
|
|
410
|
-
status: 'valid',
|
|
411
|
-
source: 'static',
|
|
412
|
-
expiryDate: cert.validUntil ? new Date(cert.validUntil).toISOString() : undefined,
|
|
413
|
-
issuedAt: cert.created ? new Date(cert.created).toISOString() : undefined,
|
|
414
|
-
routeNames: [],
|
|
415
|
-
});
|
|
416
|
-
return { success: true, message: `Certificate imported for '${cert.domainName}'` };
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydGlmaWNhdGUuaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3RzL29wc3NlcnZlci9oYW5kbGVycy9jZXJ0aWZpY2F0ZS5oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFFNUMsT0FBTyxLQUFLLFVBQVUsTUFBTSxpQ0FBaUMsQ0FBQztBQUU5RCxNQUFNLE9BQU8sa0JBQWtCO0lBR1Q7SUFGYixXQUFXLEdBQUcsSUFBSSxPQUFPLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBRTVELFlBQW9CLFlBQXVCO1FBQXZCLGlCQUFZLEdBQVosWUFBWSxDQUFXO1FBQ3pDLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDL0QsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVPLGdCQUFnQjtRQUN0QiwyQkFBMkI7UUFDM0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQzlCLElBQUksT0FBTyxDQUFDLFlBQVksQ0FBQyxZQUFZLENBQ25DLHdCQUF3QixFQUN4QixLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7WUFDaEIsTUFBTSxZQUFZLEdBQUcsTUFBTSxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztZQUMzRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ2hELE9BQU8sRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLENBQUM7UUFDbkMsQ0FBQyxDQUNGLENBQ0YsQ0FBQztRQUVGLG1EQUFtRDtRQUNuRCxJQUFJLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FDOUIsSUFBSSxPQUFPLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FDbkMsd0JBQXdCLEVBQ3hCLEtBQUssRUFBRSxPQUFPLEVB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
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../../plugins.js';
|
|
2
|
-
import type { OpsServer } from '../classes.opsserver.js';
|
|
3
|
-
export declare class ConfigHandler {
|
|
4
|
-
private opsServerRef;
|
|
5
|
-
typedrouter: plugins.typedrequest.TypedRouter;
|
|
6
|
-
constructor(opsServerRef: OpsServer);
|
|
7
|
-
private registerHandlers;
|
|
8
|
-
private getConfiguration;
|
|
9
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../../plugins.js';
|
|
2
|
-
import * as interfaces from '../../../dist_ts_interfaces/index.js';
|
|
3
|
-
export class ConfigHandler {
|
|
4
|
-
opsServerRef;
|
|
5
|
-
typedrouter = new plugins.typedrequest.TypedRouter();
|
|
6
|
-
constructor(opsServerRef) {
|
|
7
|
-
this.opsServerRef = opsServerRef;
|
|
8
|
-
// Add this handler's router to the parent
|
|
9
|
-
this.opsServerRef.typedrouter.addTypedRouter(this.typedrouter);
|
|
10
|
-
this.registerHandlers();
|
|
11
|
-
}
|
|
12
|
-
registerHandlers() {
|
|
13
|
-
// Get Configuration Handler (read-only)
|
|
14
|
-
this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('getConfiguration', async (dataArg, toolsArg) => {
|
|
15
|
-
const config = await this.getConfiguration(dataArg.section);
|
|
16
|
-
return {
|
|
17
|
-
config,
|
|
18
|
-
section: dataArg.section,
|
|
19
|
-
};
|
|
20
|
-
}));
|
|
21
|
-
}
|
|
22
|
-
async getConfiguration(section) {
|
|
23
|
-
const dcRouter = this.opsServerRef.dcRouterRef;
|
|
24
|
-
// Get email domains if email server is configured
|
|
25
|
-
let emailDomains = [];
|
|
26
|
-
if (dcRouter.emailServer && dcRouter.emailServer.domainRegistry) {
|
|
27
|
-
emailDomains = dcRouter.emailServer.domainRegistry.getAllDomains();
|
|
28
|
-
}
|
|
29
|
-
else if (dcRouter.options.emailConfig?.domains) {
|
|
30
|
-
// Fallback: get domains from email config options
|
|
31
|
-
emailDomains = dcRouter.options.emailConfig.domains.map(d => typeof d === 'string' ? d : d.domain);
|
|
32
|
-
}
|
|
33
|
-
return {
|
|
34
|
-
email: {
|
|
35
|
-
enabled: !!dcRouter.emailServer,
|
|
36
|
-
ports: dcRouter.emailServer ? [25, 465, 587, 2525] : [],
|
|
37
|
-
maxMessageSize: 10 * 1024 * 1024, // 10MB default
|
|
38
|
-
rateLimits: {
|
|
39
|
-
perMinute: 10,
|
|
40
|
-
perHour: 100,
|
|
41
|
-
perDay: 1000,
|
|
42
|
-
},
|
|
43
|
-
domains: emailDomains,
|
|
44
|
-
},
|
|
45
|
-
dns: {
|
|
46
|
-
enabled: !!dcRouter.dnsServer,
|
|
47
|
-
port: 53,
|
|
48
|
-
nameservers: dcRouter.options.dnsNsDomains || [],
|
|
49
|
-
caching: true,
|
|
50
|
-
ttl: 300,
|
|
51
|
-
},
|
|
52
|
-
proxy: {
|
|
53
|
-
enabled: !!dcRouter.smartProxy,
|
|
54
|
-
httpPort: 80,
|
|
55
|
-
httpsPort: 443,
|
|
56
|
-
maxConnections: 1000,
|
|
57
|
-
},
|
|
58
|
-
security: {
|
|
59
|
-
blockList: [],
|
|
60
|
-
rateLimit: true,
|
|
61
|
-
spamDetection: true,
|
|
62
|
-
tlsRequired: false,
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmhhbmRsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90cy9vcHNzZXJ2ZXIvaGFuZGxlcnMvY29uZmlnLmhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUU1QyxPQUFPLEtBQUssVUFBVSxNQUFNLGlDQUFpQyxDQUFDO0FBRTlELE1BQU0sT0FBTyxhQUFhO0lBR0o7SUFGYixXQUFXLEdBQUcsSUFBSSxPQUFPLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBRTVELFlBQW9CLFlBQXVCO1FBQXZCLGlCQUFZLEdBQVosWUFBWSxDQUFXO1FBQ3pDLDBDQUEwQztRQUMxQyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQy9ELElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFFTyxnQkFBZ0I7UUFDdEIsd0NBQXdDO1FBQ3hDLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUM5QixJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUNuQyxrQkFBa0IsRUFDbEIsS0FBSyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsRUFBRTtZQUMxQixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDNUQsT0FBTztnQkFDTCxNQUFNO2dCQUNOLE9BQU8sRUFBRSxPQUFPLENBQUMsT0FBTzthQUN6QixDQUFDO1FBQ0osQ0FBQyxDQUNGLENBQ0YsQ0FBQztJQUNKLENBQUM7SUFFTyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsT0FBZ0I7UUFnQzdDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDO1FBRS9DLGtEQUFrRDtRQUNsRCxJQUFJLFlBQVksR0FBYSxFQUFFLENBQUM7UUFDaEMsSUFBSSxRQUFRLENBQUMsV0FBVyxJQUFJLFFBQVEsQ0FBQyxXQUFXLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDaEUsWUFBWSxHQUFHLFFBQVEsQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3JFLENBQUM7YUFBTSxJQUFJLFFBQVEsQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLE9BQU8sRUFBRSxDQUFDO1lBQ2pELGtEQUFrRDtZQUNsRCxZQUFZLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUMxRCxPQUFPLENBQUMsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FDckMsQ0FBQztRQUNKLENBQUM7UUFFRCxPQUFPO1lBQ0wsS0FBSyxFQUFFO2dCQUNMLE9BQU8sRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLFdBQVc7Z0JBQy9CLEtBQUssRUFBRSxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUN2RCxjQUFjLEVBQUUsRUFBRSxHQUFHLElBQUksR0FBRyxJQUFJLEVBQUUsZUFBZTtnQkFDakQsVUFBVSxFQUFFO29CQUNWLFNBQVMsRUFBRSxFQUFFO29CQUNiLE9BQU8sRUFBRSxHQUFHO29CQUNaLE1BQU0sRUFBRSxJQUFJO2lCQUNiO2dCQUNELE9BQU8sRUFBRSxZQUFZO2FBQ3RCO1lBQ0QsR0FBRyxFQUFFO2dCQUNILE9BQU8sRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLFNBQVM7Z0JBQzdCLElBQUksRUFBRSxFQUFFO2dCQUNSLFdBQVcsRUFBRSxRQUFRLENBQUMsT0FBTyxDQUFDLFlBQVksSUFBSSxFQUFFO2dCQUNoRCxPQUFPLEVBQUUsSUFBSTtnQkFDYixHQUFHLEVBQUUsR0FBRzthQUNUO1lBQ0QsS0FBSyxFQUFFO2dCQUNMLE9BQU8sRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLFVBQVU7Z0JBQzlCLFFBQVEsRUFBRSxFQUFFO2dCQUNaLFNBQVMsRUFBRSxHQUFHO2dCQUNkLGNBQWMsRUFBRSxJQUFJO2FBQ3JCO1lBQ0QsUUFBUSxFQUFFO2dCQUNSLFNBQVMsRUFBRSxFQUFFO2dCQUNiLFNBQVMsRUFBRSxJQUFJO2dCQUNmLGFBQWEsRUFBRSxJQUFJO2dCQUNuQixXQUFXLEVBQUUsS0FBSzthQUNuQjtTQUNGLENBQUM7SUFDSixDQUFDO0NBQ0YifQ==
|