Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

8 Commits
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ DropKey β€” Secure Temporary File Sharing Platform

React Node.js Express MongoDB Cloudinary Vercel Render


πŸ“Œ Project Overview

DropKey is a secure and temporary file-sharing platform built using the MERN stack with Cloudinary integration. It allows users to upload files, protect them with a password, share them using a short transfer code or QR code, limit the number of downloads, and automatically delete files after a fixed expiry time.

This project was developed as a skill-based full-stack portfolio project to demonstrate practical knowledge of:

  • React & modern frontend development
  • REST API design
  • File uploads & streaming
  • Cloudinary integration
  • MongoDB data modeling
  • Background cleanup using cron jobs
  • Secure download handling
  • ZIP generation and file management

🌐 Live Demo


🎯 Aim of the Project

The main aim of DropKey is to provide a simple, secure, and temporary file transfer system where files are automatically removed after use, reducing storage overhead and improving privacy.


🌟 Key Highlights

  • πŸ” Password-protected file sharing
  • ⏳ Auto-expiry after 15 minutes
  • πŸ“₯ Download limit control
  • πŸ“¦ ZIP download for multiple files
  • ☁️ Cloudinary storage for small files and videos
  • πŸ’Ύ Local storage for large files
  • 🧹 Automatic cleanup of expired files
  • πŸ“± QR code based sharing
  • πŸ“Š Real-time upload progress
  • 🎨 Modern responsive UI with Tailwind CSS

✨ Features

πŸ‘€ User Features

  • Upload up to 10 files at once
  • Maximum 90 MB per file
  • Maximum 500 MB total upload size
  • Optional password protection
  • Set download limit (1–4 downloads)
  • Share using:
    • Transfer code
    • QR code
  • Download files individually or as ZIP
  • View file details before downloading

πŸ”’ Security Features

  • Passwords are hashed using bcrypt
  • Download limit enforcement
  • Expiry-based access control
  • Automatic deletion of expired transfers
  • Cloudinary resource cleanup
  • Local file cleanup

βš™οΈ System Features

  • Real-time upload progress

  • Processing animation during upload

  • Responsive design

  • Error handling with toast notifications

  • QR scanner support

  • Background cleanup job using node-cron

    πŸ› οΈ Tech Stack

Frontend

Technology Purpose
React (Vite) UI development
Tailwind CSS Styling
Axios API communication
React Icons Icons
QR Scanner Library QR code scanning
Sonner / Custom Toast Notifications

Backend

Technology Purpose
Node.js Runtime
Express.js API framework
Multer File upload handling
Archiver ZIP generation
bcrypt Password hashing
nanoid Transfer code generation
node-cron Background cleanup

Database & Storage

Technology Purpose
MongoDB Atlas Database
Cloudinary Cloud storage for small files/videos
Local Server Storage Large file storage

Deployment

Service Purpose
Vercel Frontend hosting
Render Backend hosting

πŸ—οΈ System Architecture

User
  β”‚
  β–Ό
React Frontend (Vercel)
  β”‚
  β–Ό
Express API (Render)
  β”‚
  β”œβ”€β”€ MongoDB Atlas
  β”œβ”€β”€ Cloudinary
  └── Local uploads folder

Upload Flow

Browser
   β”‚
   β–Ό
Express + Multer
   β”‚
   β”œβ”€β”€ Video or ≀10MB ──► Cloudinary
   β”‚                         β”‚
   β”‚                         β–Ό
   β”‚                    Save URL + publicId
   β”‚
   └── >10MB ───────────► Local Storage
                             β”‚
                             β–Ό
                        Save localPath

Download Flow

Transfer Code
      β”‚
      β–Ό
Validate code
      β”‚
      β”œβ”€β”€ Expired? ❌
      β”œβ”€β”€ Password valid? ❌
      β”œβ”€β”€ Download limit reached? ❌
      β–Ό
Return file
      β”‚
      β”œβ”€β”€ Cloudinary β†’ Redirect
      β”œβ”€β”€ Local β†’ Stream download
      └── Multiple β†’ Generate ZIP

πŸ“ Project Structure

DropKey/
β”œβ”€β”€ client/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ api/
β”‚   β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”‚   β”œβ”€β”€ upload/
β”‚   β”‚   β”‚   β”œβ”€β”€ receive/
β”‚   β”‚   β”‚   └── common/
β”‚   β”‚   β”œβ”€β”€ pages/
β”‚   β”‚   └── main.jsx
β”‚   └── package.json
β”‚
β”œβ”€β”€ server/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ config/
β”‚   β”‚   β”œβ”€β”€ controllers/
β”‚   β”‚   β”œβ”€β”€ middleware/
β”‚   β”‚   β”œβ”€β”€ models/
β”‚   β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”œβ”€β”€ jobs/
β”‚   β”‚   └── server.js
β”‚   β”œβ”€β”€ uploads/
β”‚   └── package.json
β”‚
└── README.md

πŸ“€ Upload Logic

File Classification

Condition Storage
Video files Cloudinary
Files ≀ 10MB Cloudinary
Files > 10MB Local server

Why Hybrid Storage?

DropKey uses a hybrid storage approach to balance speed, reliability, and cloud usage limits.

  • Cloudinary is used for:

    • Small files
    • Images
    • Videos
    • Frequently shared lightweight content
  • Local storage is used for:

    • Files larger than 10MB
    • Large ZIP archives
    • Temporary high-size transfers

☁️ Cloudinary Free Plan Consideration

This project is built on the Cloudinary free plan, which has limitations on:

  • Storage quota
  • Monthly bandwidth
  • Transformation usage
  • Large file handling

To avoid unnecessary cloud consumption and keep the project practical for a portfolio/demo environment, large files are intentionally stored on the server instead of Cloudinary.

This design helps:

  • Reduce cloud storage usage
  • Reduce bandwidth consumption
  • Avoid hitting free-tier limits quickly
  • Improve upload reliability for larger files

⚑ Performance Note

During development, it was observed that uploading every file to Cloudinary can introduce additional network latency, especially for larger files. Keeping large files on local temporary storage provides a faster and more stable experience for short-lived transfers.


Temporary File Handling

For Cloudinary uploads

  1. Multer saves the file temporarily.
  2. The file is uploaded to Cloudinary.
  3. url and publicId are stored in MongoDB.
  4. The temporary local file is deleted.

For Local uploads

  1. The file is stored in the server uploads folder.
  2. localPath is stored in MongoDB.
  3. The file is deleted:
    • after the final allowed download, or
    • when the transfer expires.

πŸ”„ Storage Lifecycle

Small File / Video
   ↓
Cloudinary
   ↓
Download
   ↓
Delete from Cloudinary

Large File
   ↓
Local Server
   ↓
Download
   ↓
Delete from Local Storage

This approach keeps DropKey lightweight, cost-efficient, and suitable for temporary file sharing on a free-tier cloud setup.

πŸ” Security & Expiry

Password Protection

  • Password is optional.
  • Passwords are hashed using bcrypt.
  • Plain passwords are never stored.

Download Limit

  • User can choose 1–4 downloads.
  • Download count is incremented on successful download.
  • After the final allowed download:
    • Local files are deleted immediately.
    • Cloudinary files are deleted after redirect/cleanup.
    • MongoDB document is removed.

Expiry System

  • Each transfer expires after 15 minutes.

  • Expired transfers cannot be accessed.

  • A cron job runs every minute to remove expired resources.

    QR Code & Download Flow

DropKey provides two methods for receiving files:

  1. Transfer Code
  2. QR Code

Every upload generates a unique transfer code and a QR code.

Example:

Transfer Code: AB7XK2

Receive URL: https://dropkey.vercel.app/receive/AB7XK2

The QR code contains the receive URL and can be scanned directly from another device.


Receive Process

