From 242bfac96bd5278cd0d799dc50c80292cdb6f845 Mon Sep 17 00:00:00 2001 From: Dicken Date: Tue, 26 May 2026 14:29:55 +0200 Subject: [PATCH] Dateien nach "backend/src/routes" hochladen --- backend/src/routes/calendar.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 backend/src/routes/calendar.js diff --git a/backend/src/routes/calendar.js b/backend/src/routes/calendar.js new file mode 100644 index 0000000..7084600 --- /dev/null +++ b/backend/src/routes/calendar.js @@ -0,0 +1,29 @@ +const express = require('express'); +const https = require('https'); +const http = require('http'); +const { authenticate } = require('../middleware/auth'); +const router = express.Router(); + +// Fetch iCal feed server-side (avoids CORS) +router.get('/fetch', authenticate, (req, res) => { + const { url } = req.query; + if (!url) return res.status(400).json({ error: 'URL fehlt' }); + let parsed; + try { parsed = new URL(url); } + catch { return res.status(400).json({ error: 'Ungültige URL' }); } + if (!['http:','https:'].includes(parsed.protocol)) + return res.status(400).json({ error: 'Nur HTTP/HTTPS erlaubt' }); + + const lib = parsed.protocol === 'https:' ? https : http; + const req2 = lib.get(url, { headers:{ 'User-Agent':'DickenDock/1.0' } }, r2 => { + if (r2.statusCode !== 200) + return res.status(502).json({ error: `Feed antwortet mit ${r2.statusCode}` }); + let data = ''; + r2.on('data', d => { data += d; if (data.length > 2*1024*1024) { r2.destroy(); res.status(413).json({ error: 'Feed zu groß (max 2MB)' }); } }); + r2.on('end', () => res.type('text/calendar').send(data)); + }); + req2.on('error', e => res.status(502).json({ error: e.message })); + req2.setTimeout(8000, () => { req2.destroy(); res.status(504).json({ error: 'Timeout' }); }); +}); + +module.exports = router;