File size: 3,394 Bytes
e0c5640
ae44544
 
262b7d6
e0c5640
 
ae44544
 
 
 
ce3adc9
ae44544
 
 
02cd6ee
ae44544
02cd6ee
 
ae44544
 
 
 
 
02cd6ee
bec9942
ae44544
 
 
 
 
 
 
 
 
 
 
 
429b0fe
ae44544
 
 
e0c5640
ae44544
 
 
02cd6ee
 
 
e0c5640
 
 
 
02cd6ee
e0c5640
 
 
 
 
 
 
 
 
 
 
02cd6ee
e0c5640
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ae44544
02cd6ee
429b0fe
 
e398af3
ae44544
e0c5640
 
 
 
 
 
 
 
 
 
 
02cd6ee
e0c5640
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ae44544
 
 
ce3adc9
ae44544
02cd6ee
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
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<void> => {
        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}`);
});