@serve.zone/dcrouter 13.42.3 → 13.43.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.
Files changed (44) hide show
  1. package/deno.json +11 -11
  2. package/dist_serve/bundle.js +722 -678
  3. package/dist_ts/00_commitinfo_data.js +1 -1
  4. package/dist_ts/classes.dcrouter.js +3 -3
  5. package/dist_ts/config/classes.route-config-manager.d.ts +4 -2
  6. package/dist_ts/config/classes.route-config-manager.js +17 -9
  7. package/dist_ts/config/classes.source-policy-compiler.d.ts +1 -0
  8. package/dist_ts/config/classes.source-policy-compiler.js +24 -2
  9. package/dist_ts/config/helpers.http-redirects.d.ts +10 -0
  10. package/dist_ts/config/helpers.http-redirects.js +387 -0
  11. package/dist_ts/config/index.d.ts +1 -0
  12. package/dist_ts/config/index.js +2 -1
  13. package/dist_ts/opsserver/handlers/route-management.handler.js +10 -1
  14. package/dist_ts_interfaces/data/route-management.d.ts +20 -0
  15. package/dist_ts_interfaces/requests/route-management.d.ts +14 -1
  16. package/dist_ts_web/00_commitinfo_data.js +1 -1
  17. package/dist_ts_web/appstate.d.ts +2 -0
  18. package/dist_ts_web/appstate.js +28 -1
  19. package/dist_ts_web/elements/access/ops-view-apitokens.js +2 -1
  20. package/dist_ts_web/elements/access/ops-view-gatewayclients.js +2 -1
  21. package/dist_ts_web/elements/network/index.d.ts +1 -0
  22. package/dist_ts_web/elements/network/index.js +2 -1
  23. package/dist_ts_web/elements/network/ops-view-redirects.d.ts +18 -0
  24. package/dist_ts_web/elements/network/ops-view-redirects.js +236 -0
  25. package/dist_ts_web/elements/network/ops-view-routes.js +2 -1
  26. package/dist_ts_web/elements/ops-dashboard.js +3 -1
  27. package/dist_ts_web/router.js +2 -2
  28. package/package.json +1 -1
  29. package/ts/00_commitinfo_data.ts +1 -1
  30. package/ts/classes.dcrouter.ts +2 -2
  31. package/ts/config/classes.route-config-manager.ts +22 -10
  32. package/ts/config/classes.source-policy-compiler.ts +33 -1
  33. package/ts/config/helpers.http-redirects.ts +462 -0
  34. package/ts/config/index.ts +1 -0
  35. package/ts/opsserver/handlers/route-management.handler.ts +15 -0
  36. package/ts_web/00_commitinfo_data.ts +1 -1
  37. package/ts_web/appstate.ts +32 -0
  38. package/ts_web/elements/access/ops-view-apitokens.ts +1 -0
  39. package/ts_web/elements/access/ops-view-gatewayclients.ts +1 -0
  40. package/ts_web/elements/network/index.ts +1 -0
  41. package/ts_web/elements/network/ops-view-redirects.ts +202 -0
  42. package/ts_web/elements/network/ops-view-routes.ts +1 -0
  43. package/ts_web/elements/ops-dashboard.ts +2 -0
  44. package/ts_web/router.ts +1 -1
