Initial commit
This commit is contained in:
112
backend/server.js
Normal file
112
backend/server.js
Normal file
@@ -0,0 +1,112 @@
|
||||
const express = require('express');
|
||||
const cors = require('cors');
|
||||
const helmet = require('helmet');
|
||||
const morgan = require('morgan');
|
||||
const rateLimit = require('express-rate-limit');
|
||||
require('dotenv').config();
|
||||
|
||||
const paymentRoutes = require('./routes/payment');
|
||||
const webhookRoutes = require('./routes/webhook');
|
||||
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 5000;
|
||||
|
||||
// Rate limiting
|
||||
const limiter = rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
max: 100 // limit each IP to 100 requests per windowMs
|
||||
});
|
||||
|
||||
// Middleware
|
||||
app.use(helmet());
|
||||
app.use(limiter);
|
||||
app.use(morgan('combined'));
|
||||
|
||||
// CORS configuration
|
||||
const corsOptions = {
|
||||
origin: process.env.ALLOWED_ORIGINS?.split(',') || ['http://localhost:3000'],
|
||||
credentials: true,
|
||||
optionsSuccessStatus: 200
|
||||
};
|
||||
app.use(cors(corsOptions));
|
||||
|
||||
// Body parsing middleware
|
||||
app.use('/webhook', express.raw({ type: 'application/json' })); // Raw body for webhooks
|
||||
app.use(express.json({ limit: '10mb' }));
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
|
||||
// Routes
|
||||
app.use('/api/payment', paymentRoutes);
|
||||
app.use('/webhook', webhookRoutes);
|
||||
|
||||
// Health check endpoint
|
||||
app.get('/api/health', (req, res) => {
|
||||
res.json({
|
||||
status: 'OK',
|
||||
timestamp: new Date().toISOString(),
|
||||
environment: process.env.NODE_ENV || 'development'
|
||||
});
|
||||
});
|
||||
|
||||
// Debug endpoint (only in development)
|
||||
app.get('/api/debug/env', (req, res) => {
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
return res.status(403).json({ error: 'Not available in production' });
|
||||
}
|
||||
|
||||
res.json({
|
||||
NODE_ENV: process.env.NODE_ENV,
|
||||
PORT: process.env.PORT,
|
||||
FRONTEND_URL: process.env.FRONTEND_URL,
|
||||
SKIP_WOOCOMMERCE: process.env.SKIP_WOOCOMMERCE,
|
||||
SKIP_TOKEN_VALIDATION: process.env.SKIP_TOKEN_VALIDATION,
|
||||
PAYPAL_MODE: process.env.PAYPAL_MODE,
|
||||
HAS_PAYPAL_CLIENT_ID: !!process.env.PAYPAL_CLIENT_ID,
|
||||
HAS_PAYPAL_CLIENT_SECRET: !!process.env.PAYPAL_CLIENT_SECRET,
|
||||
HAS_JWT_SECRET: !!process.env.JWT_SECRET,
|
||||
JWT_SECRET_LENGTH: process.env.JWT_SECRET?.length || 0,
|
||||
HAS_WEBHOOK_SECRET: !!process.env.WEBHOOK_SECRET,
|
||||
HAS_WC_URL: !!process.env.WOOCOMMERCE_URL,
|
||||
HAS_WC_CONSUMER_KEY: !!process.env.WOOCOMMERCE_CONSUMER_KEY,
|
||||
HAS_WC_CONSUMER_SECRET: !!process.env.WOOCOMMERCE_CONSUMER_SECRET,
|
||||
ALLOWED_ORIGINS: process.env.ALLOWED_ORIGINS
|
||||
});
|
||||
});
|
||||
|
||||
// Error handling middleware
|
||||
app.use((err, req, res, next) => {
|
||||
console.error('Error:', err);
|
||||
|
||||
// Don't expose error details in production
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
res.status(500).json({
|
||||
error: 'Internal server error',
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
} else {
|
||||
res.status(500).json({
|
||||
error: err.message,
|
||||
stack: err.stack,
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 404 handler
|
||||
app.use('*', (req, res) => {
|
||||
res.status(404).json({
|
||||
error: 'Route not found',
|
||||
path: req.originalUrl,
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
});
|
||||
|
||||
// Start server
|
||||
app.listen(PORT, () => {
|
||||
console.log(`🚀 Server running on port ${PORT}`);
|
||||
console.log(`📊 Environment: ${process.env.NODE_ENV || 'development'}`);
|
||||
console.log(`💳 PayPal Mode: ${process.env.PAYPAL_MODE || 'sandbox'}`);
|
||||
console.log(`🌐 CORS Origins: ${process.env.ALLOWED_ORIGINS || 'http://localhost:3000'}`);
|
||||
});
|
||||
|
||||
module.exports = app;
|
||||
Reference in New Issue
Block a user