diff --git a/src/Profesor/dto/profesorDto.dto.ts b/src/Profesor/dto/profesorDto.dto.ts index e4d3b2f..6e6a548 100644 --- a/src/Profesor/dto/profesorDto.dto.ts +++ b/src/Profesor/dto/profesorDto.dto.ts @@ -121,4 +121,9 @@ export class LineasInvestigacion{ @IsOptional() @Length(0,300) lineas_inv_html: string; +} + +export class UpdateProfesorImageDto { + @IsString() + fotografia: string; } \ No newline at end of file diff --git a/src/Profesor/profesor.controller.ts b/src/Profesor/profesor.controller.ts index 5943759..56c0551 100644 --- a/src/Profesor/profesor.controller.ts +++ b/src/Profesor/profesor.controller.ts @@ -3,6 +3,7 @@ import { Controller, Delete, Get, + HttpException, Logger, Param, ParseIntPipe, @@ -12,10 +13,11 @@ import { UseGuards } from "@nestjs/common"; import { ProfesorService } from "./profesor.service"; -import { profesorDto } from "./dto/profesorDto.dto"; +import { profesorDto, UpdateProfesorImageDto } from "./dto/profesorDto.dto"; import { Roles } from "../permissions/roles.decorator"; import { RolesGuard } from "../permissions/roles.guard"; import { Role } from "../permissions/role.enum"; +import { Profesor } from "./entities/profesor.entity"; @Controller("profesor") @UseGuards(RolesGuard) @@ -30,6 +32,24 @@ export class ProfesorController { return this.profesorService.register(data); } + @Put(':id_profesor/image') + async updateImage( + @Param('id_profesor') id_profesor: number, + @Body() updateProfesorImageDto: UpdateProfesorImageDto, + ): Promise { + const { fotografia } = updateProfesorImageDto; + + const profesor = await this.profesorService.findOne(id_profesor); + + if (!profesor) { + throw new HttpException('Profesor not found', 404); + } + + profesor.fotografia = fotografia; + + return this.profesorService.update(profesor); + } + @Get() findAll() { Logger.debug("findAllProfesors"); diff --git a/src/Profesor/profesor.module.ts b/src/Profesor/profesor.module.ts index 39b850c..369a463 100644 --- a/src/Profesor/profesor.module.ts +++ b/src/Profesor/profesor.module.ts @@ -10,12 +10,7 @@ import { ProyectosAcademicos } from 'src/proyectos_academicos/entities/proyectos import { DatosAcademicos } from 'src/datos_academicos/entities/datos_academicos.entity' import { LineasInvestigacion } from 'src/lineas_investigacion/entities/lineas_investigacion.entity' -import { ProyectosAcademicosService } from 'src/proyectos_academicos/proyectos_academicos.service'; -import { DatosAcademicosService } from 'src/datos_academicos/datos_academicos.service'; -import { LineasInvestigacionService } from 'src/lineas_investigacion/lineas_investigacion.service'; - import { JwtModule } from '@nestjs/jwt'; -import { RolesGuard } from '../permissions/roles.guard'; @Module({ imports: [ diff --git a/src/Profesor/profesor.service.ts b/src/Profesor/profesor.service.ts index f472293..27a5343 100644 --- a/src/Profesor/profesor.service.ts +++ b/src/Profesor/profesor.service.ts @@ -27,6 +27,14 @@ export class ProfesorService { ) { } + async findOne(id_profesor: number): Promise { + return this.profesorRepository.findOne({ where: { id_profesor } }); + } + + async update(profesor: Profesor): Promise { + return this.profesorRepository.save(profesor); + } + private async findAvailableId(): Promise { let id = 1; let exists = true; diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts index 8c2e6e6..c24a8d7 100644 --- a/src/auth/auth.controller.ts +++ b/src/auth/auth.controller.ts @@ -13,6 +13,7 @@ import { ParseIntPipe, Query, Logger, + Req, } from '@nestjs/common'; import { AuthGuard } from './auth.guard'; import { AuthService } from './auth.service'; @@ -36,7 +37,7 @@ export class AuthController { //@UseGuards() @Post('register') - //@Roles(Role.Admin) + @Roles(Role.Admin) async register(@Body() data: registerDto) { Logger.debug('register user'); return this.authService.register(data); @@ -73,9 +74,12 @@ export class AuthController { async update( @Param('id_usuario') id_usuario: number, @Body() data: registerDto, + @Req() req: any ) { - Logger.debug('update user'); - return this.authService.update(id_usuario, data); + const authHeader = req.headers['authorization']; + const [, token] = authHeader.split(' '); + + return this.authService.update(id_usuario, data, token); } //@UseGuards(AuthGuard) diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index 4466c95..62d9ad2 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -26,7 +26,7 @@ export class AuthService { //register users async register(data: registerDto) { - const { usuario, contraseña} = data; + const { usuario, contraseña } = data; if (await this.usersService.findOne(usuario)) { throw new HttpException('User already exist', 403); @@ -74,17 +74,29 @@ export class AuthService { } //update user - async update(id_usuario: number, data: registerDto) { - const { contraseña } = data; + async update( + id_usuario: number, + data: registerDto, + token: string, + ): Promise { + const { contraseña, id_tipo_usuario } = data; + + const tokenUserId = this.getTokenUserId(token); + + if (tokenUserId == id_usuario && id_tipo_usuario !== undefined) { + Logger.debug('Cannot modify id_tipo_usuario') + delete data.id_tipo_usuario; + } + + const user = await this.userRepository.findOne({ where: { id_usuario } }); + if (!user) { + throw new HttpException('User not found', 404); + } if (contraseña) { const hashedpassword = await hash(contraseña, 10); data = { ...data, contraseña: hashedpassword }; } else { - const user = await this.userRepository.findOne({ where: { id_usuario } }); - if (!user) { - throw new HttpException('User not found', 404); - } data = { ...data, contraseña: user.contraseña }; } @@ -114,7 +126,7 @@ export class AuthService { throw new UnauthorizedException('Token has expired'); } - return ; + return; } catch (error) { throw new UnauthorizedException('validation token failed'); } @@ -127,18 +139,22 @@ export class AuthService { async findAllPaginated( page: number, limit: number, - filters: any - ): Promise<{ usuarios: User[], total: number, totalPages: number }> { + filters: any, + ): Promise<{ usuarios: User[]; total: number; totalPages: number }> { const query = this.userRepository.createQueryBuilder('usuario'); if (filters.nombre) { Logger.debug('fiter by name user'); - query.andWhere('usuario.nombre LIKE :nombre', { nombre: `%${filters.nombre}%` }); + 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 }); + query.andWhere('usuario.id_tipo_usuario = :id_tipo_usuario', { + id_tipo_usuario: filters.id_tipo_usuario, + }); } const [usuarios, total] = await query @@ -156,7 +172,7 @@ export class AuthService { const user = await this.userRepository.findOne({ where: { id_usuario }, }); - + if (!user) { Logger.debug('user not found'); throw new HttpException('user not found', 404); @@ -164,4 +180,13 @@ export class AuthService { return user; } + + getTokenUserId(token: string): number { + try { + const decoded = this.jwtService.verify(token); + return decoded['id_usuario']; + } catch (error) { + throw new UnauthorizedException('Invalid token'); + } + } } diff --git a/src/images/images.service.ts b/src/images/images.service.ts index 160007f..43a468d 100644 --- a/src/images/images.service.ts +++ b/src/images/images.service.ts @@ -1,11 +1,10 @@ -import { Injectable, BadRequestException, NotFoundException, Logger } from '@nestjs/common'; +import { Injectable, BadRequestException, Logger } from '@nestjs/common'; import * as fs from 'fs'; import * as path from 'path'; -import * as sharp from 'sharp'; @Injectable() export class ImagenService { - async saveImage(fotografia: string, nombre: string): Promise { + async saveImage(fotografia: string, id: string): Promise { if (!fotografia) { throw new BadRequestException('No image provided'); } @@ -19,8 +18,7 @@ export class ImagenService { // Decode base64 string and save the image const buffer = Buffer.from(fotografia.split(',')[1], 'base64'); - const sanitizedFileName = nombre.replace(/\s+/g, '_').toLowerCase(); - const imageName = `${sanitizedFileName}.${ext}`; + const imageName = `${id}.${ext}`; // Save image to the 'imagenes' directory in the root of the project const imagePath = path.join(process.cwd(), 'imagenes', imageName); @@ -31,16 +29,15 @@ export class ImagenService { fs.mkdirSync(dirPath, { recursive: true }); } - await sharp(buffer).toFile(imagePath); + fs.writeFileSync(imagePath, buffer); - return `/imagenes/${imageName}`; + return imageName; } - async deleteImage(nombre: string): Promise { + async deleteImage(id: 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); + const imagePath = path.join(imageDir, id); const extensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'avif']; @@ -53,19 +50,18 @@ export class ImagenService { break; } } - + if (!fileFound) { console.log('Image not found, but continuing to save the new image.'); - // No se lanza excepción } } - async modify(fotografia: string, nombre: string): Promise { + async modify(fotografia: string, id: string): Promise { if (!fotografia) { throw new BadRequestException('No image provided'); } - await this.deleteImage(nombre); + await this.deleteImage(id); // Extract the image extension const matches = fotografia.match(/^data:image\/([a-zA-Z]+);base64,/); @@ -76,8 +72,7 @@ export class ImagenService { // Decode base64 string and save the image const buffer = Buffer.from(fotografia.split(',')[1], 'base64'); - const sanitizedFileName = nombre.replace(/\s+/g, '_').toLowerCase(); - const imageName = `${sanitizedFileName}.${ext}`; + const imageName = `${id}.${ext}`; // Save image to the 'imagenes' directory in the root of the project const imagePath = path.join(process.cwd(), 'imagenes', imageName); @@ -88,8 +83,8 @@ export class ImagenService { fs.mkdirSync(dirPath, { recursive: true }); } - await sharp(buffer).toFile(imagePath); + fs.writeFileSync(imagePath, buffer); - return `/imagenes/${imageName}`; + return imageName; } } diff --git a/src/main.ts b/src/main.ts index 949c1e2..68a6e1b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,14 +2,19 @@ import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { NestExpressApplication } from '@nestjs/platform-express'; import * as path from 'path'; +import * as bodyParser from 'body-parser'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.enableCors(); + app.use(bodyParser.json({ limit: '1mb' })); + app.use(bodyParser.urlencoded({ limit: '1mb', extended: true })); + app.useStaticAssets(path.join(__dirname, '..', 'imagenes'), { prefix: '/imagenes/', }); + await app.listen(3000); } bootstrap();