@serve.zone/dcrouter 11.12.4 → 11.14.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 +705 -548
- package/dist_ts_interfaces/data/index.d.ts +1 -0
- package/dist_ts_interfaces/data/index.js +2 -1
- package/dist_ts_interfaces/data/remoteingress.d.ts +10 -1
- package/dist_ts_interfaces/data/vpn.d.ts +43 -0
- package/dist_ts_interfaces/data/vpn.js +2 -0
- package/dist_ts_interfaces/requests/index.d.ts +1 -0
- package/dist_ts_interfaces/requests/index.js +2 -1
- package/dist_ts_interfaces/requests/vpn.d.ts +135 -0
- package/dist_ts_interfaces/requests/vpn.js +3 -0
- package/package.json +2 -1
- package/readme.md +107 -3
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.dcrouter.ts +126 -0
- package/ts/config/classes.route-config-manager.ts +20 -3
- package/ts/opsserver/classes.opsserver.ts +2 -0
- package/ts/opsserver/handlers/index.ts +2 -1
- package/ts/opsserver/handlers/vpn.handler.ts +257 -0
- package/ts/plugins.ts +2 -1
- package/ts/vpn/classes.vpn-manager.ts +378 -0
- package/ts/vpn/index.ts +1 -0
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/appstate.ts +164 -0
- package/ts_web/elements/index.ts +1 -0
- package/ts_web/elements/ops-dashboard.ts +6 -0
- package/ts_web/elements/ops-view-vpn.ts +330 -0
- package/ts_web/readme.md +17 -0
- package/ts_web/router.ts +1 -1
- package/dist_ts/00_commitinfo_data.d.ts +0 -8
- package/dist_ts/00_commitinfo_data.js +0 -9
- 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/classes.cert-provision-scheduler.d.ts +0 -54
- package/dist_ts/classes.cert-provision-scheduler.js +0 -118
- package/dist_ts/classes.dcrouter.d.ts +0 -356
- package/dist_ts/classes.dcrouter.js +0 -1592
- package/dist_ts/classes.storage-cert-manager.d.ts +0 -18
- package/dist_ts/classes.storage-cert-manager.js +0 -43
- package/dist_ts/config/classes.api-token-manager.d.ts +0 -46
- package/dist_ts/config/classes.api-token-manager.js +0 -150
- package/dist_ts/config/classes.route-config-manager.d.ts +0 -37
- package/dist_ts/config/classes.route-config-manager.js +0 -240
- package/dist_ts/config/index.d.ts +0 -3
- package/dist_ts/config/index.js +0 -5
- package/dist_ts/config/validator.d.ts +0 -104
- package/dist_ts/config/validator.js +0 -152
- package/dist_ts/errors/base.errors.d.ts +0 -224
- package/dist_ts/errors/base.errors.js +0 -320
- package/dist_ts/errors/error-handler.d.ts +0 -98
- package/dist_ts/errors/error-handler.js +0 -282
- package/dist_ts/errors/error.codes.d.ts +0 -115
- package/dist_ts/errors/error.codes.js +0 -136
- package/dist_ts/errors/index.d.ts +0 -54
- package/dist_ts/errors/index.js +0 -136
- package/dist_ts/errors/reputation.errors.d.ts +0 -183
- package/dist_ts/errors/reputation.errors.js +0 -292
- package/dist_ts/http3/http3-route-augmentation.d.ts +0 -50
- package/dist_ts/http3/http3-route-augmentation.js +0 -98
- package/dist_ts/http3/index.d.ts +0 -1
- package/dist_ts/http3/index.js +0 -2
- package/dist_ts/index.d.ts +0 -8
- package/dist_ts/index.js +0 -29
- package/dist_ts/logger.d.ts +0 -21
- package/dist_ts/logger.js +0 -81
- 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 -184
- package/dist_ts/monitoring/classes.metricsmanager.js +0 -744
- package/dist_ts/monitoring/index.d.ts +0 -1
- package/dist_ts/monitoring/index.js +0 -2
- package/dist_ts/opsserver/classes.opsserver.d.ts +0 -37
- package/dist_ts/opsserver/classes.opsserver.js +0 -85
- 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/api-token.handler.d.ts +0 -6
- package/dist_ts/opsserver/handlers/api-token.handler.js +0 -62
- package/dist_ts/opsserver/handlers/certificate.handler.d.ts +0 -32
- package/dist_ts/opsserver/handlers/certificate.handler.js +0 -421
- package/dist_ts/opsserver/handlers/config.handler.d.ts +0 -7
- package/dist_ts/opsserver/handlers/config.handler.js +0 -192
- package/dist_ts/opsserver/handlers/email-ops.handler.d.ts +0 -30
- package/dist_ts/opsserver/handlers/email-ops.handler.js +0 -227
- package/dist_ts/opsserver/handlers/index.d.ts +0 -11
- package/dist_ts/opsserver/handlers/index.js +0 -12
- package/dist_ts/opsserver/handlers/logs.handler.d.ts +0 -25
- package/dist_ts/opsserver/handlers/logs.handler.js +0 -256
- package/dist_ts/opsserver/handlers/radius.handler.d.ts +0 -6
- package/dist_ts/opsserver/handlers/radius.handler.js +0 -295
- package/dist_ts/opsserver/handlers/remoteingress.handler.d.ts +0 -6
- package/dist_ts/opsserver/handlers/remoteingress.handler.js +0 -156
- package/dist_ts/opsserver/handlers/route-management.handler.d.ts +0 -14
- package/dist_ts/opsserver/handlers/route-management.handler.js +0 -117
- package/dist_ts/opsserver/handlers/security.handler.d.ts +0 -9
- package/dist_ts/opsserver/handlers/security.handler.js +0 -233
- package/dist_ts/opsserver/handlers/stats.handler.d.ts +0 -11
- package/dist_ts/opsserver/handlers/stats.handler.js +0 -403
- package/dist_ts/opsserver/helpers/guards.d.ts +0 -27
- package/dist_ts/opsserver/helpers/guards.js +0 -43
- package/dist_ts/opsserver/index.d.ts +0 -1
- package/dist_ts/opsserver/index.js +0 -2
- package/dist_ts/paths.d.ts +0 -26
- package/dist_ts/paths.js +0 -45
- package/dist_ts/plugins.d.ts +0 -80
- package/dist_ts/plugins.js +0 -114
- package/dist_ts/radius/classes.accounting.manager.d.ts +0 -231
- package/dist_ts/radius/classes.accounting.manager.js +0 -462
- package/dist_ts/radius/classes.radius.server.d.ts +0 -171
- package/dist_ts/radius/classes.radius.server.js +0 -386
- package/dist_ts/radius/classes.vlan.manager.d.ts +0 -128
- package/dist_ts/radius/classes.vlan.manager.js +0 -279
- package/dist_ts/radius/index.d.ts +0 -13
- package/dist_ts/radius/index.js +0 -14
- package/dist_ts/remoteingress/classes.remoteingress-manager.d.ts +0 -94
- package/dist_ts/remoteingress/classes.remoteingress-manager.js +0 -271
- package/dist_ts/remoteingress/classes.tunnel-manager.d.ts +0 -59
- package/dist_ts/remoteingress/classes.tunnel-manager.js +0 -165
- package/dist_ts/remoteingress/index.d.ts +0 -2
- package/dist_ts/remoteingress/index.js +0 -3
- package/dist_ts/security/classes.contentscanner.d.ts +0 -164
- package/dist_ts/security/classes.contentscanner.js +0 -642
- package/dist_ts/security/classes.ipreputationchecker.d.ts +0 -160
- package/dist_ts/security/classes.ipreputationchecker.js +0 -537
- package/dist_ts/security/classes.securitylogger.d.ts +0 -144
- package/dist_ts/security/classes.securitylogger.js +0 -235
- package/dist_ts/security/index.d.ts +0 -3
- package/dist_ts/security/index.js +0 -4
- package/dist_ts/sms/classes.smsservice.d.ts +0 -15
- package/dist_ts/sms/classes.smsservice.js +0 -72
- package/dist_ts/sms/config/sms.config.d.ts +0 -93
- package/dist_ts/sms/config/sms.config.js +0 -2
- package/dist_ts/sms/config/sms.schema.d.ts +0 -5
- package/dist_ts/sms/config/sms.schema.js +0 -121
- package/dist_ts/sms/index.d.ts +0 -1
- package/dist_ts/sms/index.js +0 -2
- package/dist_ts/storage/classes.storagemanager.d.ts +0 -83
- package/dist_ts/storage/classes.storagemanager.js +0 -348
- package/dist_ts/storage/index.d.ts +0 -1
- package/dist_ts/storage/index.js +0 -3
- package/dist_ts_apiclient/classes.apitoken.d.ts +0 -41
- package/dist_ts_apiclient/classes.apitoken.js +0 -115
- package/dist_ts_apiclient/classes.certificate.d.ts +0 -57
- package/dist_ts_apiclient/classes.certificate.js +0 -69
- package/dist_ts_apiclient/classes.config.d.ts +0 -7
- package/dist_ts_apiclient/classes.config.js +0 -11
- package/dist_ts_apiclient/classes.dcrouterapiclient.d.ts +0 -41
- package/dist_ts_apiclient/classes.dcrouterapiclient.js +0 -81
- package/dist_ts_apiclient/classes.email.d.ts +0 -30
- package/dist_ts_apiclient/classes.email.js +0 -52
- package/dist_ts_apiclient/classes.logs.d.ts +0 -21
- package/dist_ts_apiclient/classes.logs.js +0 -14
- package/dist_ts_apiclient/classes.radius.d.ts +0 -59
- package/dist_ts_apiclient/classes.radius.js +0 -95
- package/dist_ts_apiclient/classes.remoteingress.d.ts +0 -54
- package/dist_ts_apiclient/classes.remoteingress.js +0 -136
- package/dist_ts_apiclient/classes.route.d.ts +0 -42
- package/dist_ts_apiclient/classes.route.js +0 -154
- package/dist_ts_apiclient/classes.stats.d.ts +0 -47
- package/dist_ts_apiclient/classes.stats.js +0 -38
- package/dist_ts_apiclient/index.d.ts +0 -10
- package/dist_ts_apiclient/index.js +0 -14
- package/dist_ts_apiclient/plugins.d.ts +0 -3
- package/dist_ts_apiclient/plugins.js +0 -5
- package/dist_ts_web/00_commitinfo_data.d.ts +0 -8
- package/dist_ts_web/00_commitinfo_data.js +0 -9
- package/dist_ts_web/appstate.d.ts +0 -216
- package/dist_ts_web/appstate.js +0 -1064
- package/dist_ts_web/elements/index.d.ts +0 -12
- package/dist_ts_web/elements/index.js +0 -13
- package/dist_ts_web/elements/ops-dashboard.d.ts +0 -23
- package/dist_ts_web/elements/ops-dashboard.js +0 -317
- package/dist_ts_web/elements/ops-view-apitokens.d.ts +0 -13
- package/dist_ts_web/elements/ops-view-apitokens.js +0 -371
- package/dist_ts_web/elements/ops-view-certificates.d.ts +0 -22
- package/dist_ts_web/elements/ops-view-certificates.js +0 -528
- package/dist_ts_web/elements/ops-view-config.d.ts +0 -19
- package/dist_ts_web/elements/ops-view-config.js +0 -339
- package/dist_ts_web/elements/ops-view-emails.d.ts +0 -21
- package/dist_ts_web/elements/ops-view-emails.js +0 -165
- package/dist_ts_web/elements/ops-view-logs.d.ts +0 -13
- package/dist_ts_web/elements/ops-view-logs.js +0 -159
- package/dist_ts_web/elements/ops-view-network.d.ts +0 -71
- package/dist_ts_web/elements/ops-view-network.js +0 -764
- package/dist_ts_web/elements/ops-view-overview.d.ts +0 -22
- package/dist_ts_web/elements/ops-view-overview.js +0 -456
- package/dist_ts_web/elements/ops-view-remoteingress.d.ts +0 -20
- package/dist_ts_web/elements/ops-view-remoteingress.js +0 -494
- package/dist_ts_web/elements/ops-view-routes.d.ts +0 -12
- package/dist_ts_web/elements/ops-view-routes.js +0 -404
- package/dist_ts_web/elements/ops-view-security.d.ts +0 -21
- package/dist_ts_web/elements/ops-view-security.js +0 -574
- package/dist_ts_web/elements/shared/css.d.ts +0 -1
- package/dist_ts_web/elements/shared/css.js +0 -10
- package/dist_ts_web/elements/shared/index.d.ts +0 -2
- package/dist_ts_web/elements/shared/index.js +0 -3
- package/dist_ts_web/elements/shared/ops-sectionheading.d.ts +0 -5
- package/dist_ts_web/elements/shared/ops-sectionheading.js +0 -82
- package/dist_ts_web/index.d.ts +0 -1
- package/dist_ts_web/index.js +0 -10
- package/dist_ts_web/plugins.d.ts +0 -6
- package/dist_ts_web/plugins.js +0 -11
- package/dist_ts_web/router.d.ts +0 -19
- package/dist_ts_web/router.js +0 -91
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DeesElement,
|
|
3
|
+
html,
|
|
4
|
+
customElement,
|
|
5
|
+
type TemplateResult,
|
|
6
|
+
css,
|
|
7
|
+
state,
|
|
8
|
+
cssManager,
|
|
9
|
+
} from '@design.estate/dees-element';
|
|
10
|
+
import * as appstate from '../appstate.js';
|
|
11
|
+
import * as interfaces from '../../dist_ts_interfaces/index.js';
|
|
12
|
+
import { viewHostCss } from './shared/css.js';
|
|
13
|
+
import { type IStatsTile } from '@design.estate/dees-catalog';
|
|
14
|
+
|
|
15
|
+
declare global {
|
|
16
|
+
interface HTMLElementTagNameMap {
|
|
17
|
+
'ops-view-vpn': OpsViewVpn;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@customElement('ops-view-vpn')
|
|
22
|
+
export class OpsViewVpn extends DeesElement {
|
|
23
|
+
@state()
|
|
24
|
+
accessor vpnState: appstate.IVpnState = appstate.vpnStatePart.getState()!;
|
|
25
|
+
|
|
26
|
+
constructor() {
|
|
27
|
+
super();
|
|
28
|
+
const sub = appstate.vpnStatePart.select().subscribe((newState) => {
|
|
29
|
+
this.vpnState = newState;
|
|
30
|
+
});
|
|
31
|
+
this.rxSubscriptions.push(sub);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async connectedCallback() {
|
|
35
|
+
await super.connectedCallback();
|
|
36
|
+
await appstate.vpnStatePart.dispatchAction(appstate.fetchVpnAction, null);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public static styles = [
|
|
40
|
+
cssManager.defaultStyles,
|
|
41
|
+
viewHostCss,
|
|
42
|
+
css`
|
|
43
|
+
.vpnContainer {
|
|
44
|
+
display: flex;
|
|
45
|
+
flex-direction: column;
|
|
46
|
+
gap: 24px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.statusBadge {
|
|
50
|
+
display: inline-flex;
|
|
51
|
+
align-items: center;
|
|
52
|
+
padding: 3px 10px;
|
|
53
|
+
border-radius: 12px;
|
|
54
|
+
font-size: 12px;
|
|
55
|
+
font-weight: 600;
|
|
56
|
+
letter-spacing: 0.02em;
|
|
57
|
+
text-transform: uppercase;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.statusBadge.enabled {
|
|
61
|
+
background: ${cssManager.bdTheme('#dcfce7', '#14532d')};
|
|
62
|
+
color: ${cssManager.bdTheme('#166534', '#4ade80')};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.statusBadge.disabled {
|
|
66
|
+
background: ${cssManager.bdTheme('#fef2f2', '#450a0a')};
|
|
67
|
+
color: ${cssManager.bdTheme('#991b1b', '#f87171')};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.configDialog {
|
|
71
|
+
padding: 16px;
|
|
72
|
+
background: ${cssManager.bdTheme('#fffbeb', '#1c1917')};
|
|
73
|
+
border: 1px solid ${cssManager.bdTheme('#fbbf24', '#92400e')};
|
|
74
|
+
border-radius: 8px;
|
|
75
|
+
margin-bottom: 16px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.configDialog pre {
|
|
79
|
+
display: block;
|
|
80
|
+
padding: 12px;
|
|
81
|
+
background: ${cssManager.bdTheme('#1f2937', '#111827')};
|
|
82
|
+
color: #10b981;
|
|
83
|
+
border-radius: 4px;
|
|
84
|
+
font-family: monospace;
|
|
85
|
+
font-size: 12px;
|
|
86
|
+
white-space: pre-wrap;
|
|
87
|
+
word-break: break-all;
|
|
88
|
+
margin: 8px 0;
|
|
89
|
+
user-select: all;
|
|
90
|
+
max-height: 300px;
|
|
91
|
+
overflow-y: auto;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.configDialog .warning {
|
|
95
|
+
font-size: 12px;
|
|
96
|
+
color: ${cssManager.bdTheme('#92400e', '#fbbf24')};
|
|
97
|
+
margin-top: 8px;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.tagBadge {
|
|
101
|
+
display: inline-flex;
|
|
102
|
+
padding: 2px 8px;
|
|
103
|
+
border-radius: 4px;
|
|
104
|
+
font-size: 12px;
|
|
105
|
+
font-weight: 500;
|
|
106
|
+
background: ${cssManager.bdTheme('#eff6ff', '#172554')};
|
|
107
|
+
color: ${cssManager.bdTheme('#1e40af', '#60a5fa')};
|
|
108
|
+
margin-right: 4px;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.serverInfo {
|
|
112
|
+
display: grid;
|
|
113
|
+
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
|
114
|
+
gap: 12px;
|
|
115
|
+
padding: 16px;
|
|
116
|
+
background: ${cssManager.bdTheme('#f9fafb', '#111827')};
|
|
117
|
+
border-radius: 8px;
|
|
118
|
+
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#1f2937')};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.serverInfo .infoItem {
|
|
122
|
+
display: flex;
|
|
123
|
+
flex-direction: column;
|
|
124
|
+
gap: 4px;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.serverInfo .infoLabel {
|
|
128
|
+
font-size: 11px;
|
|
129
|
+
font-weight: 600;
|
|
130
|
+
text-transform: uppercase;
|
|
131
|
+
letter-spacing: 0.05em;
|
|
132
|
+
color: ${cssManager.bdTheme('#6b7280', '#9ca3af')};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.serverInfo .infoValue {
|
|
136
|
+
font-size: 14px;
|
|
137
|
+
font-family: monospace;
|
|
138
|
+
color: ${cssManager.bdTheme('#111827', '#f9fafb')};
|
|
139
|
+
}
|
|
140
|
+
`,
|
|
141
|
+
];
|
|
142
|
+
|
|
143
|
+
render(): TemplateResult {
|
|
144
|
+
const status = this.vpnState.status;
|
|
145
|
+
const clients = this.vpnState.clients;
|
|
146
|
+
const connectedCount = status?.connectedClients ?? 0;
|
|
147
|
+
const totalClients = clients.length;
|
|
148
|
+
const enabledClients = clients.filter(c => c.enabled).length;
|
|
149
|
+
|
|
150
|
+
const statsTiles: IStatsTile[] = [
|
|
151
|
+
{
|
|
152
|
+
id: 'totalClients',
|
|
153
|
+
title: 'Total Clients',
|
|
154
|
+
type: 'number',
|
|
155
|
+
value: totalClients,
|
|
156
|
+
icon: 'lucide:users',
|
|
157
|
+
description: 'Registered VPN clients',
|
|
158
|
+
color: '#3b82f6',
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
id: 'connectedClients',
|
|
162
|
+
title: 'Connected',
|
|
163
|
+
type: 'number',
|
|
164
|
+
value: connectedCount,
|
|
165
|
+
icon: 'lucide:link',
|
|
166
|
+
description: 'Currently connected',
|
|
167
|
+
color: '#10b981',
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
id: 'enabledClients',
|
|
171
|
+
title: 'Enabled',
|
|
172
|
+
type: 'number',
|
|
173
|
+
value: enabledClients,
|
|
174
|
+
icon: 'lucide:shieldCheck',
|
|
175
|
+
description: 'Active client registrations',
|
|
176
|
+
color: '#8b5cf6',
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
id: 'serverStatus',
|
|
180
|
+
title: 'Server',
|
|
181
|
+
type: 'text',
|
|
182
|
+
value: status?.running ? 'Running' : 'Stopped',
|
|
183
|
+
icon: 'lucide:server',
|
|
184
|
+
description: status?.running ? `${status.forwardingMode} mode` : 'VPN server not running',
|
|
185
|
+
color: status?.running ? '#10b981' : '#ef4444',
|
|
186
|
+
},
|
|
187
|
+
];
|
|
188
|
+
|
|
189
|
+
return html`
|
|
190
|
+
<ops-sectionheading>VPN</ops-sectionheading>
|
|
191
|
+
|
|
192
|
+
${this.vpnState.newClientConfig ? html`
|
|
193
|
+
<div class="configDialog">
|
|
194
|
+
<strong>Client created successfully!</strong>
|
|
195
|
+
<div class="warning">Copy the WireGuard config now. It contains private keys that won't be shown again.</div>
|
|
196
|
+
<pre>${this.vpnState.newClientConfig}</pre>
|
|
197
|
+
<dees-button
|
|
198
|
+
@click=${async () => {
|
|
199
|
+
if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') {
|
|
200
|
+
await navigator.clipboard.writeText(this.vpnState.newClientConfig!);
|
|
201
|
+
}
|
|
202
|
+
const { DeesToast } = await import('@design.estate/dees-catalog');
|
|
203
|
+
DeesToast.createAndShow({ message: 'Config copied to clipboard', type: 'success', duration: 3000 });
|
|
204
|
+
}}
|
|
205
|
+
>Copy to Clipboard</dees-button>
|
|
206
|
+
<dees-button
|
|
207
|
+
@click=${() => {
|
|
208
|
+
const blob = new Blob([this.vpnState.newClientConfig!], { type: 'text/plain' });
|
|
209
|
+
const url = URL.createObjectURL(blob);
|
|
210
|
+
const a = document.createElement('a');
|
|
211
|
+
a.href = url;
|
|
212
|
+
a.download = 'wireguard.conf';
|
|
213
|
+
a.click();
|
|
214
|
+
URL.revokeObjectURL(url);
|
|
215
|
+
}}
|
|
216
|
+
>Download .conf</dees-button>
|
|
217
|
+
<dees-button
|
|
218
|
+
@click=${() => appstate.vpnStatePart.dispatchAction(appstate.clearNewClientConfigAction, null)}
|
|
219
|
+
>Dismiss</dees-button>
|
|
220
|
+
</div>
|
|
221
|
+
` : ''}
|
|
222
|
+
|
|
223
|
+
<dees-statsgrid .statsTiles=${statsTiles}></dees-statsgrid>
|
|
224
|
+
|
|
225
|
+
${status ? html`
|
|
226
|
+
<div class="serverInfo">
|
|
227
|
+
<div class="infoItem">
|
|
228
|
+
<span class="infoLabel">Subnet</span>
|
|
229
|
+
<span class="infoValue">${status.subnet}</span>
|
|
230
|
+
</div>
|
|
231
|
+
<div class="infoItem">
|
|
232
|
+
<span class="infoLabel">WireGuard Port</span>
|
|
233
|
+
<span class="infoValue">${status.wgListenPort}</span>
|
|
234
|
+
</div>
|
|
235
|
+
<div class="infoItem">
|
|
236
|
+
<span class="infoLabel">Forwarding Mode</span>
|
|
237
|
+
<span class="infoValue">${status.forwardingMode}</span>
|
|
238
|
+
</div>
|
|
239
|
+
${status.serverPublicKeys ? html`
|
|
240
|
+
<div class="infoItem">
|
|
241
|
+
<span class="infoLabel">WG Public Key</span>
|
|
242
|
+
<span class="infoValue" style="font-size: 11px; word-break: break-all;">${status.serverPublicKeys.wgPublicKey}</span>
|
|
243
|
+
</div>
|
|
244
|
+
` : ''}
|
|
245
|
+
</div>
|
|
246
|
+
` : ''}
|
|
247
|
+
|
|
248
|
+
<dees-table
|
|
249
|
+
.heading1=${'VPN Clients'}
|
|
250
|
+
.heading2=${'Manage WireGuard and SmartVPN client registrations'}
|
|
251
|
+
.data=${clients}
|
|
252
|
+
.displayFunction=${(client: interfaces.data.IVpnClient) => ({
|
|
253
|
+
'Client ID': client.clientId,
|
|
254
|
+
'Status': client.enabled
|
|
255
|
+
? html`<span class="statusBadge enabled">enabled</span>`
|
|
256
|
+
: html`<span class="statusBadge disabled">disabled</span>`,
|
|
257
|
+
'VPN IP': client.assignedIp || '-',
|
|
258
|
+
'Tags': client.tags?.length
|
|
259
|
+
? html`${client.tags.map(t => html`<span class="tagBadge">${t}</span>`)}`
|
|
260
|
+
: '-',
|
|
261
|
+
'Description': client.description || '-',
|
|
262
|
+
'Created': new Date(client.createdAt).toLocaleDateString(),
|
|
263
|
+
})}
|
|
264
|
+
.dataActions=${[
|
|
265
|
+
{
|
|
266
|
+
name: 'Toggle',
|
|
267
|
+
iconName: 'lucide:power',
|
|
268
|
+
action: async (client: interfaces.data.IVpnClient) => {
|
|
269
|
+
await appstate.vpnStatePart.dispatchAction(appstate.toggleVpnClientAction, {
|
|
270
|
+
clientId: client.clientId,
|
|
271
|
+
enabled: !client.enabled,
|
|
272
|
+
});
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
name: 'Delete',
|
|
277
|
+
iconName: 'lucide:trash2',
|
|
278
|
+
action: async (client: interfaces.data.IVpnClient) => {
|
|
279
|
+
const { DeesModal } = await import('@design.estate/dees-catalog');
|
|
280
|
+
DeesModal.createAndShow({
|
|
281
|
+
heading: 'Delete VPN Client',
|
|
282
|
+
content: html`<p>Are you sure you want to delete client "${client.clientId}"?</p>`,
|
|
283
|
+
menuOptions: [
|
|
284
|
+
{ name: 'Cancel', action: async (modal: any) => modal.destroy() },
|
|
285
|
+
{
|
|
286
|
+
name: 'Delete',
|
|
287
|
+
action: async (modal: any) => {
|
|
288
|
+
await appstate.vpnStatePart.dispatchAction(appstate.deleteVpnClientAction, client.clientId);
|
|
289
|
+
modal.destroy();
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
],
|
|
293
|
+
});
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
]}
|
|
297
|
+
.createNewItem=${async () => {
|
|
298
|
+
const { DeesModal, DeesForm, DeesInputText } = await import('@design.estate/dees-catalog');
|
|
299
|
+
DeesModal.createAndShow({
|
|
300
|
+
heading: 'Create VPN Client',
|
|
301
|
+
content: html`
|
|
302
|
+
<dees-form>
|
|
303
|
+
<dees-input-text id="clientId" .label=${'Client ID'} .key=${'clientId'} required></dees-input-text>
|
|
304
|
+
<dees-input-text id="description" .label=${'Description'} .key=${'description'}></dees-input-text>
|
|
305
|
+
<dees-input-text id="tags" .label=${'Tags (comma-separated)'} .key=${'tags'}></dees-input-text>
|
|
306
|
+
</dees-form>
|
|
307
|
+
`,
|
|
308
|
+
menuOptions: [
|
|
309
|
+
{ name: 'Cancel', action: async (modal: any) => modal.destroy() },
|
|
310
|
+
{
|
|
311
|
+
name: 'Create',
|
|
312
|
+
action: async (modal: any) => {
|
|
313
|
+
const form = modal.shadowRoot!.querySelector('dees-form') as any;
|
|
314
|
+
const data = await form.collectFormData();
|
|
315
|
+
const tags = data.tags ? data.tags.split(',').map((t: string) => t.trim()).filter(Boolean) : undefined;
|
|
316
|
+
await appstate.vpnStatePart.dispatchAction(appstate.createVpnClientAction, {
|
|
317
|
+
clientId: data.clientId,
|
|
318
|
+
description: data.description || undefined,
|
|
319
|
+
tags,
|
|
320
|
+
});
|
|
321
|
+
modal.destroy();
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
],
|
|
325
|
+
});
|
|
326
|
+
}}
|
|
327
|
+
></dees-table>
|
|
328
|
+
`;
|
|
329
|
+
}
|
|
330
|
+
}
|
package/ts_web/readme.md
CHANGED
|
@@ -50,6 +50,13 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
|
|
50
50
|
- **Connection token generation** — one-click "Copy Token" for easy edge provisioning
|
|
51
51
|
- Enable/disable, edit, secret regeneration, and delete actions
|
|
52
52
|
|
|
53
|
+
### 🔐 VPN Management
|
|
54
|
+
- VPN server status with forwarding mode, subnet, and WireGuard port
|
|
55
|
+
- Client registration table with create, enable/disable, and delete actions
|
|
56
|
+
- WireGuard config download and clipboard copy on client creation
|
|
57
|
+
- Per-client telemetry (bytes sent/received, keepalives)
|
|
58
|
+
- Server public key display for manual client configuration
|
|
59
|
+
|
|
53
60
|
### 📜 Log Viewer
|
|
54
61
|
- Real-time log streaming
|
|
55
62
|
- Filter by log level (error, warning, info, debug)
|
|
@@ -100,6 +107,7 @@ ts_web/
|
|
|
100
107
|
├── ops-view-emails.ts # Email queue management
|
|
101
108
|
├── ops-view-certificates.ts # Certificate overview & reprovisioning
|
|
102
109
|
├── ops-view-remoteingress.ts # Remote ingress edge management
|
|
110
|
+
├── ops-view-vpn.ts # VPN client management
|
|
103
111
|
├── ops-view-logs.ts # Log viewer
|
|
104
112
|
├── ops-view-routes.ts # Route & API token management
|
|
105
113
|
├── ops-view-config.ts # Configuration display
|
|
@@ -124,6 +132,7 @@ The app uses `@push.rocks/smartstate` v2.3+ with multiple state parts, scheduled
|
|
|
124
132
|
| `emailOpsStatePart` | Soft | Email queues, bounces, suppression list |
|
|
125
133
|
| `certificateStatePart` | Soft | Certificate list, summary, loading state |
|
|
126
134
|
| `remoteIngressStatePart` | Soft | Edge list, statuses, new edge secret |
|
|
135
|
+
| `vpnStatePart` | Soft | VPN clients, server status, new client config |
|
|
127
136
|
|
|
128
137
|
### Tab Visibility Optimization
|
|
129
138
|
|
|
@@ -173,6 +182,13 @@ regenerateRemoteIngressSecretAction(id) // New secret
|
|
|
173
182
|
toggleRemoteIngressAction(id, enabled) // Enable/disable
|
|
174
183
|
clearNewEdgeSecretAction() // Dismiss secret banner
|
|
175
184
|
fetchConnectionToken(edgeId) // Get connection token (standalone function)
|
|
185
|
+
|
|
186
|
+
// VPN
|
|
187
|
+
fetchVpnAction() // Clients + server status
|
|
188
|
+
createVpnClientAction(data) // Create new VPN client
|
|
189
|
+
deleteVpnClientAction(clientId) // Remove VPN client
|
|
190
|
+
toggleVpnClientAction(id, enabled) // Enable/disable
|
|
191
|
+
clearNewClientConfigAction() // Dismiss config banner
|
|
176
192
|
```
|
|
177
193
|
|
|
178
194
|
### Client-Side Routing
|
|
@@ -187,6 +203,7 @@ fetchConnectionToken(edgeId) // Get connection token (standalone function)
|
|
|
187
203
|
/emails/security → Security incidents
|
|
188
204
|
/certificates → Certificate management
|
|
189
205
|
/remoteingress → Remote ingress edge management
|
|
206
|
+
/vpn → VPN client management
|
|
190
207
|
/routes → Route & API token management
|
|
191
208
|
/logs → Log viewer
|
|
192
209
|
/configuration → System configuration
|
package/ts_web/router.ts
CHANGED
|
@@ -3,7 +3,7 @@ import * as appstate from './appstate.js';
|
|
|
3
3
|
|
|
4
4
|
const SmartRouter = plugins.domtools.plugins.smartrouter.SmartRouter;
|
|
5
5
|
|
|
6
|
-
export const validViews = ['overview', 'network', 'emails', 'logs', 'routes', 'apitokens', 'configuration', 'security', 'certificates', 'remoteingress'] as const;
|
|
6
|
+
export const validViews = ['overview', 'network', 'emails', 'logs', 'routes', 'apitokens', 'configuration', 'security', 'certificates', 'remoteingress', 'vpn'] as const;
|
|
7
7
|
|
|
8
8
|
export type TValidView = typeof validViews[number];
|
|
9
9
|
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* autocreated commitinfo by @push.rocks/commitinfo
|
|
3
|
-
*/
|
|
4
|
-
export const commitinfo = {
|
|
5
|
-
name: '@serve.zone/dcrouter',
|
|
6
|
-
version: '11.12.4',
|
|
7
|
-
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
|
8
|
-
};
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxzQkFBc0I7SUFDNUIsT0FBTyxFQUFFLFNBQVM7SUFDbEIsV0FBVyxFQUFFLDBFQUEwRTtDQUN4RixDQUFBIn0=
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { CacheDb } from './classes.cachedb.js';
|
|
2
|
-
/**
|
|
3
|
-
* Configuration for the cache cleaner
|
|
4
|
-
*/
|
|
5
|
-
export interface ICacheCleanerOptions {
|
|
6
|
-
/** Cleanup interval in milliseconds (default: 1 hour) */
|
|
7
|
-
intervalMs?: number;
|
|
8
|
-
/** Enable verbose logging */
|
|
9
|
-
verbose?: boolean;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* CacheCleaner - Periodically removes expired documents from the cache
|
|
13
|
-
*
|
|
14
|
-
* Runs on a configurable interval (default: hourly) and queries each
|
|
15
|
-
* collection for documents where expiresAt < now(), then deletes them.
|
|
16
|
-
*/
|
|
17
|
-
export declare class CacheCleaner {
|
|
18
|
-
private cleanupInterval;
|
|
19
|
-
private isRunning;
|
|
20
|
-
private options;
|
|
21
|
-
private cacheDb;
|
|
22
|
-
constructor(cacheDb: CacheDb, options?: ICacheCleanerOptions);
|
|
23
|
-
/**
|
|
24
|
-
* Start the periodic cleanup process
|
|
25
|
-
*/
|
|
26
|
-
start(): void;
|
|
27
|
-
/**
|
|
28
|
-
* Stop the periodic cleanup process
|
|
29
|
-
*/
|
|
30
|
-
stop(): void;
|
|
31
|
-
/**
|
|
32
|
-
* Run a single cleanup cycle
|
|
33
|
-
*/
|
|
34
|
-
runCleanup(): Promise<void>;
|
|
35
|
-
/**
|
|
36
|
-
* Clean expired documents from a specific collection using smartdata API
|
|
37
|
-
*/
|
|
38
|
-
private cleanExpiredDocuments;
|
|
39
|
-
/**
|
|
40
|
-
* Check if the cleaner is running
|
|
41
|
-
*/
|
|
42
|
-
isActive(): boolean;
|
|
43
|
-
/**
|
|
44
|
-
* Get the cleanup interval in milliseconds
|
|
45
|
-
*/
|
|
46
|
-
getIntervalMs(): number;
|
|
47
|
-
}
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../plugins.js';
|
|
2
|
-
import { logger } from '../logger.js';
|
|
3
|
-
import { CacheDb } from './classes.cachedb.js';
|
|
4
|
-
// Import document classes for cleanup
|
|
5
|
-
import { CachedEmail } from './documents/classes.cached.email.js';
|
|
6
|
-
import { CachedIPReputation } from './documents/classes.cached.ip.reputation.js';
|
|
7
|
-
/**
|
|
8
|
-
* CacheCleaner - Periodically removes expired documents from the cache
|
|
9
|
-
*
|
|
10
|
-
* Runs on a configurable interval (default: hourly) and queries each
|
|
11
|
-
* collection for documents where expiresAt < now(), then deletes them.
|
|
12
|
-
*/
|
|
13
|
-
export class CacheCleaner {
|
|
14
|
-
cleanupInterval = null;
|
|
15
|
-
isRunning = false;
|
|
16
|
-
options;
|
|
17
|
-
cacheDb;
|
|
18
|
-
constructor(cacheDb, options = {}) {
|
|
19
|
-
this.cacheDb = cacheDb;
|
|
20
|
-
this.options = {
|
|
21
|
-
intervalMs: options.intervalMs || 60 * 60 * 1000, // 1 hour default
|
|
22
|
-
verbose: options.verbose || false,
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Start the periodic cleanup process
|
|
27
|
-
*/
|
|
28
|
-
start() {
|
|
29
|
-
if (this.isRunning) {
|
|
30
|
-
logger.log('warn', 'CacheCleaner already running');
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
this.isRunning = true;
|
|
34
|
-
// Run cleanup immediately on start
|
|
35
|
-
this.runCleanup().catch((error) => {
|
|
36
|
-
logger.log('error', `Initial cache cleanup failed: ${error.message}`);
|
|
37
|
-
});
|
|
38
|
-
// Schedule periodic cleanup
|
|
39
|
-
this.cleanupInterval = setInterval(() => {
|
|
40
|
-
this.runCleanup().catch((error) => {
|
|
41
|
-
logger.log('error', `Cache cleanup failed: ${error.message}`);
|
|
42
|
-
});
|
|
43
|
-
}, this.options.intervalMs);
|
|
44
|
-
logger.log('info', `CacheCleaner started with interval: ${this.options.intervalMs / 1000 / 60} minutes`);
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Stop the periodic cleanup process
|
|
48
|
-
*/
|
|
49
|
-
stop() {
|
|
50
|
-
if (!this.isRunning) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
if (this.cleanupInterval) {
|
|
54
|
-
clearInterval(this.cleanupInterval);
|
|
55
|
-
this.cleanupInterval = null;
|
|
56
|
-
}
|
|
57
|
-
this.isRunning = false;
|
|
58
|
-
logger.log('info', 'CacheCleaner stopped');
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Run a single cleanup cycle
|
|
62
|
-
*/
|
|
63
|
-
async runCleanup() {
|
|
64
|
-
if (!this.cacheDb.isReady()) {
|
|
65
|
-
logger.log('warn', 'CacheDb not ready, skipping cleanup');
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
const now = new Date();
|
|
69
|
-
const results = [];
|
|
70
|
-
try {
|
|
71
|
-
const emailsDeleted = await this.cleanExpiredDocuments(CachedEmail, now);
|
|
72
|
-
results.push({ collection: 'CachedEmail', deleted: emailsDeleted });
|
|
73
|
-
const ipReputationDeleted = await this.cleanExpiredDocuments(CachedIPReputation, now);
|
|
74
|
-
results.push({ collection: 'CachedIPReputation', deleted: ipReputationDeleted });
|
|
75
|
-
// Log results
|
|
76
|
-
const totalDeleted = results.reduce((sum, r) => sum + r.deleted, 0);
|
|
77
|
-
if (totalDeleted > 0 || this.options.verbose) {
|
|
78
|
-
const summary = results
|
|
79
|
-
.filter((r) => r.deleted > 0)
|
|
80
|
-
.map((r) => `${r.collection}: ${r.deleted}`)
|
|
81
|
-
.join(', ');
|
|
82
|
-
logger.log('info', `Cache cleanup completed. Deleted ${totalDeleted} expired documents. ${summary || 'No deletions.'}`);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
catch (error) {
|
|
86
|
-
logger.log('error', `Cache cleanup error: ${error.message}`);
|
|
87
|
-
throw error;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Clean expired documents from a specific collection using smartdata API
|
|
92
|
-
*/
|
|
93
|
-
async cleanExpiredDocuments(documentClass, now) {
|
|
94
|
-
try {
|
|
95
|
-
// Find all expired documents
|
|
96
|
-
const expiredDocs = await documentClass.getInstances({
|
|
97
|
-
expiresAt: { $lt: now },
|
|
98
|
-
});
|
|
99
|
-
// Delete each expired document
|
|
100
|
-
let deletedCount = 0;
|
|
101
|
-
for (const doc of expiredDocs) {
|
|
102
|
-
try {
|
|
103
|
-
await doc.delete();
|
|
104
|
-
deletedCount++;
|
|
105
|
-
}
|
|
106
|
-
catch (deleteError) {
|
|
107
|
-
logger.log('warn', `Failed to delete expired document: ${deleteError.message}`);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
return deletedCount;
|
|
111
|
-
}
|
|
112
|
-
catch (error) {
|
|
113
|
-
logger.log('error', `Error cleaning collection: ${error.message}`);
|
|
114
|
-
return 0;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Check if the cleaner is running
|
|
119
|
-
*/
|
|
120
|
-
isActive() {
|
|
121
|
-
return this.isRunning;
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Get the cleanup interval in milliseconds
|
|
125
|
-
*/
|
|
126
|
-
getIntervalMs() {
|
|
127
|
-
return this.options.intervalMs;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jYWNoZS5jbGVhbmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvY2FjaGUvY2xhc3Nlcy5jYWNoZS5jbGVhbmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDdEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRS9DLHNDQUFzQztBQUN0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDbEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFZakY7Ozs7O0dBS0c7QUFDSCxNQUFNLE9BQU8sWUFBWTtJQUNmLGVBQWUsR0FBMEMsSUFBSSxDQUFDO0lBQzlELFNBQVMsR0FBWSxLQUFLLENBQUM7SUFDM0IsT0FBTyxDQUFpQztJQUN4QyxPQUFPLENBQVU7SUFFekIsWUFBWSxPQUFnQixFQUFFLFVBQWdDLEVBQUU7UUFDOUQsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLE9BQU8sR0FBRztZQUNiLFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVSxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxFQUFFLGlCQUFpQjtZQUNuRSxPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU8sSUFBSSxLQUFLO1NBQ2xDLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLO1FBQ1YsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDbkIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsOEJBQThCLENBQUMsQ0FBQztZQUNuRCxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1FBRXRCLG1DQUFtQztRQUNuQyxJQUFJ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
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import * as plugins from '../plugins.js';
|
|
2
|
-
/**
|
|
3
|
-
* Base class for all cached documents with TTL support
|
|
4
|
-
*
|
|
5
|
-
* Extends smartdata's SmartDataDbDoc to add:
|
|
6
|
-
* - Automatic timestamps (createdAt, lastAccessedAt)
|
|
7
|
-
* - TTL/expiration support (expiresAt)
|
|
8
|
-
* - Helper methods for TTL management
|
|
9
|
-
*
|
|
10
|
-
* NOTE: Subclasses MUST add @svDb() decorators to createdAt, expiresAt, and lastAccessedAt
|
|
11
|
-
* since decorators on abstract classes don't propagate correctly.
|
|
12
|
-
*/
|
|
13
|
-
export declare abstract class CachedDocument<T extends CachedDocument<T>> extends plugins.smartdata.SmartDataDbDoc<T, T> {
|
|
14
|
-
/**
|
|
15
|
-
* Timestamp when the document was created
|
|
16
|
-
* NOTE: Subclasses must add @svDb() decorator
|
|
17
|
-
*/
|
|
18
|
-
createdAt: Date;
|
|
19
|
-
/**
|
|
20
|
-
* Timestamp when the document expires and should be cleaned up
|
|
21
|
-
* NOTE: Subclasses must add @svDb() decorator
|
|
22
|
-
*/
|
|
23
|
-
expiresAt: Date;
|
|
24
|
-
/**
|
|
25
|
-
* Timestamp of last access (for LRU-style eviction if needed)
|
|
26
|
-
* NOTE: Subclasses must add @svDb() decorator
|
|
27
|
-
*/
|
|
28
|
-
lastAccessedAt: Date;
|
|
29
|
-
/**
|
|
30
|
-
* Set the TTL (time to live) for this document
|
|
31
|
-
* @param ttlMs Time to live in milliseconds
|
|
32
|
-
*/
|
|
33
|
-
setTTL(ttlMs: number): void;
|
|
34
|
-
/**
|
|
35
|
-
* Set TTL using days
|
|
36
|
-
* @param days Number of days until expiration
|
|
37
|
-
*/
|
|
38
|
-
setTTLDays(days: number): void;
|
|
39
|
-
/**
|
|
40
|
-
* Set TTL using hours
|
|
41
|
-
* @param hours Number of hours until expiration
|
|
42
|
-
*/
|
|
43
|
-
setTTLHours(hours: number): void;
|
|
44
|
-
/**
|
|
45
|
-
* Check if this document has expired
|
|
46
|
-
*/
|
|
47
|
-
isExpired(): boolean;
|
|
48
|
-
/**
|
|
49
|
-
* Update the lastAccessedAt timestamp
|
|
50
|
-
*/
|
|
51
|
-
touch(): void;
|
|
52
|
-
/**
|
|
53
|
-
* Get remaining TTL in milliseconds
|
|
54
|
-
* Returns 0 if expired, -1 if no expiration set
|
|
55
|
-
*/
|
|
56
|
-
getRemainingTTL(): number;
|
|
57
|
-
/**
|
|
58
|
-
* Extend the TTL by the specified milliseconds from now
|
|
59
|
-
* @param ttlMs Additional time to live in milliseconds
|
|
60
|
-
*/
|
|
61
|
-
extendTTL(ttlMs: number): void;
|
|
62
|
-
/**
|
|
63
|
-
* Set the document to never expire (100 years in the future)
|
|
64
|
-
*/
|
|
65
|
-
setNeverExpires(): void;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* TTL constants in milliseconds
|
|
69
|
-
*/
|
|
70
|
-
export declare const TTL: {
|
|
71
|
-
readonly HOURS_1: number;
|
|
72
|
-
readonly HOURS_24: number;
|
|
73
|
-
readonly DAYS_7: number;
|
|
74
|
-
readonly DAYS_30: number;
|
|
75
|
-
readonly DAYS_90: number;
|
|
76
|
-
};
|