@serve.zone/dcrouter 11.16.0 → 11.18.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 +272 -271
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/ops-view-vpn.d.ts +2 -1
- package/dist_ts_web/elements/ops-view-vpn.js +163 -37
- package/package.json +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/ops-view-vpn.ts +163 -36
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@serve.zone/dcrouter',
|
|
6
|
-
version: '11.
|
|
6
|
+
version: '11.18.0',
|
|
7
7
|
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxzQkFBc0I7SUFDNUIsT0FBTyxFQUFFLFNBQVM7SUFDbEIsV0FBVyxFQUFFLDBFQUEwRTtDQUN4RixDQUFBIn0=
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@serve.zone/dcrouter',
|
|
6
|
-
version: '11.
|
|
6
|
+
version: '11.18.0',
|
|
7
7
|
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfd2ViLzAwX2NvbW1pdGluZm9fZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRztJQUN4QixJQUFJLEVBQUUsc0JBQXNCO0lBQzVCLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLFdBQVcsRUFBRSwwRUFBMEU7Q0FDeEYsQ0FBQSJ9
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DeesElement, type TemplateResult } from '@design.estate/dees-element';
|
|
2
|
+
import * as plugins from '../plugins.js';
|
|
2
3
|
import * as appstate from '../appstate.js';
|
|
3
4
|
declare global {
|
|
4
5
|
interface HTMLElementTagNameMap {
|
|
@@ -9,6 +10,6 @@ export declare class OpsViewVpn extends DeesElement {
|
|
|
9
10
|
accessor vpnState: appstate.IVpnState;
|
|
10
11
|
constructor();
|
|
11
12
|
connectedCallback(): Promise<void>;
|
|
12
|
-
static styles:
|
|
13
|
+
static styles: plugins.deesElement.CSSResult[];
|
|
13
14
|
render(): TemplateResult;
|
|
14
15
|
}
|
|
@@ -33,6 +33,7 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
33
33
|
return useValue ? value : void 0;
|
|
34
34
|
};
|
|
35
35
|
import { DeesElement, html, customElement, css, state, cssManager, } from '@design.estate/dees-element';
|
|
36
|
+
import * as plugins from '../plugins.js';
|
|
36
37
|
import * as appstate from '../appstate.js';
|
|
37
38
|
import * as interfaces from '../../dist_ts_interfaces/index.js';
|
|
38
39
|
import { viewHostCss } from './shared/css.js';
|
|
@@ -220,6 +221,7 @@ let OpsViewVpn = (() => {
|
|
|
220
221
|
];
|
|
221
222
|
return html `
|
|
222
223
|
<ops-sectionheading>VPN</ops-sectionheading>
|
|
224
|
+
<div class="vpnContainer">
|
|
223
225
|
|
|
224
226
|
${this.vpnState.newClientConfig ? html `
|
|
225
227
|
<div class="configDialog">
|
|
@@ -252,7 +254,7 @@ let OpsViewVpn = (() => {
|
|
|
252
254
|
</div>
|
|
253
255
|
` : ''}
|
|
254
256
|
|
|
255
|
-
<dees-statsgrid .
|
|
257
|
+
<dees-statsgrid .tiles=${statsTiles}></dees-statsgrid>
|
|
256
258
|
|
|
257
259
|
${status ? html `
|
|
258
260
|
<div class="serverInfo">
|
|
@@ -290,31 +292,184 @@ let OpsViewVpn = (() => {
|
|
|
290
292
|
'Created': new Date(client.createdAt).toLocaleDateString(),
|
|
291
293
|
})}
|
|
292
294
|
.dataActions=${[
|
|
295
|
+
{
|
|
296
|
+
name: 'Create Client',
|
|
297
|
+
iconName: 'lucide:plus',
|
|
298
|
+
type: ['header'],
|
|
299
|
+
actionFunc: async () => {
|
|
300
|
+
const { DeesModal } = await import('@design.estate/dees-catalog');
|
|
301
|
+
await DeesModal.createAndShow({
|
|
302
|
+
heading: 'Create VPN Client',
|
|
303
|
+
content: html `
|
|
304
|
+
<dees-form>
|
|
305
|
+
<dees-input-text .key=${'clientId'} .label=${'Client ID'} .required=${true}></dees-input-text>
|
|
306
|
+
<dees-input-text .key=${'description'} .label=${'Description'}></dees-input-text>
|
|
307
|
+
<dees-input-text .key=${'tags'} .label=${'Server-Defined Tags (comma-separated)'}></dees-input-text>
|
|
308
|
+
</dees-form>
|
|
309
|
+
`,
|
|
310
|
+
menuOptions: [
|
|
311
|
+
{
|
|
312
|
+
name: 'Cancel',
|
|
313
|
+
iconName: 'lucide:x',
|
|
314
|
+
action: async (modalArg) => await modalArg.destroy(),
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
name: 'Create',
|
|
318
|
+
iconName: 'lucide:plus',
|
|
319
|
+
action: async (modalArg) => {
|
|
320
|
+
const form = modalArg.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
|
|
321
|
+
if (!form)
|
|
322
|
+
return;
|
|
323
|
+
const data = await form.collectFormData();
|
|
324
|
+
if (!data.clientId)
|
|
325
|
+
return;
|
|
326
|
+
const serverDefinedClientTags = data.tags
|
|
327
|
+
? data.tags.split(',').map((t) => t.trim()).filter(Boolean)
|
|
328
|
+
: undefined;
|
|
329
|
+
await appstate.vpnStatePart.dispatchAction(appstate.createVpnClientAction, {
|
|
330
|
+
clientId: data.clientId,
|
|
331
|
+
description: data.description || undefined,
|
|
332
|
+
serverDefinedClientTags,
|
|
333
|
+
});
|
|
334
|
+
await modalArg.destroy();
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
],
|
|
338
|
+
});
|
|
339
|
+
},
|
|
340
|
+
},
|
|
293
341
|
{
|
|
294
342
|
name: 'Toggle',
|
|
295
343
|
iconName: 'lucide:power',
|
|
296
|
-
|
|
344
|
+
type: ['contextmenu', 'inRow'],
|
|
345
|
+
actionFunc: async (actionData) => {
|
|
346
|
+
const client = actionData.item;
|
|
297
347
|
await appstate.vpnStatePart.dispatchAction(appstate.toggleVpnClientAction, {
|
|
298
348
|
clientId: client.clientId,
|
|
299
349
|
enabled: !client.enabled,
|
|
300
350
|
});
|
|
301
351
|
},
|
|
302
352
|
},
|
|
353
|
+
{
|
|
354
|
+
name: 'Export Config',
|
|
355
|
+
iconName: 'lucide:download',
|
|
356
|
+
type: ['contextmenu', 'inRow'],
|
|
357
|
+
actionFunc: async (actionData) => {
|
|
358
|
+
const client = actionData.item;
|
|
359
|
+
const { DeesModal, DeesToast } = await import('@design.estate/dees-catalog');
|
|
360
|
+
const exportConfig = async (format) => {
|
|
361
|
+
try {
|
|
362
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'exportVpnClientConfig');
|
|
363
|
+
const response = await request.fire({
|
|
364
|
+
identity: appstate.loginStatePart.getState().identity,
|
|
365
|
+
clientId: client.clientId,
|
|
366
|
+
format,
|
|
367
|
+
});
|
|
368
|
+
if (response.success && response.config) {
|
|
369
|
+
const ext = format === 'wireguard' ? 'conf' : 'json';
|
|
370
|
+
const blob = new Blob([response.config], { type: 'text/plain' });
|
|
371
|
+
const url = URL.createObjectURL(blob);
|
|
372
|
+
const a = document.createElement('a');
|
|
373
|
+
a.href = url;
|
|
374
|
+
a.download = `${client.clientId}.${ext}`;
|
|
375
|
+
a.click();
|
|
376
|
+
URL.revokeObjectURL(url);
|
|
377
|
+
DeesToast.createAndShow({ message: `${format} config downloaded`, type: 'success', duration: 3000 });
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
DeesToast.createAndShow({ message: response.message || 'Export failed', type: 'error', duration: 5000 });
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
catch (err) {
|
|
384
|
+
DeesToast.createAndShow({ message: err.message || 'Export failed', type: 'error', duration: 5000 });
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
DeesModal.createAndShow({
|
|
388
|
+
heading: `Export Config: ${client.clientId}`,
|
|
389
|
+
content: html `<p>Choose a config format to download.</p>`,
|
|
390
|
+
menuOptions: [
|
|
391
|
+
{
|
|
392
|
+
name: 'WireGuard (.conf)',
|
|
393
|
+
iconName: 'lucide:shield',
|
|
394
|
+
action: async (modalArg) => {
|
|
395
|
+
await modalArg.destroy();
|
|
396
|
+
await exportConfig('wireguard');
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
name: 'SmartVPN (.json)',
|
|
401
|
+
iconName: 'lucide:braces',
|
|
402
|
+
action: async (modalArg) => {
|
|
403
|
+
await modalArg.destroy();
|
|
404
|
+
await exportConfig('smartvpn');
|
|
405
|
+
},
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
name: 'Cancel',
|
|
409
|
+
iconName: 'lucide:x',
|
|
410
|
+
action: async (modalArg) => await modalArg.destroy(),
|
|
411
|
+
},
|
|
412
|
+
],
|
|
413
|
+
});
|
|
414
|
+
},
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
name: 'Rotate Keys',
|
|
418
|
+
iconName: 'lucide:rotate-cw',
|
|
419
|
+
type: ['contextmenu'],
|
|
420
|
+
actionFunc: async (actionData) => {
|
|
421
|
+
const client = actionData.item;
|
|
422
|
+
const { DeesModal, DeesToast } = await import('@design.estate/dees-catalog');
|
|
423
|
+
DeesModal.createAndShow({
|
|
424
|
+
heading: 'Rotate Client Keys',
|
|
425
|
+
content: html `<p>Generate new keys for "${client.clientId}"? The old keys will be invalidated and the client will need the new config to reconnect.</p>`,
|
|
426
|
+
menuOptions: [
|
|
427
|
+
{ name: 'Cancel', iconName: 'lucide:x', action: async (modalArg) => await modalArg.destroy() },
|
|
428
|
+
{
|
|
429
|
+
name: 'Rotate',
|
|
430
|
+
iconName: 'lucide:rotate-cw',
|
|
431
|
+
action: async (modalArg) => {
|
|
432
|
+
try {
|
|
433
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest('/typedrequest', 'rotateVpnClientKey');
|
|
434
|
+
const response = await request.fire({
|
|
435
|
+
identity: appstate.loginStatePart.getState().identity,
|
|
436
|
+
clientId: client.clientId,
|
|
437
|
+
});
|
|
438
|
+
if (response.success && response.wireguardConfig) {
|
|
439
|
+
appstate.vpnStatePart.setState({
|
|
440
|
+
...appstate.vpnStatePart.getState(),
|
|
441
|
+
newClientConfig: response.wireguardConfig,
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
await modalArg.destroy();
|
|
445
|
+
}
|
|
446
|
+
catch (err) {
|
|
447
|
+
DeesToast.createAndShow({ message: err.message || 'Rotate failed', type: 'error', duration: 5000 });
|
|
448
|
+
}
|
|
449
|
+
},
|
|
450
|
+
},
|
|
451
|
+
],
|
|
452
|
+
});
|
|
453
|
+
},
|
|
454
|
+
},
|
|
303
455
|
{
|
|
304
456
|
name: 'Delete',
|
|
305
457
|
iconName: 'lucide:trash2',
|
|
306
|
-
|
|
458
|
+
type: ['contextmenu'],
|
|
459
|
+
actionFunc: async (actionData) => {
|
|
460
|
+
const client = actionData.item;
|
|
307
461
|
const { DeesModal } = await import('@design.estate/dees-catalog');
|
|
308
462
|
DeesModal.createAndShow({
|
|
309
463
|
heading: 'Delete VPN Client',
|
|
310
464
|
content: html `<p>Are you sure you want to delete client "${client.clientId}"?</p>`,
|
|
311
465
|
menuOptions: [
|
|
312
|
-
{ name: 'Cancel', action: async (
|
|
466
|
+
{ name: 'Cancel', iconName: 'lucide:x', action: async (modalArg) => await modalArg.destroy() },
|
|
313
467
|
{
|
|
314
468
|
name: 'Delete',
|
|
315
|
-
|
|
469
|
+
iconName: 'lucide:trash2',
|
|
470
|
+
action: async (modalArg) => {
|
|
316
471
|
await appstate.vpnStatePart.dispatchAction(appstate.deleteVpnClientAction, client.clientId);
|
|
317
|
-
|
|
472
|
+
await modalArg.destroy();
|
|
318
473
|
},
|
|
319
474
|
},
|
|
320
475
|
],
|
|
@@ -322,37 +477,8 @@ let OpsViewVpn = (() => {
|
|
|
322
477
|
},
|
|
323
478
|
},
|
|
324
479
|
]}
|
|
325
|
-
.createNewItem=${async () => {
|
|
326
|
-
const { DeesModal, DeesForm, DeesInputText } = await import('@design.estate/dees-catalog');
|
|
327
|
-
DeesModal.createAndShow({
|
|
328
|
-
heading: 'Create VPN Client',
|
|
329
|
-
content: html `
|
|
330
|
-
<dees-form>
|
|
331
|
-
<dees-input-text id="clientId" .label=${'Client ID'} .key=${'clientId'} required></dees-input-text>
|
|
332
|
-
<dees-input-text id="description" .label=${'Description'} .key=${'description'}></dees-input-text>
|
|
333
|
-
<dees-input-text id="tags" .label=${'Tags (comma-separated)'} .key=${'tags'}></dees-input-text>
|
|
334
|
-
</dees-form>
|
|
335
|
-
`,
|
|
336
|
-
menuOptions: [
|
|
337
|
-
{ name: 'Cancel', action: async (modal) => modal.destroy() },
|
|
338
|
-
{
|
|
339
|
-
name: 'Create',
|
|
340
|
-
action: async (modal) => {
|
|
341
|
-
const form = modal.shadowRoot.querySelector('dees-form');
|
|
342
|
-
const data = await form.collectFormData();
|
|
343
|
-
const serverDefinedClientTags = data.tags ? data.tags.split(',').map((t) => t.trim()).filter(Boolean) : undefined;
|
|
344
|
-
await appstate.vpnStatePart.dispatchAction(appstate.createVpnClientAction, {
|
|
345
|
-
clientId: data.clientId,
|
|
346
|
-
description: data.description || undefined,
|
|
347
|
-
serverDefinedClientTags,
|
|
348
|
-
});
|
|
349
|
-
modal.destroy();
|
|
350
|
-
},
|
|
351
|
-
},
|
|
352
|
-
],
|
|
353
|
-
});
|
|
354
|
-
}}
|
|
355
480
|
></dees-table>
|
|
481
|
+
</div>
|
|
356
482
|
`;
|
|
357
483
|
}
|
|
358
484
|
static {
|
|
@@ -362,4 +488,4 @@ let OpsViewVpn = (() => {
|
|
|
362
488
|
return OpsViewVpn = _classThis;
|
|
363
489
|
})();
|
|
364
490
|
export { OpsViewVpn };
|
|
365
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BzLXZpZXctdnBuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfd2ViL2VsZW1lbnRzL29wcy12aWV3LXZwbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsT0FBTyxFQUNMLFdBQVcsRUFDWCxJQUFJLEVBQ0osYUFBYSxFQUViLEdBQUcsRUFDSCxLQUFLLEVBQ0wsVUFBVSxHQUNYLE1BQU0sNkJBQTZCLENBQUM7QUFDckMsT0FBTyxLQUFLLFFBQVEsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEtBQUssVUFBVSxNQUFNLG1DQUFtQyxDQUFDO0FBQ2hFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM5QyxPQUFPLEVBQW1CLE1BQU0sNkJBQTZCLENBQUM7SUFTakQsVUFBVTs0QkFEdEIsYUFBYSxDQUFDLGNBQWMsQ0FBQzs7OztzQkFDRSxXQUFXOzs7OzBCQUFuQixTQUFRLFdBQVc7Ozs7b0NBQ3hDLEtBQUssRUFBRTtZQUNSLDZLQUFTLFFBQVEsNkJBQVIsUUFBUSwyRkFBeUQ7WUFGNUUsNktBZ1RDOzs7O1FBOVNDLDZFQUF3QyxRQUFRLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRyxFQUFDO1FBQTFFLElBQVMsUUFBUSw4Q0FBeUQ7UUFBMUUsSUFBUyxRQUFRLG9EQUF5RDtRQUUxRTtZQUNFLEtBQUssRUFBRSxDQUFDOztZQUNSLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7Z0JBQ2hFLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1lBQzNCLENBQUMsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDaEM7UUFFRCxLQUFLLENBQUMsaUJBQWlCO1lBQ3JCLE1B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
|
|
491
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BzLXZpZXctdnBuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfd2ViL2VsZW1lbnRzL29wcy12aWV3LXZwbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsT0FBTyxFQUNMLFdBQVcsRUFDWCxJQUFJLEVBQ0osYUFBYSxFQUViLEdBQUcsRUFDSCxLQUFLLEVBQ0wsVUFBVSxHQUNYLE1BQU0sNkJBQTZCLENBQUM7QUFDckMsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxLQUFLLFFBQVEsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEtBQUssVUFBVSxNQUFNLG1DQUFtQyxDQUFDO0FBQ2hFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM5QyxPQUFPLEVBQW1CLE1BQU0sNkJBQTZCLENBQUM7SUFTakQsVUFBVTs0QkFEdEIsYUFBYSxDQUFDLGNBQWMsQ0FBQzs7OztzQkFDRSxXQUFXOzs7OzBCQUFuQixTQUFRLFdBQVc7Ozs7b0NBQ3hDLEtBQUssRUFBRTtZQUNSLDZLQUFTLFFBQVEsNkJBQVIsUUFBUSwyRkFBeUQ7WUFGNUUsNktBOGFDOzs7O1FBNWFDLDZFQUF3QyxRQUFRLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRyxFQUFDO1FBQTFFLElBQVMsUUFBUSw4Q0FBeUQ7UUFBMUUsSUFBUyxRQUFRLG9EQUF5RDtRQUUxRTtZQUNFLEtBQUssRUFBRSxDQUFDOztZQUNSLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7Z0JBQ2hFLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1lBQzNCLENBQUMsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7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
|
package/package.json
CHANGED
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
state,
|
|
8
8
|
cssManager,
|
|
9
9
|
} from '@design.estate/dees-element';
|
|
10
|
+
import * as plugins from '../plugins.js';
|
|
10
11
|
import * as appstate from '../appstate.js';
|
|
11
12
|
import * as interfaces from '../../dist_ts_interfaces/index.js';
|
|
12
13
|
import { viewHostCss } from './shared/css.js';
|
|
@@ -188,6 +189,7 @@ export class OpsViewVpn extends DeesElement {
|
|
|
188
189
|
|
|
189
190
|
return html`
|
|
190
191
|
<ops-sectionheading>VPN</ops-sectionheading>
|
|
192
|
+
<div class="vpnContainer">
|
|
191
193
|
|
|
192
194
|
${this.vpnState.newClientConfig ? html`
|
|
193
195
|
<div class="configDialog">
|
|
@@ -220,7 +222,7 @@ export class OpsViewVpn extends DeesElement {
|
|
|
220
222
|
</div>
|
|
221
223
|
` : ''}
|
|
222
224
|
|
|
223
|
-
<dees-statsgrid .
|
|
225
|
+
<dees-statsgrid .tiles=${statsTiles}></dees-statsgrid>
|
|
224
226
|
|
|
225
227
|
${status ? html`
|
|
226
228
|
<div class="serverInfo">
|
|
@@ -258,31 +260,185 @@ export class OpsViewVpn extends DeesElement {
|
|
|
258
260
|
'Created': new Date(client.createdAt).toLocaleDateString(),
|
|
259
261
|
})}
|
|
260
262
|
.dataActions=${[
|
|
263
|
+
{
|
|
264
|
+
name: 'Create Client',
|
|
265
|
+
iconName: 'lucide:plus',
|
|
266
|
+
type: ['header'],
|
|
267
|
+
actionFunc: async () => {
|
|
268
|
+
const { DeesModal } = await import('@design.estate/dees-catalog');
|
|
269
|
+
await DeesModal.createAndShow({
|
|
270
|
+
heading: 'Create VPN Client',
|
|
271
|
+
content: html`
|
|
272
|
+
<dees-form>
|
|
273
|
+
<dees-input-text .key=${'clientId'} .label=${'Client ID'} .required=${true}></dees-input-text>
|
|
274
|
+
<dees-input-text .key=${'description'} .label=${'Description'}></dees-input-text>
|
|
275
|
+
<dees-input-text .key=${'tags'} .label=${'Server-Defined Tags (comma-separated)'}></dees-input-text>
|
|
276
|
+
</dees-form>
|
|
277
|
+
`,
|
|
278
|
+
menuOptions: [
|
|
279
|
+
{
|
|
280
|
+
name: 'Cancel',
|
|
281
|
+
iconName: 'lucide:x',
|
|
282
|
+
action: async (modalArg: any) => await modalArg.destroy(),
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
name: 'Create',
|
|
286
|
+
iconName: 'lucide:plus',
|
|
287
|
+
action: async (modalArg: any) => {
|
|
288
|
+
const form = modalArg.shadowRoot?.querySelector('.content')?.querySelector('dees-form');
|
|
289
|
+
if (!form) return;
|
|
290
|
+
const data = await form.collectFormData();
|
|
291
|
+
if (!data.clientId) return;
|
|
292
|
+
const serverDefinedClientTags = data.tags
|
|
293
|
+
? data.tags.split(',').map((t: string) => t.trim()).filter(Boolean)
|
|
294
|
+
: undefined;
|
|
295
|
+
await appstate.vpnStatePart.dispatchAction(appstate.createVpnClientAction, {
|
|
296
|
+
clientId: data.clientId,
|
|
297
|
+
description: data.description || undefined,
|
|
298
|
+
serverDefinedClientTags,
|
|
299
|
+
});
|
|
300
|
+
await modalArg.destroy();
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
],
|
|
304
|
+
});
|
|
305
|
+
},
|
|
306
|
+
},
|
|
261
307
|
{
|
|
262
308
|
name: 'Toggle',
|
|
263
309
|
iconName: 'lucide:power',
|
|
264
|
-
|
|
310
|
+
type: ['contextmenu', 'inRow'],
|
|
311
|
+
actionFunc: async (actionData: any) => {
|
|
312
|
+
const client = actionData.item as interfaces.data.IVpnClient;
|
|
265
313
|
await appstate.vpnStatePart.dispatchAction(appstate.toggleVpnClientAction, {
|
|
266
314
|
clientId: client.clientId,
|
|
267
315
|
enabled: !client.enabled,
|
|
268
316
|
});
|
|
269
317
|
},
|
|
270
318
|
},
|
|
319
|
+
{
|
|
320
|
+
name: 'Export Config',
|
|
321
|
+
iconName: 'lucide:download',
|
|
322
|
+
type: ['contextmenu', 'inRow'],
|
|
323
|
+
actionFunc: async (actionData: any) => {
|
|
324
|
+
const client = actionData.item as interfaces.data.IVpnClient;
|
|
325
|
+
const { DeesModal, DeesToast } = await import('@design.estate/dees-catalog');
|
|
326
|
+
|
|
327
|
+
const exportConfig = async (format: 'wireguard' | 'smartvpn') => {
|
|
328
|
+
try {
|
|
329
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
330
|
+
interfaces.requests.IReq_ExportVpnClientConfig
|
|
331
|
+
>('/typedrequest', 'exportVpnClientConfig');
|
|
332
|
+
const response = await request.fire({
|
|
333
|
+
identity: appstate.loginStatePart.getState()!.identity!,
|
|
334
|
+
clientId: client.clientId,
|
|
335
|
+
format,
|
|
336
|
+
});
|
|
337
|
+
if (response.success && response.config) {
|
|
338
|
+
const ext = format === 'wireguard' ? 'conf' : 'json';
|
|
339
|
+
const blob = new Blob([response.config], { type: 'text/plain' });
|
|
340
|
+
const url = URL.createObjectURL(blob);
|
|
341
|
+
const a = document.createElement('a');
|
|
342
|
+
a.href = url;
|
|
343
|
+
a.download = `${client.clientId}.${ext}`;
|
|
344
|
+
a.click();
|
|
345
|
+
URL.revokeObjectURL(url);
|
|
346
|
+
DeesToast.createAndShow({ message: `${format} config downloaded`, type: 'success', duration: 3000 });
|
|
347
|
+
} else {
|
|
348
|
+
DeesToast.createAndShow({ message: response.message || 'Export failed', type: 'error', duration: 5000 });
|
|
349
|
+
}
|
|
350
|
+
} catch (err: any) {
|
|
351
|
+
DeesToast.createAndShow({ message: err.message || 'Export failed', type: 'error', duration: 5000 });
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
DeesModal.createAndShow({
|
|
356
|
+
heading: `Export Config: ${client.clientId}`,
|
|
357
|
+
content: html`<p>Choose a config format to download.</p>`,
|
|
358
|
+
menuOptions: [
|
|
359
|
+
{
|
|
360
|
+
name: 'WireGuard (.conf)',
|
|
361
|
+
iconName: 'lucide:shield',
|
|
362
|
+
action: async (modalArg: any) => {
|
|
363
|
+
await modalArg.destroy();
|
|
364
|
+
await exportConfig('wireguard');
|
|
365
|
+
},
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
name: 'SmartVPN (.json)',
|
|
369
|
+
iconName: 'lucide:braces',
|
|
370
|
+
action: async (modalArg: any) => {
|
|
371
|
+
await modalArg.destroy();
|
|
372
|
+
await exportConfig('smartvpn');
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
name: 'Cancel',
|
|
377
|
+
iconName: 'lucide:x',
|
|
378
|
+
action: async (modalArg: any) => await modalArg.destroy(),
|
|
379
|
+
},
|
|
380
|
+
],
|
|
381
|
+
});
|
|
382
|
+
},
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
name: 'Rotate Keys',
|
|
386
|
+
iconName: 'lucide:rotate-cw',
|
|
387
|
+
type: ['contextmenu'],
|
|
388
|
+
actionFunc: async (actionData: any) => {
|
|
389
|
+
const client = actionData.item as interfaces.data.IVpnClient;
|
|
390
|
+
const { DeesModal, DeesToast } = await import('@design.estate/dees-catalog');
|
|
391
|
+
DeesModal.createAndShow({
|
|
392
|
+
heading: 'Rotate Client Keys',
|
|
393
|
+
content: html`<p>Generate new keys for "${client.clientId}"? The old keys will be invalidated and the client will need the new config to reconnect.</p>`,
|
|
394
|
+
menuOptions: [
|
|
395
|
+
{ name: 'Cancel', iconName: 'lucide:x', action: async (modalArg: any) => await modalArg.destroy() },
|
|
396
|
+
{
|
|
397
|
+
name: 'Rotate',
|
|
398
|
+
iconName: 'lucide:rotate-cw',
|
|
399
|
+
action: async (modalArg: any) => {
|
|
400
|
+
try {
|
|
401
|
+
const request = new plugins.domtools.plugins.typedrequest.TypedRequest<
|
|
402
|
+
interfaces.requests.IReq_RotateVpnClientKey
|
|
403
|
+
>('/typedrequest', 'rotateVpnClientKey');
|
|
404
|
+
const response = await request.fire({
|
|
405
|
+
identity: appstate.loginStatePart.getState()!.identity!,
|
|
406
|
+
clientId: client.clientId,
|
|
407
|
+
});
|
|
408
|
+
if (response.success && response.wireguardConfig) {
|
|
409
|
+
appstate.vpnStatePart.setState({
|
|
410
|
+
...appstate.vpnStatePart.getState()!,
|
|
411
|
+
newClientConfig: response.wireguardConfig,
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
await modalArg.destroy();
|
|
415
|
+
} catch (err: any) {
|
|
416
|
+
DeesToast.createAndShow({ message: err.message || 'Rotate failed', type: 'error', duration: 5000 });
|
|
417
|
+
}
|
|
418
|
+
},
|
|
419
|
+
},
|
|
420
|
+
],
|
|
421
|
+
});
|
|
422
|
+
},
|
|
423
|
+
},
|
|
271
424
|
{
|
|
272
425
|
name: 'Delete',
|
|
273
426
|
iconName: 'lucide:trash2',
|
|
274
|
-
|
|
427
|
+
type: ['contextmenu'],
|
|
428
|
+
actionFunc: async (actionData: any) => {
|
|
429
|
+
const client = actionData.item as interfaces.data.IVpnClient;
|
|
275
430
|
const { DeesModal } = await import('@design.estate/dees-catalog');
|
|
276
431
|
DeesModal.createAndShow({
|
|
277
432
|
heading: 'Delete VPN Client',
|
|
278
433
|
content: html`<p>Are you sure you want to delete client "${client.clientId}"?</p>`,
|
|
279
434
|
menuOptions: [
|
|
280
|
-
{ name: 'Cancel', action: async (
|
|
435
|
+
{ name: 'Cancel', iconName: 'lucide:x', action: async (modalArg: any) => await modalArg.destroy() },
|
|
281
436
|
{
|
|
282
437
|
name: 'Delete',
|
|
283
|
-
|
|
438
|
+
iconName: 'lucide:trash2',
|
|
439
|
+
action: async (modalArg: any) => {
|
|
284
440
|
await appstate.vpnStatePart.dispatchAction(appstate.deleteVpnClientAction, client.clientId);
|
|
285
|
-
|
|
441
|
+
await modalArg.destroy();
|
|
286
442
|
},
|
|
287
443
|
},
|
|
288
444
|
],
|
|
@@ -290,37 +446,8 @@ export class OpsViewVpn extends DeesElement {
|
|
|
290
446
|
},
|
|
291
447
|
},
|
|
292
448
|
]}
|
|
293
|
-
.createNewItem=${async () => {
|
|
294
|
-
const { DeesModal, DeesForm, DeesInputText } = await import('@design.estate/dees-catalog');
|
|
295
|
-
DeesModal.createAndShow({
|
|
296
|
-
heading: 'Create VPN Client',
|
|
297
|
-
content: html`
|
|
298
|
-
<dees-form>
|
|
299
|
-
<dees-input-text id="clientId" .label=${'Client ID'} .key=${'clientId'} required></dees-input-text>
|
|
300
|
-
<dees-input-text id="description" .label=${'Description'} .key=${'description'}></dees-input-text>
|
|
301
|
-
<dees-input-text id="tags" .label=${'Tags (comma-separated)'} .key=${'tags'}></dees-input-text>
|
|
302
|
-
</dees-form>
|
|
303
|
-
`,
|
|
304
|
-
menuOptions: [
|
|
305
|
-
{ name: 'Cancel', action: async (modal: any) => modal.destroy() },
|
|
306
|
-
{
|
|
307
|
-
name: 'Create',
|
|
308
|
-
action: async (modal: any) => {
|
|
309
|
-
const form = modal.shadowRoot!.querySelector('dees-form') as any;
|
|
310
|
-
const data = await form.collectFormData();
|
|
311
|
-
const serverDefinedClientTags = data.tags ? data.tags.split(',').map((t: string) => t.trim()).filter(Boolean) : undefined;
|
|
312
|
-
await appstate.vpnStatePart.dispatchAction(appstate.createVpnClientAction, {
|
|
313
|
-
clientId: data.clientId,
|
|
314
|
-
description: data.description || undefined,
|
|
315
|
-
serverDefinedClientTags,
|
|
316
|
-
});
|
|
317
|
-
modal.destroy();
|
|
318
|
-
},
|
|
319
|
-
},
|
|
320
|
-
],
|
|
321
|
-
});
|
|
322
|
-
}}
|
|
323
449
|
></dees-table>
|
|
450
|
+
</div>
|
|
324
451
|
`;
|
|
325
452
|
}
|
|
326
453
|
}
|