FileVault is a modern, secure file storage web application built with React, TypeScript, and Supabase. It provides a simplified, user-friendly interface for personal file management and secure sharing without the complexity of role-based access control.
What it is: A personal cloud storage solution that allows users to securely upload, manage, and share files through time-limited sharing links.
What it's not: This is NOT a multi-tenant or role-based system. Each user has access only to their own files, making it perfect for personal use or small teams where users manage their own content independently.
Key Philosophy: Simplicity over complexity - we removed all role-based features (admin panels, teacher/student distinctions) to create a streamlined experience focused on core file management needs.
- Simple email/password registration and login
- Secure JWT-based authentication via Supabase Auth
- Email verification support
- Session management with automatic token refresh
- Upload files up to 10MB with drag-and-drop interface
- Real-time upload progress tracking
- File browser with sorting by upload date
- Download files with original filenames
- Delete files with confirmation prompts
- Privacy: Users can ONLY see and manage their own files
- Generate time-limited secure sharing links (7-day expiration)
- Share files with anyone via secure URLs (no account required for recipients)
- Manage active sharing links (view, copy, revoke)
- Automatic link expiration for security
- Manual revocation of sharing links before expiration
- React 18 with TypeScript for type safety
- Vite for fast development and building
- Tailwind CSS for responsive, utility-first styling
- React Router for client-side routing
- Lucide React for consistent iconography
- Node.js with Express.js server
- Supabase as Backend-as-a-Service (BaaS)
- Supabase Auth for user authentication
- Supabase Storage for file storage with automatic CDN
- Supabase Database (PostgreSQL) for metadata
-- Core tables (simplified from original role-based system) profiles ( id: uuid (references auth.users) email: text created_at: timestamp -- Note: 'role' column exists but is unused (legacy) ) files ( id: uuid (primary key) filename: text file_path: text file_size: bigint content_type: text owner_id: uuid (references profiles.id) created_at: timestamp -- Note: 'owner_role' column removed during simplification ) share_links ( id: uuid (primary key) file_id: uuid (references files.id) created_by: uuid (references profiles.id) expires_at: timestamp created_at: timestamp )
- Row Level Security (RLS) enforced at database level
- Users can only access their own files (owner_id = auth.uid())
- Share links provide temporary, secure access to specific files
- No role-based permissions - all users have equal capabilities
- Upload: Client β Express server β Supabase Storage β Database metadata
- Download: Client β Express server β Supabase Storage (signed URL)
- Share: Generate signed URL with expiration β Store in share_links table
- Access Shared: Public access via share link β Temporary signed URL
- Node.js (v18 or higher)
- npm or yarn package manager
- Supabase account and project
- Git for version control
- Clone the repository
git clone https://github.com/yourusername/eduvault.git
cd eduvault- Install dependencies
npm install
- Configure Supabase
- Create a new Supabase project
- Create the required tables and policies (see
supabase/migrations/initial_schema.sql) - Create a new storage bucket named
fileswith private access
- Set up environment variables
Create a .env file in the root directory:
# Supabase Configuration VITE_SUPABASE_URL=your_supabase_project_url VITE_SUPABASE_ANON_KEY=your_supabase_anon_key SUPABASE_SERVICE_ROLE_KEY=your_service_role_key # Optional: Development settings PORT=3001 NODE_ENV=development
- Run database migrations
npx supabase db push
- Start the development server
npm run dev
The application will be available at http://localhost:5173 (or next available port)
filevault/
βββ src/ # Frontend React application
β βββ components/ # Reusable UI components
β β βββ ui/ # Base UI components (Button, Input, etc.)
β β βββ FileUpload.tsx # Drag-and-drop file upload
β β βββ FileList.tsx # File browser component
β β βββ ShareLinkManager.tsx # Share link management
β βββ contexts/ # React contexts
β β βββ AuthContext.tsx # Authentication state management
β β βββ FileContext.tsx # File operations and state
β βββ pages/ # Route components
β β βββ Login.tsx # Login page
β β βββ Register.tsx # Registration page
β β βββ Dashboard.tsx # Main file management interface
β β βββ SharedFile.tsx # Public shared file access
β βββ lib/ # Utilities and configurations
β β βββ supabase.ts # Supabase client configuration
β βββ App.tsx # Main application component
βββ server/ # Backend Express server
β βββ index.js # API routes and server logic
βββ supabase/ # Database schema and migrations
β βββ migrations/ # SQL migration files
βββ public/ # Static assets
βββ package.json # Dependencies and scripts
Register a new user account
- Body:
{ email: string, password: string } - Response:
{ user: object, session: object } - Note: Creates profile in database automatically
Authenticate existing user
- Body:
{ email: string, password: string } - Response:
{ user: object, session: object }
Retrieve user's files (RLS enforced)
- Headers:
Authorization: Bearer <token> - Response:
{ files: Array<FileObject> } - Security: Only returns files owned by authenticated user
Upload a new file
- Headers:
Authorization: Bearer <token>,Content-Type: multipart/form-data - Body: FormData with file
- Response:
{ file: FileObject } - Limits: 10MB max file size
Download a file (owner only)
- Headers:
Authorization: Bearer <token> - Response: File stream with original filename
- Security: Verifies file ownership before serving
Delete a file and its metadata
- Headers:
Authorization: Bearer <token> - Response:
{ success: boolean } - Security: Only file owner can delete
Create a time-limited share link
- Headers:
Authorization: Bearer <token> - Response:
{ shareLink: string, expiresAt: timestamp } - Expiration: 7 days from creation
Access shared file (public endpoint)
- No authentication required
- Response: File stream
- Security: Validates link expiration before serving
Revoke an active share link
- Headers:
Authorization: Bearer <token> - Response:
{ success: boolean } - Security: Only link creator can revoke
- User registers/logs in via Supabase Auth
- JWT token stored in localStorage
- Token included in API requests via Authorization header
- Server validates token and extracts user ID for RLS
- Client selects file via drag-and-drop or file picker
- File sent to Express server as multipart/form-data
- Server uploads to Supabase Storage bucket
- Metadata stored in
filestable with owner_id - Client receives file object and updates UI
- All database operations use Row Level Security (RLS)
- File access requires ownership verification
- Share links have automatic expiration (7 days)
- No role-based access - simplified permission model
- File uploads limited to 10MB to prevent abuse
This project was simplified from a role-based educational platform:
- Removed: Admin panels, teacher/student roles, role-based file access
- Simplified: Single user type, personal file management only
- Retained: Core file operations, secure sharing, authentication
# Install dependencies npm install # Start development server (frontend + backend) npm run dev # Build for production npm run build # Preview production build npm run preview # Database operations npx supabase db push # Apply migrations npx supabase db reset # Reset database npx supabase gen types typescript --local # Generate TypeScript types
- Frontend: Can be deployed to Vercel, Netlify, or any static hosting
- Backend: Deploy Express server to Railway, Render, or similar
- Database: Supabase handles hosting and scaling
- Environment: Ensure all environment variables are set in production
- CORS: Configure for your production domain
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.