Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0d0077cbcb | |||
| c4666718a4 | |||
| 11fe86a111 | |||
| 59a5ff8c35 | |||
| 58b49ba93d | |||
| b2e992dd04 | |||
| 2df592ee89 | |||
| ee622197c1 | |||
| 6c9d003cb9 | |||
| 1895e29cf2 |
@@ -1,6 +1,7 @@
|
|||||||
# Gmail
|
# Gmail
|
||||||
USER_GMAIL=
|
USER_GMAIL=
|
||||||
PASS_GMAIL=
|
PASS_GMAIL=
|
||||||
|
ADMIN_PASSWORD=12345
|
||||||
|
|
||||||
# MariaDB database settings
|
# MariaDB database settings
|
||||||
db_type=mysql
|
db_type=mysql
|
||||||
|
|||||||
Generated
+33
@@ -15,6 +15,7 @@
|
|||||||
"@nestjs/platform-express": "^11.0.1",
|
"@nestjs/platform-express": "^11.0.1",
|
||||||
"@nestjs/swagger": "^11.0.5",
|
"@nestjs/swagger": "^11.0.5",
|
||||||
"@nestjs/typeorm": "^11.0.0",
|
"@nestjs/typeorm": "^11.0.0",
|
||||||
|
"class-validator": "^0.14.1",
|
||||||
"csv-parser": "^3.2.0",
|
"csv-parser": "^3.2.0",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"exceljs": "^4.4.0",
|
"exceljs": "^4.4.0",
|
||||||
@@ -3169,6 +3170,12 @@
|
|||||||
"@types/serve-static": "*"
|
"@types/serve-static": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/validator": {
|
||||||
|
"version": "13.12.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.12.3.tgz",
|
||||||
|
"integrity": "sha512-2ipwZ2NydGQJImne+FhNdhgRM37e9lCev99KnqkbFHd94Xn/mErARWI1RSLem1QA19ch5kOhzIZd7e8CA2FI8g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/yargs": {
|
"node_modules/@types/yargs": {
|
||||||
"version": "17.0.33",
|
"version": "17.0.33",
|
||||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
|
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
|
||||||
@@ -4643,6 +4650,17 @@
|
|||||||
"integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==",
|
"integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/class-validator": {
|
||||||
|
"version": "0.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.1.tgz",
|
||||||
|
"integrity": "sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/validator": "^13.11.8",
|
||||||
|
"libphonenumber-js": "^1.10.53",
|
||||||
|
"validator": "^13.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cli-cursor": {
|
"node_modules/cli-cursor": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
|
||||||
@@ -7929,6 +7947,12 @@
|
|||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/libphonenumber-js": {
|
||||||
|
"version": "1.12.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.6.tgz",
|
||||||
|
"integrity": "sha512-PJiS4ETaUfCOFLpmtKzAbqZQjCCKVu2OhTV4SVNNE7c2nu/dACvtCqj4L0i/KWNnIgRv7yrILvBj5Lonv5Ncxw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/lie": {
|
"node_modules/lie": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
|
||||||
@@ -11099,6 +11123,15 @@
|
|||||||
"node": ">=10.12.0"
|
"node": ">=10.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/validator": {
|
||||||
|
"version": "13.15.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/validator/-/validator-13.15.0.tgz",
|
||||||
|
"integrity": "sha512-36B2ryl4+oL5QxZ3AzD0t5SsMNGvTtQHpjgFO5tbNxfXbMFkY822ktCDe1MnlqV3301QQI9SLHDNJokDI+Z9pA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vary": {
|
"node_modules/vary": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"@nestjs/platform-express": "^11.0.1",
|
"@nestjs/platform-express": "^11.0.1",
|
||||||
"@nestjs/swagger": "^11.0.5",
|
"@nestjs/swagger": "^11.0.5",
|
||||||
"@nestjs/typeorm": "^11.0.0",
|
"@nestjs/typeorm": "^11.0.0",
|
||||||
|
"class-validator": "^0.14.1",
|
||||||
"csv-parser": "^3.2.0",
|
"csv-parser": "^3.2.0",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"exceljs": "^4.4.0",
|
"exceljs": "^4.4.0",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { MailModule } from './mail/mail.module';
|
|||||||
import {ExcelModule} from './excel/excel.module'
|
import {ExcelModule} from './excel/excel.module'
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||||
import { ConfigModule } from '@nestjs/config';
|
import { ConfigModule } from '@nestjs/config';
|
||||||
|
import { SistemaModule } from './sistema/sistema.module';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -28,6 +29,7 @@ import { ConfigModule } from '@nestjs/config';
|
|||||||
|
|
||||||
MailModule,
|
MailModule,
|
||||||
ExcelModule,
|
ExcelModule,
|
||||||
|
SistemaModule,
|
||||||
|
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -30,20 +30,20 @@ export class MailController {
|
|||||||
@Post('send')
|
@Post('send')
|
||||||
@ApiSendMail()
|
@ApiSendMail()
|
||||||
async sendMail(
|
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 }) {
|
@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.
|
// 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
|
// 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');
|
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) {
|
if (!sistem) {
|
||||||
throw new UnauthorizedException('Password incorrecto');
|
throw new UnauthorizedException('Password incorrecto');
|
||||||
@@ -73,7 +73,7 @@ export class MailController {
|
|||||||
throw new UnauthorizedException('Header "Password" es requerido');
|
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) {
|
if (!sistem) {
|
||||||
throw new UnauthorizedException('Password incorrecto');
|
throw new UnauthorizedException('Password incorrecto');
|
||||||
|
|||||||
@@ -10,7 +10,17 @@ export const ApiSendMail = () => {
|
|||||||
- **subject**: Asunto del correo.
|
- **subject**: Asunto del correo.
|
||||||
- **text**: Cuerpo del mensaje.
|
- **text**: Cuerpo del mensaje.
|
||||||
- **fecha_recibido**: Fecha en que se registró la solicitud.
|
- **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({
|
ApiHeader({
|
||||||
name: 'password',
|
name: 'password',
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ import {
|
|||||||
Correo,
|
Correo,
|
||||||
Sistema,
|
Sistema,
|
||||||
}from 'src/typeorm/votacionesPrueba.entity'
|
}from 'src/typeorm/votacionesPrueba.entity'
|
||||||
|
import { SistemaModule } from 'src/sistema/sistema.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
providers: [MailService],
|
providers: [MailService],
|
||||||
imports: [
|
imports: [
|
||||||
ExcelModule,
|
ExcelModule,
|
||||||
|
SistemaModule,
|
||||||
TypeOrmModule.forFeature([
|
TypeOrmModule.forFeature([
|
||||||
Status,
|
Status,
|
||||||
Correo,
|
Correo,
|
||||||
|
|||||||
@@ -19,17 +19,18 @@ export class MailService {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* {
|
/* this.transporter = nodemailer.createTransport({
|
||||||
service: 'gmail',
|
host: 'smtp-relay.gmail.com',
|
||||||
|
port: 587,
|
||||||
|
secure: false,
|
||||||
|
requireTLS: true,
|
||||||
auth: {
|
auth: {
|
||||||
user: process.env.USER_GMAIL,
|
user: process.env.USER_GMAIL,
|
||||||
pass: process.env.PASS_GMAIL,
|
pass: process.env.PASS_GMAIL,
|
||||||
},
|
},
|
||||||
} */
|
}); */
|
||||||
|
|
||||||
|
this.transporter = nodemailer.createTransport({
|
||||||
this.transporter = nodemailer.createTransport(
|
|
||||||
{
|
|
||||||
host: 'smtp.gmail.com', // o smtp‑relay.gmail.com (ver punto 2)
|
host: 'smtp.gmail.com', // o smtp‑relay.gmail.com (ver punto 2)
|
||||||
port: 587,
|
port: 587,
|
||||||
secure: false,
|
secure: false,
|
||||||
@@ -40,9 +41,24 @@ export class MailService {
|
|||||||
maxMessages: 100, // reabrir después de 100 envíos
|
maxMessages: 100, // reabrir después de 100 envíos
|
||||||
rateDelta: 2000, // ventana 1 s
|
rateDelta: 2000, // ventana 1 s
|
||||||
rateLimit: 1 // máx. 5 mensajes/seg
|
rateLimit: 1 // máx. 5 mensajes/seg
|
||||||
}
|
});
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
|
/* this.transporter = nodemailer.createTransport({
|
||||||
|
host: 'smtp-relay.gmail.com', // o smtp‑relay.gmail.com (ver punto 2)
|
||||||
|
port: 587,
|
||||||
|
secure: false,
|
||||||
|
requireTLS: true, // TLS STARTTLS
|
||||||
|
//auth: { user: process.env.USER_GMAIL, pass: process.env.PASS_GMAIL },
|
||||||
|
name:"acatlan.unam.mx",
|
||||||
|
|
||||||
|
pool: true, // <‑‑ activa reuse
|
||||||
|
maxConnections: 1, // una sola conexión viva
|
||||||
|
maxMessages: 100, // reabrir después de 100 envíos
|
||||||
|
rateDelta: 2000, // ventana 1 s
|
||||||
|
rateLimit: 1 // máx. 5 mensajes/seg
|
||||||
|
}); */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -99,6 +115,10 @@ export class MailService {
|
|||||||
|
|
||||||
|
|
||||||
let resMail = await this.transporter.sendMail(mailOptions);
|
let resMail = await this.transporter.sendMail(mailOptions);
|
||||||
|
|
||||||
|
console.log("este es el resultado del envio",resMail);
|
||||||
|
//console.log("este es el resultado del envio",resMail.accepted.length);
|
||||||
|
|
||||||
const statusTexto = resMail.accepted.length > 0 ? "Enviado" : "Fallido";
|
const statusTexto = resMail.accepted.length > 0 ? "Enviado" : "Fallido";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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';
|
import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne, JoinColumn } from 'typeorm';
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
@@ -5,12 +6,15 @@ export class Sistema {
|
|||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id_sistema: number;
|
id_sistema: number;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50 })
|
@Column({ type: 'varchar', length: 255, nullable: true })
|
||||||
password: string;
|
token: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 50 })
|
@Column({ type: 'varchar', length: 50 })
|
||||||
nombre_sistema: string;
|
nombre_sistema: string;
|
||||||
|
|
||||||
|
@Column({ type: 'varchar', length: 50 })
|
||||||
|
ip:string
|
||||||
|
|
||||||
@OneToMany(() => Correo, (correo) => correo.id_sistema)
|
@OneToMany(() => Correo, (correo) => correo.id_sistema)
|
||||||
correos: Correo[];
|
correos: Correo[];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user