aboutsummaryrefslogtreecommitdiffstats
path: root/backend/src/index.ts
diff options
context:
space:
mode:
authorPinapelz <yukais@pinapelz.com>2025-06-29 19:55:51 -0700
committerPinapelz <yukais@pinapelz.com>2025-06-29 22:06:39 -0700
commiteda5691cfcb3be0bb6ccf1b2ad4fa92801ad86c4 (patch)
treeee83300ec2d7fc2763ba6b7887d61c2af0208c7a /backend/src/index.ts
parent1b66788e84c1d2eef875534cd02685b56d08547f (diff)
seperate routes and middleware into seperate files
Diffstat (limited to 'backend/src/index.ts')
-rw-r--r--backend/src/index.ts242
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}`);
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage