Complete authentication system for the PERN Bug Tracker is now built!
- ✅ Database Schema — Users table with indexes
- ✅ Auth Controller — register, login, getMe functions
- ✅ JWT Middleware — Token verification for protected routes
- ✅ Auth Routes — POST /register, POST /login, GET /me
- ✅ Token Generator — JWT creation with configurable expiration
- ✅ Express Integration — Routes mounted in server/index.js
- ✅ AuthContext — Global auth state management
- ✅ useAuth Hook — Easy access to auth context
- ✅ Login Page — Beautiful form with validation
- ✅ Register Page — Full registration with confirmation
- ✅ Protected Routes — Redirects non-authenticated users
- ✅ Auth API — Axios calls for all endpoints
Option A: Local PostgreSQL
# Create database
createdb bugtracker
# Create tables from schema
psql -d bugtracker -f server/sql/schema.sqlOption B: Cloud Database (Neon, Supabase, Railway)
# Get your DATABASE_URL from the provider dashboard
# Paste it into .env file
# Run schema via your provider's SQL editor or CLIEdit .env file:
PORT=5000
NODE_ENV=development
CORS_ORIGIN=http://localhost:5173
DATABASE_URL=postgresql://user:password@localhost:5432/bugtracker
JWT_SECRET=your_super_secret_key_change_in_production
JWT_EXPIRES_IN=7d
VITE_API_BASE_URL=http://localhost:5000/apiJWT_SECRET to something unique and secure!
Server:
cd server
npm installClient:
cd client
npm installTerminal 1 — Backend:
cd server
npm run devTerminal 2 — Frontend:
cd client
npm run devVisit http://localhost:5173 in your browser.
- Click "Create Account" on login page
- Fill in name, email, password
- Click "Create Account"
- Should redirect to dashboard
- Enter email and password
- Click "Sign In"
- Should redirect to dashboard
- Token is stored in localStorage as
authToken - Token is attached to all API requests via Authorization header
- Logout clears the token and redirects to login
server/
├── sql/
│ └── schema.sql ✨ Complete database schema
├── controllers/
│ └── auth.controller.js ✨ Register, login, getMe
├── middleware/
│ ├── auth.middleware.js ✨ JWT verification
│ └── error.middleware.js ✅ Error handler
├── routes/
│ └── auth.routes.js ✨ All auth endpoints
├── utils/
│ └── generateToken.js ✨ JWT creation
├── config/
│ └── db.js ✅ PostgreSQL pool
└── index.js ✅ Updated with auth routes
client/
├── src/
│ ├── api/
│ │ └── auth.api.js ✨ Axios API calls
│ ├── context/
│ │ └── AuthContext.jsx ✨ Global auth state
│ ├── hooks/
│ │ └── useAuth.js ✨ Custom hook
│ ├── pages/
│ │ ├── LoginPage.jsx ✨ Login form
│ │ └── RegisterPage.jsx ✨ Register form
│ ├── components/
│ │ └── common/
│ │ └── ProtectedRoute.jsx ✨ Route protection
│ └── App.jsx ✅ Updated with routes & provider
1. User fills login/register form
2. Form submitted to /api/auth/login or /api/auth/register
3. Backend validates email and password
4. bcryptjs compares passwords
5. JWT token created and sent to frontend
6. Frontend stores token in localStorage
7. Token attached to all future API requests
8. Frontend redirects to /dashboard
9. Dashboard uses ProtectedRoute to verify auth
If token invalid/expired → redirect to login
- Database connected (check:
npm run devshows "Database pool connected") - Can register new user
- Can login with registered email
- Token stored in localStorage
- Dashboard accessible after login
- Logout clears token and redirects
- Navigating to /dashboard without token redirects to login
- Password confirmation validation works
- Error messages display properly
- Check DATABASE_URL in .env
- Ensure PostgreSQL is running
- Verify database exists:
psql -l
- Add JWT_SECRET to .env file
- Restart server with
npm run dev
- Change PORT in .env or kill process using port 5000
- Check CORS_ORIGIN matches frontend URL (http://localhost:5173)
- Restart backend server
- Verify user exists in database:
SELECT * FROM users; - Check password was hashed correctly
After testing Auth, next we'll build:
- Projects CRUD (create, read, update, delete)
- Project members (invite team)
- Project dashboard
- Filtering and search
- Check Network Tab — Open DevTools to see API requests
- Check Database — Use
psqlto inspect tables - Check Token — Look at localStorage in DevTools → Application tab
- Check Logs — Both backend and frontend logs show errors
Day 2 Complete! ✨ Ready for Day 3? Just say "Day 3 projects" and we'll build the project management system!