Add token expiry, edit notice, log allowlist, local-zone test; merge PLAN.md into SPECS.md
get_logs needs a unit from an allowlist (router-*, kea, unbound, networkd, nftables, ddclient, acme, sshd, kernel). API tokens are valid for 1, 7, 30 (default) or 90 days, or without limit. The overview and the Changes page say which token made the unapplied changes. options.json (router://options) no longer holds the options' source paths: they differ between builds of a release, so a router rebuilding itself offline had to build the file and failed (found by the update test). Web UI: panels flow into columns on wide screens and the width is no longer capped; on phones the navigation is a menu button; the Advanced page uses panels; VLAN dropdowns show their chosen names; the duplicate WireGuard heading is gone. basic: a subtest for wan -> local rules. SPECS.md is now the only document (decisions, how each part works, and what is not done yet); PLAN.md is gone. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AeFqV9dZrK6nipHkPfyM4F
This commit is contained in:
@@ -4,8 +4,14 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// How long a new token works (the form's choices; 0 is never).
|
||||
var tokenLifetimes = map[string]time.Duration{
|
||||
"1d": 24 * time.Hour, "7d": 7 * 24 * time.Hour, "30d": 30 * 24 * time.Hour, "90d": 90 * 24 * time.Hour, "never": 0,
|
||||
}
|
||||
|
||||
type tokensData struct {
|
||||
Tokens []Token
|
||||
Audit []AuditEntry
|
||||
@@ -24,7 +30,11 @@ func (a *app) tokensPage(w http.ResponseWriter, r *http.Request, sess session) {
|
||||
}
|
||||
|
||||
func (a *app) tokenCreate(w http.ResponseWriter, r *http.Request, sess session) {
|
||||
tok, secret, err := a.tokens.Create(r.PostFormValue("name"), r.PostFormValue("scope"))
|
||||
valid, ok := tokenLifetimes[r.PostFormValue("valid")]
|
||||
if !ok {
|
||||
valid = tokenLifetimes["30d"]
|
||||
}
|
||||
tok, secret, err := a.tokens.CreateFor(r.PostFormValue("name"), r.PostFormValue("scope"), valid)
|
||||
p := page{Title: "API access", CSRF: sess.csrf, LoggedIn: true}
|
||||
d := a.tokensData(r)
|
||||
if err != nil {
|
||||
@@ -50,6 +60,6 @@ func (a *app) tokenRevoke(w http.ResponseWriter, r *http.Request, _ session) {
|
||||
// ones, for a person to review before applying.
|
||||
func (a *app) changesPage(w http.ResponseWriter, r *http.Request, sess session) {
|
||||
a.render(w, "changes", page{Title: "Changes", CSRF: sess.csrf, LoggedIn: true, Data: map[string]any{
|
||||
"Diff": a.sys.pendingChanges(), "Unapplied": a.sys.Status().Unapplied,
|
||||
"Diff": a.sys.pendingChanges(), "Unapplied": a.sys.Status().Unapplied, "TokenEdit": a.sys.Status().TokenEdit,
|
||||
}})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user