81 lines
2.4 KiB
TypeScript
81 lines
2.4 KiB
TypeScript
import 'reflect-metadata';
|
|
import dotenv from 'dotenv';
|
|
import path from 'path';
|
|
import fs from 'fs';
|
|
import { createServer as createHttpServer } from 'http';
|
|
import { createServer as createHttpsServer } from 'https';
|
|
import { resolveCertificateDirectory, resolveEnvFilePath } from './runtime-paths';
|
|
|
|
// Load .env from project root (one level up from server/)
|
|
dotenv.config({ path: resolveEnvFilePath() });
|
|
|
|
import { initDatabase } from './db/database';
|
|
import { deleteStaleJoinRequests } from './cqrs';
|
|
import { createApp } from './app';
|
|
import {
|
|
ensureVariablesConfig,
|
|
getVariablesConfigPath,
|
|
hasKlipyApiKey
|
|
} from './config/variables';
|
|
import { setupWebSocket } from './websocket';
|
|
|
|
const USE_SSL = (process.env.SSL ?? 'false').toLowerCase() === 'true';
|
|
const PORT = process.env.PORT || 3001;
|
|
|
|
function buildServer(app: ReturnType<typeof createApp>) {
|
|
if (USE_SSL) {
|
|
const certDir = resolveCertificateDirectory();
|
|
const certFile = path.join(certDir, 'localhost.crt');
|
|
const keyFile = path.join(certDir, 'localhost.key');
|
|
|
|
if (!fs.existsSync(certFile) || !fs.existsSync(keyFile)) {
|
|
console.error(`SSL=true but certs not found in ${certDir}`);
|
|
console.error('Run ./generate-cert.sh first.');
|
|
process.exit(1);
|
|
}
|
|
|
|
return createHttpsServer(
|
|
{ cert: fs.readFileSync(certFile), key: fs.readFileSync(keyFile) },
|
|
app
|
|
);
|
|
}
|
|
|
|
return createHttpServer(app);
|
|
}
|
|
|
|
async function bootstrap(): Promise<void> {
|
|
ensureVariablesConfig();
|
|
console.log('[Config] Variables loaded from:', getVariablesConfigPath());
|
|
|
|
if (!hasKlipyApiKey()) {
|
|
console.log('[KLIPY] API key not configured. GIF search is disabled.');
|
|
}
|
|
|
|
await initDatabase();
|
|
|
|
const app = createApp();
|
|
const server = buildServer(app);
|
|
|
|
setupWebSocket(server);
|
|
|
|
// Periodically clean up stale join requests (older than 24 h)
|
|
setInterval(() => {
|
|
deleteStaleJoinRequests(24 * 60 * 60 * 1000)
|
|
.catch(err => console.error('Failed to clean up stale join requests:', err));
|
|
}, 60 * 1000);
|
|
|
|
server.listen(PORT, () => {
|
|
const proto = USE_SSL ? 'https' : 'http';
|
|
const wsProto = USE_SSL ? 'wss' : 'ws';
|
|
|
|
console.log(`MetoYou signaling server running on port ${PORT} (SSL=${USE_SSL})`);
|
|
console.log(` REST API: ${proto}://localhost:${PORT}/api`);
|
|
console.log(` WebSocket: ${wsProto}://localhost:${PORT}`);
|
|
});
|
|
}
|
|
|
|
bootstrap().catch((err) => {
|
|
console.error('Failed to start server:', err);
|
|
process.exit(1);
|
|
});
|