A collaborative platform for ITI students to share and view lab solutions. Built with Next.js 16, React 19, TypeScript, Supabase, and Tailwind CSS.
- Secure Authentication: OTP-based email authentication with JWT tokens and server-side sessions (device-bound with fingerprinting)
- Terms & Conditions: First-time users must accept terms before accessing the platform
- Lab Management: Browse labs by course and track with many-to-many course-track relationships
- Solution Sharing: Upload and share lab solutions with code files and file attachments
- Dual File Support:
- Code Files: Direct code editing with syntax highlighting (JavaScript, TypeScript, Python, C++, Java, etc.)
- File Attachments: Upload PDFs, images, and other files stored in Supabase Storage
- Comments System: Comment on submissions with markdown support (bold, code blocks, inline code)
- View Tracking: Track how many times your solutions are viewed
- Access Control: Lab unlocking system - submit your solution to unlock others
- Date & Time Display: All dates show both date and time (hours and minutes)
- Server-Side Security: All database operations validated server-side with proper authorization
- Framework: Next.js 16 (App Router)
- Language: TypeScript
- UI Library: React 19
- Styling: Tailwind CSS 4
- UI Components: Radix UI
- Database: Supabase (PostgreSQL)
- Storage: Supabase Storage (for file attachments)
- Authentication: Custom OTP flow with JWT tokens and server-side sessions (device fingerprinting)
- Email: Resend
- Syntax Highlighting: react-syntax-highlighter
- Deployment: Vercel (recommended)
- Node.js 18+
- npm, yarn, or pnpm
- Supabase account and project
- Resend account (for email OTP)
- PostgreSQL database (via Supabase)
git clone <repository-url>
cd LabSharenpm install
# or
yarn install
# or
pnpm installCreate a .env.local file in the root directory:
# Supabase
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key # Required for storage operations
# Resend (for email OTP)
RESEND_API_KEY=your_resend_api_key
# JWT Authentication
JWT_SECRET=your_jwt_secret_key # Generate a secure random string (e.g., openssl rand -hex 32)
JWT_EXPIRES_IN=7d # JWT expiration time (default: 7d, supports formats like "1h", "30d", etc.)
# Database (optional - for migration script)
DATABASE_URL=postgresql://postgres.[PROJECT-REF]:[PASSWORD]@[HOST]:[PORT]/postgres
# Node Environment
NODE_ENV=developmentCreate a storage bucket in Supabase:
- Go to Supabase Dashboard β Storage
- Create a new bucket named
submission-attachments - Set it to Public (or configure RLS policies as needed)
- Enable the bucket for file uploads
Run the database migrations:
npm run db:migrateThis will execute the SQL scripts in the scripts/ directory in order:
001_create_schema.sql- Creates database schema with all tables and RLS policies002_seed_data.sql- Seeds initial data (tracks, courses, labs, students)003_fix_timestamps_utc.sql- Fixes timestamp timezone issues004_remove_versions_separate_code_attachments.sql- Migration to separate code files from attachments005_add_performance_indexes.sql- Adds performance indexes for common queries006_create_sessions_table.sql- Creates sessions table for JWT-based authentication
Note: See scripts/README.md for detailed migration instructions and alternative methods.
npm run devOpen http://localhost:3000 in your browser.
LabShare/
βββ app/ # Next.js App Router
β βββ api/ # API routes (server-side)
β β βββ auth/ # Authentication endpoints
β β β βββ accept-terms/ # Terms acceptance
β β β βββ check-terms/ # Terms verification
β β β βββ logout/ # Logout
β β β βββ status/ # Auth status
β β β βββ request-otp/ # Request OTP
β β β βββ send-otp/ # Send OTP email
β β β βββ verify-otp/ # Verify OTP code
β β βββ dashboard/ # Dashboard data
β β βββ lab/ # Lab endpoints
β β βββ labs/ # Labs listing
β β βββ submission/ # Submission endpoints
β β βββ [id]/
β β βββ comments/ # Comment management
β β βββ route.ts # Submission CRUD
β βββ dashboard/ # Dashboard page
β βββ lab/ # Lab detail pages
β β βββ [id]/
β β βββ locked/ # Locked lab page
β β βββ page.tsx # Lab detail page
β βββ labs/ # Labs listing page
β βββ login/ # Login page
β βββ terms/ # Terms & conditions page
β βββ submission/ # Submission detail pages
β β βββ [id]/page.tsx
β βββ last-updates/ # Changelog page
β βββ layout.tsx # Root layout
β βββ page.tsx # Home page (redirects)
βββ components/ # React components
β βββ ui/ # Reusable UI components (Radix UI)
β βββ navigation.tsx # Navigation bar
β βββ comments-section.tsx # Comments component
β βββ last-updates.tsx # Changelog component
β βββ theme-provider.tsx
βββ lib/ # Utility libraries
β βββ auth.ts # Authentication utilities
β βββ auth/ # Authentication modules
β β βββ jwt.ts # JWT signing and verification
β β βββ sessions.ts # Session management
β β βββ fingerprint.ts # Device fingerprinting
β βββ storage.ts # Storage operations (Supabase)
β βββ supabase/ # Supabase clients
β β βββ client.ts # Client-side client
β β βββ server.ts # Server-side client
β β βββ middleware.ts # Middleware client
β β βββ service.ts # Service role client
β βββ utils.ts # General utilities (formatDateTime, etc.)
βββ scripts/ # Database migration scripts
β βββ 001_create_schema.sql
β βββ 002_seed_data.sql
β βββ 003_fix_timestamps_utc.sql
β βββ 004_remove_versions_separate_code_attachments.sql
β βββ 005_add_performance_indexes.sql
β βββ 006_create_sessions_table.sql
β βββ run-migrations.js # Migration runner
β βββ README.md # Migration guide
βββ data/ # Static data
β βββ lastUpdates.ts # Changelog data
βββ hooks/ # React hooks
βββ public/ # Static assets
βββ styles/ # Global styles
- Server-Side Validation: All database queries run server-side with authentication checks
- JWT Authentication: Secure JWT tokens with server-side session validation
- Device Fingerprinting: Sessions are bound to device fingerprints to detect token theft
- Session Management: Server-side session revocation and multi-device support
- HttpOnly Cookies: Secure cookie-based token storage (httpOnly, secure, sameSite)
- Terms Acceptance: First-time users must accept terms before accessing the platform
- Authorization Checks: Users can only access/modify their own data
- Input Validation: Server-side validation for all API routes
- SQL Injection Protection: Using Supabase client with parameterized queries
- Row Level Security (RLS): All tables have RLS policies enabled
- File Upload Security: Filename sanitization and path validation
All API routes require authentication via JWT tokens in httpOnly cookies (except login/OTP endpoints):
POST /api/auth/request-otp- Request OTP codePOST /api/auth/send-otp- Send OTP emailPOST /api/auth/verify-otp- Verify OTP and create sessionGET /api/auth/status- Check authentication statusGET /api/auth/check-terms- Check if terms are acceptedPOST /api/auth/accept-terms- Accept terms and conditionsPOST /api/auth/logout- Logout user
GET /api/dashboard- Get dashboard data (student, track, courses, recent submissions)GET /api/labs- Get labs for authenticated student (grouped by course)GET /api/lab/[id]- Get specific lab data with submissions
GET /api/submission/[id]- Get submission details (with code files and attachments)POST /api/submission/upload- Upload/update submission (code files + attachments)DELETE /api/submission/[id]- Delete submission (and associated files)
GET /api/submission/[id]/comments- Get comments for a submissionPOST /api/submission/[id]/comments- Add a commentDELETE /api/submission/[id]/comments/[commentId]- Delete a comment
students- Student information (name, email, track_id)tracks- ITI tracks (code, name)courses- Course information (name, description)course_track- Many-to-many relationship between courses and trackslabs- Lab assignments (course_id, lab_number, title, description)auth_codes- OTP codes for authentication (student_id, code, expires_at, used)sessions- User sessions for JWT authentication (user_id, fingerprint, last_seen, revoked)
submissions- Student submissions (student_id, lab_id, title, view_count)submission_code- Code files (submission_id, filename, language, content)submission_attachments- File attachments stored in Supabase Storage (submission_id, filename, storage_path, mime_type, file_size)
comments- Comments on submissions (submission_id, student_id, content)lab_unlocks- Track which labs students have unlocked (student_id, lab_id, unlocked_at)
- Students belong to one Track (many-to-one)
- Courses can belong to multiple Tracks (many-to-many via
course_track) - Labs belong to one Course (many-to-one)
- Submissions belong to one Student and one Lab (one-to-one per student-lab)
- Submissions have multiple Code Files and Attachments (one-to-many)
- Submissions have multiple Comments (one-to-many)
- Lab unlocks track which labs a student can access (many-to-many)
The application uses Supabase Storage for file attachments:
- Bucket:
submission-attachments - Structure:
submissions/{submissionId}/{filename} - File Types: PDFs, images, documents, and other non-code files
- Code Files: Stored directly in database (
submission_codetable) for syntax highlighting
- Push your code to GitHub
- Import project in Vercel
- Add environment variables in Vercel dashboard
- Deploy!
Make sure to set all environment variables in your deployment platform:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEYSUPABASE_SERVICE_ROLE_KEYRESEND_API_KEYJWT_SECRET- Secure random string for signing JWTsJWT_EXPIRES_IN- JWT expiration time (default: "7d")NODE_ENV=productionDATABASE_URL(optional, for migrations)
npm run dev- Start development servernpm run build- Build for productionnpm run start- Start production servernpm run lint- Run ESLintnpm run db:migrate- Run database migrations
The database has evolved through several migrations:
- 001_create_schema.sql - Initial schema creation
- 002_seed_data.sql - Initial data seeding
- 003_fix_timestamps_utc.sql - UTC timestamp fixes
- 004_remove_versions_separate_code_attachments.sql - Removed version system, separated code files from attachments
- 005_add_performance_indexes.sql - Added performance indexes for common queries
- 006_create_sessions_table.sql - Created sessions table for JWT-based authentication with device fingerprinting
- Syntax Highlighting: Code files support multiple languages with Prism.js
- Markdown Support: Comments support bold (
**text**), inline code (`code`), and code blocks (code) - Date Formatting: All dates display with time (e.g., "12/25/2023, 3:45 PM")
- Responsive Design: Mobile-friendly interface with Tailwind CSS
- Dark Mode Ready: Theme provider included (can be enabled)
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Contributors are credited in the "Last Updates" section on the dashboard.
This project is private and proprietary.
- ITI Development Team
- Built with Next.js
- UI components from Radix UI
- Database powered by Supabase
- Email service by Resend
- Syntax highlighting by react-syntax-highlighter
For issues and questions, please open an issue in the repository or contact the development team.
Note: This is a private project for ITI students. Unauthorized access is prohibited.