Skip to content

preranah7/cloudDrive

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

☁ CloudDrive

A secure, full-stack cloud file storage application - similar to Google Drive - built as an internship project.

Author: Prerana Hippargi


πŸ›  Tech Stack

Layer Technology
Frontend React 18, Vite, React Router v6, Axios
Backend Node.js, Express.js
Authentication Google OAuth 2.0
Storage Google Cloud Storage (GCS)
Security Helmet, express-rate-limit, HPP
Logging Winston

✨ Features

  • πŸ” Google OAuth 2.0 login - secure sign-in with your Google account
  • πŸ“€ Drag & drop file upload - with real-time progress bar
  • πŸ“₯ Signed download URLs - secure, time-limited download links
  • πŸ•“ File versioning - every upload creates a new version; view history and restore any version
  • πŸ”— Shareable links - generate expiring public links for any file
  • πŸ—‘ File management - delete files (all versions) with one click
  • πŸ” File search - filter your files instantly
  • πŸ”” Toast notifications - real-time feedback on every action

πŸ”’ Security

Feature Implementation
Secure HTTP headers Helmet.js (15+ headers)
Rate limiting express-rate-limit (per route)
HTTP Parameter Pollution hpp middleware
File type validation MIME type whitelist
Filename sanitization Strips path traversal & dangerous chars
IDOR protection gcsPath ownership verified on every request
Session security httpOnly + sameSite cookies, 32-char secret enforced
Input validation UUID format checks on all params
Error safety Stack traces never exposed to client in production

Rate Limits

