Files
noteflow/server.js
T
2025-11-06 14:03:16 +01:00

76 lines
2.1 KiB
JavaScript

const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const path = require('path');
const winston = require('winston');
const fs = require('fs');
const { db } = require('./config/database');
// Ensure uploads directory exists
const uploadsDir = path.join(__dirname, 'public/uploads');
if (!fs.existsSync(uploadsDir)) {
fs.mkdirSync(uploadsDir, { recursive: true });
}
// Configure logger
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new winston.transports.Console()
]
});
// Create Express app
const app = express();
// Middleware
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'"],
styleSrc: ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
fontSrc: ["'self'", "https://fonts.gstatic.com"],
imgSrc: ["'self'", "data:"],
connectSrc: ["'self'"]
}
}
}));
app.use(cors());
app.use(express.json());
app.use(express.static('public'));
// Set JWT_SECRET environment variable if not set
if (!process.env.JWT_SECRET) {
process.env.JWT_SECRET = 'default_development_secret';
logger.warn('JWT_SECRET not set, using default (insecure) value');
}
// Routes
app.use('/api/auth', require('./routes/auth.routes'));
app.use('/api/users', require('./routes/users.routes'));
app.use('/api/notes', require('./routes/notes.routes'));
// Serve static files
app.use('/uploads', express.static(path.join(__dirname, 'public/uploads')));
// SPA fallback
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'public/index.html'));
});
// Error handling
app.use((err, req, res, next) => {
logger.error('Unhandled error:', err);
res.status(500).json({ message: 'Internal server error' });
});
// Start server
const PORT = process.env.PORT || 2222;
app.listen(PORT, () => {
logger.info(`Server running on port ${PORT}`);
});