Se agregó módulo de sistemas
This commit is contained in:
@@ -5,6 +5,7 @@ import { MailModule } from './mail/mail.module';
|
||||
import {ExcelModule} from './excel/excel.module'
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { SistemaModule } from './sistema/sistema.module';
|
||||
|
||||
|
||||
|
||||
@@ -28,6 +29,7 @@ import { ConfigModule } from '@nestjs/config';
|
||||
|
||||
MailModule,
|
||||
ExcelModule,
|
||||
SistemaModule,
|
||||
|
||||
|
||||
],
|
||||
|
||||
@@ -30,24 +30,24 @@ export class MailController {
|
||||
@Post('send')
|
||||
@ApiSendMail()
|
||||
async sendMail(
|
||||
@Headers() headers:{password:string},
|
||||
@Headers() headers:{token:string},
|
||||
@Body() body: { to: string; subject: string; text: string; fecha_recibido: Date, html:string, adjuntos:any }) {
|
||||
|
||||
/*
|
||||
|
||||
|
||||
// esta parte hay que rehacerla, se tiene que obtener la contraseña del sistema en base a la clave del sistema.
|
||||
// debe de existir un modulo para crear contraseñas para las apis y administrar esas contraseñas
|
||||
|
||||
|
||||
if (!headers.password) {
|
||||
if (!headers.token) {
|
||||
throw new UnauthorizedException('Header "Password" es requerido');
|
||||
}
|
||||
|
||||
const sistem = await this.sistemaRepository.findOne({ where: { password: headers.password } });
|
||||
const sistem = await this.sistemaRepository.findOne({ where: { token: headers.token } });
|
||||
|
||||
if (!sistem) {
|
||||
throw new UnauthorizedException('Password incorrecto');
|
||||
} */
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ export class MailController {
|
||||
throw new UnauthorizedException('Header "Password" es requerido');
|
||||
}
|
||||
|
||||
const sistem = await this.sistemaRepository.findOne({ where: { password: headers.password } });
|
||||
const sistem = await this.sistemaRepository.findOne({ where: { token: headers.password } });
|
||||
|
||||
if (!sistem) {
|
||||
throw new UnauthorizedException('Password incorrecto');
|
||||
|
||||
@@ -10,8 +10,18 @@ export const ApiSendMail = () => {
|
||||
- **subject**: Asunto del correo.
|
||||
- **text**: Cuerpo del mensaje.
|
||||
- **fecha_recibido**: Fecha en que se registró la solicitud.
|
||||
- **sistema**: contraseña del sistema.`,
|
||||
}),
|
||||
- **sistema**: contraseña del sistema.
|
||||
- **html**: se puede mandar html
|
||||
- **adjuntos**:mandar qr
|
||||
(Se requiere una contraseña de aplicación
|
||||
No caducan automáticamente.
|
||||
Pero se invalidan si:
|
||||
Cambias la contraseña de tu cuenta.
|
||||
Desactivas la verificación en dos pasos.
|
||||
Revocas el acceso desde https://myaccount.google.com/apppasswords.
|
||||
Google detecta actividad sospechosa o problemas de seguridad.))`,
|
||||
|
||||
}),
|
||||
ApiHeader({
|
||||
name: 'password',
|
||||
description: 'Contraseña del sistema para autenticación',
|
||||
|
||||
@@ -8,11 +8,13 @@ import {
|
||||
Correo,
|
||||
Sistema,
|
||||
}from 'src/typeorm/votacionesPrueba.entity'
|
||||
import { SistemaModule } from 'src/sistema/sistema.module';
|
||||
|
||||
@Module({
|
||||
providers: [MailService],
|
||||
imports: [
|
||||
ExcelModule,
|
||||
SistemaModule,
|
||||
TypeOrmModule.forFeature([
|
||||
Status,
|
||||
Correo,
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { IsString, IsOptional, IsBoolean, IsNotEmpty } from 'class-validator';
|
||||
|
||||
export class CreateSistemaDto {
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
Nombre:string;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
ip:string;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
password: string;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common';
|
||||
import { SistemaService } from './sistema.service';
|
||||
import { CreateSistemaDto } from './dto/create-sistema.dto';
|
||||
import { ApiCreateSistema, ApiGenerarToken } from './sistema.decorators';
|
||||
|
||||
|
||||
@Controller('sistema')
|
||||
export class SistemaController {
|
||||
constructor(private readonly sistemaService: SistemaService) {}
|
||||
|
||||
@Post()
|
||||
@ApiCreateSistema()
|
||||
create(@Body() createSistemaDto: CreateSistemaDto, password:string) {
|
||||
return this.sistemaService.create(createSistemaDto);
|
||||
}
|
||||
|
||||
@Patch(':nombre_sistema')
|
||||
@ApiGenerarToken()
|
||||
update(@Param('nombre_sistema') nombre_sistema: string, @Body() password: string) {
|
||||
return this.sistemaService.Generar_Token(nombre_sistema, password);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import { applyDecorators } from '@nestjs/common';
|
||||
import { ApiBody, ApiOperation, ApiParam } from '@nestjs/swagger';
|
||||
|
||||
export const ApiCreateSistema = () => {
|
||||
return applyDecorators(
|
||||
ApiOperation({
|
||||
summary: 'Registrar un nuevo sistema',
|
||||
description: `Este endpoint permite dar de alta un sistema para poder utilizar funcionalidades autenticadas mediante contraseña.
|
||||
Se debe proporcionar:
|
||||
- **Nombre**: Nombre único del sistema.
|
||||
- **ip**: Dirección IP desde la cual se harán peticiones.
|
||||
- **password**: Contraseña segura que el sistema usará para autenticarse.`,
|
||||
}),
|
||||
ApiBody({
|
||||
description: 'Datos del sistema a registrar',
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
Nombre: { type: 'string', example: 'Sistema de Reportes' },
|
||||
ip: { type: 'string', example: '192.168.1.100' },
|
||||
password: { type: 'string', example: 'clave-segura-123' },
|
||||
},
|
||||
required: ['Nombre', 'ip', 'password'],
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
export const ApiGenerarToken = () => {
|
||||
return applyDecorators(
|
||||
ApiOperation({
|
||||
summary: 'Generar token JWT para un sistema',
|
||||
description: `Este endpoint permite generar un token de acceso válido para el sistema registrado.
|
||||
Se debe enviar el nombre del sistema como parámetro de ruta y la contraseña como cuerpo.`,
|
||||
}),
|
||||
ApiParam({
|
||||
name: 'nombre_sistema',
|
||||
required: true,
|
||||
description: 'Nombre exacto del sistema registrado',
|
||||
example: 'Sistema de Reportes',
|
||||
}),
|
||||
ApiBody({
|
||||
description: 'Contraseña del sistema',
|
||||
schema: {
|
||||
type: 'string',
|
||||
example: 'clave-segura-123',
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { SistemaService } from './sistema.service';
|
||||
import { SistemaController } from './sistema.controller';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { Sistema } from 'src/typeorm/votacionesPrueba.entity';
|
||||
|
||||
@Module({
|
||||
controllers: [SistemaController],
|
||||
providers: [SistemaService],
|
||||
imports:[
|
||||
TypeOrmModule.forFeature([
|
||||
Sistema])
|
||||
],
|
||||
exports:[SistemaModule]
|
||||
})
|
||||
export class SistemaModule {}
|
||||
@@ -0,0 +1,53 @@
|
||||
import { Injectable, NotFoundException, UnauthorizedException } from '@nestjs/common';
|
||||
import { CreateSistemaDto } from './dto/create-sistema.dto';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Sistema } from 'src/typeorm/votacionesPrueba.entity';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { randomBytes } from 'crypto';
|
||||
|
||||
@Injectable()
|
||||
export class SistemaService {
|
||||
constructor(
|
||||
@InjectRepository(Sistema) private readonly sistemaRepository: Repository<Sistema>
|
||||
|
||||
){}
|
||||
|
||||
generarPassword(longitud = 12): string {
|
||||
return randomBytes(longitud)
|
||||
.toString('base64')
|
||||
.slice(0, longitud)
|
||||
.replace(/[+/=]/g, () => String.fromCharCode(33 + Math.floor(Math.random() * 94))); // reemplaza caracteres raros
|
||||
}
|
||||
|
||||
|
||||
async Generar_Token(nombreSistema:string,adminPasword:string) {
|
||||
if(adminPasword!==process.env.ADMIN_PASSWORD){
|
||||
throw new UnauthorizedException('Password erroneo');
|
||||
}
|
||||
const sistema = await this.sistemaRepository.findOneBy({nombre_sistema:nombreSistema})
|
||||
if(!sistema){
|
||||
throw new NotFoundException('Sistema no encontrado')
|
||||
}
|
||||
sistema.token=this.generarPassword()
|
||||
|
||||
this.sistemaRepository.save(sistema)
|
||||
return sistema.token;
|
||||
}
|
||||
|
||||
async create(createSistemaDto: CreateSistemaDto) {
|
||||
if(createSistemaDto.password!==process.env.ADMIN_PASSWORD){
|
||||
throw new UnauthorizedException('Password erroneo');
|
||||
}
|
||||
|
||||
const sistem = this.sistemaRepository.create({
|
||||
nombre_sistema:createSistemaDto.Nombre,
|
||||
ip:createSistemaDto.ip,
|
||||
});
|
||||
await this.sistemaRepository.save(sistem)
|
||||
|
||||
return this.Generar_Token(createSistemaDto.Nombre,createSistemaDto.password);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { isEmpty } from 'class-validator';
|
||||
import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne, JoinColumn } from 'typeorm';
|
||||
|
||||
@Entity()
|
||||
@@ -5,12 +6,15 @@ export class Sistema {
|
||||
@PrimaryGeneratedColumn()
|
||||
id_sistema: number;
|
||||
|
||||
@Column({ type: 'varchar', length: 50 })
|
||||
password: string;
|
||||
@Column({ type: 'varchar', length: 255, nullable: true })
|
||||
token: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 50 })
|
||||
nombre_sistema: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 50 })
|
||||
ip:string
|
||||
|
||||
@OneToMany(() => Correo, (correo) => correo.id_sistema)
|
||||
correos: Correo[];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user