@@ -0,0 +1,387 @@
1
+ import * as plugins from '../plugins.js';
2
+ const AUTO_REDIRECT_ROUTE_PREFIX = 'dcrouter-auto-http-redirect';
3
+ const REDIRECT_STATUS_CODE = 301;
4
+ const REDIRECT_PRIORITY = 0;
5
+ const REDIRECT_TARGET_TEMPLATE = 'https://{domain}{path}';
6
+ const REDIRECT_INITIAL_DATA_TIMEOUT_MS = 10_000;
7
+ export function deriveHttpRedirectConfiguration(routes) {
8
+ const candidates = collectRedirectCandidates(routes);
9
+ const httpRoutes = routes.filter((route) => isExplicitHttpRoute(route));
10
+ const redirects = [];
11
+ const runtimeRoutes = [];
12
+ for (const candidate of candidates) {
13
+ const conflict = findHttpConflict(candidate, httpRoutes);
14
+ const redirectInfo = {
15
+ id: candidate.id,
16
+ status: conflict ? (conflict.covers ? 'covered' : 'skipped') : 'active',
17
+ domainPattern: candidate.domainPattern,
18
+ pathPattern: candidate.pathPattern,
19
+ fromTemplate: 'http://{domain}{path}',
20
+ toTemplate: REDIRECT_TARGET_TEMPLATE,
21
+ statusCode: REDIRECT_STATUS_CODE,
22
+ priority: REDIRECT_PRIORITY,
23
+ sourceRouteNames: [...candidate.sourceRouteNames].sort(),
24
+ sourceRouteIds: [...candidate.sourceRouteIds].sort(),
25
+ coveredByRouteNames: conflict ? [conflict.routeName] : [],
26
+ remoteIngress: Boolean(candidate.remoteIngress?.enabled),
27
+ notes: conflict
28
+ ? conflict.covers
29
+ ? 'An explicit HTTP route already covers this redirect scope.'
30
+ : 'Skipped because an explicit HTTP route overlaps this redirect scope.'
31
+ : undefined,
32
+ };
33
+ redirects.push(redirectInfo);
34
+ if (redirectInfo.status === 'active') {
35
+ runtimeRoutes.push(buildRuntimeRedirectRoute(candidate));
36
+ }
37
+ }
38
+ return { redirects, runtimeRoutes };
39
+ }
40
+ export function deriveHttpRedirects(routes) {
41
+ return deriveHttpRedirectConfiguration(routes).redirects;
42
+ }
43
+ export function buildHttpRedirectRuntimeRoutes(routes) {
44
+ return deriveHttpRedirectConfiguration(routes).runtimeRoutes;
45
+ }
46
+ function collectRedirectCandidates(routes) {
47
+ const candidates = new Map();
48
+ for (const route of routes) {
49
+ if (!isHttpsRedirectSource(route)) {
50
+ continue;
51
+ }
52
+ for (const domainPattern of getDomainPatterns(route)) {
53
+ const key = createRedirectKey(domainPattern, route.match.path);
54
+ const existing = candidates.get(key);
55
+ if (existing) {
56
+ existing.sourceRouteNames.add(getRouteDisplayName(route));
57
+ if (route.id)
58
+ existing.sourceRouteIds.add(route.id);
59
+ existing.remoteIngress = mergeRemoteIngress(existing.remoteIngress, route.remoteIngress);
60
+ continue;
61
+ }
62
+ const id = createRedirectRouteName(domainPattern, route.match.path);
63
+ candidates.set(key, {
64
+ key,
65
+ id,
66
+ domainPattern,
67
+ pathPattern: route.match.path,
68
+ sourceRouteNames: new Set([getRouteDisplayName(route)]),
69
+ sourceRouteIds: new Set(route.id ? [route.id] : []),
70
+ remoteIngress: mergeRemoteIngress(undefined, route.remoteIngress),
71
+ });
72
+ }
73
+ }
74
+ return [...candidates.values()].sort((a, b) => a.id.localeCompare(b.id));
75
+ }
76
+ function isHttpsRedirectSource(route) {
77
+ if (isGeneratedRedirectRoute(route))
78
+ return false;
79
+ if (route.enabled === false)
80
+ return false;
81
+ if (route.action.type !== 'forward')
82
+ return false;
83
+ if (!route.match.ports)
84
+ return false;
85
+ if (!plugins.smartproxy.portRangeIncludes(route.match.ports, 443))
86
+ return false;
87
+ if (!route.action.tls)
88
+ return false;
89
+ if (!route.match.domains)
90
+ return false;
91
+ if (route.match.transport === 'udp')
92
+ return false;
93
+ if (route.match.protocol && route.match.protocol !== 'http')
94
+ return false;
95
+ if (route.match.clientIp || route.match.headers || route.match.tlsVersion)
96
+ return false;
97
+ return true;
98
+ }
99
+ function isExplicitHttpRoute(route) {
100
+ if (isGeneratedRedirectRoute(route))
101
+ return false;
102
+ if (route.enabled === false)
103
+ return false;
104
+ if (!route.match.ports)
105
+ return false;
106
+ if (!plugins.smartproxy.portRangeIncludes(route.match.ports, 80))
107
+ return false;
108
+ if (route.match.transport === 'udp')
109
+ return false;
110
+ return true;
111
+ }
112
+ function findHttpConflict(candidate, httpRoutes) {
113
+ for (const route of httpRoutes) {
114
+ if (!httpRouteOverlapsCandidate(route, candidate)) {
115
+ continue;
116
+ }
117
+ return {
118
+ routeName: getRouteDisplayName(route),
119
+ covers: httpRouteCoversCandidate(route, candidate),
120
+ };
121
+ }
122
+ return undefined;
123
+ }
124
+ function httpRouteOverlapsCandidate(route, candidate) {
125
+ return routeDomainOverlapsCandidate(route, candidate.domainPattern)
126
+ && pathOverlaps(route.match.path, candidate.pathPattern);
127
+ }
128
+ function httpRouteCoversCandidate(route, candidate) {
129
+ if (route.match.clientIp || route.match.headers || route.match.tlsVersion) {
130
+ return false;
131
+ }
132
+ return routeDomainCoversCandidate(route, candidate.domainPattern)
133
+ && pathCovers(route.match.path, candidate.pathPattern);
134
+ }
135
+ function routeDomainOverlapsCandidate(route, candidatePattern) {
136
+ const routePatterns = getDomainPatterns(route);
137
+ if (routePatterns.length === 0) {
138
+ return true;
139
+ }
140
+ return routePatterns.some((pattern) => domainPatternsOverlap(pattern, candidatePattern));
141
+ }
142
+ function routeDomainCoversCandidate(route, candidatePattern) {
143
+ const routePatterns = getDomainPatterns(route);
144
+ if (routePatterns.length === 0) {
145
+ return true;
146
+ }
147
+ return routePatterns.some((pattern) => domainPatternCovers(pattern, candidatePattern));
148
+ }
149
+ function getDomainPatterns(route) {
150
+ if (!route.match.domains)
151
+ return [];
152
+ return Array.isArray(route.match.domains) ? route.match.domains : [route.match.domains];
153
+ }
154
+ function normalizePattern(pattern) {
155
+ return pattern.trim().toLowerCase().replace(/\.$/, '');
156
+ }
157
+ function domainPatternCovers(coverPattern, candidatePattern) {
158
+ const cover = normalizePattern(coverPattern);
159
+ const candidate = normalizePattern(candidatePattern);
160
+ if (cover === candidate)
161
+ return true;
162
+ if (!candidate.includes('*'))
163
+ return domainPatternMatchesHostname(cover, candidate);
164
+ const coverSuffix = getLeadingWildcardSuffix(cover);
165
+ const candidateSuffix = getLeadingWildcardSuffix(candidate);
166
+ if (coverSuffix && candidateSuffix) {
167
+ return candidateSuffix.endsWith(coverSuffix);
168
+ }
169
+ return false;
170
+ }
171
+ function domainPatternsOverlap(firstPattern, secondPattern) {
172
+ const first = normalizePattern(firstPattern);
173
+ const second = normalizePattern(secondPattern);
174
+ if (first === second)
175
+ return true;
176
+ if (!first.includes('*'))
177
+ return domainPatternMatchesHostname(second, first);
178
+ if (!second.includes('*'))
179
+ return domainPatternMatchesHostname(first, second);
180
+ const firstSuffix = getLeadingWildcardSuffix(first);
181
+ const secondSuffix = getLeadingWildcardSuffix(second);
182
+ if (firstSuffix && secondSuffix) {
183
+ return firstSuffix.endsWith(secondSuffix) || secondSuffix.endsWith(firstSuffix);
184
+ }
185
+ return false;
186
+ }
187
+ function domainPatternMatchesHostname(pattern, hostname) {
188
+ const regex = wildcardPatternToRegex(normalizePattern(pattern));
189
+ return regex.test(normalizePattern(hostname));
190
+ }
191
+ function wildcardPatternToRegex(pattern) {
192
+ const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&');
193
+ return new RegExp(`^${escaped.replace(/\*/g, '.*')}$`, 'i');
194
+ }
195
+ function getLeadingWildcardSuffix(pattern) {
196
+ if (!pattern.startsWith('*'))
197
+ return undefined;
198
+ if (pattern.slice(1).includes('*'))
199
+ return undefined;
200
+ return pattern.slice(1);
201
+ }
202
+ function pathCovers(coverPath, candidatePath) {
203
+ if (!coverPath)
204
+ return true;
205
+ if (!candidatePath)
206
+ return false;
207
+ if (coverPath === candidatePath)
208
+ return true;
209
+ if (!coverPath.includes('*'))
210
+ return false;
211
+ const coverPrefix = coverPath.split('*')[0];
212
+ if (!candidatePath.includes('*'))
213
+ return candidatePath.startsWith(coverPrefix);
214
+ const candidatePrefix = candidatePath.split('*')[0];
215
+ return candidatePrefix.startsWith(coverPrefix);
216
+ }
217
+ function pathOverlaps(firstPath, secondPath) {
218
+ if (!firstPath || !secondPath)
219
+ return true;
220
+ if (firstPath === secondPath)
221
+ return true;
222
+ const firstPrefix = firstPath.split('*')[0];
223
+ const secondPrefix = secondPath.split('*')[0];
224
+ return firstPrefix.startsWith(secondPrefix) || secondPrefix.startsWith(firstPrefix);
225
+ }
226
+ function buildRuntimeRedirectRoute(candidate) {
227
+ return {
228
+ id: candidate.id,
229
+ name: candidate.id,
230
+ description: 'Generated HTTP to HTTPS redirect',
231
+ priority: REDIRECT_PRIORITY,
232
+ tags: ['system', 'redirect', 'auto'],
233
+ match: {
234
+ ports: 80,
235
+ domains: candidate.domainPattern,
236
+ ...(candidate.pathPattern ? { path: candidate.pathPattern } : {}),
237
+ },
238
+ action: {
239
+ type: 'socket-handler',
240
+ socketHandler: createHttpRedirectHandler(REDIRECT_TARGET_TEMPLATE, REDIRECT_STATUS_CODE),
241
+ },
242
+ ...(candidate.remoteIngress ? { remoteIngress: candidate.remoteIngress } : {}),
243
+ };
244
+ }
245
+ function mergeRemoteIngress(current, next) {
246
+ if (!next?.enabled)
247
+ return current;
248
+ if (!current?.enabled) {
249
+ return {
250
+ enabled: true,
251
+ ...(next.edgeFilter?.length ? { edgeFilter: [...next.edgeFilter] } : {}),
252
+ };
253
+ }
254
+ const currentFilter = current.edgeFilter || [];
255
+ const nextFilter = next.edgeFilter || [];
256
+ if (currentFilter.length === 0 || nextFilter.length === 0) {
257
+ return { enabled: true };
258
+ }
259
+ return {
260
+ enabled: true,
261
+ edgeFilter: [...new Set([...currentFilter, ...nextFilter])].sort(),
262
+ };
263
+ }
264
+ function createRedirectKey(domainPattern, pathPattern) {
265
+ return `${normalizePattern(domainPattern)}|${pathPattern || ''}`;
266
+ }
267
+ function createRedirectRouteName(domainPattern, pathPattern) {
268
+ const key = createRedirectKey(domainPattern, pathPattern);
269
+ const slug = key
270
+ .replace(/\*/g, 'wildcard')
271
+ .replace(/[^a-zA-Z0-9]+/g, '-')
272
+ .replace(/^-+|-+$/g, '')
273
+ .slice(0, 48) || 'route';
274
+ const hash = plugins.crypto.createHash('sha1').update(key).digest('hex').slice(0, 8);
275
+ return `${AUTO_REDIRECT_ROUTE_PREFIX}-${slug}-${hash}`;
276
+ }
277
+ function getRouteDisplayName(route) {
278
+ return route.name || route.id || 'unnamed-route';
279
+ }
280
+ function isGeneratedRedirectRoute(route) {
281
+ return Boolean(route.name?.startsWith(AUTO_REDIRECT_ROUTE_PREFIX) || route.id?.startsWith(AUTO_REDIRECT_ROUTE_PREFIX));
282
+ }
283
+ function createHttpRedirectHandler(locationTemplate, statusCode) {
284
+ return (socket, context) => {
285
+ const cleanup = () => {
286
+ clearTimeout(timeout);
287
+ socket.removeListener('data', handleData);
288
+ socket.removeListener('error', cleanup);
289
+ socket.removeListener('close', cleanup);
290
+ };
291
+ const handleData = (data) => {
292
+ cleanup();
293
+ const request = parseHttpRequest(data);
294
+ if (!request) {
295
+ socket.end('HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n');
296
+ return;
297
+ }
298
+ const domain = normalizeHostHeader(request.headers.host) || context.domain || 'localhost';
299
+ const finalLocation = locationTemplate
300
+ .replace('{domain}', domain)
301
+ .replace('{port}', String(context.port))
302
+ .replace('{path}', request.path || '/')
303
+ .replace('{clientIp}', context.clientIp);
304
+ const message = `Redirecting to ${finalLocation}`;
305
+ const response = [
306
+ `HTTP/1.1 ${statusCode} ${getHttpStatusText(statusCode)}`,
307
+ `Location: ${finalLocation}`,
308
+ 'Content-Type: text/plain',
309
+ `Content-Length: ${message.length}`,
310
+ 'Connection: close',
311
+ '',
312
+ message,
313
+ ].join('\r\n');
314
+ socket.end(response);
315
+ };
316
+ const timeout = setTimeout(() => {
317
+ cleanup();
318
+ socket.end('HTTP/1.1 408 Request Timeout\r\nConnection: close\r\n\r\n');
319
+ }, REDIRECT_INITIAL_DATA_TIMEOUT_MS);
320
+ timeout.unref?.();
321
+ socket.once('data', handleData);
322
+ socket.once('error', cleanup);
323
+ socket.once('close', cleanup);
324
+ };
325
+ }
326
+ function parseHttpRequest(data) {
327
+ const requestText = typeof data === 'string' ? data : new TextDecoder().decode(data);
328
+ const headerEnd = requestText.indexOf('\r\n\r\n');
329
+ const headerText = headerEnd >= 0 ? requestText.slice(0, headerEnd) : requestText;
330
+ const lines = headerText.split('\r\n');
331
+ const [method, rawPath] = (lines[0] || '').split(' ');
332
+ if (!method || !rawPath)
333
+ return undefined;
334
+ const headers = {};
335
+ for (const line of lines.slice(1)) {
336
+ const colonIndex = line.indexOf(':');
337
+ if (colonIndex <= 0)
338
+ continue;
339
+ const key = line.slice(0, colonIndex).trim().toLowerCase();
340
+ const value = line.slice(colonIndex + 1).trim();
341
+ headers[key] = value;
342
+ }
343
+ return {
344
+ method,
345
+ path: normalizeRequestPath(rawPath),
346
+ headers,
347
+ };
348
+ }
349
+ function normalizeRequestPath(rawPath) {
350
+ if (rawPath.startsWith('http://') || rawPath.startsWith('https://')) {
351
+ try {
352
+ const url = new URL(rawPath);
353
+ return `${url.pathname}${url.search}` || '/';
354
+ }
355
+ catch {
356
+ return '/';
357
+ }
358
+ }
359
+ return rawPath.startsWith('/') ? rawPath : '/';
360
+ }
361
+ function normalizeHostHeader(hostHeader) {
362
+ if (!hostHeader)
363
+ return undefined;
364
+ const host = hostHeader.split(',')[0].trim();
365
+ if (!host || /[\s\x00-\x1f\x7f]/.test(host))
366
+ return undefined;
367
+ if (host.startsWith('[')) {
368
+ const bracketIndex = host.indexOf(']');
369
+ return bracketIndex > 0 ? host.slice(0, bracketIndex + 1) : undefined;
370
+ }
371
+ return host.replace(/:(80|443)$/, '');
372
+ }
373
+ function getHttpStatusText(statusCode) {
374
+ switch (statusCode) {
375
+ case 301:
376
+ return 'Moved Permanently';
377
+ case 302:
378
+ return 'Found';
379
+ case 307:
380
+ return 'Temporary Redirect';
381
+ case 308:
382
+ return 'Permanent Redirect';
383
+ default:
384
+ return 'Redirect';
385
+ }
386
+ }
387
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy5odHRwLXJlZGlyZWN0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL2NvbmZpZy9oZWxwZXJzLmh0dHAtcmVkaXJlY3RzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBSXpDLE1BQU0sMEJBQTBCLEdBQUcsNkJBQTZCLENBQUM7QUFDakUsTUFBTSxvQkFBb0IsR0FBRyxHQUFHLENBQUM7QUFDakMsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLENBQUM7QUFDNUIsTUFBTSx3QkFBd0IsR0FBRyx3QkFBd0IsQ0FBQztBQUMxRCxNQUFNLGdDQUFnQyxHQUFHLE1BQU0sQ0FBQztBQXNCaEQsTUFBTSxVQUFVLCtCQUErQixDQUM3QyxNQUF5QztJQUV6QyxNQUFNLFVBQVUsR0FBRyx5QkFBeUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNyRCxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBQ3hFLE1BQU0sU0FBUyxHQUF3QixFQUFFLENBQUM7SUFDMUMsTUFBTSxhQUFhLEdBQTJCLEVBQUUsQ0FBQztJQUVqRCxLQUFLLE1BQU0sU0FBUyxJQUFJLFVBQVUsRUFBRSxDQUFDO1FBQ25DLE1BQU0sUUFBUSxHQUFHLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUN6RCxNQUFNLFlBQVksR0FBc0I7WUFDdEMsRUFBRSxFQUFFLFNBQVMsQ0FBQyxFQUFFO1lBQ2hCLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUTtZQUN2RSxhQUFhLEVBQUUsU0FBUyxDQUFDLGFBQWE7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
@@ -4,5 +4,6 @@ export { ApiTokenManager } from './classes.api-token-manager.js';
4
4
  export { GatewayClientManager } from './classes.gateway-client-manager.js';
5
5
  export { ReferenceResolver } from './classes.reference-resolver.js';
6
6
  export { SourcePolicyCompiler } from './classes.source-policy-compiler.js';
7
+ export * from './helpers.http-redirects.js';
7
8
  export { DbSeeder } from './classes.db-seeder.js';
8
9
  export { TargetProfileManager } from './classes.target-profile-manager.js';
@@ -5,6 +5,7 @@ export { ApiTokenManager } from './classes.api-token-manager.js';
5
5
  export { GatewayClientManager } from './classes.gateway-client-manager.js';
6
6
  export { ReferenceResolver } from './classes.reference-resolver.js';
7
7
  export { SourcePolicyCompiler } from './classes.source-policy-compiler.js';
8
+ export * from './helpers.http-redirects.js';
8
9
  export { DbSeeder } from './classes.db-seeder.js';
9
10
  export { TargetProfileManager } from './classes.target-profile-manager.js';
10
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9jb25maWcvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0JBQStCO0FBQy9CLGNBQWMsZ0JBQWdCLENBQUM7QUFDL0IsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDdkUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzNFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzNFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQyJ9
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9jb25maWcvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0JBQStCO0FBQy9CLGNBQWMsZ0JBQWdCLENBQUM7QUFDL0IsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDdkUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzNFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3BFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzNFLGNBQWMsNkJBQTZCLENBQUM7QUFDNUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2xELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHFDQUFxQyxDQUFDIn0=
@@ -30,6 +30,15 @@ export class RouteManagementHandler {
30
30
  }
