feat: file manager with browse, search, upload, chmod/chown

- Full file browser page at /files with lazy-load, breadcrumbs, drag&drop
- FileBrowserModal component for path selection from Samba/NFS forms
- PathField component replaces bare inputs in share/export forms
- Backend: /api/files/* routes with List, Mkdir, Rename, Delete, Chmod, Chown, Upload, Download, Preview, Search
- Reuses NASCTL_ALLOWED_ROOTS for path validation
- NASCTL_UPLOAD_MAX_BYTES (100MB) and NASCTL_PREVIEW_MAX_BYTES (256KB) env vars
- Capabilities endpoint returns chmod/chown availability (requires root)
- Version bump: 0.3.2 -> 0.4.0
This commit is contained in:
2026-07-06 01:56:40 -04:00
parent 0da789cd96
commit 50ed8abe95
17 changed files with 2209 additions and 30 deletions
+28 -16
View File
@@ -190,29 +190,41 @@ func (s *Server) RequireAuth(next http.Handler) http.Handler {
}
type Server struct {
DB *db.DB
Engine *engine.Engine
AllowedRoots []string
Auth *AuthService
SMBConfPath string
ExportsPath string
DB *db.DB
Engine *engine.Engine
AllowedRoots []string
Auth *AuthService
SMBConfPath string
ExportsPath string
UploadMaxBytes int64
PreviewMaxBytes int64
}
type Options struct {
AllowedRoots []string
Auth *AuthService
SMBConfPath string
ExportsPath string
AllowedRoots []string
Auth *AuthService
SMBConfPath string
ExportsPath string
UploadMaxBytes int64
PreviewMaxBytes int64
}
func NewServer(database *db.DB, eng *engine.Engine, opts Options) *Server {
if opts.UploadMaxBytes == 0 {
opts.UploadMaxBytes = 100 << 20 // 100 MB
}
if opts.PreviewMaxBytes == 0 {
opts.PreviewMaxBytes = 256 << 10 // 256 KB
}
return &Server{
DB: database,
Engine: eng,
AllowedRoots: opts.AllowedRoots,
Auth: opts.Auth,
SMBConfPath: opts.SMBConfPath,
ExportsPath: opts.ExportsPath,
DB: database,
Engine: eng,
AllowedRoots: opts.AllowedRoots,
Auth: opts.Auth,
SMBConfPath: opts.SMBConfPath,
ExportsPath: opts.ExportsPath,
UploadMaxBytes: opts.UploadMaxBytes,
PreviewMaxBytes: opts.PreviewMaxBytes,
}
}