Skip to content

feat: Download a transfer or folder with api v2#618

Merged
sirambd merged 61 commits intomainfrom
download-folder
Apr 30, 2026
Merged

feat: Download a transfer or folder with api v2#618
sirambd merged 61 commits intomainfrom
download-folder

Conversation

@sirambd
Copy link
Copy Markdown
Member

@sirambd sirambd commented Apr 1, 2026

No description provided.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 1, 2026

PR Reviewer Guide 🔍

(Review updated until commit 23554ac)

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 Security concerns

Path Traversal:
The download path construction in AppDownloadManager uses unsanitized user-controlled input (transfer.displayTitle and fileUi.fileName/fileUi.path) when building file system paths. An attacker controlling the transfer metadata could potentially inject path traversal sequences (e.g., "../../../") to write files to arbitrary locations on the device's storage. This should be mitigated by validating or sanitizing the title and filename inputs to remove or escape path separators and parent directory references.

⚡ Recommended focus areas for review

Hardcoded UniqueDownloadId

The scheduleWork method returns UniqueDownloadId(999) as a hardcoded constant. If multiple downloads are scheduled concurrently, they will all share the same ID, which could cause confusion in logging or tracking. While the current implementation appears to use the transfer UUID and folder ID for actual work identification, returning a constant value defeats the purpose of having a unique ID type. Consider returning a unique value derived from the work request or transfer identifier.

return UniqueDownloadId(999)
Incorrect TAG constant

The TAG is defined as AppDownloadManager::javaClass.name which evaluates to "java.lang.Class" rather than the actual class name. This will cause all Sentry logs to be tagged incorrectly. It should be changed to AppDownloadManager::class.java.name or a hardcoded string.

private val TAG = AppDownloadManager::javaClass.name
Path Traversal Risk

The computeFolderDownloadPathWith function constructs file paths using transfer.displayTitle and fileUi.path without sanitizing path traversal sequences (e.g., "../"). If the server returns malicious filenames or transfer titles containing such sequences, the app could write files outside the intended Downloads/SwissTransfer directory. This affects both the MediaStore implementation (API 29+) and the direct File access (API < 29). Validate or sanitize these inputs to prevent directory traversal attacks.

fun TransferUi.computeFolderDownloadPathWith(fileUi: FileUi): String {
    val filePath = fileUi.path?.takeIf { it.contains("/") }?.let {
        if (it.startsWith("/")) it.substringAfter("/") else it
    }
    return "$ROOT_FOLDER_NAME/${this.displayTitle}/${filePath?.substringBeforeLast("/") ?: ""}"

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 2, 2026

Persistent review updated to latest commit 23554ac

Comment thread app/src/main/java/com/infomaniak/swisstransfer/services/DownloadWorker.kt Outdated
Comment thread app/src/main/java/com/infomaniak/swisstransfer/services/AppDownloadManager.kt Outdated
Comment thread app/src/main/res/values/strings.xml Outdated
Comment thread app/src/main/java/com/infomaniak/swisstransfer/ui/utils/NotificationsUtils.kt Outdated
Comment thread app/src/main/java/com/infomaniak/swisstransfer/ui/utils/NotificationsUtils.kt Outdated
Comment thread app/src/main/java/com/infomaniak/swisstransfer/ui/utils/NotificationsUtils.kt Outdated
Comment thread app/src/main/java/com/infomaniak/swisstransfer/services/DownloadWorker.kt Outdated
Comment thread app/src/main/java/com/infomaniak/swisstransfer/services/DownloadWorker.kt Outdated
Comment thread app/src/main/java/com/infomaniak/swisstransfer/services/DownloadWorker.kt Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for downloading an entire transfer or a folder when using SwissTransfer API v2, shifting those downloads to a WorkManager-based implementation while keeping legacy behavior for API v1.

Changes:

  • Bump swisstransfer dependency to 7.1.1 and add Ktor network dependency.
  • Introduce DownloadWorker + AppDownloadManager to download transfers/folders in the background and report progress via notifications.
  • Update UI/viewmodels and helpers to route API v2 download/preview flows through the new scheduler and add new strings for download notifications.

Reviewed changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
gradle/libs.versions.toml Bumps SwissTransfer library version.
app/build.gradle.kts Adds Ktor dependency needed for new download implementation.
app/src/main/res/values*/strings.xml Adds new strings for download notifications and “Feedback” button across locales.
app/src/main/java/com/infomaniak/swisstransfer/ui/utils/TransferUiExt.kt Adds displayTitle helper for transfer display naming.
app/src/main/java/com/infomaniak/swisstransfer/ui/utils/NotificationsUtils.kt Adds a download notification channel and download success/progress notifications.
app/src/main/java/com/infomaniak/swisstransfer/ui/screen/newtransfer/filesdetails/FilesDetailsViewModel.kt Injects DownloadWorker.Scheduler and passes it to preview/download flows.
app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/transferdetails/TransferManagerExt.kt Routes preview URI/status handling based on API version.
app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/transferdetails/TransferDownload.kt Switches v2 transfer/folder downloads to worker-based scheduling and updates open/delete handling.
app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/transferdetails/TransferDetailsViewModel.kt Injects scheduler and wires it into preview/download flows.
app/src/main/java/com/infomaniak/swisstransfer/ui/screen/main/transferdetails/TransferDetailsScreen.kt Enables download action in the top app bar for sent transfers.
app/src/main/java/com/infomaniak/swisstransfer/ui/components/transfer/TransferItem.kt Uses displayTitle for transfer list items.
app/src/main/java/com/infomaniak/swisstransfer/services/DownloadWorker.kt New WorkManager worker + scheduler for v2 downloads with foreground progress notifications.
app/src/main/java/com/infomaniak/swisstransfer/services/AppDownloadManager.kt New downloader that streams files into Public Downloads (MediaStore / filesystem).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread app/src/main/java/com/infomaniak/swisstransfer/services/DownloadWorker.kt Outdated
Comment thread app/src/main/java/com/infomaniak/swisstransfer/services/AppDownloadManager.kt Outdated
Comment thread app/src/main/java/com/infomaniak/swisstransfer/ui/utils/TransferUiExt.kt Outdated
Comment thread app/src/main/java/com/infomaniak/swisstransfer/services/AppDownloadManager.kt Outdated
Comment thread app/src/main/java/com/infomaniak/swisstransfer/services/AppDownloadManager.kt Outdated
@sonarqubecloud
Copy link
Copy Markdown

@sirambd sirambd merged commit 2e9920c into main Apr 30, 2026
7 checks passed
@sirambd sirambd deleted the download-folder branch April 30, 2026 07:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants