operador mejorado antes de meterme con auth

This commit is contained in:
lemuel 2022-10-15 22:24:22 -05:00
parent cc0f3e8773
commit 132d1b18d9
9 changed files with 79 additions and 75 deletions

View File

@ -84,7 +84,7 @@ import { InformacionModuloView } from './modulo/entity/views/informacion-modulo.
import { MinInformacionModuloView } from './modulo/entity/views/min-informacion-modulo.view';
import { FullInformacionMultaView } from './multa/entity/views/full-informacion-multa.view';
import { InformacionMultaView } from './multa/entity/views/informacion-multa.view';
import { InformacionOperadorView } from './operador/entity/views/informacion-operador.view';
import { FullInformacionOperadorView } from './operador/entity/views/full-informacion-operador.view';
import { FullInformacionPrestamoView } from './prestamo/entity/views/full-informacion-prestamo.view';
import { PrestamoInformacionView } from './prestamo/entity/views/prestamo-informacion.view';
import { InformacionPrestamoView } from './prestamo/entity/views/informacion-prestamo.view';
@ -161,7 +161,7 @@ import { InformacionUsuarioView } from './usuario/entity/views/informacion-usuar
MinInformacionModuloView,
FullInformacionMultaView,
InformacionMultaView,
InformacionOperadorView,
FullInformacionOperadorView,
FullInformacionPrestamoView,
PrestamoInformacionView,
InformacionPrestamoView,

View File

@ -34,7 +34,7 @@ export class JwtStrategyService extends PassportStrategy(Strategy) {
.then((usuario) => (user.usuario = usuario));
else if (payload.id_operador)
await this.operadorService
.findById(payload.id_operador)
.findInfoOperadorById(payload.id_operador)
.then(async (operador) => {
if (!operador.activo)
throw new ForbiddenException('Esta cuenta esta desactivada.');

View File

@ -30,7 +30,7 @@ export class EquipoMotivoService {
const ahora = moment();
const operador =
typeof id_operador === 'number'
? await this.operadorService.findById(id_operador)
? await this.operadorService.findInfoOperadorById(id_operador)
: id_operador;
const status =
typeof id_status === 'number'

View File

@ -46,7 +46,7 @@ export class MultaService {
: id_prestamo;
const operador =
typeof id_operador === 'number'
? await this.operadorService.findById(id_operador)
? await this.operadorService.findInfoOperadorById(id_operador)
: id_operador;
const data: DeepPartial<Multa> = {
descripcion,

View File

@ -1,7 +1,7 @@
import { DataSource, ViewEntity, ViewColumn } from 'typeorm';
import { Institucion } from '../../../institucion/entity/institucion.entity';
import { TipoUsuario } from '../../../tipo-usuario/entity/tipo-usuario.entity';
import { Operador } from '../operador.entity';
import { TipoUsuario } from '../../../tipo-usuario/entity/tipo-usuario.entity';
@ViewEntity({
expression: (dataSource: DataSource) =>
@ -14,9 +14,13 @@ import { Operador } from '../operador.entity';
.addSelect('o.nombre', 'nombre')
.addSelect('o.operador', 'operador')
.addSelect('o.password', 'password')
.from(Operador, 'o'),
.addSelect('i.institucion', 'institucion')
.addSelect('tu.tipo_usuario', 'tipo_usuario')
.from(Operador, 'o')
.innerJoin(Institucion, 'i', 'i.id_institucion = o.id_institucion')
.innerJoin(TipoUsuario, 'tu', 'tu.id_tipo_usuario = o.id_tipo_usuario'),
})
export class InformacionOperadorView {
export class FullInformacionOperadorView {
@ViewColumn()
id_operador: number;
@ -29,6 +33,9 @@ export class InformacionOperadorView {
@ViewColumn()
id_tipo_usuario: number;
@ViewColumn()
institucion: string;
@ViewColumn()
nombre: string;
@ -37,4 +44,7 @@ export class InformacionOperadorView {
@ViewColumn()
password: string;
@ViewColumn()
tipo_usuario: string;
}

View File

@ -154,11 +154,6 @@ export class OperadorController {
);
}
// @Get('reporte')
// @UseGuards(AuthGuard('jwt'))
// @ApiBearerAuth('jwt')
// reporte() {}
@Put()
@UseGuards(AuthGuard('jwt'))
@ApiOperation({

View File

@ -4,7 +4,7 @@ import { TypeOrmModule } from '@nestjs/typeorm';
import { OperadorController } from './operador.controller';
import { OperadorService } from './operador.service';
import { Operador } from './entity/operador.entity';
import { InformacionOperadorView } from './entity/views/informacion-operador.view';
import { FullInformacionOperadorView } from './entity/views/full-informacion-operador.view';
import { BcryptModule } from '../bcrypt/bcrypt.module';
import { InstitucionModule } from '../institucion/institucion.module';
import { NodemailerModule } from '../nodemailer/nodemailer.module';
@ -18,7 +18,7 @@ import { ValidarUsuarioModule } from '../validar-usuario/validar-usuario.module'
NodemailerModule,
PassportModule.register({ defaultStrategy: 'jwt' }),
TipoUsuarioModule,
TypeOrmModule.forFeature([Operador, InformacionOperadorView]),
TypeOrmModule.forFeature([Operador, FullInformacionOperadorView]),
ValidarUsuarioModule,
],
controllers: [OperadorController],

View File

@ -7,7 +7,7 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Between, Repository } from 'typeorm';
import { Institucion } from '../institucion/entity/institucion.entity';
import { Operador } from './entity/operador.entity';
import { InformacionOperadorView } from './entity/views/informacion-operador.view';
import { FullInformacionOperadorView } from './entity/views/full-informacion-operador.view';
import { BcryptService } from '../bcrypt/bcrypt.service';
import { InstitucionService } from '../institucion/institucion.service';
import { NodemailerService } from '../nodemailer/nodemailer.service';
@ -17,8 +17,8 @@ import { TipoUsuarioService } from '../tipo-usuario/tipo-usuario.service';
export class OperadorService {
constructor(
@InjectRepository(Operador) private repository: Repository<Operador>,
@InjectRepository(InformacionOperadorView)
private informacionOperadorView: Repository<InformacionOperadorView>,
@InjectRepository(FullInformacionOperadorView)
private fullInformacionOperadorView: Repository<FullInformacionOperadorView>,
private bcryptService: BcryptService,
private institucionService: InstitucionService,
private nodemailerService: NodemailerService,
@ -39,24 +39,38 @@ export class OperadorService {
: id_institucion;
const tipoUsuario = await this.tipoUsuarioService.findById(id_tipo_usuario);
// Solo se puede crear admins y operadores
if (tipoUsuario.id_tipo_usuario < 3 || tipoUsuario.id_tipo_usuario > 4)
throw new ConflictException(
'No se puede asignar un tipo de usuario distinto a admin y operador',
);
return this.findAdmin(operador, false)
// Ver que ningún admin tenga este usuario
return this.repository
.findOne({
select: ['id_operador'],
where: {
operador,
tipoUsuario: { id_tipo_usuario: Between(2, 3) },
},
})
.then((existeAdmin) => {
// Error si lo hay
if (existeAdmin)
throw new ConflictException(
'Ya existe un admin con ese nombre, intenta de nuevo con otro.',
);
return this.findByOperador(institucion, operador, false);
// Ver que no haya un operador en esta institución con este usuario
return this.repository.findOne({ where: { institucion, operador } });
})
.then(async (existeOperador) => {
// Error si lo hay
if (existeOperador)
throw new ConflictException(
'Ya existe un operador en esta institución con ese nombre, intenta de nuevo con otro.',
);
// Crear password si no se mandó
if (!password) password = this.bcryptService.generarPassword();
// Crear registro
return this.repository.save(
this.repository.create({
correo,
@ -69,6 +83,7 @@ export class OperadorService {
);
})
.then((operador) =>
// Correo con credenciales
this.nodemailerService.sendEmail({
email: operador.correo,
subject: 'Credenciales Pc Puma',
@ -89,21 +104,6 @@ export class OperadorService {
}));
}
findAdmin(admin: string, validarNoExiste = true) {
return this.repository
.findOne({
where: {
operador: admin,
tipoUsuario: { id_tipo_usuario: Between(2, 3) },
},
})
.then((admin) => {
if (validarNoExiste && !admin)
throw new NotFoundException('No existe este admin.');
return admin;
});
}
async findAll(filtros: {
pagina: string;
id_institucion?: string;
@ -146,9 +146,17 @@ export class OperadorService {
return query.getManyAndCount();
}
findById(id_operador: number) {
findInfoOperadorById(id_operador: number) {
return this.repository
.findOne({ where: { id_operador } })
.findOne({
select: {
id_operador: true,
activo: true,
institucion: { id_institucion: true },
tipoUsuario: { id_tipo_usuario: true },
},
where: { id_operador },
})
.then((operador) => {
if (!operador)
throw new NotFoundException('No existe este id operador.');
@ -156,27 +164,8 @@ export class OperadorService {
});
}
async findByOperador(
id_institucion: number | Institucion,
operador: string,
validarNoExiste = true,
) {
const institucion =
typeof id_institucion === 'number'
? await this.institucionService.findInfoInstitucionById(id_institucion)
: id_institucion;
return this.repository
.findOne({ where: { institucion, operador } })
.then((operador) => {
if (validarNoExiste && !operador)
throw new NotFoundException('No existe este operador.');
return operador;
});
}
informacionAdmin(admin: string) {
return this.informacionOperadorView
return this.fullInformacionOperadorView
.findOne({
where: {
operador: admin,
@ -202,7 +191,7 @@ export class OperadorService {
}
informacionOperador(institucion: Institucion, operador: string) {
return this.informacionOperadorView
return this.fullInformacionOperadorView
.findOne({
where: { operador, id_institucion: institucion.id_institucion },
})
@ -232,14 +221,18 @@ export class OperadorService {
}
passwordReset(admin: Operador, id_operador: number, password?: string) {
return this.findById(id_operador)
return this.findInfoOperadorById(id_operador)
.then((operador) => {
this.validarUpdate(admin, operador);
// Si no se manda una password se genera una
if (!password) password = this.bcryptService.generarPassword();
// Encriptación
operador.password = this.bcryptService.encriptar(password);
// Guardar
return this.repository.save(operador);
})
.then((operador) =>
// Reenviar correo
this.nodemailerService.sendEmail({
email: operador.correo,
subject: 'Credenciales PC Puma',
@ -255,24 +248,23 @@ export class OperadorService {
),
}),
)
.then((_) => ({
message: 'Se cambió correctamente la constraseña.',
}));
.then((_) => ({ message: 'Se cambió correctamente la constraseña.' }));
}
update(admin: Operador, attrs: Partial<Operador>) {
return this.findById(attrs.id_operador)
return this.findInfoOperadorById(attrs.id_operador)
.then((operador) => {
this.validarUpdate(admin, operador);
// Paso los valores enviados del front a mi objeto
Object.assign(operador, attrs);
// Guardar
return this.repository.save(operador);
})
.then((_) => ({
message: 'Se guardaron los cambios correctamente.',
}));
.then((_) => ({ message: 'Se guardaron los cambios correctamente.' }));
}
validarUpdate(admin: Operador, operador: Operador) {
// Valido que el super admin solo puedar modificar admins
if (
admin.tipoUsuario.id_tipo_usuario === 2 &&
operador.tipoUsuario.id_tipo_usuario != 3
@ -280,12 +272,19 @@ export class OperadorService {
throw new ConflictException(
`El super admin solo puede modificar la infomración de los admins.`,
);
if (
admin.tipoUsuario.id_tipo_usuario === 3 &&
admin.institucion.id_institucion != operador.institucion.id_institucion
)
throw new ConflictException(
`No puedes actualizar la información de este ${operador.tipoUsuario.tipo_usuario.toLowerCase()} porque no pertenece a tu institución.`,
);
if (admin.tipoUsuario.id_tipo_usuario === 3) {
// Valido admin no pueda modificar admins
if (operador.tipoUsuario.id_tipo_usuario === 3)
throw new ConflictException(
`No puedes actualizar la información de otro admin.`,
);
// Valido que admin solo pueda modificar operadores de su institución
if (
admin.institucion.id_institucion != operador.institucion.id_institucion
)
throw new ConflictException(
`No puedes actualizar la información de este operador porque no pertenece a tu institución.`,
);
}
}
}

View File

@ -450,12 +450,12 @@ export class PrestamoService {
? await this.moduloService.findInfoModuloById(parseInt(filtros.id_modulo))
: null;
const operadorEntrega = filtros.id_operador_entrega
? await this.operadorService.findById(
? await this.operadorService.findInfoOperadorById(
parseInt(filtros.id_operador_entrega),
)
: null;
const operadorRegreso = filtros.id_operador_regreso
? await this.operadorService.findById(
? await this.operadorService.findInfoOperadorById(
parseInt(filtros.id_operador_regreso),
)
: null;