31
31
  return manager.getMergedRoutes();
32
32
  }));
33
+ // Get generated HTTP redirects
34
+ this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('getHttpRedirects', async (dataArg) => {
35
+ await this.requireAuth(dataArg, 'routes:read');
36
+ const manager = this.opsServerRef.dcRouterRef.routeConfigManager;
37
+ if (!manager) {
38
+ return { redirects: [] };
39
+ }
40
+ return { redirects: manager.getHttpRedirects() };
41
+ }));
33
42
  // Create route
34
43
  this.typedrouter.addTypedHandler(new plugins.typedrequest.TypedHandler('createRoute', async (dataArg) => {
35
44
  const userId = await this.requireAuth(dataArg, 'routes:write');
@@ -74,4 +83,4 @@ export class RouteManagementHandler {
74
83
  }));
75
84
  }
76
85
  }
77
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUtbWFuYWdlbWVudC5oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdHMvb3Bzc2VydmVyL2hhbmRsZXJzL3JvdXRlLW1hbmFnZW1lbnQuaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBRTVDLE9BQU8sS0FBSyxVQUFVLE1BQU0saUNBQWlDLENBQUM7QUFDOUQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRXBELE1BQU0sT0FBTyxzQkFBc0I7SUFHYjtJQUZiLFdBQVcsR0FBRyxJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7SUFFNUQsWUFBb0IsWUFBdUI7UUFBdkIsaUJBQVksR0FBWixZQUFZLENBQVc7UUFDekMsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMvRCxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssS0FBSyxDQUFDLFdBQVcsQ0FDdkIsT0FBb0UsRUFDcEUsYUFBOEM7UUFFOUMsTUFBTSxJQUFJLEdBQUcsTUFBTSxjQUFjLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxPQUFPLEVBQUU7WUFDNUQsS0FBSyxFQUFFLGFBQWE7WUFDcEIsb0JBQW9CLEVBQUUsYUFBYSxFQUFFLFFBQVEsQ0FBQyxRQUFRLENBQUM7U0FDeEQsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JCLENBQUM7SUFFTyxnQkFBZ0I7UUFDdEIsb0JBQW9CO1FBQ3BCLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUM5QixJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUNuQyxpQkFBaUIsRUFDakIsS0FBSyxFQUFFLE9BQU8s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
86
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUtbWFuYWdlbWVudC5oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdHMvb3Bzc2VydmVyL2hhbmRsZXJzL3JvdXRlLW1hbmFnZW1lbnQuaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBRTVDLE9BQU8sS0FBSyxVQUFVLE1BQU0saUNBQWlDLENBQUM7QUFDOUQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRXBELE1BQU0sT0FBTyxzQkFBc0I7SUFHYjtJQUZiLFdBQVcsR0FBRyxJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7SUFFNUQsWUFBb0IsWUFBdUI7UUFBdkIsaUJBQVksR0FBWixZQUFZLENBQVc7UUFDekMsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMvRCxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssS0FBSyxDQUFDLFdBQVcsQ0FDdkIsT0FBb0UsRUFDcEUsYUFBOEM7UUFFOUMsTUFBTSxJQUFJLEdBQUcsTUFBTSxjQUFjLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxPQUFPLEVBQUU7WUFDNUQsS0FBSyxFQUFFLGFBQWE7WUFDcEIsb0JBQW9CLEVBQUUsYUFBYSxFQUFFLFFBQVEsQ0FBQyxRQUFRLENBQUM7U0FDeEQsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JCLENBQUM7SUFFTyxnQkFBZ0I7UUFDdEIsb0JBQW9CO1FBQ3BCLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUM5QixJQUFJLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUNuQyxpQkFBaUIsRUFDakIsS0FBSyxFQUFFLE9BQU8s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
@@ -145,6 +145,26 @@ export interface IRouteWarning {
145
145
  routeName: string;
146
146
  message: string;
147
147
  }
