Skip to content

Somak-2001/LinkVault

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

9 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

LinkVault πŸ”’

LinkVault is a full-stack web application that allows users to securely upload text or files and share them using a unique, hard-to-guess link. The uploaded content is accessible only to users who possess the link and is automatically deleted after a specified expiry time.

The application features a full user authentication system allowing users to create accounts, manage their uploads, and track their content through a personalized dashboard.

The application is inspired by link-based sharing systems such as Pastebin and Google Drive's "anyone with the link" feature.


✨ Features

Core Features

  • Upload plain text or a file (one per upload)
  • Generate a unique shareable URL
  • Access content strictly via the generated link
  • View and copy uploaded text
  • Download uploaded files
  • Optional password protection for uploads
  • View limits - restrict number of times content can be accessed
  • Custom expiry times - set when content should automatically delete
  • Automatic expiry of content (default: 10 minutes)

User Account System πŸ†•

  • User Registration - Create secure accounts with email and password
  • JWT Authentication - Token-based authentication with session persistence
  • User Dashboard - View and manage all your uploads in one place
  • Content Ownership - Only you can delete your content
  • Protected Routes - Secure access to user-specific features
  • Guest Mode - Upload without an account (backward compatible)

UI/UX

  • Modern glassmorphism design with gradient accents
  • Responsive interface that adapts to all screen sizes
  • Toast notifications for user feedback
  • Drag-and-drop file upload
  • Beautiful animations and transitions
  • Clean and intuitive navigation

πŸ› οΈ Tech Stack

Frontend

  • React (Vite)
  • React Router - Client-side routing
  • Axios - HTTP requests with interceptors
  • CSS3 - Custom styling with glassmorphism effects
  • Context API - State management for authentication

Backend

  • Node.js - Runtime environment
  • Express.js - Web framework
  • Multer - File upload handling
  • bcrypt - Password hashing
  • jsonwebtoken - JWT authentication
  • Cloudinary - Cloud file storage

Database

  • MongoDB Atlas - Cloud database
  • Mongoose - ODM for MongoDB
  • TTL Indexes - Automatic content expiration

πŸ—οΈ Architecture

πŸ“Š For detailed architecture diagrams and data flows, see ARCHITECTURE.md

This document includes:

  • System architecture overview diagram
  • 7 detailed sequence diagrams (registration, login, uploads, dashboard, content access, delete)
  • Component interaction tables
  • Database schemas
  • Security architecture

Authentication Flow

  1. User registers with name, email, and password
  2. Password is hashed using bcrypt (10 salt rounds)
  3. JWT token is generated and returned to client
  4. Token is stored in localStorage for session persistence
  5. Axios interceptors automatically attach token to requests
  6. Protected routes verify token via middleware
  7. Expired tokens redirect user to login

Content Flow

  • Authenticated Users: Content is associated with user's account via userId
  • Guest Users: Content is created with userId: null
  • All content gets unique IDs and shareable links
  • Content is stored in Cloudinary (files) or database (text)
  • TTL index automatically deletes expired content

πŸš€ Getting Started

Prerequisites

  • Node.js (v14 or higher)
  • MongoDB Atlas account
  • Cloudinary account

Environment Variables

Create a .env file in the backend directory:

# Server Configuration
PORT=3000

# Database
MONGO_URI=your_mongodb_connection_string

# Cloudinary
CLOUDINARY_URL=cloudinary://api_key:api_secret@cloud_name
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret

# JWT Authentication
JWT_SECRET=your_super_secret_key_change_in_production
JWT_EXPIRE=7d

⚠️ Important: Change JWT_SECRET to a long, random string in production!

Installation

  1. Clone the repository
git clone <repository-url>
cd LinkVault
  1. Install backend dependencies
cd backend
npm install
  1. Install frontend dependencies
cd ../frontend
npm install
  1. Configure environment variables
  • Create .env file in backend/ with the variables listed above
  1. Start the backend server
cd backend
npm start
# Server runs on http://localhost:3000
  1. Start the frontend development server
cd frontend
npm run dev
# Frontend runs on http://localhost:5173
  1. Access the application

πŸ“‘ API Overview

Authentication Endpoints

POST /api/auth/register

Register a new user account.

Request Body:

{
  "name": "John Doe",
  "email": "[email protected]",
  "password": "securepassword123"
}

Response:

{
  "success": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "_id": "...",
    "name": "John Doe",
    "email": "[email protected]",
    "createdAt": "2026-02-15T19:51:52.021Z"
  }
}

POST /api/auth/login

