logingest/server.js

136 lines
4.3 KiB
JavaScript
Raw Permalink Normal View History

2025-06-15 14:47:15 +00:00
import { createServer } from 'http';
import { URL } from 'url';
import pkg from 'pg';
import { authenticateBasic } from './middleware/auth.js';
import { validateLogData } from './utils/validation.js';
import { createLogEntry } from './services/logService.js';
const { Client } = pkg;
const PORT = process.env.PORT || 3000;
// PostgreSQL connection configuration from environment variables
const dbConfig = {
host: process.env.DB_HOST || 'localhost',
port: process.env.DB_PORT || 5432,
database: process.env.DB_NAME || 'postgres',
user: process.env.DB_USER || 'postgres',
password: process.env.DB_PASSWORD || 'password',
ssl: process.env.DB_SSL === 'true' ? { rejectUnauthorized: false } : false
};
// Initialize PostgreSQL client
const client = new Client(dbConfig);
// Connect to PostgreSQL
try {
await client.connect();
console.log('Connected to PostgreSQL database');
// Create logs table if it doesn't exist
await client.query(`
CREATE TABLE IF NOT EXISTS logs (
2025-06-18 12:05:24 +00:00
id varchar(20) PRIMARY KEY,
2025-06-15 14:47:15 +00:00
body text NOT NULL,
project text NOT NULL DEFAULT 'Project 1',
type text NOT NULL DEFAULT 'Info',
2025-06-18 12:05:24 +00:00
date text NOT NULL,
2025-06-15 14:47:15 +00:00
avatar_src text NOT NULL DEFAULT '/rectangle-15.png',
owner text NOT NULL DEFAULT 'N/A',
description text NOT NULL,
created_at timestamptz NOT NULL DEFAULT now(),
status text NOT NULL DEFAULT 'Pending'
)
`);
console.log('Logs table ready');
} catch (error) {
console.error('Failed to connect to PostgreSQL:', error);
process.exit(1);
}
const server = createServer(async (req, res) => {
// Set CORS headers
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
// Handle preflight requests
if (req.method === 'OPTIONS') {
res.writeHead(200);
res.end();
return;
}
const url = new URL(req.url, `http://localhost:${PORT}`);
try {
// Health check endpoint
if (req.method === 'GET' && url.pathname === '/health') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ status: 'healthy', timestamp: new Date().toISOString() }));
return;
}
// Log entry endpoint
if (req.method === 'POST' && url.pathname === '/logs') {
// Authenticate request
const authResult = authenticateBasic(req);
if (!authResult.success) {
res.writeHead(401, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Unauthorized', message: authResult.message }));
return;
}
// Parse request body
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', async () => {
try {
const data = JSON.parse(body);
// Validate input data
const validation = validateLogData(data);
if (!validation.isValid) {
res.writeHead(400, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Invalid input', errors: validation.errors }));
return;
}
// Create log entry
const logEntry = await createLogEntry(client, data);
res.writeHead(201, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
success: true,
message: 'Log entry created successfully',
id: logEntry.id
}));
} catch (error) {
console.error('Error processing request:', error);
res.writeHead(500, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Internal server error' }));
}
});
return;
}
// 404 for unknown routes
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Not found' }));
} catch (error) {
console.error('Server error:', error);
res.writeHead(500, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Internal server error' }));
}
});
server.listen(PORT, () => {
console.log(`Log microservice running on port ${PORT}`);
console.log(`Health check available at: http://localhost:${PORT}/health`);
console.log(`Log endpoint available at: http://localhost:${PORT}/logs`);
});