Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions internal/api/sabnzbd_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -1456,6 +1456,12 @@ func (s *Server) calculateHistoryStoragePath(item *database.ImportQueueItem, bas
cfg := s.configManager.GetConfig()
storagePath := *item.StoragePath

// Sanitize storagePath: strip host-temporary prefixes if present
tempUploadDir := filepath.Join(os.TempDir(), "altmount-uploads")
if strings.HasPrefix(storagePath, tempUploadDir) {
storagePath = strings.TrimPrefix(storagePath, tempUploadDir)
}

// Determine category folder
category := config.DefaultCategoryName
if item.Category != nil && *item.Category != "" {
Expand All @@ -1481,7 +1487,6 @@ func (s *Server) calculateHistoryStoragePath(item *database.ImportQueueItem, bas
}

// 3. Determine the base path for reporting
// For NONE, use MountPath. For others, use ImportDir.
finalBasePath := cfg.MountPath
if cfg.Import.ImportStrategy != config.ImportStrategyNone {
if cfg.Import.ImportDir != nil && *cfg.Import.ImportDir != "" {
Expand All @@ -1495,7 +1500,10 @@ func (s *Server) calculateHistoryStoragePath(item *database.ImportQueueItem, bas
if cfg.SABnzbd.CompleteDir != "" {
pathParts = append(pathParts, strings.Trim(cfg.SABnzbd.CompleteDir, "/"))
}
pathParts = append(pathParts, category)
// Avoid double-prefixing category if it's already in finalBasePath
if !strings.HasSuffix(filepath.Join(pathParts...), category) {
pathParts = append(pathParts, category)
}
pathParts = append(pathParts, relPath)

fullStoragePath := filepath.Join(pathParts...)
Expand Down
8 changes: 3 additions & 5 deletions internal/importer/filesystem/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,14 @@ func CalculateVirtualDirectory(nzbPath, relativePath string) string {

relPath, err := filepath.Rel(relativePath, nzbPath)
if err != nil || strings.HasPrefix(relPath, "..") {
if strings.HasPrefix(relativePath, "/") {
return filepath.Clean(relativePath)
}
return "/" + strings.ReplaceAll(relativePath, string(filepath.Separator), "/")
// If nzbPath is not inside relativePath, we cannot derive a valid relative virtual path.
// Return root as a safe default instead of potentially returning a host-absolute path.
return "/"
}

relDir := filepath.Dir(relPath)
if relDir == "." || relDir == "" {
// If the file is at the root, return root
// The processor will handle creating a folder if needed (e.g. for archives or multi-file NZBs)
return "/"
}

Expand Down
8 changes: 7 additions & 1 deletion internal/importer/scanner/directory.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,13 @@ func (d *DirectoryScanner) performScan(ctx context.Context, scanPath string) {
return nil
}

if err := d.queueAdder.AddToQueue(ctx, path, &scanPath, nil); err != nil {
// Calculate path relative to the scan root for accurate queue mapping
relPath, relErr := filepath.Rel(scanPath, path)
if relErr != nil {
relPath = path // Fallback if rel fails, though it shouldn't
}

if err := d.queueAdder.AddToQueue(ctx, path, &relPath, nil); err != nil {
d.log.ErrorContext(ctx, "Failed to add file to queue during scan", "file", path, "error", err)
}

Expand Down
13 changes: 13 additions & 0 deletions internal/importer/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,19 @@ func (s *Service) processNzbItem(ctx context.Context, item *database.ImportQueue
}

func (s *Service) calculateProcessVirtualDir(item *database.ImportQueueItem, basePath *string) string {
// Sanitize basePath to strip any absolute path prefix that might have leaked from temp dirs
cleanBase := *basePath
// Strip common temp upload prefixes
tempUploadDir := filepath.Join(os.TempDir(), "altmount-uploads")
if strings.HasPrefix(cleanBase, tempUploadDir) {
cleanBase = strings.TrimPrefix(cleanBase, tempUploadDir)
}
// Ensure we are not dealing with a hardcoded absolute path
if strings.HasPrefix(cleanBase, "/") {
cleanBase = filepath.Base(cleanBase)
}
*basePath = cleanBase

// Calculate initial virtual directory from physical/relative path
virtualDir := filesystem.CalculateVirtualDirectory(item.NzbPath, *basePath)

Expand Down
Loading