Login to existing account.

Request Body:

{
  "email": "[email protected]",
  "password": "securepassword123"
}

Response:

{
  "success": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "_id": "...",
    "name": "John Doe",
    "email": "[email protected]",
    "createdAt": "2026-02-15T19:51:52.021Z"
  }
}

GET /api/auth/me

Get current user details (requires authentication).

Headers:

Authorization: Bearer <token>

Response:

{
  "success": true,
  "user": {
    "_id": "...",
    "name": "John Doe",
    "email": "[email protected]",
    "createdAt": "2026-02-15T19:51:52.021Z"
  }
}

Content Endpoints

POST /api/upload

Upload text or file. Optional authentication (attaches to user if logged in).

Request:

  • multipart/form-data
  • Fields:
    • text (optional) - Text content
    • file (optional) - File to upload
    • password (optional) - Password protection
    • maxViews (optional) - View limit
    • expiry (optional) - Custom expiry date

Headers (Optional):

Authorization: Bearer <token>

Response:

{
  "url": "http://localhost:5173/view/<id>"
}

GET /api/user/content

Get all content uploaded by authenticated user (requires auth).

Headers:

Authorization: Bearer <token>

Response:

{
  "success": true,
  "count": 5,
  "content": [
    {
      "_id": "...",
      "type": "text",
      "text": "Sample content",
      "userId": "...",
      "createdAt": "2026-02-15T19:51:52.021Z",
      "expiresAt": "2026-02-15T20:01:52.021Z"
    }
  ]
}

DELETE /api/content/:id

Delete user's own content (requires auth).

Headers:

Authorization: Bearer <token>

Response:

{
  "success": true,
  "message": "Content deleted successfully"
}

GET /api/content/:id

View uploaded content (public).

Response:

{
  "success": true,
  "content": {
    "type": "text",
    "text": "Sample content",
    "createdAt": "2026-02-15T19:51:52.021Z"
  }
}

🎨 Design Decisions

Database Choice

MongoDB was chosen due to its flexible schema and built-in support for TTL (Time-To-Live) indexes. TTL indexes allow expired content to be deleted automatically at the database level without requiring background cleanup jobs.

Authentication Strategy

  • JWT Tokens: Stateless authentication, no server-side session storage
  • bcrypt: Industry-standard password hashing with salt rounds
  • Optional Auth: Users can upload without accounts (guest mode)
  • Session Persistence: localStorage for seamless user experience

Access Control

Access control is enforced through multiple layers:

  • Link-based access: Secure, randomly generated MongoDB ObjectIDs
  • Password protection: Optional bcrypt-hashed passwords for uploads
  • Content ownership: Users can only delete their own content
  • No public listing: No search or browse functionality
  • Protected routes: User dashboard and management require authentication

Expiry Handling

  • Users may optionally specify an expiry date and time
  • If no expiry is provided, content expires 10 minutes after upload
  • Expired content is automatically deleted by MongoDB TTL index
  • Background cleanup job runs every hour as backup

File Storage

Uploaded files are stored in Cloudinary (cloud storage), while metadata is stored in MongoDB. This design:

  • Allows for reliable, scalable file storage
  • Provides CDN delivery for fast access
  • Supports automatic deletion via Cloudinary API
  • Separates concerns (metadata vs. actual files)

πŸ” Security Features

Backend Security

  • Password Hashing: bcrypt with 10 salt rounds
  • JWT Tokens: Signed with secret key, configurable expiration
  • Protected Routes: Middleware verification for user endpoints
  • Input Validation: Email format, password length requirements
  • Password Exclusion: Password field excluded from queries by default
  • Ownership Checks: Users can only modify their own content
  • CORS: Configured for specific origins

Frontend Security

  • Token Storage: localStorage with automatic attachment to requests
  • 401 Handling: Auto-redirect to login on token expiration
  • Protected Routes: Dashboard requires authentication
  • No Password Exposure: Passwords never stored client-side
  • Secure API Calls: HTTPS-ready configuration

πŸ“± User Guide

Creating an Account

  1. Navigate to LinkVault
  2. Click "Sign Up" button
  3. Enter your name, email, and password (minimum 6 characters)
  4. Click "Sign Up" to create your account
  5. You'll be automatically logged in

Uploading Content

As a Registered User

  1. Log in to your account
  2. Upload text or files as usual
  3. Content is automatically associated with your account
  4. Access it anytime from your Dashboard

As a Guest

  1. Upload directly without logging in
  2. Content is created but not associated with any account
  3. You'll get a shareable link
  4. Cannot be managed or deleted later