Method 1: Transfer Code

  1. User enters the transfer code.
  2. Frontend requests transfer details.
  3. Backend validates:
    • Transfer exists
    • Transfer is not expired
  4. Metadata is returned.
  5. User downloads the file.

Method 2: QR Code

  1. User opens scanner.
  2. QR code is scanned.
  3. Transfer code is extracted.
  4. Transfer details are loaded automatically.
  5. User downloads the file.

Single File Download

When only one file exists:

Cloudinary Storage

Backend redirects directly to the Cloudinary file URL.

Example:

https://res.cloudinary.com/.../file.mp4

Benefits:

  • Faster download
  • Reduced server load
  • CDN delivery
  • Better scalability

Local Storage

Backend serves the file using:

res.download()

The file is streamed directly from the server.

Benefits:

  • Supports large files
  • No Cloudinary bandwidth usage
  • No external dependency

Multiple File Download

When more than one file exists:

  1. Files are collected.
  2. ZIP archive is generated dynamically.
  3. ZIP stream is sent to the user.
  4. No ZIP file is permanently stored on the server.

Technology Used:

  • Archiver

Benefits:

  • Saves disk space
  • Faster cleanup
  • No temporary ZIP storage required

Download Limits

Each transfer has a download limit.

Example:

Download Limit = 2

Download #1 β†’ Allowed Download #2 β†’ Allowed Download #3 β†’ Blocked

Once the limit is reached:

  • Transfer becomes unavailable
  • Files are deleted
  • Database record is removed

Password Protected Downloads

If a password exists:

  1. User enters password.
  2. Backend compares hash using bcrypt.
  3. Access granted only if password matches.

Passwords are never stored in plain text.

Only hashed versions are saved.

API Documentation

Base URL

http://localhost:5000/api/v1/files

Production:

https://dropkey.onrender.com/api/v1/files


Upload Files

POST /upload

Request

Content-Type:

multipart/form-data

Body:

files[] password (optional) downloadLimit

Response

{ "success": true, "data": { "transferCode": "AB7XK2", "totalFiles": 3, "totalSize": 15325212 } }


Get Transfer Details

GET /:code

Example:

GET /AB7XK2

Response

{ "success": true, "data": { "files": [...], "totalFiles": 3, "totalSize": 15325212, "downloadsLeft": 2, "isPasswordProtected": true, "expiresAt": "..." } }


Download File

POST /:code/download

Request

{ "password": "123456" }

Success

Single File: 302 Redirect (Cloudinary)

or

Binary File Stream

Multiple Files: ZIP Stream

Error Responses

400 - Password Required

401 - Incorrect Password

404 - Invalid Transfer Code

410 - Transfer Expired

500 - Internal Server Error


Rate Limiting

Upload API: Limited to prevent abuse.

Search API: Limited to prevent brute force attempts.

Download API: Limited to prevent excessive downloads.

Implemented using:

express-rate-limit

βš™οΈ Environment Variables

Create a .env file inside the server directory.

Server (.env)

PORT=5000

MongoDB

MONGODB_URL=your_mongodb_connection_string

Cloudinary

  • CLOUDINARY_CLOUD_NAME=your_cloud_name
  • CLOUDINARY_API_KEY=your_api_key
  • CLOUDINARY_API_SECRET=your_api_secret

Frontend URL

FRONTEND_URL=https://dropkey.vercel.app


Important Notes

  • Never commit .env files to GitHub.
  • Add .env to .gitignore.
  • Set the same variables in Render Environment Variables.

πŸ§ͺ Local Development Setup

1. Clone Repository

git clone https://github.com/saurav-09/DropKey

cd DropKey


2. Install Frontend Dependencies

cd client

npm install


3. Install Backend Dependencies

cd ../server

npm install


4. Create Environment File

Create server/.env and add all required variables.


5. Start Backend

npm run dev

Server runs on:

http://localhost:5000


6. Start Frontend

cd ../client

npm run dev