148
+ export type THttpRedirectStatus = 'active' | 'covered' | 'skipped';
149
+ /**
150
+ * Derived HTTP-to-HTTPS redirect shown in the Ops UI.
151
+ * These entries are generated from configured HTTPS routes and are not stored as routes.
152
+ */
153
+ export interface IHttpRedirectInfo {
154
+ id: string;
155
+ status: THttpRedirectStatus;
156
+ domainPattern: string;
157
+ pathPattern?: string;
158
+ fromTemplate: string;
159
+ toTemplate: string;
160
+ statusCode: number;
161
+ priority: number;
162
+ sourceRouteNames: string[];
163
+ sourceRouteIds: string[];
164
+ coveredByRouteNames: string[];
165
+ remoteIngress: boolean;
166
+ notes?: string;
167
+ }
148
168
  /**
149
169
  * Public info about an API token (never includes the hash).
150
170
  */
@@ -1,6 +1,6 @@
1
1
  import * as plugins from '../plugins.js';
2
2
  import type * as authInterfaces from '../data/auth.js';
3
- import type { IMergedRoute, IRouteWarning, IRouteMetadata } from '../data/route-management.js';
3
+ import type { IHttpRedirectInfo, IMergedRoute, IRouteWarning, IRouteMetadata } from '../data/route-management.js';
4
4
  import type { IDcRouterRouteConfig } from '../data/remoteingress.js';