Managing Your Content

  1. Click "Dashboard" in the header
  2. View all your uploads in a card grid
  3. Click "View" to access any item
  4. Click "Delete" to permanently remove items
  5. Confirm deletion when prompted

Advanced Upload Options

  • Password Protection: Add a password that viewers must enter
  • View Limit: Restrict how many times content can be accessed
  • Custom Expiry: Set a specific date/time for auto-deletion

πŸ—‚οΈ Project Structure

LinkVault/
β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ models/
β”‚   β”‚   β”‚   β”œβ”€β”€ User.js           # User schema with auth
β”‚   β”‚   β”‚   └── Content.js        # Content schema with userId
β”‚   β”‚   β”œβ”€β”€ controllers/
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.controller.js   # Auth endpoints
β”‚   β”‚   β”‚   β”œβ”€β”€ upload.controller.js # Upload handling
β”‚   β”‚   β”‚   └── content.controller.js # Content CRUD
β”‚   β”‚   β”œβ”€β”€ middleware/
β”‚   β”‚   β”‚   └── auth.middleware.js   # JWT verification
β”‚   β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.routes.js
β”‚   β”‚   β”‚   β”œβ”€β”€ upload.routes.js
β”‚   β”‚   β”‚   └── content.routes.js
β”‚   β”‚   β”œβ”€β”€ utils/
β”‚   β”‚   β”‚   └── cleanup.js        # Expired content cleanup
β”‚   β”‚   β”œβ”€β”€ app.js                # Express app
β”‚   β”‚   └── index.js              # Server entry point
β”‚   β”œβ”€β”€ .env                      # Environment variables
β”‚   └── package.json
β”‚
└── frontend/
    β”œβ”€β”€ src/
    β”‚   β”œβ”€β”€ components/
    β”‚   β”‚   β”œβ”€β”€ Header.jsx        # Navigation with auth state
    β”‚   β”‚   β”œβ”€β”€ ProtectedRoute.jsx # Auth guard
    β”‚   β”‚   β”œβ”€β”€ UploadForm.jsx    # Main upload UI
    β”‚   β”‚   └── Toast.jsx         # Notifications
    β”‚   β”œβ”€β”€ contexts/
    β”‚   β”‚   β”œβ”€β”€ AuthContext.jsx   # Auth state management
    β”‚   β”‚   └── ToastContext.jsx  # Toast notifications
    β”‚   β”œβ”€β”€ pages/
    β”‚   β”‚   β”œβ”€β”€ Home.jsx          # Upload page
    β”‚   β”‚   β”œβ”€β”€ Login.jsx         # Login form
    β”‚   β”‚   β”œβ”€β”€ Register.jsx      # Registration form
    β”‚   β”‚   β”œβ”€β”€ Dashboard.jsx     # User content management
    β”‚   β”‚   β”œβ”€β”€ ViewContent.jsx   # Content display
    β”‚   β”‚   └── NotFound.jsx      # 404 page
    β”‚   β”œβ”€β”€ services/
    β”‚   β”‚   └── api.js            # Axios with interceptors
    β”‚   β”œβ”€β”€ styles/
    β”‚   β”‚   β”œβ”€β”€ Auth.css          # Auth pages styling
    β”‚   β”‚   β”œβ”€β”€ Dashboard.css     # Dashboard styling
    β”‚   β”‚   β”œβ”€β”€ Header.css        # Header styling
    β”‚   β”‚   └── index.css         # Global styles
    β”‚   β”œβ”€β”€ App.jsx               # Main app with routes
    β”‚   └── main.jsx              # Entry point
    └── package.json

πŸ§ͺ Testing

Backend API Testing

Test the authentication endpoints using curl:

# Register a new user
curl -X POST http://localhost:3000/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"name":"Test User","email":"[email protected]","password":"test123"}'

# Login
curl -X POST http://localhost:3000/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"test123"}'

# Get current user (replace <TOKEN> with actual token)
curl http://localhost:3000/api/auth/me \
  -H "Authorization: Bearer <TOKEN>"

Frontend Testing

  1. Open http://localhost:5173
  2. Test registration flow
  3. Test login/logout
  4. Test authenticated uploads
  5. Test dashboard content management
  6. Test guest uploads (without login)

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.


πŸ™ Acknowledgments

  • Inspired by Pastebin and Google Drive
  • Built with modern web technologies
  • Designed for security and user experience

LinkVault - Secure, Simple, Seamless πŸ”’βœ¨

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors