1
0
forked from wrenn/wrenn

Add admin capsule management, fix file browser for special files, normalize dialog styles

- Admin capsule CRUD: list, create (platform templates), get detail with
  terminal/files/metrics, snapshot, destroy
- First signup auto-promotes to platform admin
- JWT auth via query param for WebSocket connections
- File browser: handle non-regular files (devices, pipes, sockets) gracefully
  instead of showing raw backend errors
- Normalize admin template dialogs to match established dialog patterns:
  remove accent bars, unify animation/shadow/button styles
This commit is contained in:
2026-04-13 04:12:36 +06:00
parent f920023ecf
commit 90bea52ccd
19 changed files with 1417 additions and 50 deletions

View File

@ -126,6 +126,14 @@ func (h *authHandler) Signup(w http.ResponseWriter, r *http.Request) {
qtx := h.db.WithTx(tx)
// The first user to sign up becomes a platform admin.
userCount, err := qtx.CountUsers(ctx)
if err != nil {
writeError(w, http.StatusInternalServerError, "db_error", "failed to check user count")
return
}
isFirstUser := userCount == 0
userID := id.NewUserID()
_, err = qtx.InsertUser(ctx, db.InsertUserParams{
ID: userID,
@ -143,6 +151,13 @@ func (h *authHandler) Signup(w http.ResponseWriter, r *http.Request) {
return
}
if isFirstUser {
if err := qtx.SetUserAdmin(ctx, db.SetUserAdminParams{ID: userID, IsAdmin: true}); err != nil {
writeError(w, http.StatusInternalServerError, "db_error", "failed to set admin status")
return
}
}
// Create default team.
teamID := id.NewTeamID()
if _, err := qtx.InsertTeam(ctx, db.InsertTeamParams{
@ -169,7 +184,7 @@ func (h *authHandler) Signup(w http.ResponseWriter, r *http.Request) {
return
}
token, err := auth.SignJWT(h.jwtSecret, userID, teamID, req.Email, req.Name, "owner", false)
token, err := auth.SignJWT(h.jwtSecret, userID, teamID, req.Email, req.Name, "owner", isFirstUser)
if err != nil {
writeError(w, http.StatusInternalServerError, "internal_error", "failed to generate token")
return