feat: add file-sharing example with shareable download links#32
feat: add file-sharing example with shareable download links#32erhnysr wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ba3a19abfe
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const db = loadDB(); | ||
| db[id] = drop; | ||
| saveDB(db); |
There was a problem hiding this comment.
Make drops.json updates atomic across concurrent requests
Avoid read-modify-write on drops.json without synchronization: /upload reads the file, mutates it, and writes it back after an await, so two overlapping uploads can each start from the same snapshot and the later write will silently discard the earlier drop record. The same pattern is used for download counters, so concurrent downloads can undercount. This causes real data loss/inaccurate metadata under normal parallel traffic.
Useful? React with 👍 / 👎.
| const app = express(); | ||
|
|
||
| app.use(express.json()); | ||
| app.use(express.static(path.join(import.meta.dirname, "..", "public"))); |
There was a problem hiding this comment.
Serve an actual landing page for browser-based uploads
This middleware mounts ../public, but this commit does not add any apps/file-sharing/public files and there is no explicit GET / handler, so visiting http://localhost:3000 returns 404 and the documented browser upload flow is unavailable. Either include the frontend assets in this app or provide a route that returns an upload page.
Useful? React with 👍 / 👎.
|
Addressed the two issues flagged by Cursor Bugbot:
Both fixes are in commit ea2c1b6. |
|
Follow-up fixes based on Codex suggestions:
All 4 issues are now resolved. PR is ready for review. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Reviewed by Cursor Bugbot for commit f660210. Configure here.
| saveDB(db); | ||
| }); | ||
| return dbWriteLock; | ||
| } |
There was a problem hiding this comment.
Mutex promise chain permanently breaks on any error
Medium Severity
The updateDB function chains operations via .then() on dbWriteLock, but if any operation in the chain throws (e.g., corrupted drops.json causing JSON.parse to fail, or db[drop.id] being undefined on line 163), the resulting rejected promise becomes the new dbWriteLock. All subsequent .then() calls on a rejected promise skip execution, so every future updateDB call silently fails. This means after a single error, new uploads still push files to Shelby but their metadata is never persisted — download links become permanently broken. Adding a .catch() to reset the chain would prevent this cascading failure.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit f660210. Configure here.
| } | ||
|
|
||
| const { originalname, path: tmpPath, size } = req.file; | ||
| const safeName = originalname.replace(/[^a-zA-Z0-9._-]/g, "_"); |
There was a problem hiding this comment.
Duplicate filename sanitization logic not using shared function
Low Severity
Line 95 applies an inline regex (/[^a-zA-Z0-9._-]/g) to sanitize originalname, which is functionally identical to the sanitizeFilename function defined on line 71. Having two copies of the same sanitization logic means a future fix to one (e.g., tightening the allowed character set) could easily miss the other, risking inconsistent behavior.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit f660210. Configure here.


Summary
This PR adds a new example application demonstrating decentralized file sharing built on the Shelby SDK.
What it does
Upload any file → receive a unique shareable link → anyone can download it directly from Shelby. Every file is SHA-256 hashed locally before upload, providing verifiable integrity on Aptos blockchain.
Think of it as a decentralized alternative to WeTransfer.
How it works
client.upload()drops.json/drop/:id/downloadto stream the file from Shelby viaclient.download()API endpoints
Tech stack
Testing
Tested on Shelby testnet with successful uploads and downloads. Live demo: https://shelby-vibe-storage-production.up.railway.app
Checklist
Note
Low Risk
Adds a new isolated example Express app plus dependencies/lockfile updates; minimal risk to existing production code, with the main concern being typical file upload/streaming edge cases within the example.
Overview
Introduces a new
apps/file-sharingexample app that lets users upload a file to Shelby, generates a short shareable drop ID, and serves download links that stream the blob back from Shelby.The server computes and returns a local SHA-256 hash for integrity, persists drop metadata (including expiry and download count) in
drops.jsonwith a simple write mutex, and includes new setup docs/config viaREADME.md,.env.example, TypeScript config, and workspace lockfile dependency additions.Reviewed by Cursor Bugbot for commit f660210. Bugbot is set up for automated code reviews on this repo. Configure here.