import express from 'express'; import cors from 'cors'; import { getValue, setValue, getUsuarioByDni, getUsuarioById, getAllUsuarios, createUsuario, updateUsuario, deleteUsuario, verifyPassword, hashPassword } from './db.js'; const app = express(); app.use(cors()); app.use(express.json({ limit: '5mb' })); const PORT = process.env.PORT || 4001; const STORAGE_KEY = 'hospital-data-v1'; app.get('/api/state', async (req, res) => { try { const v = await getValue(STORAGE_KEY); if (!v) return res.json(null); res.json(JSON.parse(v)); } catch (err) { console.error(err); res.status(500).json({ error: 'failed to read state' }); } }); app.put('/api/state', async (req, res) => { try { const body = req.body; await setValue(STORAGE_KEY, JSON.stringify(body)); res.json({ ok: true }); } catch (err) { console.error(err); res.status(500).json({ error: 'failed to save state' }); } }); app.listen(PORT, () => { console.log(`API server listening on http://localhost:${PORT}`); }); // Crear usuario admin inicial si no existe async function initAdminUser() { try { const adminExists = await getUsuarioByDni('12345678'); if (!adminExists) { const passwordHash = await hashPassword('admin123'); const adminUser = { id: generateUUID(), apellido: 'Admin', nombre: 'Sistema', dni: '12345678', fechaNacimiento: '1970-01-01', email: 'admin@hospital.gob.ar', rol: 'admin', matriculaProfesional: null, passwordHash, areaId: null, fechaCreacion: new Date().toISOString().split('T')[0] }; await createUsuario(adminUser); console.log('Usuario admin creado: DNI 12345678, Password admin123'); } } catch (err) { console.error('Error creating admin user:', err); } } initAdminUser(); // === AUTENTICACIÓN === function generateUUID() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { const r = (Math.random() * 16) | 0; const v = c === 'x' ? r : (r & 0x3) | 0x8; return v.toString(16); }); } app.post('/api/auth/login', async (req, res) => { try { const { dni, password } = req.body; if (!dni || !password) { return res.status(400).json({ error: 'DNI y contraseña requeridos' }); } const usuario = await getUsuarioByDni(dni); if (!usuario) { return res.status(401).json({ error: 'Usuario no encontrado' }); } const validPassword = await verifyPassword(dni, password); if (!validPassword) { return res.status(401).json({ error: 'Contraseña incorrecta' }); } const { passwordHash, ...userWithoutPassword } = usuario; res.json(userWithoutPassword); } catch (err) { console.error(err); res.status(500).json({ error: 'Error en autenticación' }); } }); app.post('/api/auth/change-password', async (req, res) => { try { const { dni, oldPassword, newPassword } = req.body; if (!dni || !oldPassword || !newPassword) { return res.status(400).json({ error: 'Todos los campos son requeridos' }); } const validPassword = await verifyPassword(dni, oldPassword); if (!validPassword) { return res.status(401).json({ error: 'Contraseña actual incorrecta' }); } const newHash = await hashPassword(newPassword); await updateUsuarioByDni(dni, { passwordHash: newHash }); res.json({ ok: true }); } catch (err) { console.error(err); res.status(500).json({ error: 'Error al cambiar contraseña' }); } }); app.put('/api/auth/update-email', async (req, res) => { try { const { dni, newEmail } = req.body; if (!dni || !newEmail) { return res.status(400).json({ error: 'DNI y email son requeridos' }); } await updateUsuarioByDni(dni, { email: newEmail }); res.json({ ok: true }); } catch (err) { console.error(err); res.status(500).json({ error: 'Error al actualizar email' }); } }); // === GESTIÓN DE USUARIOS (ADMIN) === app.get('/api/usuarios', async (req, res) => { try { const usuarios = await getAllUsuarios(); const usuariosSinPassword = usuarios.map(({ passwordHash, ...u }) => u); res.json(usuariosSinPassword); } catch (err) { console.error(err); res.status(500).json({ error: 'Error al obtener usuarios' }); } }); app.post('/api/usuarios', async (req, res) => { try { const { apellido, nombre, dni, fechaNacimiento, email, rol, matriculaProfesional, password, areaId } = req.body; if (!apellido || !nombre || !dni || !fechaNacimiento || !email || !rol || !password) { return res.status(400).json({ error: 'Todos los campos obligatorios deben estar presentes' }); } const existente = await getUsuarioByDni(dni); if (existente) { return res.status(400).json({ error: 'Ya existe un usuario con ese DNI' }); } const passwordHash = await hashPassword(password); const usuario = { id: generateUUID(), apellido, nombre, dni, fechaNacimiento, email, rol, matriculaProfesional: matriculaProfesional || null, passwordHash, areaId: areaId || null, fechaCreacion: new Date().toISOString().split('T')[0] }; await createUsuario(usuario); res.json({ ...usuario, passwordHash: undefined }); } catch (err) { console.error(err); res.status(500).json({ error: 'Error al crear usuario' }); } }); app.put('/api/usuarios/:id', async (req, res) => { try { const { id } = req.params; const { apellido, nombre, fechaNacimiento, email, rol, matriculaProfesional, areaId, password } = req.body; const usuario = await getUsuarioById(id); if (!usuario) { return res.status(404).json({ error: 'Usuario no encontrado' }); } const datos = {}; if (apellido !== undefined) datos.apellido = apellido; if (nombre !== undefined) datos.nombre = nombre; if (fechaNacimiento !== undefined) datos.fechaNacimiento = fechaNacimiento; if (email !== undefined) datos.email = email; if (rol !== undefined) datos.rol = rol; if (matriculaProfesional !== undefined) datos.matriculaProfesional = matriculaProfesional; if (areaId !== undefined) datos.areaId = areaId; if (password) { datos.passwordHash = await hashPassword(password); } await updateUsuario(id, datos); res.json({ ok: true }); } catch (err) { console.error(err); res.status(500).json({ error: 'Error al actualizar usuario' }); } }); app.delete('/api/usuarios/:id', async (req, res) => { try { const { id } = req.params; await deleteUsuario(id); res.json({ ok: true }); } catch (err) { console.error(err); res.status(500).json({ error: 'Error al eliminar usuario' }); } }); // Helper para actualizar por DNI async function updateUsuarioByDni(dni, datos) { const { getUsuarioByDni, updateUsuario } = await import('./db.js'); const usuario = await getUsuarioByDni(dni); if (usuario) { await updateUsuario(usuario.id, datos); } }