import express, { Request, Response } from 'express'; import cors from 'cors'; import dotenv from 'dotenv'; import { prisma } from './prisma_client'; import crypto from 'crypto'; dotenv.config(); const app = express(); const port = process.env.PORT ? parseInt(process.env.PORT, 10) : 10000; // Whitelist of allowed client origins const allowedOrigins = [ // for testing 'http://localhost:3000', // deployed frontend 'https://mcp-hackathon.vercel.app' ]; // Strict CORS configuration for protected routes const strictCorsOptions = { origin: (origin: string | undefined, callback: (err: Error | null, allow?: boolean) => void) => { // disallows CURL, Postman, etc. if (origin && allowedOrigins.includes(origin)) { callback(null, true); } else { callback(new Error('Not allowed by CORS')); } }, methods: ['GET', 'POST'], credentials: true }; // Open CORS configuration for public routes const openCorsOptions = { origin: '*', methods: ['GET', 'POST', 'OPTIONS'], credentials: true }; // Middleware app.use(express.json()); // Generates Key // TODO: add verification that key doesn't exist and add key if needed. // currently relying on sheer probablistic chance :P function generateApiKey(): string { return crypto.randomBytes(32).toString('hex'); } // Public route (no CORS restrictions) app.post('/api/verifyKey', cors(openCorsOptions), async (req: Request, res: Response) => { try { const { apiKey } = req.body; if (!apiKey) { res.status(400).json({ error: 'API key is required' }); return; } // See if key is in database const key = await prisma.key.findFirst({ where: { apiKey } }); if (!key) { res.status(401).json({ valid: false }); return; } else { res.json({ valid: true }); } } catch (error) { console.error('Error verifying API key:', error); res.status(500).json({ error: 'Failed to verify API key' }); } } ); // Protected route with strict CORS and authentication app.options('/api/addKey', cors(strictCorsOptions)); app.options('/api/addKey/', cors(strictCorsOptions)); app.post('/api/addKey', cors(strictCorsOptions), async (req: Request, res: Response): Promise => { try { const { email } = req.body; if (!email) { res.status(400).json({ error: 'Email is required' }); return; } const apiKey = generateApiKey(); // Add key to database const newKey = await prisma.key.create({ data: { email, apiKey, } }); res.json({ message: 'API key generated successfully', apiKey: newKey.apiKey }); } catch (error) { console.error('Error creating API key:', error); res.status(500).json({ error: 'Failed to create API key' }); } } ); app.listen(port, '0.0.0.0', () => { console.log(`Server running on port ${port}`); });