-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
149 lines (123 loc) · 4.28 KB
/
server.js
File metadata and controls
149 lines (123 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
const express = require('express');
const session = require('express-session');
const cors = require('cors');
const bodyParser = require('body-parser');
const path = require('path');
require('dotenv').config();
const app = express();
const PORT = process.env.PORT || 3000;
// HTTP Basic Auth middleware (password only)
const basicAuth = (req, res, next) => {
const AUTH_PASSWORD = process.env.AUTH_PASSWORD || 'migration2024';
// Get the Authorization header
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Basic ')) {
// Send authentication challenge
res.set('WWW-Authenticate', 'Basic realm="Email Migration Tool"');
return res.status(401).send('Authentication required');
}
// Decode the Base64 encoded credentials
const base64Credentials = authHeader.split(' ')[1];
const credentials = Buffer.from(base64Credentials, 'base64').toString('ascii');
// For password-only auth, we expect format: ":password" or "password"
// Split on : and take the last part as password
const parts = credentials.split(':');
const password = parts.length > 1 ? parts.slice(1).join(':') : parts[0];
if (password !== AUTH_PASSWORD) {
res.set('WWW-Authenticate', 'Basic realm="Email Migration Tool"');
return res.status(401).send('Invalid password');
}
next();
};
// Apply Basic Auth to all routes
app.use(basicAuth);
// Middleware
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
// Set up express-ejs-layouts for layout support
const expressLayouts = require('express-ejs-layouts');
app.use(expressLayouts);
app.set('layout', 'layout');
// Session configuration
app.use(session({
secret: process.env.SESSION_SECRET || 'your-secret-key',
resave: false,
saveUninitialized: false,
cookie: {
secure: false, // Set to true if using HTTPS
maxAge: 24 * 60 * 60 * 1000 // 24 hours
}
}));
// Database initialization
const db = require('./config/database');
db.init();
// Routes
const authRoutes = require('./routes/auth');
const migrationRoutes = require('./routes/migration');
const apiRoutes = require('./routes/api');
const jobRoutes = require('./routes/jobs');
const pairsRoutes = require('./routes/pairs');
app.use('/auth', authRoutes);
app.use('/migration', migrationRoutes);
app.use('/api', apiRoutes);
app.use('/jobs', jobRoutes);
app.use('/pairs', pairsRoutes);
// Home route
app.get('/', (req, res) => {
res.render('index', {
title: 'Email Migration Tool',
user: req.session.user
});
});
// Health check
app.get('/health', (req, res) => {
res.json({ status: 'OK', timestamp: new Date().toISOString() });
});
// Error handling middleware
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).render('error', {
title: 'Error',
message: 'Something went wrong!',
error: process.env.NODE_ENV === 'development' ? err : {}
});
});
// 404 handler
app.use((req, res) => {
res.status(404).render('error', {
title: '404 - Page Not Found',
message: 'The page you are looking for does not exist.'
});
});
// Initialize background processing if enabled
if (process.env.ENABLE_BACKGROUND_PROCESSING !== 'false') {
const WorkerManager = require('./workers/worker-manager');
const progressService = require('./services/progress-service');
const workerManager = new WorkerManager();
// Initialize progress service
progressService.init();
// Start workers
const numWorkers = parseInt(process.env.MAX_WORKERS) || 2;
workerManager.startWorkers(numWorkers);
workerManager.startHeartbeat();
// Graceful shutdown handling
process.on('SIGTERM', async () => {
console.log('🛑 Received SIGTERM, shutting down gracefully...');
await workerManager.stopAllWorkers();
process.exit(0);
});
process.on('SIGINT', async () => {
console.log('🛑 Received SIGINT, shutting down gracefully...');
await workerManager.stopAllWorkers();
process.exit(0);
});
console.log(`🔧 Background processing enabled with ${numWorkers} workers`);
}
app.listen(PORT, () => {
console.log(`GW-Migrate server running on port ${PORT}`);
console.log(`Visit http://localhost:${PORT} to get started`);
});