feat: support folder uploads and sanitize upload paths

- Implement `cleanUploadDisplayName` in the backend to safely sanitize uploaded file paths, preserving directory structures while stripping unsafe characters and preventing path traversal.
- Add folder upload capability in the frontend using the Directory Picker API.
- Implement desktop notifications for completed uploads.
This commit is contained in:
2026-06-10 18:14:29 +03:00
parent 0b8d4a3ab9
commit 5d77b36634
7 changed files with 299 additions and 19 deletions

View File

@@ -319,7 +319,7 @@ func (s *UploadService) CreateProcessingBoxFromResumable(sessionID string) (Uplo
}
box.Files = append(box.Files, File{
ID: fileID,
Name: filepath.Base(incoming.Name),
Name: cleanUploadDisplayName(incoming.Name),
StoredName: storedName,
Size: incoming.Size,
ContentType: contentType,
@@ -557,7 +557,7 @@ func (s *UploadService) saveResumableSession(session ResumableSession) error {
func (s *UploadService) resumableFilesFromInput(files []ResumableFileInput, opts UploadOptions, chunkSize int64, existing map[string]bool) ([]ResumableFile, error) {
sessionFiles := make([]ResumableFile, 0, len(files))
for _, file := range files {
file.Name = filepath.Base(strings.TrimSpace(file.Name))
file.Name = cleanUploadDisplayName(file.Name)
if file.Name == "." || file.Name == "" {
return nil, fmt.Errorf("file name is required")
}
@@ -594,7 +594,7 @@ func (s *UploadService) resumableFilesFromInput(files []ResumableFileInput, opts
}
func resumableFileKey(name string, size int64, fingerprint string) string {
return strings.TrimSpace(fingerprint) + "|" + filepath.Base(strings.TrimSpace(name)) + "|" + fmt.Sprintf("%d", size)
return strings.TrimSpace(fingerprint) + "|" + cleanUploadDisplayName(name) + "|" + fmt.Sprintf("%d", size)
}
type resumableIncomingFile struct {