diff options
| author | Pinapelz <yukais@pinapelz.com> | 2025-06-29 19:55:51 -0700 |
|---|---|---|
| committer | Pinapelz <yukais@pinapelz.com> | 2025-06-29 22:06:39 -0700 |
| commit | eda5691cfcb3be0bb6ccf1b2ad4fa92801ad86c4 (patch) | |
| tree | ee83300ec2d7fc2763ba6b7887d61c2af0208c7a /backend/src/index.ts | |
| parent | 1b66788e84c1d2eef875534cd02685b56d08547f (diff) | |
seperate routes and middleware into seperate files
Diffstat (limited to 'backend/src/index.ts')
| -rw-r--r-- | backend/src/index.ts | 242 |
1 files changed, 12 insertions, 230 deletions
diff --git a/backend/src/index.ts b/backend/src/index.ts index 37b64a8..3e2c559 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -1,10 +1,13 @@ import express from 'express'; import cors from 'cors'; -import bcrypt from 'bcrypt'; -import crypto from 'crypto'; import session from 'express-session'; import cookieParser from 'cookie-parser'; -import { PrismaClient } from '@prisma/client'; +import { requireAuth } from './middleware/requireAuth'; +import { startSessionCleanup } from './utils/session'; + +// Routes +import * as authRoutes from './routes/authRoutes'; +import * as userRoutes from './routes/userRoutes'; const app = express(); const port = 5000; @@ -31,241 +34,20 @@ app.use(session({ } })); -const prisma = new PrismaClient(); - - declare module 'express-session' { interface SessionData { userId: number; } } -// Middleware to check if user is authenticated -const requireAuth = async (req: express.Request, res: express.Response, next: express.NextFunction) => { - if (!req.session.userId) { - return res.status(401).json({ error: 'Authentication required' }); - } - - try { - const user = await prisma.user.findUnique({ - where: { id: req.session.userId }, - select: { id: true, username: true, email: true } - }); - - if (!user) { - req.session.destroy((err) => { - if (err) console.error('Session destroy error:', err); - }); - return res.status(401).json({ error: 'Invalid session' }); - } - - // Attach user to request object - (req as any).user = user; - next(); - } catch (error) { - console.error('Auth middleware error:', error); - res.status(500).json({ error: 'Internal server error' }); - } -}; - -// Create session in database -const createSession = async (userId: number): Promise<string> => { - const sessionId = crypto.randomUUID(); - const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000); // 24 hours - - await prisma.session.create({ - data: { - id: sessionId, - userId, - expiresAt - } - }); - - return sessionId; -}; - -// Clean up expired sessions -const cleanupExpiredSessions = async () => { - try { - await prisma.session.deleteMany({ - where: { - expiresAt: { - lt: new Date() - } - } - }); - } catch (error) { - console.error('Session cleanup error:', error); - } -}; - -// Run cleanup every hour -setInterval(cleanupExpiredSessions, 60 * 60 * 1000); - -app.post('/api/register', async (req, res) => { - try { - const { username, password, email } = req.body; - - if (!username || !password || !email) { - return res.status(400).json({ error: 'All fields are required' }); - } - - const existingUser = await prisma.user.findFirst({ - where: { - OR: [ - { username }, - { email } - ] - } - }); - - if (existingUser) { - return res.status(400).json({ error: 'Username or email already exists' }); - } - - const salt = crypto.randomBytes(16).toString('hex'); - const hashedPassword = await bcrypt.hash(password + salt, 12); - - const user = await prisma.user.create({ - data: { - username, - password: hashedPassword, - salt, - email, - } - }); - - // Create session for the new user - req.session.userId = user.id; - const sessionId = await createSession(user.id); - - res.status(201).json({ - id: user.id, - username: user.username, - email: user.email, - sessionId - }); - } catch (error) { - console.error('Registration error:', error); - res.status(500).json({ error: 'Internal server error' }); - } -}); - -app.post('/api/authenticate', async (req, res) => { - try { - const { username, password } = req.body; +startSessionCleanup(); - if (!username || !password) { - return res.status(400).json({ error: 'Username and password are required' }); - } +app.post('/api/register', authRoutes.handleRegistration); +app.post('/api/authenticate', authRoutes.handleAuthentication); +app.post('/api/logout', requireAuth, authRoutes.handleLogout); - const user = await prisma.user.findUnique({ - where: { username } - }); - - if (!user) { - return res.status(401).json({ error: 'Invalid credentials' }); - } - - const isValidPassword = await bcrypt.compare(password + user.salt, user.password); - if (!isValidPassword) { - return res.status(401).json({ error: 'Invalid credentials' }); - } - - // Create session - req.session.userId = user.id; - const sessionId = await createSession(user.id); - - res.json({ - id: user.id, - username: user.username, - email: user.email, - sessionId - }); - } catch (error) { - console.error('Login error:', error); - res.status(500).json({ error: 'Internal server error' }); - } -}); - -app.post('/api/logout', requireAuth, async (req, res) => { - try { - const userId = req.session.userId; - - // Remove all sessions for this user from database - await prisma.session.deleteMany({ - where: { userId } - }); - - // Destroy the session - req.session.destroy((err) => { - if (err) { - console.error('Session destroy error:', err); - return res.status(500).json({ error: 'Logout failed' }); - } - - res.clearCookie('connect.sid'); // Clear the session cookie - res.json({ message: 'Logged out successfully' }); - }); - } catch (error) { - console.error('Logout error:', error); - res.status(500).json({ error: 'Internal server error' }); - } -}); - -app.get('/api/me', requireAuth, async (req, res) => { - try { - const user = (req as any).user; - res.json(user); - } catch (error) { - console.error('Me endpoint error:', error); - res.status(500).json({ error: 'Internal server error' }); - } -}); - -app.get('/api/users', async (req, res) => { - try { - const users = await prisma.user.findMany({ - select: { - id: true, - username: true, - } - }); - res.json(users); - } catch (error) { - console.error('Users endpoint error:', error); - res.status(500).json({ error: 'Internal server error' }); - } -}); - -// Check session status -app.get('/api/session', async (req, res) => { - try { - if (!req.session.userId) { - return res.json({ authenticated: false }); - } - - const user = await prisma.user.findUnique({ - where: { id: req.session.userId }, - select: { id: true, username: true, email: true } - }); - - if (!user) { - req.session.destroy((err) => { - if (err) console.error('Session destroy error:', err); - }); - return res.json({ authenticated: false }); - } - - res.json({ - authenticated: true, - user - }); - } catch (error) { - console.error('Session check error:', error); - res.status(500).json({ error: 'Internal server error' }); - } -}); +app.get('/api/me', userRoutes.handleMeRoute); +app.get('/api/session', userRoutes.handleGetCurrentSession); app.listen(port, () => { console.log(`Server listening on port ${port}`); |