Route Limit
All /api/* 100 requests / 15 min
/auth/* 10 requests / 15 min
File uploads 20 uploads / hour
Share link creation 30 links / hour
Public downloads 50 downloads / hour

πŸ“ Project Structure

clouddrive/
β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ .env.example
β”‚   β”œβ”€β”€ package.json
β”‚   β”œβ”€β”€ logs/                          ← auto-generated at runtime
β”‚   └── src/
β”‚       β”œβ”€β”€ index.js                   ← Express entry + all security wired in
β”‚       β”œβ”€β”€ config/
β”‚       β”‚   β”œβ”€β”€ gcs.js                 ← Google Cloud Storage client
β”‚       β”‚   β”œβ”€β”€ oauth.js               ← Google OAuth2 setup
β”‚       β”‚   └── logger.js              ← Winston logger
β”‚       β”œβ”€β”€ middleware/
β”‚       β”‚   β”œβ”€β”€ auth.js                ← session guard (requireAuth)
β”‚       β”‚   └── security.js            ← rate limiters, helmet, MIME whitelist
β”‚       β”œβ”€β”€ routes/
β”‚       β”‚   β”œβ”€β”€ auth.js                ← /auth/login, /callback, /me, /logout
β”‚       β”‚   β”œβ”€β”€ files.js               ← /api/files (upload, download, versions)
β”‚       β”‚   └── share.js               ← /api/share (create, list, revoke)
β”‚       └── services/
β”‚           β”œβ”€β”€ fileService.js         ← all GCS operations + versioning
β”‚           └── shareService.js        ← share token management
β”‚
└── frontend/
    β”œβ”€β”€ index.html                     ← Vite entry HTML (root level)
    β”œβ”€β”€ vite.config.js                 ← Vite config + proxy to backend
    β”œβ”€β”€ package.json
    └── src/
        β”œβ”€β”€ main.jsx                   ← React entry point
        β”œβ”€β”€ App.jsx                    ← Router + auth guards
        β”œβ”€β”€ index.css                  ← Global design system
        β”œβ”€β”€ context/
        β”‚   └── AuthContext.jsx        ← Global auth state
        β”œβ”€β”€ hooks/
        β”‚   └── useToast.js            ← Toast notification system
        β”œβ”€β”€ utils/
        β”‚   └── api.js                 ← All Axios API calls
        β”œβ”€β”€ pages/
        β”‚   β”œβ”€β”€ LoginPage.jsx/css      ← Google OAuth login screen
        β”‚   β”œβ”€β”€ Dashboard.jsx/css      ← Main file manager UI
        β”‚   └── SharePage.jsx/css      ← Public file download page
        └── components/
            β”œβ”€β”€ Dropzone.jsx/css       ← Drag & drop upload
            β”œβ”€β”€ FileCard.jsx/css       ← File row with actions
            β”œβ”€β”€ VersionsModal.jsx      ← Version history + restore
            └── ShareModal.jsx         ← Generate & copy share links

πŸš€ Getting Started

Prerequisites

  • Node.js v18+
  • A Google Cloud Platform account (free tier is sufficient)

Step 1 β€” GCP Project Setup

  1. Go to console.cloud.google.com
  2. Create a new project and note your Project ID
  3. Enable these APIs:
    • Cloud Storage API
    • Google OAuth2 API

Step 2 β€” Create a GCS Bucket

  1. Go to Cloud Storage β†’ Buckets β†’ Create
  2. Give it a globally unique name e.g. clouddrive-yourname-2025
  3. Region: us-central1
  4. Leave all other settings as default β†’ Create

Step 3 β€” Service Account Key

  1. Go to IAM & Admin β†’ Service Accounts β†’ Create Service Account
  2. Name: clouddrive-sa β†’ Create
  3. Grant role: Storage Object Admin β†’ Done
  4. Click the service account β†’ Keys β†’ Add Key β†’ JSON
  5. Download and rename to service-account-key.json
  6. Place it inside your backend/ folder

Step 4 β€” Google OAuth 2.0 Credentials

  1. Go to APIs & Services β†’ Credentials β†’ Create Credentials β†’ OAuth 2.0 Client ID
  2. Configure the OAuth consent screen first if prompted (External, fill in app name + email)
  3. Application type: Web application
  4. Authorized redirect URIs β†’ add: http://localhost:5000/auth/callback
  5. Copy the Client ID and Client Secret

Step 5 β€” Environment Variables

cd backend
cp .env.example .env

Fill in your .env:

PORT=5000
NODE_ENV=development

# Generate with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
SESSION_SECRET=your-32-char-minimum-secret-here

GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
GOOGLE_REDIRECT_URI=http://localhost:5000/auth/callback

GCP_PROJECT_ID=your-gcp-project-id
GCP_KEY_FILE=./service-account-key.json
GCS_BUCKET_NAME=clouddrive-yourname-2025

CLIENT_URL=http://localhost:3000
LOG_LEVEL=info

Generate a secure SESSION_SECRET:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Step 6 β€” Install Dependencies

Backend:

cd backend
npm install

Frontend:

cd frontend
npm install

Step 7 β€” Run the Project

Open two terminals:

Terminal 1 β€” Backend:

cd backend
npm run dev

Expected output:

πŸš€ CloudDrive backend running on http://localhost:5000

Terminal 2 β€” Frontend:

cd frontend
npm run dev

Expected output:

  VITE v5.x  ready in xxx ms
  ➜  Local:   http://localhost:3000/

Open http://localhost:3000 in your browser and log in with Google!


πŸ”Œ API Reference

Auth Endpoints

Method Endpoint Auth Description
GET /auth/login No Redirect to Google OAuth
GET /auth/callback No OAuth2 callback
GET /auth/me No Get current session user
POST /auth/logout Yes Destroy session

File Endpoints

Method Endpoint Auth Description
GET /api/files Yes List all files (latest versions)
POST /api/files/upload Yes Upload a new file
POST /api/files/:id/version Yes Upload new version of existing file
GET /api/files/:id/versions Yes Get full version history
GET /api/files/:id/download Yes Get signed download URL
POST /api/files/:id/restore Yes Restore an older version
DELETE /api/files/:id Yes Delete file and all versions

Share Endpoints

Method Endpoint Auth Description
POST /api/share/create Yes Create a share token
GET /api/share/mine Yes List your share links
DELETE /api/share/:token Yes Revoke a share link
GET /api/share/info/:token No Public: get file metadata
GET /api/share/download/:token No Public: get download URL

πŸ—„ GCS Storage Layout

gs://your-bucket/
β”œβ”€β”€ users/{userId}/files/{fileId}/v1/filename.pdf
β”œβ”€β”€ users/{userId}/files/{fileId}/v2/filename.pdf   ← new version
β”œβ”€β”€ users/{userId}/files/{fileId}/v3/filename.pdf   ← restored version
└── share-index.json                                ← share token registry

πŸ› Common Errors & Fixes

Error Fix
SESSION_SECRET must be at least 32 chars Generate one with the crypto command above
CORS blocked for origin Ensure CLIENT_URL=http://localhost:3000 in .env
Could not load default credentials Check GCP_KEY_FILE path points to your JSON key
Access denied on GCS bucket Ensure service account has Storage Object Admin role
redirect_uri_mismatch Add http://localhost:5000/auth/callback in GCP OAuth credentials
JSX syntax extension not enabled Ensure you're using the updated vite.config.js
Port already in use Change PORT=5001 in .env

☁ Deploying to GCP Cloud Run (Production)

Backend:

cd backend
gcloud run deploy clouddrive-backend \
  --source . \
  --region us-central1 \
  --allow-unauthenticated \
  --set-env-vars="NODE_ENV=production,SESSION_SECRET=xxx,..."

Frontend:

cd frontend
npm run build
# deploy the dist/ folder to Firebase Hosting or GCS static site

Don't forget to:

  • Add your Cloud Run URL to the OAuth 2.0 authorized redirect URIs in GCP
  • Update CLIENT_URL in backend env vars to your frontend's production URL
  • Use Workload Identity instead of a service account key file in production

πŸ“‹ Checklist

  • Google OAuth 2.0 login/logout
  • Drag & drop file upload with progress bar
  • Signed URL file download
  • File versioning β€” upload, view history, restore
  • Shareable links with configurable expiry
  • Share link revocation
  • File deletion (all versions)
  • File search
  • Toast notifications
  • Rate limiting on all endpoints
  • Secure HTTP headers (Helmet)
  • MIME type validation
  • IDOR protection
  • Winston request/error logging

About

A GCP and GCS related full stack project.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors