diff options
| author | historia <[not public]> | 2026-07-11 18:30:58 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-07-11 18:30:58 -0400 |
| commit | 2bacbb08d1ac67c4f63ee535728cd4e8760e3211 (patch) | |
| tree | d8ee366b3d32b486eb05c5e10bc65cf194ae4c23 /internal/admin/api_files.go | |
| parent | 131cbbe586463a7232f332650af5f0b2c13dc7e9 (diff) | |
| download | thehouseoficarus-2bacbb08d1ac67c4f63ee535728cd4e8760e3211.tar.gz | |
feat(admin): unify context menu, add context menu to files tab
Diffstat (limited to 'internal/admin/api_files.go')
| -rw-r--r-- | internal/admin/api_files.go | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/internal/admin/api_files.go b/internal/admin/api_files.go index 2a87dd3..496b08d 100644 --- a/internal/admin/api_files.go +++ b/internal/admin/api_files.go @@ -8,6 +8,71 @@ import ( "strings" ) +func (s *AdminServer) handleFileRename(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, "method not allowed", http.StatusMethodNotAllowed) + return + } + var body struct { + Path string `json:"path"` + NewName string `json:"new_name"` + } + if err := readJSON(r, &body); err != nil || body.Path == "" || body.NewName == "" { + writeJSON(w, map[string]any{"error": "missing path or new_name"}) + return + } + + newName := strings.TrimSpace(body.NewName) + if newName == "" || newName == "." || newName == ".." || strings.ContainsAny(newName, "/\\") { + writeJSON(w, map[string]any{"error": "invalid file name"}) + return + } + for _, c := range newName { + if c < 32 || c == 127 { + writeJSON(w, map[string]any{"error": "file name contains invalid characters"}) + return + } + } + + relPath := strings.TrimPrefix(body.Path, "/") + relPath = strings.TrimPrefix(relPath, "data/") + oldAbs := filepath.Join(s.dataDir, relPath) + + oldContent, err := snapshotFile(oldAbs) + if err != nil { + writeJSON(w, map[string]any{"error": "file not found: " + relPath}) + return + } + + newAbs := filepath.Join(filepath.Dir(oldAbs), newName) + if _, err := os.Stat(newAbs); err == nil { + writeJSON(w, map[string]any{"error": "a file named " + newName + " already exists"}) + return + } + + if err := os.WriteFile(newAbs, oldContent, 0644); err != nil { + writeJSON(w, map[string]any{"error": "write error: " + err.Error()}) + return + } + if err := os.Remove(oldAbs); err != nil { + writeJSON(w, map[string]any{"error": "remove error: " + err.Error()}) + return + } + + newRelPath := filepath.Join(filepath.Dir(relPath), newName) + if filepath.Dir(relPath) == "." { + newRelPath = newName + } + s.undoStack.Push(ChangeDesc{ + Description: "Renamed file " + relPath + " to " + newRelPath, + FilePath: oldAbs, + NewFilePath: newAbs, + OldContent: oldContent, + NewContent: oldContent, + }) + writeJSON(w, map[string]any{"ok": true, "path": newRelPath}) +} + func (s *AdminServer) handleFiles(w http.ResponseWriter, r *http.Request) { relPath := r.URL.Query().Get("path") relPath = strings.TrimPrefix(relPath, "/") |
