From 867f055de9b52fa54e67d7fcf60dba94905043b6 Mon Sep 17 00:00:00 2001 From: TioSam77 Date: Mon, 8 Jul 2024 17:41:08 -0600 Subject: [PATCH 1/5] Pruba 4 --- package-lock.json | 34 ++++++++++++++++++++++++++++++++++ package.json | 1 + 2 files changed, 35 insertions(+) diff --git a/package-lock.json b/package-lock.json index 7abc231..705eb39 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@nestjs/mapped-types": "*", "@nestjs/passport": "^10.0.3", "@nestjs/platform-express": "^10.3.9", + "@nestjs/serve-static": "^4.0.2", "@nestjs/typeorm": "^10.0.2", "bcrypt": "^5.1.1", "bcryptjs": "^2.4.3", @@ -2490,6 +2491,39 @@ "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", "dev": true }, + "node_modules/@nestjs/serve-static": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@nestjs/serve-static/-/serve-static-4.0.2.tgz", + "integrity": "sha512-cT0vdWN5ar7jDI2NKbhf4LcwJzU4vS5sVpMkVrHuyLcltbrz6JdGi1TfIMMatP2pNiq5Ie/uUdPSFDVaZX/URQ==", + "license": "MIT", + "dependencies": { + "path-to-regexp": "0.2.5" + }, + "peerDependencies": { + "@fastify/static": "^6.5.0 || ^7.0.0", + "@nestjs/common": "^9.0.0 || ^10.0.0", + "@nestjs/core": "^9.0.0 || ^10.0.0", + "express": "^4.18.1", + "fastify": "^4.7.0" + }, + "peerDependenciesMeta": { + "@fastify/static": { + "optional": true + }, + "express": { + "optional": true + }, + "fastify": { + "optional": true + } + } + }, + "node_modules/@nestjs/serve-static/node_modules/path-to-regexp": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.2.5.tgz", + "integrity": "sha512-l6qtdDPIkmAmzEO6egquYDfqQGPMRNGjYtrU13HAXb3YSRrt7HSb1sJY0pKp6o2bAa86tSB6iwaW2JbthPKr7Q==", + "license": "MIT" + }, "node_modules/@nestjs/testing": { "version": "10.3.9", "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.3.9.tgz", diff --git a/package.json b/package.json index 64cb046..eb9f73d 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "@nestjs/mapped-types": "*", "@nestjs/passport": "^10.0.3", "@nestjs/platform-express": "^10.3.9", + "@nestjs/serve-static": "^4.0.2", "@nestjs/typeorm": "^10.0.2", "bcrypt": "^5.1.1", "bcryptjs": "^2.4.3", From 9fcb69acd53da7cb5732d37738f5c3a348ed1a9b Mon Sep 17 00:00:00 2001 From: TioSam77 Date: Mon, 8 Jul 2024 19:25:43 -0600 Subject: [PATCH 2/5] Pruba 5 --- imagenes/1sam.png | Bin 0 -> 7895 bytes imagenes/3manu.png | Bin 0 -> 7895 bytes imagenes/ábrego_santos_raquel.png | Bin 0 -> 7895 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 imagenes/1sam.png create mode 100644 imagenes/3manu.png create mode 100644 imagenes/ábrego_santos_raquel.png diff --git a/imagenes/1sam.png b/imagenes/1sam.png new file mode 100644 index 0000000000000000000000000000000000000000..a2d7f6ddabe59b943160cdeca4c99413ad0793de GIT binary patch literal 7895 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 Date: Mon, 29 Jul 2024 19:18:06 -0600 Subject: [PATCH 3/5] log into professors --- src/Profesor/profesor.controller.ts | 71 +++++++++++----- src/Profesor/profesor.service.ts | 125 +++++++++++++++------------- 2 files changed, 117 insertions(+), 79 deletions(-) diff --git a/src/Profesor/profesor.controller.ts b/src/Profesor/profesor.controller.ts index 2e2e763..5943759 100644 --- a/src/Profesor/profesor.controller.ts +++ b/src/Profesor/profesor.controller.ts @@ -1,48 +1,75 @@ -import { Body, Controller, Delete, Get, Param, ParseIntPipe, Post, Put, Query,UseGuards } from '@nestjs/common'; -import { ProfesorService } from './profesor.service'; -import { profesorDto } from './dto/profesorDto.dto'; -import {Roles} from '../permissions/roles.decorator' -import {RolesGuard} from '../permissions/roles.guard' -import {Role} from '../permissions/role.enum' +import { + Body, + Controller, + Delete, + Get, + Logger, + Param, + ParseIntPipe, + Post, + Put, + Query, + UseGuards +} from "@nestjs/common"; +import { ProfesorService } from "./profesor.service"; +import { profesorDto } from "./dto/profesorDto.dto"; +import { Roles } from "../permissions/roles.decorator"; +import { RolesGuard } from "../permissions/roles.guard"; +import { Role } from "../permissions/role.enum"; -@Controller('profesor') +@Controller("profesor") @UseGuards(RolesGuard) export class ProfesorController { - constructor(private profesorService: ProfesorService) {} + constructor(private profesorService: ProfesorService) { + } @Post() - @Roles(Role.Responsable,Role.Admin) + @Roles(Role.Responsable, Role.Admin) async register(@Body() data: profesorDto) { + Logger.debug("register profesor"); return this.profesorService.register(data); } @Get() findAll() { + Logger.debug("findAllProfesors"); return this.profesorService.findAll(); } - @Get('page') - findAllPaginated(@Query('page') page: number = 1, @Query('limit') limit: number = 10, @Query() filters: any) { - page = page < 1 ? 1 : page; - limit = limit > 10 || limit < 1 ? 10 : limit; + @Get("page") + findAllPaginated(@Query("page") page: number = 1, @Query("limit") limit: number = 10, @Query() filters: any) { + try { + Logger.debug("Page Profesors"); + page = page < 1 ? 1 : page; + limit = limit > 10 || limit < 1 ? 10 : limit; + return this.profesorService.findAllPaginated(page, limit, filters); + } catch (err) { + Logger.error("profesor controller ", err.error); + return []; + } - return this.profesorService.findAllPaginated(page, limit, filters); } - @Put(':id_profesor') - @Roles(Role.Responsable,Role.Admin) - async modify(@Param('id_profesor', ParseIntPipe) id_profesor: number, @Body() data: profesorDto) { + @Put(":id_profesor") + @Roles(Role.Responsable, Role.Admin) + async modify(@Param("id_profesor", ParseIntPipe) id_profesor: number, @Body() data: profesorDto) { + Logger.debug("put Profesors by id"); + return this.profesorService.modify(id_profesor, data); } - @Delete(':id_profesor') - @Roles(Role.Responsable,Role.Admin) - async remove(@Param('id_profesor', ParseIntPipe) id_profesor: number) { + @Delete(":id_profesor") + @Roles(Role.Responsable, Role.Admin) + async remove(@Param("id_profesor", ParseIntPipe) id_profesor: number) { + Logger.debug("delete Profesors by id"); + return this.profesorService.remove(id_profesor); } - @Get(':id_profesor') - async profile(@Param('id_profesor', ParseIntPipe) id_profesor: number) { + @Get(":id_profesor") + async profile(@Param("id_profesor", ParseIntPipe) id_profesor: number) { + Logger.debug("get Profesors by id"); + return this.profesorService.profile(id_profesor); } diff --git a/src/Profesor/profesor.service.ts b/src/Profesor/profesor.service.ts index a5b1d04..51a8465 100644 --- a/src/Profesor/profesor.service.ts +++ b/src/Profesor/profesor.service.ts @@ -1,19 +1,19 @@ -import { HttpException, Injectable } from '@nestjs/common'; -import { Profesor } from './entities/profesor.entity'; -import { DatosAcademicosService } from '../datos_academicos/datos_academicos.service'; -import { LineasInvestigacionService } from '../lineas_investigacion/lineas_investigacion.service'; -import { ProyectosAcademicosService } from '../proyectos_academicos/proyectos_academicos.service'; -import { InjectRepository } from '@nestjs/typeorm'; -import { Repository } from 'typeorm'; -import { profesorDto } from './dto/profesorDto.dto'; -import { ProyectosAcademicos } from '../proyectos_academicos/entities/proyectos_academicos.entity'; -import { DatosAcademicos } from '../datos_academicos/entities/datos_academicos.entity' -import { LineasInvestigacion } from '../lineas_investigacion/entities/lineas_investigacion.entity' +import { HttpException, Injectable, Logger } from "@nestjs/common"; +import { Profesor } from "./entities/profesor.entity"; +import { DatosAcademicosService } from "../datos_academicos/datos_academicos.service"; +import { LineasInvestigacionService } from "../lineas_investigacion/lineas_investigacion.service"; +import { ProyectosAcademicosService } from "../proyectos_academicos/proyectos_academicos.service"; +import { InjectRepository } from "@nestjs/typeorm"; +import { Repository } from "typeorm"; +import { profesorDto } from "./dto/profesorDto.dto"; +import { ProyectosAcademicos } from "../proyectos_academicos/entities/proyectos_academicos.entity"; +import { DatosAcademicos } from "../datos_academicos/entities/datos_academicos.entity"; +import { LineasInvestigacion } from "../lineas_investigacion/entities/lineas_investigacion.entity"; @Injectable() export class ProfesorService { constructor( - @InjectRepository(Profesor) + @InjectRepository(Profesor) private readonly profesorRepository: Repository, private readonly datosAcademicosService: DatosAcademicosService, private readonly lineasInvestigacionService: LineasInvestigacionService, @@ -23,13 +23,14 @@ export class ProfesorService { @InjectRepository(LineasInvestigacion) private readonly lineasInvestigacionRepository: Repository, @InjectRepository(ProyectosAcademicos) - private readonly proyectosAcademicosRepository: Repository, - ) {} + private readonly proyectosAcademicosRepository: Repository + ) { + } private async findAvailableId(): Promise { let id = 1; let exists = true; - + while (exists) { if (!await this.profesorRepository.findOne({ where: { id_profesor: id } })) { exists = false; @@ -41,14 +42,14 @@ export class ProfesorService { //register teacher async register(data: profesorDto): Promise { - const { num_trabajador, rfc, proyectosAcademicos, datosAcademicos, lineasInvestigacion} = data; + const { num_trabajador, rfc, proyectosAcademicos, datosAcademicos, lineasInvestigacion } = data; if (await this.profesorRepository.findOne({ where: { rfc } })) { - throw new HttpException('rfc already exist', 403); + throw new HttpException("rfc already exist", 403); } if (await this.profesorRepository.findOne({ where: { num_trabajador } })) { - throw new HttpException('number of worker already exist', 403); + throw new HttpException("number of worker already exist", 403); } const availableId = await this.findAvailableId(); @@ -61,7 +62,7 @@ export class ProfesorService { const newProyecto = this.proyectosAcademicosRepository.create({ ...proyecto, profesor: savedProfesor, - id_profesor: savedProfesor.id_profesor, + id_profesor: savedProfesor.id_profesor }); return newProyecto; }); @@ -73,7 +74,7 @@ export class ProfesorService { const newLinea = this.lineasInvestigacionRepository.create({ ...linea, profesor: savedProfesor, - id_profesor: savedProfesor.id_profesor, + id_profesor: savedProfesor.id_profesor }); return newLinea; }); @@ -85,7 +86,7 @@ export class ProfesorService { const newDato = this.datosAcademicosRepository.create({ ...datosAcademicos, profesor: savedProfesor, - id_profesor: savedProfesor.id_profesor, + id_profesor: savedProfesor.id_profesor }); return newDato; }); @@ -99,8 +100,8 @@ export class ProfesorService { async findAll(): Promise { return this.profesorRepository.find({ order: { - nombre: 'ASC', - }, + nombre: "ASC" + } }); } @@ -108,7 +109,7 @@ export class ProfesorService { async modify(id_profesor: number, data: profesorDto) { const profesor = await this.profesorRepository.findOne({ where: { id_profesor } }); if (!profesor) { - throw new HttpException('Profesor not found', 404); + throw new HttpException("Profesor not found", 404); } const { proyectosAcademicos, datosAcademicos, lineasInvestigacion, ...profesorData } = data; @@ -122,7 +123,7 @@ export class ProfesorService { const newProyecto = this.proyectosAcademicosRepository.create({ ...proyecto, profesor: savedProfesor, - id_profesor: savedProfesor.id_profesor, + id_profesor: savedProfesor.id_profesor }); return newProyecto; }); @@ -130,12 +131,12 @@ export class ProfesorService { } if (lineasInvestigacion) { - await this.lineasInvestigacionRepository.delete({ profesor: {id_profesor}}); + await this.lineasInvestigacionRepository.delete({ profesor: { id_profesor } }); const lineas = lineasInvestigacion.map(linea => { const newLinea = this.lineasInvestigacionRepository.create({ ...linea, profesor: savedProfesor, - id_profesor: savedProfesor.id_profesor, + id_profesor: savedProfesor.id_profesor }); return newLinea; }); @@ -148,7 +149,7 @@ export class ProfesorService { const newDato = this.datosAcademicosRepository.create({ ...datosAcademicos, profesor: savedProfesor, - id_profesor: savedProfesor.id_profesor, + id_profesor: savedProfesor.id_profesor }); return newDato; }); @@ -160,28 +161,28 @@ export class ProfesorService { //remove teacher async remove(id_profesor: number) { - const profesor = await this.profesorRepository.findOne({ where: { id_profesor }, relations: ['datosAcademicos'] }); + const profesor = await this.profesorRepository.findOne({ where: { id_profesor }, relations: ["datosAcademicos"] }); if (!profesor) { - throw new HttpException('Profesor not found', 404); + throw new HttpException("Profesor not found", 404); } - await this.datosAcademicosService.removeByProfesorId(id_profesor); - await this.lineasInvestigacionService.removeByProfesorId(id_profesor); - await this.proyectosAcademicosService.removeByProfesorId(id_profesor); + await this.datosAcademicosService.removeByProfesorId(id_profesor); + await this.lineasInvestigacionService.removeByProfesorId(id_profesor); + await this.proyectosAcademicosService.removeByProfesorId(id_profesor); await this.profesorRepository.remove(profesor); - return { message: 'Profesor removed successfully' }; + return { message: "Profesor removed successfully" }; } //brings teachers by id async profile(id_profesor: number) { const profesor = await this.profesorRepository.findOne({ where: { id_profesor }, - relations: ['proyectosAcademicos', 'datosAcademicos', 'lineasInvestigacion'], + relations: ["proyectosAcademicos", "datosAcademicos", "lineasInvestigacion"] }); - + if (!profesor) { - throw new HttpException('Profesor not found', 404); + throw new HttpException("Profesor not found", 404); } return profesor; @@ -192,43 +193,53 @@ export class ProfesorService { limit: number, filters: any ): Promise<{ profesores: Profesor[], total: number, totalPages: number }> { - const query = this.profesorRepository.createQueryBuilder('profesor'); - + const query = this.profesorRepository.createQueryBuilder("profesor"); + if (filters.nombre) { - query.andWhere('profesor.nombre LIKE :nombre', { nombre: `%${filters.nombre}%` }); + Logger.debug('fiter by name'); + + query.andWhere("profesor.nombre LIKE :nombre", { nombre: `%${filters.nombre}%` }); } - + if (filters.adscripcion) { - query.andWhere('profesor.adscripcion = :adscripcion', { adscripcion: filters.adscripcion }); + Logger.debug("fiter by adscription"); + + query.andWhere("profesor.adscripcion = :adscripcion", { adscripcion: filters.adscripcion }); } - + if (filters.categoria) { - query.andWhere('profesor.categoria = :categoria', { categoria: filters.categoria }); + Logger.debug("fiter by category"); + + query.andWhere("profesor.categoria = :categoria", { categoria: filters.categoria }); } - + if (filters.edificio) { - query.andWhere('profesor.edificio = :edificio', { edificio: filters.edificio }); + Logger.debug("fiter by building"); + + query.andWhere("profesor.edificio = :edificio", { edificio: filters.edificio }); } - - if (typeof filters.activo !== 'undefined') { - query.andWhere('profesor.activo = :activo', { activo: filters.activo }); + + if (typeof filters.activo !== "undefined") { + Logger.debug("fiter by is active"); + + query.andWhere("profesor.activo = :activo", { activo: filters.activo }); } else { - query.orderBy('profesor.activo', 'DESC'); + query.orderBy("profesor.activo", "DESC"); } - - query.addOrderBy('profesor.nombre', 'ASC'); - + + query.addOrderBy("profesor.nombre", "ASC"); + const [profesores, total] = await query .skip((page - 1) * limit) .take(limit) .getManyAndCount(); - + const totalPages = Math.ceil(total / limit); - + return { profesores, total, totalPages }; } - - + + async updateImageURL(id_profesor: number, imageUrl: string): Promise { await this.profesorRepository.update(id_profesor, { fotografia: imageUrl }); } From 71b65ad5a5db36f8539051ae09f6f1e040d23f7a Mon Sep 17 00:00:00 2001 From: IO Date: Mon, 29 Jul 2024 20:02:27 -0600 Subject: [PATCH 4/5] si funciona no le muevas --- .gitignore | 2 ++ src/images/dto/imagesDto.dto.ts | 0 src/images/helpers/images.helper.ts | 15 --------------- src/users/entities/user.entity.ts | 2 +- 4 files changed, 3 insertions(+), 16 deletions(-) delete mode 100644 src/images/dto/imagesDto.dto.ts delete mode 100644 src/images/helpers/images.helper.ts diff --git a/.gitignore b/.gitignore index 4b56acf..1f69350 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,5 @@ pids # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +imagenes diff --git a/src/images/dto/imagesDto.dto.ts b/src/images/dto/imagesDto.dto.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/images/helpers/images.helper.ts b/src/images/helpers/images.helper.ts deleted file mode 100644 index fe1c560..0000000 --- a/src/images/helpers/images.helper.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { extname } from 'path'; - -export const renameImage = (req, file, callback) => { - const profesorName = req.body.nombre.toLowerCase().replace(/ /g, '_'); - const fileExtName = extname(file.originalname); - const fileName = `${profesorName}${fileExtName}`; - callback(null, fileName); -}; - -export const fileFilter = (req, file, callback) => { - if (!file.originalname.match(/\.(jpg|jpeg|png)$/)) { - return callback(new Error('Invalid format type'), false); - } - callback(null, true); -}; diff --git a/src/users/entities/user.entity.ts b/src/users/entities/user.entity.ts index 68b5532..9927747 100644 --- a/src/users/entities/user.entity.ts +++ b/src/users/entities/user.entity.ts @@ -5,7 +5,7 @@ import { Profesor } from 'src/Profesor/entities/profesor.entity'; @Entity({ name: 'usuario' }) export class User { - @PrimaryGeneratedColumn({ name: 'PK_usuario' }) + @PrimaryGeneratedColumn() id_usuario: number; @Column({ type: 'int', nullable: false }) From 1e4e7f2d6556585ca9b4041b05759c8ad62dfef4 Mon Sep 17 00:00:00 2001 From: IO Date: Mon, 29 Jul 2024 20:21:38 -0600 Subject: [PATCH 5/5] loger --- src/Profesor/profesor.service.ts | 1 + src/adscripcion/adscripcion.controller.ts | 3 +- src/auth/auth.controller.ts | 37 ++++++++++++------- src/auth/auth.service.ts | 4 ++ src/categoria/categoria.controller.ts | 3 +- .../datos_academicos.controller.ts | 7 +++- .../datos_academicos.service.ts | 1 - src/edificio/edificio.controller.ts | 3 +- src/images/images.controller.ts | 12 ++---- src/images/images.service.ts | 3 +- .../lineas_investigacion.controller.ts | 3 +- src/permissions/roles.guard.ts | 24 +++++++----- .../proyectos_academicos.controller.ts | 3 +- src/users/users.service.ts | 4 +- 14 files changed, 66 insertions(+), 42 deletions(-) diff --git a/src/Profesor/profesor.service.ts b/src/Profesor/profesor.service.ts index 51a8465..f472293 100644 --- a/src/Profesor/profesor.service.ts +++ b/src/Profesor/profesor.service.ts @@ -33,6 +33,7 @@ export class ProfesorService { while (exists) { if (!await this.profesorRepository.findOne({ where: { id_profesor: id } })) { + Logger.debug(`id_profesor = ${id}`); exists = false; return id; } diff --git a/src/adscripcion/adscripcion.controller.ts b/src/adscripcion/adscripcion.controller.ts index f35a4b0..6625136 100644 --- a/src/adscripcion/adscripcion.controller.ts +++ b/src/adscripcion/adscripcion.controller.ts @@ -1,4 +1,4 @@ -import { Controller, Get } from '@nestjs/common'; +import { Controller, Get, Logger } from '@nestjs/common'; import { AdscripcionService } from './adscripcion.service'; @Controller('adscripcion') @@ -7,6 +7,7 @@ export class AdscripcionController { @Get() findAll() { + Logger.debug('find all adscripcion'); return this.adscripcionService.findAll(); } } diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts index d82dd07..8c2e6e6 100644 --- a/src/auth/auth.controller.ts +++ b/src/auth/auth.controller.ts @@ -11,15 +11,15 @@ import { UseGuards, Delete, ParseIntPipe, - Query + Query, + Logger, } from '@nestjs/common'; import { AuthGuard } from './auth.guard'; import { AuthService } from './auth.service'; import { registerDto } from './dto/registerDto.dto'; -import {Roles} from '../permissions/roles.decorator' -import {RolesGuard} from '../permissions/roles.guard' -import {Role} from '../permissions/role.enum' - +import { Roles } from '../permissions/roles.decorator'; +import { RolesGuard } from '../permissions/roles.guard'; +import { Role } from '../permissions/role.enum'; @Controller('auth') @UseGuards(RolesGuard) @@ -29,20 +29,22 @@ export class AuthController { @HttpCode(HttpStatus.OK) @Post('login') async signIn(@Body() data: registerDto) { + Logger.debug('signIn'); const { rememberMe } = data; return this.authService.signIn(data, rememberMe); } //@UseGuards() - @Post("register") + @Post('register') //@Roles(Role.Admin) - async register(@Body() data: registerDto){ - return this.authService.register(data) + async register(@Body() data: registerDto) { + Logger.debug('register user'); + return this.authService.register(data); } - //@UseGuards(AuthGuard) @Get() findAll() { + Logger.debug('find all users'); return this.authService.findAll(); } @@ -50,23 +52,29 @@ export class AuthController { findAllPaginated( @Query('page') page: number = 1, @Query('limit') limit: number = 10, - @Query() filters: any + @Query() filters: any, ) { + Logger.debug('find all users max 10'); page = page < 1 ? 1 : page; limit = limit > 10 || limit < 1 ? 10 : limit; - return this.authService.findAllPaginated(page, limit,filters); + return this.authService.findAllPaginated(page, limit, filters); } @Get(':id_usuario') async profile(@Param('id_usuario', ParseIntPipe) id_usuario: number) { + Logger.debug('find one user'); return this.authService.profile(id_usuario); } //@UseGuards(AuthGuard) @Put(':id_usuario') @Roles(Role.Admin) - async update(@Param('id_usuario') id_usuario: number, @Body() data: registerDto) { + async update( + @Param('id_usuario') id_usuario: number, + @Body() data: registerDto, + ) { + Logger.debug('update user'); return this.authService.update(id_usuario, data); } @@ -74,6 +82,7 @@ export class AuthController { @Delete(':id_usuario') @Roles(Role.Admin) async remove(@Param('id_usuario') id_usuario: number) { + Logger.debug('delete user'); await this.authService.remove(id_usuario); return { message: 'User successfully deleted' }; } @@ -81,7 +90,7 @@ export class AuthController { @HttpCode(HttpStatus.OK) @Post('validate') async validateToken(@Body('token') token: string) { + Logger.debug('validate user'); return this.authService.validateToken(token); } - -} \ No newline at end of file +} diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index ab39039..4466c95 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -2,6 +2,7 @@ import { HttpException, Inject, Injectable, + Logger, UnauthorizedException, } from '@nestjs/common'; import { UsersService } from '../users/users.service'; @@ -131,10 +132,12 @@ export class AuthService { const query = this.userRepository.createQueryBuilder('usuario'); if (filters.nombre) { + Logger.debug('fiter by name user'); query.andWhere('usuario.nombre LIKE :nombre', { nombre: `%${filters.nombre}%` }); } if (filters.id_tipo_usuario) { + Logger.debug('fiter by id user'); query.andWhere('usuario.id_tipo_usuario = :id_tipo_usuario', { id_tipo_usuario: filters.id_tipo_usuario }); } @@ -155,6 +158,7 @@ export class AuthService { }); if (!user) { + Logger.debug('user not found'); throw new HttpException('user not found', 404); } diff --git a/src/categoria/categoria.controller.ts b/src/categoria/categoria.controller.ts index 0e51ac3..72293cc 100644 --- a/src/categoria/categoria.controller.ts +++ b/src/categoria/categoria.controller.ts @@ -1,4 +1,4 @@ -import { Controller, Get } from '@nestjs/common'; +import { Controller, Get, Logger } from '@nestjs/common'; import { CategoriaService } from './categoria.service'; @Controller('categoria') @@ -7,6 +7,7 @@ export class CategoriaController { @Get() findAll() { + Logger.debug('find all categoria'); return this.categoriaService.findAll(); } } diff --git a/src/datos_academicos/datos_academicos.controller.ts b/src/datos_academicos/datos_academicos.controller.ts index 80549b6..f36c829 100644 --- a/src/datos_academicos/datos_academicos.controller.ts +++ b/src/datos_academicos/datos_academicos.controller.ts @@ -1,12 +1,15 @@ -import { Controller, Get } from '@nestjs/common'; +import { Controller, Get, Logger } from '@nestjs/common'; import { DatosAcademicosService } from './datos_academicos.service'; @Controller('datos-academicos') export class DatosAcademicosController { - constructor(private readonly datosAcademicosService: DatosAcademicosService) {} + constructor( + private readonly datosAcademicosService: DatosAcademicosService, + ) {} @Get() findAll() { + Logger.debug('find all datos academicos'); return this.datosAcademicosService.findAll(); } } diff --git a/src/datos_academicos/datos_academicos.service.ts b/src/datos_academicos/datos_academicos.service.ts index e275376..bfdd655 100644 --- a/src/datos_academicos/datos_academicos.service.ts +++ b/src/datos_academicos/datos_academicos.service.ts @@ -10,7 +10,6 @@ export class DatosAcademicosService { private readonly datosAcademicosRepository: Repository, ) {} - // Add methods to manage DatosAcademicos entities as needed async removeByProfesorId(id_profesor: number): Promise { await this.datosAcademicosRepository.delete({ profesor: { id_profesor } }); } diff --git a/src/edificio/edificio.controller.ts b/src/edificio/edificio.controller.ts index 8875a84..fbe06cc 100644 --- a/src/edificio/edificio.controller.ts +++ b/src/edificio/edificio.controller.ts @@ -1,4 +1,4 @@ -import { Controller, Get } from '@nestjs/common'; +import { Controller, Get, Logger } from '@nestjs/common'; import { EdificioService } from './edificio.service'; @Controller('edificio') @@ -7,6 +7,7 @@ export class EdificioController { @Get() findAll() { + Logger.debug('find all edificio'); return this.edificioService.findAll(); } } diff --git a/src/images/images.controller.ts b/src/images/images.controller.ts index 70b55c8..ca9a90d 100644 --- a/src/images/images.controller.ts +++ b/src/images/images.controller.ts @@ -1,9 +1,4 @@ -import { - Controller, - Post, - Body, - Put, -} from '@nestjs/common'; +import { Controller, Post, Body, Put, Logger } from '@nestjs/common'; import { ImagenService } from './images.service'; @Controller('imagen') @@ -12,8 +7,9 @@ export class ImagenController { @Post() async upload(@Body() body) { + Logger.debug('upload image'); const { fotografia, nombre } = body; - + const imageUrl = await this.imagenService.saveImage(fotografia, nombre); return { message: 'Image uploaded successfully', imageUrl }; @@ -21,11 +17,11 @@ export class ImagenController { @Put() async modify(@Body() body) { + Logger.debug('modify image'); const { fotografia, nombre } = body; const imageUrl = await this.imagenService.modify(fotografia, nombre); return { message: 'Image uploaded successfully', imageUrl }; } - } diff --git a/src/images/images.service.ts b/src/images/images.service.ts index a7fc010..160007f 100644 --- a/src/images/images.service.ts +++ b/src/images/images.service.ts @@ -1,4 +1,4 @@ -import { Injectable, BadRequestException, NotFoundException } from '@nestjs/common'; +import { Injectable, BadRequestException, NotFoundException, Logger } from '@nestjs/common'; import * as fs from 'fs'; import * as path from 'path'; import * as sharp from 'sharp'; @@ -37,6 +37,7 @@ export class ImagenService { } async deleteImage(nombre: string): Promise { + Logger.debug('delete image'); const sanitizedFileName = nombre.replace(/\s+/g, '_').toLowerCase(); const imageDir = path.join(process.cwd(), 'imagenes'); const imagePath = path.join(imageDir, sanitizedFileName); diff --git a/src/lineas_investigacion/lineas_investigacion.controller.ts b/src/lineas_investigacion/lineas_investigacion.controller.ts index c35e25e..c831d3a 100644 --- a/src/lineas_investigacion/lineas_investigacion.controller.ts +++ b/src/lineas_investigacion/lineas_investigacion.controller.ts @@ -1,4 +1,4 @@ -import { Controller, Get } from '@nestjs/common'; +import { Controller, Get, Logger } from '@nestjs/common'; import { LineasInvestigacionService } from './lineas_investigacion.service'; @Controller('lineas-investigacion') @@ -7,6 +7,7 @@ export class LineasInvestigacionController { @Get() findAll() { + Logger.debug('find all lineas de investigacion'); return this.lineasInvestigacionService.findAll(); } } diff --git a/src/permissions/roles.guard.ts b/src/permissions/roles.guard.ts index 9671a16..5d13c18 100644 --- a/src/permissions/roles.guard.ts +++ b/src/permissions/roles.guard.ts @@ -1,4 +1,10 @@ -import { Injectable, CanActivate, ExecutionContext, UnauthorizedException } from '@nestjs/common'; +import { + Injectable, + CanActivate, + ExecutionContext, + UnauthorizedException, + Logger, +} from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { JwtService } from '@nestjs/jwt'; import { Role } from './role.enum'; @@ -10,17 +16,18 @@ export class RolesGuard implements CanActivate { constructor( private reflector: Reflector, private jwtService: JwtService, - private configService: ConfigService + private configService: ConfigService, ) {} async canActivate(context: ExecutionContext): Promise { + Logger.debug('verify roles'); const requiredRoles = this.reflector.getAllAndOverride(ROLES_KEY, [ context.getHandler(), context.getClass(), ]); if (!requiredRoles) { - return true; // Permitir acceso si no se especifican roles requeridos + return true; } const request = context.switchToHttp().getRequest(); @@ -30,18 +37,15 @@ export class RolesGuard implements CanActivate { throw new UnauthorizedException('No authorization header provided'); } - const [, token] = authHeader.split(' '); + const [, token] = authHeader.split(' '); if (!token) { throw new UnauthorizedException('No token provided'); } try { - const userPayload = await this.jwtService.verifyAsync( - token, - { - secret: this.configService.get('JWT_SECRET'), - } - ); + const userPayload = await this.jwtService.verifyAsync(token, { + secret: this.configService.get('JWT_SECRET'), + }); const userRole: Role = userPayload.id_tipo_usuario; const userId: number = userPayload.id_usuario; diff --git a/src/proyectos_academicos/proyectos_academicos.controller.ts b/src/proyectos_academicos/proyectos_academicos.controller.ts index a226ba0..4822559 100644 --- a/src/proyectos_academicos/proyectos_academicos.controller.ts +++ b/src/proyectos_academicos/proyectos_academicos.controller.ts @@ -1,4 +1,4 @@ -import { Controller,Get } from '@nestjs/common'; +import { Controller,Get, Logger } from '@nestjs/common'; import { ProyectosAcademicosService } from './proyectos_academicos.service'; @Controller('proyectos-academicos') @@ -7,6 +7,7 @@ export class ProyectosAcademicosController { @Get() findAll() { + Logger.debug('find all proyectos academicos'); return this.proyectosAcademicosService.findAll(); } } diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 9b17aa0..eb740b7 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, Logger } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { User } from './entities/user.entity'; @@ -14,12 +14,14 @@ export class UsersService { async findOne(usuario: string): Promise { return this.users.findOne({ where: { usuario } }); } + async updateTokenAndDates( id: number, token: string, lastLogin: Date, jwtExpiry: Date, ): Promise { + Logger.debug('update token and date user'); await this.users.update(id, { jwt: token, lastlog: lastLogin,