Frontend runs on:

http://localhost:5173


7. Test Upload

  1. Open frontend
  2. Select files
  3. Upload
  4. Copy transfer code
  5. Open receive page
  6. Download files

πŸš€ Deployment Guide

Frontend Deployment (Vercel)

Steps

  1. Push project to GitHub
  2. Open Vercel
  3. Import repository
  4. Set root directory: client
  5. Deploy

Frontend Environment Variable

VITE_API_URL=https://dropkey.onrender.com/api/v1


Backend Deployment (Render)

Steps

  1. Open Render
  2. Create Web Service
  3. Connect GitHub repository
  4. Set root directory: server
  5. Build command:

npm install

  1. Start command:

npm start


Render Environment Variables

  • PORT=5000
  • MONGODB_URL=...
  • CLOUDINARY_CLOUD_NAME=...
  • CLOUDINARY_API_KEY=...
  • CLOUDINARY_API_SECRET=...
  • FRONTEND_URL=https://dropkey.vercel.app

CORS Configuration

The backend allows:

  • Main Vercel domain
  • Vercel preview deployments

Important Deployment Notes

Local Storage on Render

Render provides temporary filesystem storage.

This is acceptable for DropKey because:

  • Files expire after 15 minutes
  • Expired files are cleaned automatically
  • The project is intended for temporary sharing

Cloudinary Persistence

Files uploaded to Cloudinary remain available until:

  • Download limit is reached, or
  • Cron cleanup deletes them.

πŸ” Security Features

Password Hashing

  • Implemented using bcrypt
  • Salt rounds: 10

Rate Limiting

Upload API

Prevents excessive file uploads.

Search API

Prevents transfer code enumeration.

Download API

Prevents abuse and repeated requests.


Expiry Validation

Every request checks:

  • Transfer exists
  • Transfer is not expired

Download Validation

Checks are performed in this order:

  1. Transfer exists
  2. Transfer not expired
  3. Password valid
  4. Download limit available

Automatic Cleanup

Expired resources are removed from:

  • MongoDB
  • Cloudinary
  • Local server storage

No Permanent Public Links

Transfer codes are short-lived and automatically invalidated.

πŸ“„ Description

Short Version

Built DropKey, a secure temporary file-sharing platform using React, Node.js, Express, MongoDB, and Cloudinary with password protection, download limits, QR-based sharing, ZIP downloads, and automatic file cleanup using cron jobs.


Detailed Version

Developed a full-stack temporary file transfer application that supports secure sharing through transfer codes and QR codes. Implemented hybrid storage using Cloudinary for small files and local storage for larger files, added bcrypt-based password protection, download-limit enforcement, dynamic ZIP generation, and automatic deletion of expired files from MongoDB, Cloudinary, and server storage.

πŸ‘¨β€πŸ’» Author

Saurav

  • MERN Stack Developer
  • React β€’ Node.js β€’ Express β€’ MongoDB β€’ Cloudinary
  • DSA in Java

GitHub: https://github.com/saurav-09

LinkedIn: www.linkedin.com/in/saurav-dev


πŸ“œ License

This project is licensed under the MIT License.

You are free to:

  • Use
  • Modify
  • Distribute
  • Learn from the code

For educational and portfolio purposes.


πŸ™Œ Acknowledgements

  • React
  • Express.js
  • MongoDB Atlas
  • Cloudinary
  • Tailwind CSS
  • Render
  • Vercel

⭐ Final Note

DropKey was created as a real-world full-stack practice project focused on secure temporary file sharing, cloud integration, streaming downloads, background cleanup, and modern user experience design.

If you found this project useful, consider giving it a ⭐ on GitHub.

About

DropKey is a secure account-free temporary file-sharing platform built with React, Node.js, Express, MongoDB, and Cloudinary, featuring QR sharing, password-protected downloads, configurable download limits, ZIP downloads, hybrid cloud/local storage, and automatic file cleanup after 15 minutes.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages