todo-helden/routes/childAuth.js
Michi 0ebe7fa13d
Some checks failed
🚀 Continuous Integration / 🔧 Backend Tests (18.x) (push) Has been cancelled
🚀 Continuous Integration / 🔧 Backend Tests (20.x) (push) Has been cancelled
🚀 Continuous Integration / 🎨 Frontend Tests (18.x) (push) Has been cancelled
🚀 Continuous Integration / 🎨 Frontend Tests (20.x) (push) Has been cancelled
🚀 Continuous Integration / 🔍 Code Quality (push) Has been cancelled
🚀 Continuous Integration / 🔒 Security Checks (push) Has been cancelled
🚀 Continuous Integration / 🎨 Theme Tests (push) Has been cancelled
🚀 Continuous Integration / ♿ Accessibility Tests (push) Has been cancelled
🚀 Continuous Integration / 📱 Cross-Browser Tests (push) Has been cancelled
🚀 Continuous Integration / 🏗️ Build Tests (push) Has been cancelled
🚀 Continuous Integration / 📊 Performance Tests (push) Has been cancelled
🚀 Continuous Integration / 🎯 Integration Tests (push) Has been cancelled
🚀 Continuous Integration / ✅ All Tests Passed (push) Has been cancelled
Initial commit: ToDo Kids v1.0.0
2025-08-04 15:46:08 +02:00

137 lines
3.4 KiB
JavaScript

const express = require('express');
const { body, validationResult } = require('express-validator');
const jwt = require('jsonwebtoken');
const Child = require('../models/Child');
const router = express.Router();
// @route POST /api/child-auth/login
// @desc Kind-Anmeldung mit Benutzername und PIN
// @access Public
router.post('/login', [
body('username')
.trim()
.isLength({ min: 3, max: 20 })
.withMessage('Benutzername muss zwischen 3 und 20 Zeichen lang sein')
.matches(/^[a-zA-Z0-9_]+$/)
.withMessage('Benutzername darf nur Buchstaben, Zahlen und Unterstriche enthalten'),
body('pin')
.isLength({ min: 4, max: 6 })
.withMessage('PIN muss zwischen 4 und 6 Zeichen lang sein')
.matches(/^[0-9]+$/)
.withMessage('PIN darf nur Zahlen enthalten')
], async (req, res) => {
try {
// Validierungsfehler prüfen
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
success: false,
message: 'Ungültige Eingaben',
errors: errors.array()
});
}
const { username, pin } = req.body;
// Kind finden
const child = await Child.findOne({
username: username.toLowerCase(),
isActive: true
}).populate('parent', 'familyName');
if (!child) {
return res.status(401).json({
success: false,
message: 'Benutzername oder PIN ist falsch'
});
}
// PIN verifizieren
const isValidPin = await child.verifyPin(pin);
if (!isValidPin) {
return res.status(401).json({
success: false,
message: 'Benutzername oder PIN ist falsch'
});
}
// JWT Token erstellen (für Kinder)
const payload = {
child: {
id: child._id,
username: child.username,
name: child.name,
parent: child.parent._id
}
};
const token = jwt.sign(
payload,
process.env.JWT_SECRET,
{ expiresIn: '7d' } // Längere Gültigkeit für Kinder
);
// Letzte Aktivität aktualisieren
child.lastActivity = new Date();
await child.save();
res.json({
success: true,
message: `Willkommen zurück, ${child.name}!`,
token,
child: child.toSafeObject()
});
} catch (error) {
console.error('Kind-Anmeldung-Fehler:', error.message);
res.status(500).json({
success: false,
message: 'Server-Fehler bei der Anmeldung'
});
}
});
// @route POST /api/child-auth/verify-token
// @desc Kind-Token verifizieren
// @access Public
router.post('/verify-token', async (req, res) => {
try {
const token = req.header('x-auth-token') || req.body.token;
if (!token) {
return res.status(401).json({
success: false,
message: 'Kein Token vorhanden'
});
}
// Token verifizieren
const decoded = jwt.verify(token, process.env.JWT_SECRET);
// Kind laden
const child = await Child.findById(decoded.child.id)
.populate('parent', 'familyName');
if (!child || !child.isActive) {
return res.status(401).json({
success: false,
message: 'Ungültiger Token'
});
}
res.json({
success: true,
child: child.toSafeObject()
});
} catch (error) {
console.error('Token-Verifikation-Fehler:', error.message);
res.status(401).json({
success: false,
message: 'Ungültiger Token'
});
}
});
module.exports = router;