Initial Commit
This commit is contained in:
129
server/index.ts
Normal file
129
server/index.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import express, { Request, Response } from 'express';
|
||||
import http from 'http';
|
||||
import { Server as SocketIOServer } from 'socket.io';
|
||||
import cors from 'cors';
|
||||
import cookieParser from 'cookie-parser';
|
||||
import session from 'express-session';
|
||||
import passport from 'passport';
|
||||
import path from 'path';
|
||||
|
||||
import { setupSocketIO } from './socket';
|
||||
import { db } from './database';
|
||||
import { config } from './config';
|
||||
import {
|
||||
securityHeaders,
|
||||
createRateLimit,
|
||||
requestLogger,
|
||||
sanitizeInput
|
||||
} from './middleware';
|
||||
import { logger } from './logger';
|
||||
import './auth';
|
||||
|
||||
const app = express();
|
||||
const server = http.createServer(app);
|
||||
const io = new SocketIOServer(server, {
|
||||
cors: {
|
||||
origin: config.security.corsOrigin,
|
||||
methods: ['GET', 'POST'],
|
||||
credentials: true
|
||||
},
|
||||
transports: ['polling', 'websocket']
|
||||
});
|
||||
|
||||
// Security middleware
|
||||
app.use(securityHeaders);
|
||||
app.use(requestLogger);
|
||||
app.use(sanitizeInput);
|
||||
|
||||
// Cookie parsing
|
||||
app.use(cookieParser());
|
||||
|
||||
// Rate limiting
|
||||
app.use('/api', createRateLimit);
|
||||
|
||||
// Session configuration
|
||||
const SQLiteStore = require('connect-sqlite3')(session);
|
||||
const sessionMiddleware = session({
|
||||
store: new SQLiteStore({ db: 'sessions.db', dir: './data' }),
|
||||
secret: process.env.NEXTAUTH_SECRET || 'fallback-secret-change-in-production',
|
||||
resave: false,
|
||||
saveUninitialized: false,
|
||||
cookie: { secure: false, maxAge: 24 * 60 * 60 * 1000 } // 24 hours
|
||||
});
|
||||
|
||||
app.use(sessionMiddleware);
|
||||
|
||||
// Passport initialization
|
||||
app.use(passport.initialize());
|
||||
app.use(passport.session());
|
||||
|
||||
// Body parsing
|
||||
app.use(express.json({ limit: '10mb' }));
|
||||
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
|
||||
|
||||
// CORS with specific origin
|
||||
app.use(cors({
|
||||
origin: config.server.nodeEnv === 'development'
|
||||
? ['http://localhost:3000', 'http://localhost:5173']
|
||||
: config.security.corsOrigin,
|
||||
credentials: true
|
||||
}));
|
||||
|
||||
app.use(express.static(path.join(__dirname, '../client/dist')));
|
||||
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
||||
});
|
||||
|
||||
// Auth routes
|
||||
app.get('/auth/github', passport.authenticate('github'));
|
||||
|
||||
app.get('/auth/github/callback',
|
||||
passport.authenticate('github', { failureRedirect: '/login' }),
|
||||
(req, res) => {
|
||||
res.redirect('/');
|
||||
}
|
||||
);
|
||||
|
||||
app.get('/api/user', (req, res) => {
|
||||
if (req.user) {
|
||||
res.json(req.user);
|
||||
} else {
|
||||
res.status(401).json({ error: 'Not authenticated' });
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/api/socket-token', (req, res) => {
|
||||
if (req.user) {
|
||||
// Create a token containing user info
|
||||
const user = req.user as any; // Use any to bypass typing issues
|
||||
const token = Buffer.from(JSON.stringify({
|
||||
userId: user.id,
|
||||
username: user.username,
|
||||
timestamp: Date.now()
|
||||
})).toString('base64');
|
||||
|
||||
res.json({ token, user: req.user });
|
||||
} else {
|
||||
res.status(401).json({ error: 'Not authenticated' });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
// SPA catch-all route
|
||||
app.get('*', (req, res) => {
|
||||
res.sendFile(path.join(__dirname, '../client/dist/index.html'));
|
||||
});
|
||||
|
||||
io.use((socket: any, next: any) => {
|
||||
next();
|
||||
});
|
||||
|
||||
setupSocketIO(io);
|
||||
|
||||
const PORT = config.server.port;
|
||||
|
||||
server.listen(PORT, () => {
|
||||
console.log(`Server running on port ${PORT}`);
|
||||
});
|
||||
Reference in New Issue
Block a user