diff --git a/package-lock.json b/package-lock.json index 6979b6c..7845c4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "mariadb": "^2.5.3", "moment": "^2.29.1", "multer": "^1.4.4", + "nodemailer": "^7.0.5", "sequelize": "^6.6.2", "validator": "^13.6.0" }, @@ -1768,9 +1769,16 @@ } }, "node_modules/nodemailer": { +<<<<<<< HEAD "version": "6.7.2", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.7.2.tgz", "integrity": "sha512-Dz7zVwlef4k5R71fdmxwR8Q39fiboGbu3xgswkzGwczUfjp873rVxt1O46+Fh0j1ORnAC6L9+heI8uUpO6DT7Q==", +======= + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.5.tgz", + "integrity": "sha512-nsrh2lO3j4GkLLXoeEksAMgAOqxOv6QumNRVQTJwKH4nuiww6iC2y7GyANs9kRAxCexg3+lTWM3PZ91iLlVjfg==", + "license": "MIT-0", +>>>>>>> origin/santiago "engines": { "node": ">=6.0.0" } @@ -4120,9 +4128,15 @@ } }, "nodemailer": { +<<<<<<< HEAD "version": "6.7.2", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.7.2.tgz", "integrity": "sha512-Dz7zVwlef4k5R71fdmxwR8Q39fiboGbu3xgswkzGwczUfjp873rVxt1O46+Fh0j1ORnAC6L9+heI8uUpO6DT7Q==" +======= + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.5.tgz", + "integrity": "sha512-nsrh2lO3j4GkLLXoeEksAMgAOqxOv6QumNRVQTJwKH4nuiww6iC2y7GyANs9kRAxCexg3+lTWM3PZ91iLlVjfg==" +>>>>>>> origin/santiago }, "nodemon": { "version": "2.0.15", diff --git a/package.json b/package.json index 50c72ff..aa6099b 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "mariadb": "^2.5.3", "moment": "^2.29.1", "multer": "^1.4.4", + "nodemailer": "^7.0.5", "sequelize": "^6.6.2", "validator": "^13.6.0" }, diff --git a/server/app.js b/server/app.js index 8640a9d..3f1d904 100644 --- a/server/app.js +++ b/server/app.js @@ -13,6 +13,21 @@ app.use( }) ); +/* +const alumnoRoutes = require('./routes/alumno'); +app.use('/alumnos', alumnoRoutes); +*/ + +//agregue esto +app.use(bodyParser.json()); // esto debe ir antes de app.use('/api', rutaProfesor) +app.use(express.json()); + + +//const rutaProfesor = require('./routes/Profesor'); +//app.use('/api', rutaProfesor); +app.use('/api/profesores', require('./routes/Profesor')); + + app.use(bodyParser.json()); app.get('/', (req, res) => res.send('API de Inscripciones a CEDETEC')); diff --git a/server/config/config.js b/server/config/config.js index b7736ee..3ec5225 100644 --- a/server/config/config.js +++ b/server/config/config.js @@ -9,3 +9,5 @@ try { } catch (err) { console.log('El archivo .env no se cargo.'.underline.bold.red); } + + diff --git a/server/config/mariadb.conf.js b/server/config/mariadb.conf.js index af585d5..5b9ecda 100644 --- a/server/config/mariadb.conf.js +++ b/server/config/mariadb.conf.js @@ -27,13 +27,21 @@ const obtenerDatosUsr = async (numeroCuenta) => { }); }; +<<<<<<< HEAD const usuarioInscrito = async (numeroCuenta, idArea) => { const conn = await pool.getConnection().catch((err) => { throw new Error('No se pudo conectar con la db. ' + err); +======= +// Agregue para profesores +const buscarProfesorPorNumero = async (numeroTrabajador) => { + const conn = await pool2.getConnection().catch((err) => { + throw new Error('No se pudo conectar con la base de datos. ' + err); +>>>>>>> origin/santiago }); return conn .query( +<<<<<<< HEAD `INSERT INTO alumno_inscrito(realizo_pago, id_cuenta, id_periodo, id_plataforma) values(1, ${numeroCuenta}, 22, ${idArea})` ) .then((rows) => { @@ -130,3 +138,33 @@ module.exports = { borrarRecibo, borrarDetalleServicio, }; +======= + `SELECT nombre, idUsuario, numeroCuenta FROM usuario WHERE numeroCuenta = ?`, + [numeroTrabajador] // NUmero de cuenta + ) + .then((rows) => { + conn.end(); + if (rows.length === 0) return null; + return rows[0]; // { nombre: 'Juan', rfc: 'JUAP123' } + }) + .catch((err) => { + conn.end(); + throw new Error('Error al buscar el profesor: ' + err); + }); +}; + +// Para envios de correos +const nodemailer = require('nodemailer'); + +const enviarCorreoInscripcion = async (destinatario, nombreProfesor) => { + const transporter = nodemailer.createTransport({ + service: 'gmail', // o smtp host como 'smtp.mailtrap.io' + auth: { + user: process.env.CORREO_ORIGEN, // tu correo + pass: process.env.CORREO_PASSWORD, // tu contraseña o app password + }, + }); +}; + +module.exports = { obtenerIdCarrera, obtenerCarrera, usuarioInscrito, buscarProfesorPorNumero }; +>>>>>>> origin/santiago diff --git a/server/controller/Profesor/buscarProfesor.js b/server/controller/Profesor/buscarProfesor.js new file mode 100644 index 0000000..2a38aea --- /dev/null +++ b/server/controller/Profesor/buscarProfesor.js @@ -0,0 +1,38 @@ +const { buscarProfesorPorNumero } = require('../../config/mariadb.conf'); +const Inscripcion = require('../../db/tablas/Inscripcion'); + +async function buscarProfesor(req, res) { + const { numeroTrabajador } = req.params; + + try { + // Borrar esta linea de codigo + //console.log('Buscando profesor con RFC:', numeroTrabajador); + + const profesor = await buscarProfesorPorNumero(numeroTrabajador); + + if (!profesor) { + return res.status(404).json({ message: 'Profesor no encontrado' }); + } + + // Verificar si existe ya en la tabla de incripcion + const existeIncripcion = await Inscripcion.findOne({ + where: { + idUsuario: profesor.idUsuario + } + }); + + if (existeIncripcion) { + return res.status(409).json({ + //yaInscrito: true, + message: 'El usuario ya está inscrito.', + }); + } + + + res.status(200).json(profesor); // { nombre, correo } + } catch (error) { + res.status(500).json({ message: error.message }); + } +} + +module.exports = buscarProfesor; diff --git a/server/controller/Profesor/confirmarInscripcion.js b/server/controller/Profesor/confirmarInscripcion.js new file mode 100644 index 0000000..63c37f3 --- /dev/null +++ b/server/controller/Profesor/confirmarInscripcion.js @@ -0,0 +1,23 @@ + +/*const { inscripcion } = require('../../db/tablas/Inscripcion') + +const confirmacionInscripcion = async (req, res) => { + try { + const { idUsuario } = req.body; + + const [update] = await inscripcion.update( + { confirmacion: true}, + { where: { idUsuario } } + ); + + if (update > 0) { + return res.status(200).json({ message: 'Inscripción confirmada con éxito.'}); + } else { + return res.status(404).json({ message: 'No se encontro la inscripcion para confirmar'}); + } + } catch (error) { + console.error('Error al confirmar inscripcion: ', error); + return res.status(500).json({ message: 'Error al confirmar inscripcion.'}); + } +} +*/ \ No newline at end of file diff --git a/server/controller/Profesor/enviarCorreo.js b/server/controller/Profesor/enviarCorreo.js new file mode 100644 index 0000000..024e704 --- /dev/null +++ b/server/controller/Profesor/enviarCorreo.js @@ -0,0 +1,33 @@ +const nodemailer = require('nodemailer'); + +async function enviarCorreoInscripcion(correo, nombre) { + const transporter = nodemailer.createTransport({ + service: 'gmail', + auth: { + user: process.env.CORREO_ORIGEN, + pass: process.env.CORREO_PASSWORD + } + }); + + const mailOptions = { + from: '"CEDETEC"', + to: correo, + subject: 'Confirmación de inscripción CEDETEC', + html: ` +
    +

    Estimado profesor(a) ${nombre}

    +

    Informo que su inscripción fue realizad con éxito.

    +
+ ¿Cómo puede hacer uso de los servicios? +

Es necesario revise los siguientes + videos + para solicitar equipo en el área de profesores.

+

Nota: Es importante revisar los + lineamientos de uso para hacer uso de los servicios que ofrece el CEDETEC.

+ ` + }; + + await transporter.sendMail(mailOptions); +} + +module.exports = enviarCorreoInscripcion; diff --git a/server/controller/Profesor/inscripcionProfesor.js b/server/controller/Profesor/inscripcionProfesor.js new file mode 100644 index 0000000..e4a80e2 --- /dev/null +++ b/server/controller/Profesor/inscripcionProfesor.js @@ -0,0 +1,66 @@ +const Usuario = require('../../db/tablas/Usuario'); // Asegúrate de importar correctamente +const inscripcion = require('../../db/tablas/Inscripcion'); +const enviarCorreoInscripcion = require('../../controller/Profesor/enviarCorreo'); // Ajusta si está en otra ruta +const { where } = require('sequelize'); + +async function realizarInscripcion(req, res) { + const { idUsuario, nombre, numeroCuenta, correo } = req.body; + + try { + if (!nombre || !numeroCuenta || !idUsuario) { + return res.status(400).json({ message: 'Faltan datos requeridos.' }); + } + + // 1. Buscar si el usuario existe + const usuario = await Usuario.findOne({ where: { numeroCuenta } }); + + if (!usuario) { + return res.status(404).json({ message: 'Usuario no encontrado en la base de datos.' }); + } + + // 2. Verificar si ya tiene inscripción + const inscripcionExistente = await inscripcion.findOne({ + where: { idUsuario: usuario.idUsuario } + }); + + if (inscripcionExistente) { + return res.status(200).json({ + yaInscrito: true, + message: 'El usuario ya está inscrito.', + }); + } + + // 3. Crear inscripción + await inscripcion.create({ + idUsuario: usuario.idUsuario, + idArea: 1, // Cambiar si se requiere otro valor + validacion: 2, + confirmacion: false, + folio: null, + monto: null, + hizoPago: null, + rutaTicket: null, + extension: null, + fechaInscripcion: null, // fechaInscripcion: new Date() + fechaTicket: null + }); + + // 4. Realizar confirmacion + await inscripcion.update( + { confirmacion: true }, + { where: { idUsuario: usuario.idUsuario } } + ); + + // 5. Enviar correo + await enviarCorreoInscripcion(correo, nombre); + + // 6. Respuesta final + res.status(200).json({ message: 'Inscripción creada y correo enviado correctamente.' }); + + } catch (error) { + console.error('Error en realizarInscripcion:', error); + res.status(500).json({ message: 'Error al procesar la inscripción o enviar el correo.' }); + } +} + +module.exports = { realizarInscripcion }; diff --git a/server/db/install.js b/server/db/install.js index 21b7de9..511b8c4 100644 --- a/server/db/install.js +++ b/server/db/install.js @@ -7,6 +7,8 @@ const Area = require('./tablas/Area'); const FechaInscripcion = require('./tablas/FechaInscripcion'); const Inscripcion = require('./tablas/Inscripcion'); const Admin = require('./tablas/Admin'); +const ProfesorInscrito = require('./tablas/ProfesorInscrito'); +const Profesor = require('./tablas/Profesor'); const drop = async () => { console.log('\nPaso 1) Desinstalando la db.'.bold.blue); @@ -28,6 +30,15 @@ const drop = async () => { await Carrera.drop(); console.log('La tabla Carrera se desinstalo correctamente.'.magenta); + /* + await ProfesorInscrito.drop(); + console.log('La tabla ProfesorInscrito se desinstalo correctamente.'.magenta); + + await Profesor.drop(); + console.log('La tabla Profesor se desinstalo correctamente.'.magenta); + */ + //await ProfesorInscrito.drop().catch(console.error); // Tiene FK hacia Profesor + //await Profesor.drop().catch(console.error); }; const sync = async () => { @@ -50,6 +61,14 @@ const sync = async () => { await Inscripcion.sync(); console.log('La tabla Inscripcion se instalo correctamente.'.magenta); + + /* + await Profesor.sync(); + console.log('La tabla Profesor se instalo correctamente.'.magenta); + + await ProfesorInscrito.sync(); + console.log('La tabla ProfesorInscrito se instalo correctamente.'.magenta); + */ }; const dataArea = async () => { @@ -61,6 +80,16 @@ const dataArea = async () => { const dataAdmin = async () => { console.log('\nPaso 4) Insertando admin.'.bold.blue); + + /* + //Borrar esta linea de codigo + console.log('Admin password:', process.env.ADMIN_PASSWORD); + + //Eliminar esta linea de codigo + const pwdHasheada = encriptar.encriptar(process.env.ADMIN_PASSWORD); + console.log('Password hasheada:', pwdHasheada); + */ + await Admin.create({ idTipoUsuario: 1, usuario: 'Araceli', diff --git a/server/db/tablas/Profesor.js b/server/db/tablas/Profesor.js new file mode 100644 index 0000000..e05e2b5 --- /dev/null +++ b/server/db/tablas/Profesor.js @@ -0,0 +1,39 @@ +const { unique } = require("next/dist/build/utils"); +const { DataTypes, Model } = require("sequelize"); +const sequelize = require('../../config/sequelize.conf'); + +class Profesor extends Model{} +Profesor.init( + { + idProfesor: { + type: DataTypes.INTEGER, + primaryKey: true, + allowNull: false, + unique: true, + autoIncrement: true, + }, + nombre: { + type: DataTypes.STRING(100), + allowNull: true, + defaultValue: null, + }, + rfc: { + type: DataTypes.STRING(10), + allowNull: false, + unique: true, + }, + homo: { + type: DataTypes.STRING(3), + allowNull: false, + unique: true, + }, + }, + { + sequelize, + modelName: 'Profesor', + tableName: 'profesor', + timestamps: false, + }, +) + +module.exports = Profesor; \ No newline at end of file diff --git a/server/db/tablas/ProfesorInscrito.js b/server/db/tablas/ProfesorInscrito.js new file mode 100644 index 0000000..862131f --- /dev/null +++ b/server/db/tablas/ProfesorInscrito.js @@ -0,0 +1,42 @@ +const { Model, DataTypes } = require("sequelize"); +const Profesor = require("./Profesor"); +const sequelize = require('../../config/sequelize.conf'); + +class ProfesorInscrito extends Model {} + +ProfesorInscrito.init( + { + idProfesorInscrito: { + type: DataTypes.INTEGER, + primaryKey: true, + unique: true, + allowNull: false, + autoIncrement: true, + }, + fechaRegistro: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: DataTypes.NOW, + }, + }, + { + sequelize, + modelName: 'ProfesorInscrito', + tableName: 'profesorInscrito', + timestamps: false, + } +); + +// Relación (Sequelize crea automáticamente idProfesor con FK) +ProfesorInscrito.belongsTo(Profesor, { + foreignKey: { + name: 'idProfesor', + type: DataTypes.INTEGER, + allowNull: false, + }, +}); + + +module.exports = ProfesorInscrito; + + diff --git a/server/db/tablas/Usuario.js b/server/db/tablas/Usuario.js index fff1dcd..914cf7f 100644 --- a/server/db/tablas/Usuario.js +++ b/server/db/tablas/Usuario.js @@ -44,11 +44,19 @@ Usuario.init( ); Usuario.belongsTo(Carrera, { +<<<<<<< HEAD foreignKey: { name: 'idCarrera', type: DataTypes.INTEGER, allowNull: false, }, +======= + foreignKey: { + name: 'idCarrera', + type: DataTypes.INTEGER, + allowNull: false, + }, +>>>>>>> origin/santiago }); module.exports = Usuario; diff --git a/server/helper/encriptar.js b/server/helper/encriptar.js index 423c929..a853b33 100644 --- a/server/helper/encriptar.js +++ b/server/helper/encriptar.js @@ -6,8 +6,22 @@ const comparar = (password, dbPassword) => { return true; }; -const encriptar = (password) => - bcrypt.hashSync(password, Number(process.env.SALT_ROUNDS)); +const encriptar = (password) => { + /* + bcrypt.hashSync(password, Number(process.env.SALT_ROUNDS)); + + const rounds = Number(process.env.SALT_ROUNDS) || 10; + console.log('Rounds para hashSync:', rounds); + return bcrypt.hashSync(password, rounds); + + const rounds = Number(process.env.SALT_ROUNDS) || 10; + console.log('Rounds para hashSync:', rounds); + console.log('Password recibido en encriptar:', password); // <-- agrega esto + return bcrypt.hashSync(password, rounds); + */ + const rounds = Number(process.env.SALT_ROUNDS) || 10; + return bcrypt.hashSync(password, rounds); +} const generarPassword = () => { const length = 8; diff --git a/server/middleware/autentificacion.js b/server/middleware/autentificacion.js index 48ea5d8..9c95cbc 100644 --- a/server/middleware/autentificacion.js +++ b/server/middleware/autentificacion.js @@ -37,4 +37,17 @@ const crearTokenAdmin = (data) => { }); }; +<<<<<<< HEAD +======= +const crearTokenOperador = (data) => { + return jwt.sign({ data }, process.env.KEY, { + expiresIn: Number(process.env.CADUCIDAD_TOKEN_OPERADOR), + }); +}; + + + + + +>>>>>>> origin/santiago module.exports = { verificaToken, crearToken, crearTokenAdmin }; diff --git a/server/routes/Profesor.js b/server/routes/Profesor.js new file mode 100644 index 0000000..643247b --- /dev/null +++ b/server/routes/Profesor.js @@ -0,0 +1,76 @@ +const express = require('express'); +const router = express.Router(); +const buscarProfesor = require('../controller/Profesor/buscarProfesor'); +const { realizarInscripcion } = require('../controller/Profesor/inscripcionProfesor'); + +//const Usuario = require('../controller/Profesor/Usuario'); + + +router.get('/:numeroTrabajador', buscarProfesor); + +// POST: inscribir profesor y enviar correo +router.post('/inscripcion', realizarInscripcion); + + +/* +// Ruta POST para inscribir profesor y enviar correo +router.post('/inscripcion', async (req, res) => { + // Buscar al usuario por correo o nombre, dependiendo de qué campo sea único o útil + const usuario = await Usuario.findOne({ + where: { correo } // o por nombre si es único, pero mejor por correo + }); + + if (!usuario) { + return res.status(404).json({ message: 'Usuario no encontrado en la base de datos.' }); + } + + // Verificar si ya tiene una inscripción + const inscripcionExistente = await Inscripcion.findOne({ + where: { idUsuario: usuario.idUsuario } + }); + + if (inscripcionExistente) { + return res.status(200).json({ message: 'El usuario ya está inscrito.' }); + } + + // Crear inscripción con campos opcionales como null + await Inscripcion.create({ + idUsuario: usuario.idUsuario, + idArea: 1, // puedes cambiar esto si lo tienes dinámico + validacion: 2, + confirmacion: false, + folio: null, + monto: null, + hizoPago: null, + rutaTicket: null, + extension: null, + fechaInscripcion: null, + fechaTicket: null, + }); + + try { + const { correo, nombre } = req.body; + + //Borrar esta linea de codigo + //console.log('Datos recibidos:', correo, nombre); // ← Agrega esto + //console.log('Datos recibidos:', req.body); // Agrega esto + + if (!correo || !nombre) { + return res.status(400).json({ message: 'Faltan datos requeridos.' }); + } + + //aqui tengo que aplicar la logica para crear al prodesor inscrito + + + await enviarCorreoInscripcion(correo, nombre); + res.status(200).json({ message: 'Correo enviado correctamente.' }); + } catch (error) { + console.error(error); + res.status(500).json({ message: 'Error al enviar el correo.' }); + } + +}); +*/ + + +module.exports = router;