import { MongoAPIError, ObjectId } from 'mongodb'; import bcrypt from 'bcrypt'; import { getCollections, update_pflux } from '../db/mongo.js'; export function registerApiRoutes(app, requireLogin) { const { usersCollection, propCollection } = getCollections(); app.get('/api/check-email', async (req, res) => { const email = (req.query.email || '').toLowerCase().trim(); if (!email) return res.json({ exists: false }); try { const existingUser = await usersCollection.findOne({ email:`${email}` }); res.json({ exists: !!existingUser }); } catch (err) { console.error(err); res.status(500).json({ error: 'Fehler bei der E-Mail-Prüfung' }); } }); app.post('/api/save', requireLogin, async (req, res) => { let { espId, sensorNumber, name, description} = req.body; if (!espId || !sensorNumber) { return res.json({ error: 'ESP-ID und Sensornummer sind Pflichtfelder' }); } sensorNumber = parseInt(sensorNumber, 10); try { const doc = { id: espId, name: name || '', description: description || '', lastUpdatedAt: new Date() }; await update_pflux(sensorNumber, doc) res.json({ success: true }); } catch (err) { console.error(err); res.status(500).json({ error: 'Fehler beim Speichern' }); } }); app.get('/api/list', requireLogin, async (req, res) => { const { id } = req.query; if (id) { try { const item = await propCollection.findOne({ _id: parseInt(id) }); if (item) return res.json([item]); return res.json([]); } catch (err) { console.error(err); return res.status(500).json({ error: 'Fehler beim Laden' }); } } let gesamtZahl = 0 try { gesamtZahl = await propCollection.countDocuments({chip: {$exists: true}}) } catch (err) { console.error(err); } const page = parseInt(req.query.page) || 1; const limit = parseInt(req.query.limit) || 50; const skip = (page - 1) * limit; try { const items = await propCollection.find({chip: {$exists: true}}) .sort({ "chip.lastUpdatedAt": -1 }) .skip(skip) .limit(limit) .toArray(); const data = {items: items, anzahl: gesamtZahl} res.json(data); } catch (err) { console.error(err); res.status(500).json({ error: 'Fehler beim Laden' }); } }); app.delete('/api/delete/:id', requireLogin, async (req, res) => { await propCollection.deleteOne({ _id: parseInt(req.params.id) }); res.json({ success: true }); }); app.post('/api/createUser', requireLogin, async (req, res) => { if (!req.session.isAdmin) return res.status(403).json({ error: 'Nur Admins erlaubt' }); const { username, password, role } = req.body; if (!username || !password) return res.status(400).json({ error: 'Benutzername und Passwort erforderlich' }); try { const hash = await bcrypt.hash(password, 10); await usersCollection.insertOne({ email: username.toLowerCase(), passwordHash: hash, role: role || 'user' }); res.json({ success: true }); } catch (err) { res.status(500).json({ error: 'Fehler beim Anlegen' }); } }); app.post('/api/changePassword', requireLogin, async (req, res) => { const { currentPassword, newPassword } = req.body; if (!currentPassword || !newPassword) { return res.status(400).json({ error: 'Aktuelles und neues Passwort erforderlich' }); } try { const user = await usersCollection.findOne({ _id: new ObjectId(req.session.userId) }); if (!user) return res.status(404).json({ error: 'User nicht gefunden' }); const match = await bcrypt.compare(currentPassword, user.passwordHash); if (!match) return res.status(403).json({ error: 'Aktuelles Passwort ist falsch' }); const hash = await bcrypt.hash(newPassword, 10); await usersCollection.updateOne({ _id: user._id }, { $set: { passwordHash: hash } }); res.json({ success: true }); } catch (err) { res.status(500).json({ error: 'Fehler beim Ändern des Passworts' }); } }); app.post('/api/resetPassword', requireLogin, async (req, res) => { if (!req.session.isAdmin) return res.status(403).json({ error: 'Nur Admins erlaubt' }); const { email, newPassword } = req.body; if (!email || !newPassword) return res.status(400).json({ error: 'Email und neues Passwort erforderlich' }); try { const hash = await bcrypt.hash(newPassword, 10); const result = await usersCollection.updateOne( { email: email.toLowerCase() }, { $set: { passwordHash: hash } } ); if (result.matchedCount === 0) return res.status(404).json({ error: 'User nicht gefunden' }); res.json({ success: true }); } catch (err) { res.status(500).json({ error: 'Fehler beim Zurücksetzen' }); } }); app.get('/api/users', requireLogin, async (req, res) => { if (!req.session.isAdmin) return res.status(403).json({ error: 'Nur Admins erlaubt' }); try { const users = await usersCollection.find({}, { projection: { email: 1, role: 1 } }).sort({ email: 1 }).toArray(); res.json(users); } catch (err) { res.status(500).json({ error: 'Fehler beim Laden der User' }); } }); app.delete('/api/users/:id', requireLogin, async (req, res) => { if (!req.session.isAdmin) return res.status(403).json({ error: 'Nur Admins erlaubt' }); const { id } = req.params; if (id === String(req.session.userId)) { return res.status(400).json({ error: 'Der eigene Account kann nicht gelöscht werden' }); } try { const result = await usersCollection.deleteOne({ _id: new ObjectId(id) }); if (result.deletedCount === 0) return res.status(404).json({ error: 'User nicht gefunden' }); res.json({ success: true }); } catch (err) { res.status(500).json({ error: 'Fehler beim Löschen' }); } }); }