5
5
  /**
6
6
  * Get all routes with warnings.
@@ -16,6 +16,19 @@ export interface IReq_GetMergedRoutes extends plugins.typedrequestInterfaces.imp
16
16
  warnings: IRouteWarning[];
17
17
  };
18
18
  }
19
+ /**
20
+ * Get derived HTTP-to-HTTPS redirects.
21
+ */
22
+ export interface IReq_GetHttpRedirects extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_GetHttpRedirects> {
23
+ method: 'getHttpRedirects';
24
+ request: {
25
+ identity?: authInterfaces.IIdentity;
26
+ apiToken?: string;
27
+ };
28
+ response: {
29
+ redirects: IHttpRedirectInfo[];
30
+ };
31
+ }
19
32
  /**
20
33
  * Create a new route.
21
34
  */
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@serve.zone/dcrouter',
6
- version: '13.42.3',
6
+ version: '13.43.0',
7
7
  description: 'A multifaceted routing service handling mail and SMS delivery functions.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfd2ViLzAwX2NvbW1pdGluZm9fZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRztJQUN4QixJQUFJLEVBQUUsc0JBQXNCO0lBQzVCLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLFdBQVcsRUFBRSwwRUFBMEU7Q0FDeEYsQ0FBQSJ9
@@ -142,6 +142,7 @@ export declare const remoteIngressStatePart: plugins.deesElement.domtools.plugin
142
142
  export interface IRouteManagementState {
143
143
  mergedRoutes: interfaces.data.IMergedRoute[];
144
144
  warnings: interfaces.data.IRouteWarning[];
145
+ httpRedirects: interfaces.data.IHttpRedirectInfo[];
145
146
  apiTokens: interfaces.data.IApiTokenInfo[];
146
147
  gatewayClients: interfaces.data.IGatewayClient[];
147
148
  isLoading: boolean;
@@ -476,6 +477,7 @@ export declare const updateAcmeConfigAction: plugins.deesElement.domtools.plugin
476
477
  renewThresholdDays?: number;
477
478
  }>;
478
479
  export declare const fetchMergedRoutesAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IRouteManagementState, unknown>;
480
+ export declare const fetchHttpRedirectsAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IRouteManagementState, unknown>;
479
481
  export declare const createRouteAction: plugins.deesElement.domtools.plugins.smartstate.StateAction<IRouteManagementState, {
480
482
  route: any;
481
483
  enabled?: boolean;