@serve.zone/dcrouter 13.28.0 → 13.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.smartconfig.json +32 -10
- package/dist_serve/bundle.js +561 -544
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.dcrouter.d.ts +7 -0
- package/dist_ts/classes.dcrouter.js +12 -2
- package/dist_ts/config/classes.route-config-manager.js +8 -7
- package/dist_ts/opsserver/classes.opsserver.js +4 -1
- package/dist_ts/opsserver/handlers/admin.handler.d.ts +21 -6
- package/dist_ts/opsserver/handlers/admin.handler.js +188 -29
- package/dist_ts/opsserver/handlers/target-profile.handler.js +3 -1
- package/dist_ts/opsserver/handlers/users.handler.js +2 -2
- package/dist_ts/plugins.d.ts +2 -0
- package/dist_ts/plugins.js +4 -1
- package/dist_ts/vpn/classes.vpn-manager.d.ts +2 -0
- package/dist_ts/vpn/classes.vpn-manager.js +41 -20
- package/dist_ts_interfaces/requests/admin.d.ts +38 -0
- package/dist_ts_interfaces/requests/users.d.ts +2 -5
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/appstate.d.ts +17 -0
- package/dist_ts_web/appstate.js +27 -1
- package/dist_ts_web/elements/ops-dashboard.d.ts +4 -0
- package/dist_ts_web/elements/ops-dashboard.js +100 -3
- package/package.json +15 -22
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.dcrouter.ts +20 -1
- package/ts/config/classes.route-config-manager.ts +8 -6
- package/ts/opsserver/classes.opsserver.ts +3 -0
- package/ts/opsserver/handlers/admin.handler.ts +244 -32
- package/ts/opsserver/handlers/target-profile.handler.ts +2 -0
- package/ts/opsserver/handlers/users.handler.ts +1 -1
- package/ts/plugins.ts +7 -0
- package/ts/vpn/classes.vpn-manager.ts +56 -25
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/appstate.ts +49 -0
- package/ts_web/elements/ops-dashboard.ts +100 -0
|
@@ -66,6 +66,9 @@ export class OpsDashboard extends DeesElement {
|
|
|
66
66
|
isLoggedIn: false,
|
|
67
67
|
};
|
|
68
68
|
|
|
69
|
+
private bootstrapStepper?: any;
|
|
70
|
+
private bootstrapCheckPromise?: Promise<void>;
|
|
71
|
+
|
|
69
72
|
@state() accessor uiState: appstate.IUiState = {
|
|
70
73
|
activeView: 'overview',
|
|
71
74
|
activeSubview: null,
|
|
@@ -336,6 +339,7 @@ export class OpsDashboard extends DeesElement {
|
|
|
336
339
|
await (simpleLogin as any).switchToSlottedContent();
|
|
337
340
|
await appstate.statsStatePart.dispatchAction(appstate.fetchAllStatsAction, null);
|
|
338
341
|
await appstate.configStatePart.dispatchAction(appstate.fetchConfigurationAction, null);
|
|
342
|
+
await this.ensureAdminBootstrap();
|
|
339
343
|
} else {
|
|
340
344
|
// Server rejected the JWT — clear state, show login
|
|
341
345
|
await appstate.loginStatePart.dispatchAction(appstate.logoutAction, null);
|
|
@@ -370,10 +374,106 @@ export class OpsDashboard extends DeesElement {
|
|
|
370
374
|
await simpleLogin!.switchToSlottedContent();
|
|
371
375
|
await appstate.statsStatePart.dispatchAction(appstate.fetchAllStatsAction, null);
|
|
372
376
|
await appstate.configStatePart.dispatchAction(appstate.fetchConfigurationAction, null);
|
|
377
|
+
await this.ensureAdminBootstrap();
|
|
373
378
|
} else {
|
|
374
379
|
form!.setStatus('error', 'Login failed!');
|
|
375
380
|
await domtools.convenience.smartdelay.delayFor(2000);
|
|
376
381
|
form!.reset();
|
|
377
382
|
}
|
|
378
383
|
}
|
|
384
|
+
|
|
385
|
+
private async ensureAdminBootstrap(): Promise<void> {
|
|
386
|
+
if (!this.loginState.identity || this.bootstrapStepper?.isConnected) {
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
if (this.bootstrapCheckPromise) {
|
|
390
|
+
return this.bootstrapCheckPromise;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
this.bootstrapCheckPromise = (async () => {
|
|
394
|
+
try {
|
|
395
|
+
const status = await appstate.getAdminBootstrapStatus();
|
|
396
|
+
if (status.needsBootstrap) {
|
|
397
|
+
await this.showAdminBootstrapStepper(status);
|
|
398
|
+
}
|
|
399
|
+
} catch (error) {
|
|
400
|
+
console.error('Admin bootstrap status check failed:', error);
|
|
401
|
+
} finally {
|
|
402
|
+
this.bootstrapCheckPromise = undefined;
|
|
403
|
+
}
|
|
404
|
+
})();
|
|
405
|
+
|
|
406
|
+
return this.bootstrapCheckPromise;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
private async showAdminBootstrapStepper(statusArg: appstate.IAdminBootstrapStatus): Promise<void> {
|
|
410
|
+
const { DeesStepper } = await import('@design.estate/dees-catalog');
|
|
411
|
+
this.bootstrapStepper = await DeesStepper.createAndShow({
|
|
412
|
+
cancelable: false,
|
|
413
|
+
steps: [
|
|
414
|
+
{
|
|
415
|
+
title: 'Create Persisted Admin',
|
|
416
|
+
content: html`
|
|
417
|
+
<div style="display: grid; gap: 16px; color: var(--dees-color-text-secondary); font-size: 14px; line-height: 1.5;">
|
|
418
|
+
<p style="margin: 0;">
|
|
419
|
+
This router is currently using the temporary bootstrap admin. Create the first persisted admin account to continue.
|
|
420
|
+
</p>
|
|
421
|
+
<dees-form>
|
|
422
|
+
<dees-input-text .key=${'email'} .label=${'Admin email'} .required=${true}></dees-input-text>
|
|
423
|
+
<dees-input-text .key=${'name'} .label=${'Display name'}></dees-input-text>
|
|
424
|
+
<dees-input-text .key=${'password'} .label=${'Password'} .required=${true} .isPasswordBool=${true}></dees-input-text>
|
|
425
|
+
<dees-input-text .key=${'passwordConfirm'} .label=${'Confirm password'} .required=${true} .isPasswordBool=${true}></dees-input-text>
|
|
426
|
+
<dees-input-checkbox
|
|
427
|
+
.key=${'enableIdpGlobalAuth'}
|
|
428
|
+
.label=${'Allow idp.global login for this email'}
|
|
429
|
+
.description=${statusArg.idpGlobalConfigured
|
|
430
|
+
? 'The local account remains authoritative; idp.global only verifies identity.'
|
|
431
|
+
: 'Requires DCROUTER_IDP_GLOBAL_URL before idp.global logins can work.'}
|
|
432
|
+
></dees-input-checkbox>
|
|
433
|
+
</dees-form>
|
|
434
|
+
</div>
|
|
435
|
+
`,
|
|
436
|
+
menuOptions: [
|
|
437
|
+
{
|
|
438
|
+
name: 'Create admin',
|
|
439
|
+
action: async (stepperArg: any) => {
|
|
440
|
+
const form = stepperArg.shadowRoot?.querySelector('.selected dees-form') as any;
|
|
441
|
+
if (!form) return;
|
|
442
|
+
const formData = await form.collectFormData();
|
|
443
|
+
const email = String(formData.email || '').trim();
|
|
444
|
+
const name = String(formData.name || '').trim();
|
|
445
|
+
const password = String(formData.password || '');
|
|
446
|
+
const passwordConfirm = String(formData.passwordConfirm || '');
|
|
447
|
+
|
|
448
|
+
if (!email || !password) {
|
|
449
|
+
form.setStatus?.('error', 'Email and password are required.');
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
if (password !== passwordConfirm) {
|
|
453
|
+
form.setStatus?.('error', 'Passwords do not match.');
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
try {
|
|
458
|
+
form.setStatus?.('pending', 'Creating persisted admin...');
|
|
459
|
+
await appstate.createInitialAdminUser({
|
|
460
|
+
email,
|
|
461
|
+
name,
|
|
462
|
+
password,
|
|
463
|
+
enableIdpGlobalAuth: Boolean(formData.enableIdpGlobalAuth),
|
|
464
|
+
});
|
|
465
|
+
form.setStatus?.('success', 'Persisted admin created.');
|
|
466
|
+
await stepperArg.destroy();
|
|
467
|
+
this.bootstrapStepper = undefined;
|
|
468
|
+
await appstate.usersStatePart.dispatchAction(appstate.fetchUsersAction, null);
|
|
469
|
+
} catch (error) {
|
|
470
|
+
form.setStatus?.('error', error instanceof Error ? error.message : 'Failed to create admin.');
|
|
471
|
+
}
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
],
|
|
475
|
+
},
|
|
476
|
+
],
|
|
477
|
+
});
|
|
478
|
+
}
|
|
379
479
|
}
|