Spaces:
Sleeping
Sleeping
Sasha commited on
Commit ·
963afd2
1
Parent(s): 981287f
security: sync CORS and error handling security updates in main repo
Browse files- server/server.js +25 -14
server/server.js
CHANGED
|
@@ -55,7 +55,7 @@ if (process.env.ALLOWED_ORIGINS) {
|
|
| 55 |
|
| 56 |
app.use(cors({
|
| 57 |
origin: function (origin, callback) {
|
| 58 |
-
if (!origin || allowedOrigins.indexOf(origin) !== -1
|
| 59 |
callback(null, true);
|
| 60 |
} else {
|
| 61 |
callback(new Error('Not allowed by CORS'));
|
|
@@ -207,7 +207,8 @@ app.post('/api/log/voice', authenticateWorker, async (req, res) => {
|
|
| 207 |
await logVoiceWords(words, timestamp);
|
| 208 |
res.json({ success: true, count: words.length });
|
| 209 |
} catch (err) {
|
| 210 |
-
|
|
|
|
| 211 |
}
|
| 212 |
});
|
| 213 |
|
|
@@ -218,7 +219,8 @@ app.post('/api/log/mod-action', authenticateWorker, async (req, res) => {
|
|
| 218 |
await logModAction(action);
|
| 219 |
res.json({ success: true });
|
| 220 |
} catch (err) {
|
| 221 |
-
|
|
|
|
| 222 |
}
|
| 223 |
});
|
| 224 |
|
|
@@ -228,7 +230,8 @@ app.post('/api/log/stream-end', authenticateWorker, async (req, res) => {
|
|
| 228 |
await endActiveStream();
|
| 229 |
res.json({ success: true });
|
| 230 |
} catch (err) {
|
| 231 |
-
|
|
|
|
| 232 |
}
|
| 233 |
});
|
| 234 |
|
|
@@ -238,7 +241,8 @@ app.get('/api/streams/pending-backfill', authenticateWorker, async (req, res) =>
|
|
| 238 |
const streams = await getPendingBackfillStreams();
|
| 239 |
res.json({ success: true, streams });
|
| 240 |
} catch (err) {
|
| 241 |
-
|
|
|
|
| 242 |
}
|
| 243 |
});
|
| 244 |
|
|
@@ -249,7 +253,8 @@ app.post('/api/streams/mark-backfilled', authenticateWorker, async (req, res) =>
|
|
| 249 |
await markStreamBackfilled(streamId, twitchStreamId);
|
| 250 |
res.json({ success: true });
|
| 251 |
} catch (err) {
|
| 252 |
-
|
|
|
|
| 253 |
}
|
| 254 |
});
|
| 255 |
|
|
@@ -264,7 +269,8 @@ app.post('/api/streams/reset-backfill', requireModeratorRole, async (req, res) =
|
|
| 264 |
cache.flush();
|
| 265 |
res.json({ success: true });
|
| 266 |
} catch (err) {
|
| 267 |
-
|
|
|
|
| 268 |
}
|
| 269 |
});
|
| 270 |
|
|
@@ -279,7 +285,8 @@ app.delete('/api/streams/:id', requireAdminRole, async (req, res) => {
|
|
| 279 |
cache.flush();
|
| 280 |
res.json({ success: true });
|
| 281 |
} catch (err) {
|
| 282 |
-
|
|
|
|
| 283 |
}
|
| 284 |
});
|
| 285 |
|
|
@@ -298,7 +305,8 @@ app.put('/api/streams/:id', requireAdminRole, async (req, res) => {
|
|
| 298 |
cache.flush();
|
| 299 |
res.json({ success: true });
|
| 300 |
} catch (err) {
|
| 301 |
-
|
|
|
|
| 302 |
}
|
| 303 |
});
|
| 304 |
|
|
@@ -309,7 +317,8 @@ app.post('/api/admin/cleanup', requireAdminRole, async (req, res) => {
|
|
| 309 |
cache.flush();
|
| 310 |
res.json({ success: true, count: deletedCount });
|
| 311 |
} catch (err) {
|
| 312 |
-
|
|
|
|
| 313 |
}
|
| 314 |
});
|
| 315 |
|
|
@@ -320,7 +329,8 @@ app.get('/api/admin/stats', requireAdminRole, async (req, res) => {
|
|
| 320 |
const cacheStats = cache.getStats();
|
| 321 |
res.json({ success: true, stats, cacheStats });
|
| 322 |
} catch (err) {
|
| 323 |
-
|
|
|
|
| 324 |
}
|
| 325 |
});
|
| 326 |
|
|
@@ -769,8 +779,8 @@ app.post('/api/streams/sync-vods', async (req, res) => {
|
|
| 769 |
|
| 770 |
res.json({ success: true, count: syncedStreams.length, streams: syncedStreams });
|
| 771 |
} catch (err) {
|
| 772 |
-
console.error('[Twitch API] Error syncing VODs:', err
|
| 773 |
-
res.status(500).json({ error:
|
| 774 |
}
|
| 775 |
});
|
| 776 |
|
|
@@ -786,7 +796,8 @@ app.post('/api/streams/sync-vod-direct', authenticateWorker, async (req, res) =>
|
|
| 786 |
}
|
| 787 |
res.status(500).json({ error: 'Failed to sync stream session' });
|
| 788 |
} catch (err) {
|
| 789 |
-
|
|
|
|
| 790 |
}
|
| 791 |
});
|
| 792 |
|
|
|
|
| 55 |
|
| 56 |
app.use(cors({
|
| 57 |
origin: function (origin, callback) {
|
| 58 |
+
if (!origin || allowedOrigins.indexOf(origin) !== -1) {
|
| 59 |
callback(null, true);
|
| 60 |
} else {
|
| 61 |
callback(new Error('Not allowed by CORS'));
|
|
|
|
| 207 |
await logVoiceWords(words, timestamp);
|
| 208 |
res.json({ success: true, count: words.length });
|
| 209 |
} catch (err) {
|
| 210 |
+
console.error('[API Error] /api/log/voice:', err);
|
| 211 |
+
res.status(500).json({ error: 'Internal Server Error' });
|
| 212 |
}
|
| 213 |
});
|
| 214 |
|
|
|
|
| 219 |
await logModAction(action);
|
| 220 |
res.json({ success: true });
|
| 221 |
} catch (err) {
|
| 222 |
+
console.error('[API Error] /api/log/mod-action:', err);
|
| 223 |
+
res.status(500).json({ error: 'Internal Server Error' });
|
| 224 |
}
|
| 225 |
});
|
| 226 |
|
|
|
|
| 230 |
await endActiveStream();
|
| 231 |
res.json({ success: true });
|
| 232 |
} catch (err) {
|
| 233 |
+
console.error('[API Error] /api/log/stream-end:', err);
|
| 234 |
+
res.status(500).json({ error: 'Internal Server Error' });
|
| 235 |
}
|
| 236 |
});
|
| 237 |
|
|
|
|
| 241 |
const streams = await getPendingBackfillStreams();
|
| 242 |
res.json({ success: true, streams });
|
| 243 |
} catch (err) {
|
| 244 |
+
console.error('[API Error] /api/streams/pending-backfill:', err);
|
| 245 |
+
res.status(500).json({ error: 'Internal Server Error' });
|
| 246 |
}
|
| 247 |
});
|
| 248 |
|
|
|
|
| 253 |
await markStreamBackfilled(streamId, twitchStreamId);
|
| 254 |
res.json({ success: true });
|
| 255 |
} catch (err) {
|
| 256 |
+
console.error('[API Error] /api/streams/mark-backfilled:', err);
|
| 257 |
+
res.status(500).json({ error: 'Internal Server Error' });
|
| 258 |
}
|
| 259 |
});
|
| 260 |
|
|
|
|
| 269 |
cache.flush();
|
| 270 |
res.json({ success: true });
|
| 271 |
} catch (err) {
|
| 272 |
+
console.error('[API Error] /api/streams/reset-backfill:', err);
|
| 273 |
+
res.status(500).json({ error: 'Internal Server Error' });
|
| 274 |
}
|
| 275 |
});
|
| 276 |
|
|
|
|
| 285 |
cache.flush();
|
| 286 |
res.json({ success: true });
|
| 287 |
} catch (err) {
|
| 288 |
+
console.error('[API Error] /api/streams/:id (DELETE):', err);
|
| 289 |
+
res.status(500).json({ error: 'Internal Server Error' });
|
| 290 |
}
|
| 291 |
});
|
| 292 |
|
|
|
|
| 305 |
cache.flush();
|
| 306 |
res.json({ success: true });
|
| 307 |
} catch (err) {
|
| 308 |
+
console.error('[API Error] /api/streams/:id (PUT):', err);
|
| 309 |
+
res.status(500).json({ error: 'Internal Server Error' });
|
| 310 |
}
|
| 311 |
});
|
| 312 |
|
|
|
|
| 317 |
cache.flush();
|
| 318 |
res.json({ success: true, count: deletedCount });
|
| 319 |
} catch (err) {
|
| 320 |
+
console.error('[API Error] /api/admin/cleanup:', err);
|
| 321 |
+
res.status(500).json({ error: 'Internal Server Error' });
|
| 322 |
}
|
| 323 |
});
|
| 324 |
|
|
|
|
| 329 |
const cacheStats = cache.getStats();
|
| 330 |
res.json({ success: true, stats, cacheStats });
|
| 331 |
} catch (err) {
|
| 332 |
+
console.error('[API Error] /api/admin/stats:', err);
|
| 333 |
+
res.status(500).json({ error: 'Internal Server Error' });
|
| 334 |
}
|
| 335 |
});
|
| 336 |
|
|
|
|
| 779 |
|
| 780 |
res.json({ success: true, count: syncedStreams.length, streams: syncedStreams });
|
| 781 |
} catch (err) {
|
| 782 |
+
console.error('[Twitch API] Error syncing VODs:', err);
|
| 783 |
+
res.status(500).json({ error: 'Internal Server Error' });
|
| 784 |
}
|
| 785 |
});
|
| 786 |
|
|
|
|
| 796 |
}
|
| 797 |
res.status(500).json({ error: 'Failed to sync stream session' });
|
| 798 |
} catch (err) {
|
| 799 |
+
console.error('[API Error] /api/streams/sync-vod-direct:', err);
|
| 800 |
+
res.status(500).json({ error: 'Internal Server Error' });
|
| 801 |
}
|
| 802 |
});
|
| 803 |
|