Skip to content

feat(api): refuse downloads until host-side decryption exists - #3

Merged
mpiton merged 2 commits into
mainfrom
feat/mat-136-honest-refusal
Jul 18, 2026
Merged

feat(api): refuse downloads until host-side decryption exists#3
mpiton merged 2 commits into
mainfrom
feat/mat-136-honest-refusal

Conversation

@mpiton

@mpiton mpiton commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Part of MAT-136 (R-04): MEGA can't produce fake successful downloads of encrypted data.

MEGA CDN bytes are AES-128-CTR ciphertext and the Vortex host has no decryption pipeline yet, so a "successful" download would write unreadable bytes to disk. The host's hoster contract also requires direct_url and drops encryption metadata, so returning the CDN URL from extract_links leaves the ciphertext path open even if resolve_stream_url refuses.

What changed

  • extract_links and resolve_stream_url now validate the URL, then refuse with PluginError::DecryptionNotSupported ("MEGA downloads are not supported yet: files are end-to-end encrypted...").
  • can_handle and supports_playlist still work, so link recognition and honest error surfacing in the UI are unchanged.
  • The resolution and crypto code (api_client, crypto, key_parser, node_parser) stays in the library, tested and ready to rewire when host-side decryption ships. See git history for the previous wiring.
  • Version 1.0.0 -> 1.1.0.

After merge

Tag v1.1.0 and publish the GitHub release with the exact built artifacts. The vortex registry PR (feat/mat-136-align-capabilities) already carries their checksums:

  • vortex_mod_mega.wasm sha256 c846257ab043b4863c359f6e6385c9af598e2cd3b27eab0ecc2b957f51abbe52
  • plugin.toml sha256 330d8c9540b1018c9ad1d13385dbaab0f9ab625fc055fc383d32b83e213d3392

Tests

68 tests pass, clippy clean, wasm32-wasip1 release builds.

Summary by CodeRabbit

  • Breaking Changes
    • MEGA extraction and stream URL resolution are now refused until decryption support is available (file and folder URLs).
    • Calls to extract_links and resolve_stream_url now fail with a “not supported yet” decryption error instead of returning metadata/URLs.
  • Bug Fixes
    • Added a dedicated error for unsupported MEGA decryption with clearer messaging.
  • Tests
    • Updated WASM and folder E2E tests to validate the new refusal behavior.
  • Documentation
    • Refreshed README and plugin/module contract docs to reflect current MEGA limitations.
  • Chores
    • Bumped plugin and crate versions to 1.1.0.

extract_links used to hand the host a raw CDN URL whose bytes are
AES-128-CTR ciphertext; the host contract ignores the encryption
metadata, so MEGA links downloaded 'successfully' as unreadable files.
Both download-facing exports now return an explicit
DecryptionNotSupported error. Resolution and crypto code stays in the
library, ready to rewire once Vortex can decrypt during download
(MAT-136 R-04).
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The plugin now validates supported MEGA URLs and refuses link extraction and stream resolution because decryption is unavailable. It adds a dedicated error, removes HTTP resolution wiring, updates documentation and tests, and bumps crate and plugin versions to 1.1.0.

Changes

MEGA decryption refusal

Layer / File(s) Summary
Decryption refusal API
src/error.rs, src/plugin_api.rs
Adds PluginError::DecryptionNotSupported; both WASM operations validate URLs and return this error without API calls or URL resolution.
Refusal contract and validation
src/lib.rs, README.md, tests/folder_e2e.rs, tests/wasm_smoke.rs
Documentation describes the refusal behavior, and tests verify unsupported errors for file and folder URLs.
Release metadata
Cargo.toml, plugin.toml
Updates crate and plugin versions from 1.0.0 to 1.1.0 and revises the plugin capability description.

