feat(upload): add voided.host uploaders with shared config and settings UI - #480
feat(upload): add voided.host uploaders with shared config and settings UI#480Lixqa wants to merge 1 commit into
Conversation
Not up to standards ⛔🔴 Issues
|
| Category | Results |
|---|---|
| Compatibility | 4 medium |
| BestPractice | 7 medium |
| ErrorProne | 20 critical 1 high |
| Security | 2 critical 2 high |
| CodeStyle | 3 minor |
| Complexity | 5 medium |
🟢 Metrics 100 complexity · 8 duplication
Metric Results Complexity 100 Duplication 8
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
|
Hi, thanks for submitting a PR. I was initially considering closing this because I'm still hesitant to add any uploaders I don't personally know yet. Considering that it isn't in https://github.com/SnapXL/CustomUploaders. However, I do appreciate the initiative. I looked into your host more, and it seems to have been around for more than a summer, so that's good. Since you're providing anonymous uploads for SnapX users, I'm down to approve this, provided you fix up this PR by removing the UniversalUploader type (no other uploader uses this). The next version of SnapX is the rewrite. No more changes on develop are being made. Currently, the rewrite branch is only on my local machine. When the rewrite hits develop, I will adapt this PR to it. Also, while our CONTRIBUTING.md doesn't explicitly mention it, AI disclosure is required for contributions. |
|
Hi @BrycensRanch, I added If you'd prefer the existing design, let me know and I'll remove |
| /// for the shared guest account. Guest mode stays off in the UI and in CheckConfig until this is non-empty. | ||
| /// Omit from public repos — set at release build time only. | ||
| /// </summary> | ||
| public const string GuestUploadApiKey = "MTA3NQ.MTc3ODMzMzE1MDI3NA.wIeJFNAwaYymgvgMIhLCxRamvUXWtZMtSGmjQNZDfGDKGVqx"; |
There was a problem hiding this comment.
Shared guest credential is exposed
Anyone with the public source or a distributed binary can extract GuestUploadApiKey and submit image, paste, or file uploads directly under SnapX's shared guest identity, causing quota abuse or credential revocation that disables guest uploads for all users. How this was verified: The guest-key selection path returns this constant and the multipart uploader passes it verbatim in the Authorization header.
|
Ignore the review; I am testing new tools that can assist in code review. Anything it suggests I'll be fixing myself. |
Preface
SnapX did not have a built-in voided.host destination. voided.host supports image, text, and file uploads through one shared upload key, so adding it means implementing shared upload logic rather than three unrelated uploaders.
This change adds voided.host as a first-class SnapX uploader with encrypted config, AOT-friendly JSON parsing, and Avalonia settings UI.
Description of Change
Adds voided.host as a built-in uploader for image, text, and file destinations.
Core (SnapX.Core):
UI (SnapX.Avalonia):
Uploads use multipart requests to api.voided.host with Authorization header auth, optional guest mode, and structured JSON error handling.
Possible Alternatives
Separate settings pages per destination type: rejected because voided.host uses one upload key for images, pastes, and files. Three pages would duplicate the same controls.
Single uploader class for all three types: rejected to stay consistent with SnapX's existing pattern of separate image, text, and file services, while sharing logic through VoidedHostMultipartUploader.
Implementation Details
Upload logic lives in VoidedHostMultipartUploader, which all three uploaders delegate to with different API URLs:
Image: https://api.voided.host/v2/images
Text: https://api.voided.host/v2/pastes
File: https://api.voided.host/v2/files
Multipart fields use p=snapx, v=1, and a timestamp. Guest mode is enabled when VoidedHostUseGuest is true and a guest API key is present in the build.
Settings are grouped under Universal uploaders because the configuration is destination-agnostic. voided.host still appears separately in the image, text, and file destination pickers when choosing where to upload.
Notes
Tested on
Greptile Summary
This PR adds voided.host as a shared image, text, and file destination with encrypted personal-key configuration and an Avalonia settings page. It also:
Confidence Score: 3/5
This PR should not merge until the exposed shared guest credential is revoked and replaced with a design that does not distribute a reusable secret to clients.
The guest upload path embeds a reusable authorization value in public source, returns it as the effective upload key, and sends it directly to all three upload endpoints, allowing external abuse of the shared identity.
Files Needing Attention: SnapX.Core/Upload/Img/VoidedHostUploader.cs
Security Review
The guest authorization credential is committed directly in source and transmitted as a bearer-style
Authorizationvalue. Anyone with the source or a distributed binary can reuse it outside SnapX to upload content under the shared guest identity. How this was verified: The constant returned by the guest-key selection path is passed verbatim into the multipart request'sAuthorizationheader.Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart LR UI[voided.host settings] --> Config[Shared UploadersConfig] Config --> Factory[UploaderFactory] Factory --> Image[Image uploader] Factory --> Text[Text uploader] Factory --> File[File uploader] Image --> Multipart[Shared multipart uploader] Text --> Multipart File --> Multipart Config -->|Guest mode| GuestKey[Bundled guest key] Config -->|Personal mode| PersonalKey[Encrypted personal key] GuestKey --> Multipart PersonalKey --> Multipart Multipart --> API[api.voided.host] API --> Parser[Shared JSON response parser]Reviews (1): Last reviewed commit: "feat(upload): add voided.host uploaders ..." | Re-trigger Greptile