-
Notifications
You must be signed in to change notification settings - Fork 1
/
server.js
255 lines (228 loc) · 9.17 KB
/
server.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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
require("dotenv").config();
const mongoose = require("mongoose");
const express = require("express");
const session = require("express-session");
const MongoStore = require('connect-mongo');
const authRoutes = require("./routes/authRoutes");
const adminRoutes = require('./routes/adminRoutes');
const userManagementRoutes = require('./routes/userManagementRoutes');
const chatRoomRoutes = require('./routes/chatRoomRoutes');
const llmAgentRoutes = require('./routes/llmAgentRoutes');
const apiKeyRoutes = require('./routes/apiKeyRoutes');
const { isAuthenticated, isAdmin } = require('./routes/middleware/authMiddleware');
const { checkRole } = require('./routes/middleware/roleMiddleware');
const http = require('http');
const socketIo = require('socket.io');
const ChatRoom = require('./models/ChatRoom');
const { triggerMultipleAgentResponses } = require('./services/llmAgentService');
const ApiKey = require('./models/ApiKey');
const User = require('./models/User');
console.log('Starting server...');
if (!process.env.DATABASE_URL || !process.env.SESSION_SECRET) {
console.error("Error: config environment variables not set. Please create/edit .env configuration file.");
process.exit(-1);
}
const app = express();
const port = process.env.PORT || 3000;
const server = http.createServer(app);
const io = socketIo(server);
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.set("view engine", "ejs");
app.use(express.static("public"));
mongoose.connect(process.env.DATABASE_URL)
.then(() => {
console.log('Connected to database');
server.listen(port, () => {
console.log(`Server running on port ${port}`);
});
})
.catch((error) => {
console.error('Error connecting to database:', error);
});
app.use(
session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
store: MongoStore.create({ mongoUrl: process.env.DATABASE_URL }),
}),
);
app.on("error", (error) => {
console.error(`Server error: ${error.message}`);
console.error(error.stack);
});
app.use((req, res, next) => {
const sess = req.session;
res.locals.session = sess;
if (!sess.views) {
sess.views = 1;
console.log("Session created at: ", new Date().toISOString());
} else {
sess.views++;
console.log(
`Session accessed again at: ${new Date().toISOString()}, Views: ${sess.views}, User ID: ${sess.userId || '(unauthenticated)'}`,
);
}
next();
});
io.on('connection', (socket) => {
console.log('A user connected');
socket.on('join room', ({ roomId, username, userId }) => {
socket.join(roomId);
console.log(`User ${username} joined room ${roomId}`);
socket.username = username;
socket.userId = userId; // Store userId in the socket
});
socket.on('get next message time', async ({ roomId }) => {
try {
const chatRoom = await ChatRoom.findById(roomId);
if (chatRoom && chatRoom.nextMessageTime) {
socket.emit('next message time', chatRoom.nextMessageTime.getTime());
}
} catch (error) {
console.error('Error fetching next message time:', error);
console.error(error.stack);
}
});
socket.on('chat message', async ({ roomId, message }) => {
try {
const chatRoom = await ChatRoom.findById(roomId);
const user = await User.findById(socket.userId);
console.log(`Received chat message. Room ID: ${roomId}, User ID: ${socket.userId}, User Role: ${user.role}, Chat Room Creator: ${chatRoom.creator}`);
if (chatRoom && (user.role === 'admin' || chatRoom.creator.toString() === socket.userId)) {
console.log(`User ${socket.userId} is authorized to send messages in room ${roomId}`);
console.log(`Received message for room ${roomId}: ${message}`);
console.log(`Current socket username: ${socket.username}`);
console.log(`Chat room ${roomId} status: ${chatRoom.status}`);
console.log(`Number of agents in room: ${chatRoom.agents.length}`);
if (chatRoom.status === 'stopped') {
console.log(`Chat room ${roomId} is stopped. Ignoring message.`);
return;
}
const newMessage = { content: message, sender: socket.username || 'Anonymous', timestamp: new Date() };
chatRoom.messages.push(newMessage);
await chatRoom.save();
io.to(roomId).emit('chat message', newMessage);
console.log(`Emitted message to room ${roomId}:`, newMessage);
// Only trigger agent responses if not already generating
if (!chatRoom.isGeneratingResponse) {
console.log(`Triggering agent responses for room ${roomId}`);
triggerMultipleAgentResponses(io, roomId, newMessage, socket.userId);
} else {
console.log(`Agent responses already being generated for room ${roomId}`);
}
} else {
console.log(`User ${socket.userId} is not authorized to send messages in room ${roomId}`);
}
} catch (error) {
console.error('Error handling chat message:', error);
console.error(error.stack);
}
});
socket.on('stop conversation', async ({ roomId }) => {
try {
const chatRoom = await ChatRoom.findById(roomId);
const user = await User.findById(socket.userId);
if (chatRoom && (user.role === 'admin' || chatRoom.creator.toString() === socket.userId)) {
chatRoom.status = 'stopped';
chatRoom.isGeneratingResponse = false; // Resetting the flag
await chatRoom.save();
io.to(roomId).emit('conversation stopped');
console.log(`Emitted conversation stopped event for room ${roomId}`);
} else {
console.log(`User ${socket.userId} is not authorized to stop conversation in room ${roomId}`);
}
} catch (error) {
console.error('Error stopping conversation:', error);
console.error(error.stack);
}
});
socket.on('resume conversation', async ({ roomId }) => {
try {
const chatRoom = await ChatRoom.findById(roomId);
const user = await User.findById(socket.userId);
if (chatRoom && (user.role === 'admin' || chatRoom.creator.toString() === socket.userId) && chatRoom.status === 'stopped' && !chatRoom.isGeneratingResponse) {
chatRoom.status = 'active';
await chatRoom.save();
io.to(roomId).emit('conversation resumed');
console.log(`Chat room ${roomId} status updated to active`);
console.log(`Emitted conversation resumed event to room ${roomId}`);
console.log(`Triggering agent responses after resuming conversation for room ${roomId}`);
triggerMultipleAgentResponses(io, roomId, { content: 'Conversation resumed', sender: 'System' }, socket.userId);
} else {
console.log(`User ${socket.userId} is not authorized to resume conversation in room ${roomId}`);
}
} catch (error) {
console.error('Error resuming conversation:', error);
console.error(error.stack);
}
});
socket.on('disconnect', () => {
console.log('User disconnected');
});
});
app.use(authRoutes);
app.use(adminRoutes);
app.use('/api', userManagementRoutes);
app.use('/api/chatrooms', chatRoomRoutes);
app.use('/api/llmagents', llmAgentRoutes);
app.use('/chatroom', chatRoomRoutes);
app.use(apiKeyRoutes);
app.get('/admin', isAuthenticated, isAdmin, (req, res) => {
res.send('Admin panel');
});
app.get('/contributor', isAuthenticated, checkRole(['contributor', 'admin']), (req, res) => {
res.send('Contributor area');
});
app.get('/viewer', isAuthenticated, checkRole(['viewer', 'contributor', 'admin']), (req, res) => {
res.send('Viewer area');
});
app.get("/chatroom/:id", isAuthenticated, async (req, res) => {
try {
const chatRoom = await ChatRoom.findById(req.params.id).populate('agents');
if (!chatRoom) {
return res.status(404).render('error', { message: 'Chat room not found' });
}
let apiKeys = { openaiKey: '', anthropicKey: '' };
if (req.session.userId) {
apiKeys = await ApiKey.findOne({ userId: req.session.userId }) || apiKeys;
}
res.render('chatRoom', {
chatRoom,
messages: chatRoom.messages,
session: req.session,
username: req.session.username || 'Anonymous',
apiKeys, // Keep the apiKeys
userId: req.session.userId // Add this line
});
} catch (error) {
console.error('Error fetching chat room:', error);
console.error(error.stack);
res.status(500).render('error', { message: 'Error fetching chat room' });
}
});
app.get("/", async (req, res) => {
let apiKeys = { openaiKey: '', anthropicKey: '' };
let userData = null;
if (req.session.userId) {
apiKeys = await ApiKey.findOne({ userId: req.session.userId }) || apiKeys;
const user = await User.findById(req.session.userId);
if (user) {
userData = { id: user._id, username: user.username, role: user.role };
}
}
console.log('Rendering index with user data:', userData);
res.render("index", { user: userData, apiKeys });
});
app.use((req, res, next) => {
res.status(404).send("Page not found.");
});
app.use((err, req, res, next) => {
console.error(`Unhandled application error: ${err.message}`);
console.error(err.stack);
res.status(500).send("There was an error serving your request.");
});
server.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});