Estimated code review effort: 3 (Moderate) | ~15 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: MEGA downloads are now refused until host-side decryption exists.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Cargo.toml`:
- Line 3: Update the package version in Cargo.toml from 1.1.0 to 2.0.0, and
update the corresponding version field in plugin.toml to 2.0.0 so both version
files remain aligned.

In `@plugin.toml`:
- Line 3: Update the manifest capability description near version 1.1.0 to
remove claims of URL resolution and AES-128-CTR streaming decryption. Describe
recognition and playlist support, and explicitly state that downloads are
unavailable until host-side decryption is implemented.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a33957a1-27b1-42f3-b4c3-e1f1f2e7c547

📥 Commits

Reviewing files that changed from the base of the PR and between af2749a and 0e044ed.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • Cargo.toml
  • plugin.toml
  • src/error.rs
  • src/lib.rs
  • src/plugin_api.rs

Comment thread Cargo.toml
Comment thread plugin.toml

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

cubic analysis

2 issues found across 6 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="plugin.toml">

<violation number="1" location="plugin.toml:3">
P2: The 1.1.0 manifest still advertises host-usable AES-128-CTR decryption even though MEGA downloads now fail with `DecryptionNotSupported`, so the catalog can present this hoster as downloadable when it is not. According to linked Linear issue MAT-136 (R-04), the manifest should describe MEGA downloads as unavailable until host-side decryption exists.</violation>
</file>

<file name="src/lib.rs">

<violation number="1" location="src/lib.rs:6">
P2: According to linked Linear issue MAT-136 (R-04), unavailable MEGA downloads must be presented honestly; this new contract is not propagated to the README or WASM smoke test, leaving users with the old capability description and CI with assertions for the superseded behavior. Updating the contract documentation and test expectations alongside this change would keep the release surface consistent.</violation>
</file>

Linked issue analysis

Linked issue: MAT-136: [Lot 3] Aligner l’interface et le catalogue sur les capacités réelles

Status Acceptance criteria Notes
R-04 — MEGA and 1fichier must not produce a fake successful download of encrypted data or an HTML page. The PR changes the download-facing exports to refuse with a clear DecryptionNotSupported error, adds the error variant and a unit test for the message, and leaves link recognition unchanged so UI can show honest errors.

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread plugin.toml
Comment thread src/lib.rs
//! - `supports_playlist(url)` → `"true"` for folder URLs, `"false"` otherwise
//! - `extract_links(url)` → JSON metadata for a single MEGA file
//! - `resolve_stream_url(input)` → encrypted CDN URL (host fetches + decrypts)
//! - `extract_links(url)` / `resolve_stream_url(input)` → refused with an

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: According to linked Linear issue MAT-136 (R-04), unavailable MEGA downloads must be presented honestly; this new contract is not propagated to the README or WASM smoke test, leaving users with the old capability description and CI with assertions for the superseded behavior. Updating the contract documentation and test expectations alongside this change would keep the release surface consistent.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/lib.rs, line 6:

<comment>According to linked Linear issue MAT-136 (R-04), unavailable MEGA downloads must be presented honestly; this new contract is not propagated to the README or WASM smoke test, leaving users with the old capability description and CI with assertions for the superseded behavior. Updating the contract documentation and test expectations alongside this change would keep the release surface consistent.</comment>

<file context>
@@ -3,8 +3,8 @@
 //! - `supports_playlist(url)` → `"true"` for folder URLs, `"false"` otherwise
-//! - `extract_links(url)` → JSON metadata for a single MEGA file
-//! - `resolve_stream_url(input)` → encrypted CDN URL (host fetches + decrypts)
+//! - `extract_links(url)` / `resolve_stream_url(input)` → refused with an
+//!   explicit error until the host can decrypt MEGA payloads (MAT-136 R-04)
 //!
</file context>

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Valid — CI was red on exactly this: folder_e2e and the wasm_smoke extraction test still asserted the old contract. Fixed in 650b0c6: the README contract table and status now describe the refusal, wasm_smoke asserts both exports refuse a valid file URL, and folder_e2e is slimmed to a wasm-boundary check that folder URLs refuse too (the synthetic decryption fixture stays in git history for the rewire).

@mpiton
mpiton merged commit a6549ac into main Jul 18, 2026
7 checks passed
@mpiton
mpiton deleted the feat/mat-136-honest-refusal branch July 18, 2026 16:40
@mpiton

mpiton commented Jul 18, 2026

Copy link
Copy Markdown
Owner Author

v1.1.0 is tagged and released. The CI-built wasm hashes ad2aceaf0eb6df6746e2ddf5d403003b6601e363fb4d68fd71116fbc0bed836f (the local-build hash quoted above differed — the wasm is not byte-reproducible across machines); the registry in mpiton/vortex#175 now carries the released artifact's checksum. Use the release SHA256SUMS as the reference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant