Admin name at init, token rotation, read-only forms, token role presets

- stewardd init asks for the first administrator's name on a terminal.
- Tokens can be rotated (steward token rotate, POST /tokens/{id}/rotate,
  Rotate in the web UI), with a grace period for the old secret, as in
  Jarl. Schema migration 2 adds the token columns.
- Read-only users see the settings and a subnet's settings locked,
  instead of editable fields without a Save button.
- The New token dialog only offers roles within what the user may do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
abrown38andClaude Opus 5.5 committed 2026-10-14 13:42:37 +01:00
1 parent db3f245962
commit 8a69038ab5
23 files changed
+418 -28

No files matched your search

+3 -3
View File
@@ -1,5 +1,5 @@
// A subnet's page: its leases, its reservations and its settings.
import { h, mount, badge, errorBox, confirmDialog, modal, input, debounce } from "../ui.js";
import { h, mount, badge, errorBox, confirmDialog, modal, input, debounce, readOnly } from "../ui.js";
import { get, change, can } from "../api.js";
import { usageBar, subnetForm, fmtSeconds, subnetLabel } from "../widgets.js";
import { leasesTable } from "./leases.js";
@@ -53,11 +53,11 @@ async function reservationsTab(el, s) {
async function settingsTab(el, s) {
const settings = await get("/settings");
const form = await subnetForm(s, settings);
if (!can("config", true)) {
mount(el, h("div", { class: "panel" }, h("pre", null, JSON.stringify(s, null, 2))));
mount(el, h("div", { class: "msg info" }, "You can see the subnet's settings but not change them (that needs config:write)."), readOnly(h("div", { class: "panel" }, form)));
return;
}
const form = await subnetForm(s, settings);
const err = h("div");
const save = async (dry) => {
mount(err);