diff options
Diffstat (limited to 'backend/src/routes')
| -rw-r--r-- | backend/src/routes/authRoutes.ts | 116 | ||||
| -rw-r--r-- | backend/src/routes/userRoutes.ts | 41 |
2 files changed, 157 insertions, 0 deletions
diff --git a/backend/src/routes/authRoutes.ts b/backend/src/routes/authRoutes.ts new file mode 100644 index 0000000..4c6c374 --- /dev/null +++ b/backend/src/routes/authRoutes.ts @@ -0,0 +1,116 @@ +import { prisma } from '../config/db'; +import express from 'express'; +import { createSession } from '../utils/session' +import bcrypt from 'bcrypt'; +import crypto from 'crypto'; + +export const handleRegistration = async (req: express.Request, res: express.Response) => { + 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' }); + } +} + +export const handleAuthentication = async (req: express.Request, res: express.Response) => { + try { + const { username, password } = req.body; + + if (!username || !password) { + return res.status(400).json({ error: 'Username and password are required' }); + } + + 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' }); + } +} + +export const handleLogout = async (req: express.Request, res: express.Response,) => { + 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' }); + } +} diff --git a/backend/src/routes/userRoutes.ts b/backend/src/routes/userRoutes.ts new file mode 100644 index 0000000..a03ece0 --- /dev/null +++ b/backend/src/routes/userRoutes.ts @@ -0,0 +1,41 @@ +// Routes about self (or users in general) +import express from 'express'; +import { prisma } from '../config/db'; + +export const handleMeRoute = async (req: express.Request, res: express.Response) => { + 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' }); + } +} + +export const handleGetCurrentSession = async (req: express.Request, res: express.Response) => { + 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' }); + } +} |
