-
Notifications
You must be signed in to change notification settings - Fork 23
/
routes.js
216 lines (192 loc) · 8.45 KB
/
routes.js
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
const express = require('express');
const router = express.Router();
const axios = require('axios');
const Repository = require('./repository');
const User = require('./models/user');
const { processRepository } = require('./processRepository');
const { interactWithRepository } = require('./chatService');
const { isAuthenticated } = require('./middleware/auth');
const OpenAI = require("openai");
console.log('Router middleware is set up.');
// Protect routes that require authentication
router.get('/', isAuthenticated, async (req, res) => {
const user = await User.findById(req.session.userId);
console.log('User data fetched:', { userId: user._id, hasApiKey: !!user.openaiApiKey });
res.render('index', {
userId: req.session.userId,
userApiKey: user.openaiApiKey ? '**********' : null,
apiKeyMessage: user.openaiApiKey ? 'Your API key is already set. Enter a new key to update.' : null
});
});
// Registration route
router.get('/register', (req, res) => {
res.render('register', { userId: req.session ? req.session.userId : null });
});
router.post('/register', async (req, res) => {
try {
const { email, password } = req.body;
const user = new User({ email, password });
await user.save();
req.session.userId = user._id;
res.redirect('/');
} catch (error) {
console.error('Error handling POST /register:', error.message, error.stack);
res.render('register', { error: 'Registration failed. Please try again.', userId: req.session ? req.session.userId : null });
}
});
// Login route
router.get('/login', (req, res) => {
res.render('login', { userId: req.session ? req.session.userId : null });
});
router.post('/login', async (req, res) => {
try {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (user && await user.comparePassword(password)) {
req.session.userId = user._id;
res.redirect('/');
} else {
res.render('login', { error: 'Invalid email or password', userId: req.session ? req.session.userId : null });
}
} catch (error) {
console.error('Error handling POST /login:', error.message, error.stack);
res.render('login', { error: 'Login failed. Please try again.', userId: req.session ? req.session.userId : null });
}
});
// Logout route
router.get('/logout', (req, res) => {
req.session.destroy((err) => {
if (err) {
console.error('Error destroying session:', err);
}
res.redirect('/login');
});
});
router.post('/submit', isAuthenticated, async (req, res) => {
console.log('POST request made to /submit');
const { githubUrl } = req.body;
if (!githubUrl) {
return res.status(400).render('submit', { message: 'Repository URL is required.', userId: req.session.userId });
}
try {
const user = await User.findById(req.session.userId);
if (!user.openaiApiKey) {
return res.status(400).render('submit', { message: 'Please set your OpenAI API key before submitting a repository.', userId: req.session.userId });
}
const repoResponse = await axios.get(githubUrl.replace('https://github.com', 'https://api.github.com/repos'));
if (repoResponse.data.private) {
console.error('Repository is private:', githubUrl);
return res.status(400).render('submit', { message: 'Repository is private or does not exist.', userId: req.session.userId });
} else if (repoResponse.data.size === 0) {
console.log(`Repository ${githubUrl} is empty and cannot be processed.`);
return res.status(400).render('submit', { message: 'The repository is empty and cannot be processed.', userId: req.session.userId });
} else if (repoResponse.data.size > 500) {
console.error('Repository has more than 500 files:', githubUrl);
return res.status(400).render('submit', { message: 'Repository has more than 500 files and cannot be processed.', userId: req.session.userId });
}
let existingRepo = await Repository.findOne({ githubUrl });
if (existingRepo) {
if (existingRepo.isProcessed) {
console.log(`Redirecting to existing processed repository: ${existingRepo.uuid}`);
return res.redirect(`/explain/${existingRepo.uuid}`);
} else {
if (!existingRepo.emails.includes(user.email)) {
existingRepo.emails.push(user.email);
await existingRepo.save();
}
console.log(`Repository is currently being processed: ${githubUrl}`);
return res.status(200).render('submit', { message: 'Repository is currently being processed. You will be notified when it\'s ready.', userId: req.session.userId });
}
} else {
const newRepo = new Repository({ githubUrl, emails: [user.email] });
await newRepo.save();
console.log(`New repository saved with URL: ${githubUrl}`);
await processRepository(newRepo.githubUrl, user.openaiApiKey);
console.log(`Processing started for repository: ${newRepo.githubUrl}`);
res.status(201).render('submit', { message: 'Repository processing started. You will receive an email when it is complete.', userId: req.session.userId });
}
} catch (error) {
console.error('Error handling POST /submit:', error.message, error.stack);
res.status(400).render('submit', { message: 'Error checking repository. Make sure the URL is correct and the repository is public.', userId: req.session.userId });
}
});
router.get('/explain/:uuid', async (req, res) => {
const uuid = req.params.uuid;
console.log(`GET request made to /explain/${uuid}`);
try {
const repository = await Repository.findOne({ uuid: uuid });
console.log(`Repository search result for UUID: ${uuid}:`, repository);
if (!repository) {
console.error(`No repository found with UUID: ${uuid}`);
return res.status(404).send('Repository not found');
}
if (repository.isProcessed) {
console.log(`Found and serving processed repository with UUID: ${uuid}`);
res.render('explain', { summary: repository.summary, uuid: uuid, githubUrl: repository.githubUrl, userId: req.session ? req.session.userId : null });
} else {
console.log(`Repository with UUID: ${uuid} is not processed yet`);
res.status(200).send('Processing is not yet complete. Please wait for an email notification.');
}
} catch (error) {
console.error(`Error retrieving repository with UUID: ${uuid}: ${error.message}`, error.stack);
res.status(500).send('Error fetching repository');
}
});
router.post('/interact/:uuid', async (req, res) => {
const uuid = req.params.uuid;
const userMessage = req.body.question;
console.log(`POST request made to /interact/${uuid} with question: ${userMessage}`);
try {
// Fetch the user from the database
const user = await User.findById(req.session.userId);
if (!user || !user.openaiApiKey) {
throw new Error('User not found or API key not set');
}
// Pass the API key to interactWithRepository
const answer = await interactWithRepository(uuid, userMessage, user.openaiApiKey);
console.log(`Answer retrieved from interactWithRepository for UUID: ${uuid}`);
res.json({ answer });
} catch (error) {
console.error('Error in POST /interact/:uuid:', error.message, error.stack);
res.status(500).json({ error: 'Error processing your question.' });
}
});
router.post('/set-api-key', isAuthenticated, async (req, res) => {
const { openaiApiKey } = req.body;
const userId = req.session.userId;
console.log('Received API key update request:', { userId, keyLength: openaiApiKey ? openaiApiKey.length : 0 });
try {
const user = await User.findById(userId);
if (openaiApiKey === '**********') {
// API key unchanged
return res.render('index', {
apiKeyMessage: 'API key unchanged.',
userApiKey: '**********',
userId: req.session.userId
});
}
// Verify the API key
const openai = new OpenAI({
apiKey: openaiApiKey,
});
await openai.models.list();
// If verification succeeds, update the user's API key
user.openaiApiKey = openaiApiKey;
await user.save();
res.render('index', {
apiKeyMessage: 'API key verified and saved successfully.',
apiKeySuccess: true,
userApiKey: '**********',
userId: req.session.userId
});
} catch (error) {
console.error('Error verifying OpenAI API key:', error.message, error.stack);
res.render('index', {
apiKeyMessage: 'Failed to verify API key. Please check and try again.',
apiKeySuccess: false,
userApiKey: null,
userId: req.session.userId
});
}
});
module.exports = router;