feat: user roles - admins and users limited to the machines given to them, user editor with machines, password sign-in and its lock; direct address without Cloudflare as the agents' fallback and in the installer; version 0.1.2

This commit is contained in:
redtea committed 2026-10-15 10:56:19 +03:00
1 parent 36dc12b69d
commit 021da93229
29 files changed
+844 -97

No files matched your search

+15 -2
View File
@@ -75,12 +75,20 @@ func (c *challenges) take(id string, adminID int64) bool {
return ok && ch.adminID == adminID && time.Now().Before(ch.expires)
}
// rpID is the site the keys belong to: the host the browser is on.
// mainHost is the main address's host name, set when the server starts.
var mainHost = func() string { return "" }
// rpID is the site the keys belong to: the host the browser is on, or the
// main address's host when the browser is on it or under it - so the keys
// made on lpra.example.com also sign in on direct.lpra.example.com.
func rpID(r *http.Request) string {
host := r.Host
if h, _, err := net.SplitHostPort(host); err == nil {
host = h
}
if m := mainHost(); m != "" && strings.HasSuffix(host, "."+m) {
return m
}
return host
}
@@ -353,7 +361,8 @@ func (s *Server) handleAccount(w http.ResponseWriter, r *http.Request) {
for _, k := range keys {
list = append(list, map[string]any{"id": k.ID, "name": k.Name, "created": k.CreatedAt, "last_used": k.LastUsed})
}
writeJSON(w, map[string]any{"username": a.Username, "keys": list, "password_off": s.db.PasswordOff(a.ID), "pin": s.db.AdminPin(a.ID) != ""})
writeJSON(w, map[string]any{"username": a.Username, "keys": list, "password_off": s.db.PasswordOff(a.ID), "pin": s.db.AdminPin(a.ID) != "",
"pw_locked": a.PwLocked, "admin": a.IsAdmin()})
}
// POST /api/panel/account/password/change - a new password, given the
@@ -406,6 +415,10 @@ func (s *Server) handlePasswordToggle(w http.ResponseWriter, r *http.Request) {
writeJSON(w, map[string]any{"ok": false, "error": "плохой запрос"})
return
}
if a.PwLocked {
writeJSON(w, map[string]any{"ok": false, "error": "вход по паролю закрепил администратор"})
return
}
if in.Off && s.db.CountAdminKeys(a.ID) == 0 {
writeJSON(w, map[string]any{"ok": false, "error": "сначала добавьте ключ доступа"})
return