nuevo operador listo

This commit is contained in:
lemuel 2022-10-15 23:51:56 -05:00
parent 132d1b18d9
commit b383da979f
11 changed files with 190 additions and 207 deletions

View File

@ -77,10 +77,8 @@ export class AuthController {
@Get('validar-token')
@UseGuards(AuthGuard('jwt'))
@ApiOperation({
description: 'Endpoint utilizado para validar un token.',
})
@ApiOperation({ description: 'Endpoint utilizado para validar un token.' })
validarToken() {
return true;
return { valido: true };
}
}

View File

@ -4,10 +4,14 @@ import {
UnauthorizedException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { Operador } from '../operador/entity/operador.entity';
import { BcryptService } from '../bcrypt/bcrypt.service';
import { ModuloService } from '../modulo/modulo.service';
import { OperadorService } from '../operador/operador.service';
import { UsuarioService } from '../usuario/usuario.service';
import { JwtPayloadAdmin } from './dto/jwt-payload-admin';
import { JwtPayloadOperador } from './dto/jwt-payload-operador';
import { JwtPayloadUsuario } from './dto/jwt-payload-usuario';
@Injectable()
export class AuthService {
@ -20,19 +24,23 @@ export class AuthService {
) {}
loginAdmin(admin: string, password: string) {
return this.operadorService.informacionAdmin(admin).then((data) => {
if (
!data.operador ||
!this.bcryptService.comparar(password, data.password)
)
throw new BadRequestException(
'Usuario y/o password incorrectos, ingresa unas credenciales válidas.',
);
if (!data.activo)
throw new UnauthorizedException(
'Esta cuenta se encuentra desactivada.',
);
return { token: this.jwtService.sign(data.operador) };
return this.operadorService.findInfoOperadorAdmin(admin).then((admin) => {
this.validacionBasica(admin, password);
const JwtPayload: JwtPayloadAdmin = {
Operador: {
id_operador: admin.id_operador,
operador: admin.operador,
nombre: admin.nombre,
institucion: {
id_institucion: admin.institucion.id_institucion,
},
tipoUsuario: {
id_tipo_usuario: admin.tipoUsuario.id_tipo_usuario,
},
},
};
return { token: this.jwtService.sign(JwtPayload) };
});
}
@ -40,22 +48,27 @@ export class AuthService {
const modulo = await this.moduloService.findInfoModuloById(id_modulo);
return this.operadorService
.informacionOperador(modulo.institucion, operador)
.then((data) => {
if (
!data.operador ||
!this.bcryptService.comparar(password, data.password)
)
throw new BadRequestException(
'Usuario y/o password incorrectos, ingresa unas credenciales válidas.',
);
if (!data.activo)
throw new UnauthorizedException(
'Esta cuenta se encuentra desactivada.',
);
if (data.operador.tipoUsuario.id_tipo_usuario === 4)
data.operador.id_modulo = modulo.id_modulo;
return { token: this.jwtService.sign(data.operador) };
.findInfoOperador(modulo.institucion, operador)
.then((operador) => {
this.validacionBasica(operador, password);
const JwtPayload: JwtPayloadOperador = {
Operador: {
id_operador: operador.id_operador,
operador: operador.operador,
nombre: operador.nombre,
institucion: {
id_institucion: operador.institucion.id_institucion,
},
tipoUsuario: {
id_tipo_usuario: operador.tipoUsuario.id_tipo_usuario,
},
},
};
if (operador.tipoUsuario.id_tipo_usuario === 4)
JwtPayload.Modulo.id_modulo = modulo.id_modulo;
return { token: this.jwtService.sign(JwtPayload) };
});
}
@ -75,4 +88,13 @@ export class AuthService {
return { token: this.jwtService.sign(data.usuario) };
});
}
private validacionBasica(operador: Operador, password: string) {
if (!operador || !this.bcryptService.comparar(password, operador.password))
throw new BadRequestException(
'Usuario y/o password incorrectos, ingresa unas credenciales válidas.',
);
if (!operador.activo)
throw new UnauthorizedException('Esta cuenta se encuentra desactivada.');
}
}

View File

@ -1,11 +1,9 @@
export class JwtPayload {
nombre: string;
id_operador: number;
institucion: { id_institucion: number };
operador: string;
tipoUsuario: { id_tipo_usuario: number };
export interface JwtPayloadAdmin {
Operador: {
id_operador: number;
nombre: string;
operador: string;
institucion: { id_institucion: number };
tipoUsuario: { id_tipo_usuario: number };
};
}

View File

@ -1,13 +1,10 @@
export class JwtPayload {
nombre: string;
id_modulo: number;
id_operador: number;
institucion: { id_institucion: number };
operador: string;
tipoUsuario: { id_tipo_usuario: number };
export interface JwtPayloadOperador {
Operador: {
id_operador: number;
nombre: string;
operador: string;
institucion: { id_institucion: number };
tipoUsuario: { id_tipo_usuario: number };
};
Modulo?: { id_modulo: number };
}

View File

@ -1,18 +1,8 @@
export class JwtPayload {
nombre: string;
id_usuario: number;
instituciones: {
id_institucion_usuario: number;
institucionCarrera: {
id_institucion_carrera: number;
institucion: { id_institucion: number };
carrera: { id_carrera: number };
};
}[];
tipoUsuario: { id_tipo_usuario: number };
usuario: string;
export interface JwtPayloadUsuario {
Usuario: {
id_usuario: number;
nombre: string;
usuario: string;
tipoUsuario: { id_tipo_usuario: number };
};
}

View File

@ -1,26 +0,0 @@
export class JwtPayload {
nombre: string;
tipoUsuario: { id_tipo_usuario: number };
id_modulo?: number;
id_operador?: number;
id_usuario?: number;
operador?: string;
usuario?: string;
institucion?: { id_institucion: number };
instituciones?: {
id_institucion_usuario: number;
institucionCarrera: {
id_institucion_carrera: number;
institucion: { id_institucion: number };
carrera: { id_carrera: number };
};
}[];
}

View File

@ -8,7 +8,9 @@ import { UsuarioService } from '../../usuario/usuario.service';
import { Modulo } from '../../modulo/entity/modulo.entity';
import { Operador } from '../../operador/entity/operador.entity';
import { Usuario } from '../../usuario/entity/usuario.entity';
import { JwtPayload } from '../dto/jwt-payload';
import { JwtPayloadAdmin } from '../dto/jwt-payload-admin';
import { JwtPayloadOperador } from '../dto/jwt-payload-operador';
import { JwtPayloadUsuario } from '../dto/jwt-payload-usuario';
@Injectable()
export class JwtStrategyService extends PassportStrategy(Strategy) {
@ -24,32 +26,32 @@ export class JwtStrategyService extends PassportStrategy(Strategy) {
});
}
async validate(payload: JwtPayload) {
async validate(
payload: JwtPayloadAdmin | JwtPayloadOperador | JwtPayloadUsuario,
) {
const user: { modulo?: Modulo; usuario?: Usuario; operador?: Operador } =
{};
if (payload.id_usuario)
if ('Usuario' in payload)
await this.usuarioService
.findById(payload.id_usuario, true, true)
.findById(payload.Usuario.id_usuario, true, true)
.then((usuario) => (user.usuario = usuario));
else if (payload.id_operador)
else if ('Operador' in payload)
await this.operadorService
.findInfoOperadorById(payload.id_operador)
.findInfoOperadorById(payload.Operador.id_operador)
.then(async (operador) => {
if (!operador.activo)
throw new ForbiddenException('Esta cuenta esta desactivada.');
/*
if (operador.tipoUsuario.id_tipo_usuario === 4) {
if (payload.id_modulo)
if ('Modulo' in payload)
await this.moduloService
.findById(payload.id_modulo)
.findInfoModuloById(payload.Modulo.id_modulo)
.then((modulo) => (user.modulo = modulo));
else
throw new ForbiddenException(
'Credenciales no válidas, inicia sesión de nuevo.',
);
}
*/
user.operador = operador;
});
return user;

View File

@ -32,15 +32,11 @@ export class Operador {
@Column({ type: String, nullable: false, length: 60 })
password: string;
@ManyToOne(() => Institucion, (institucion) => institucion.operadores, {
eager: true,
})
@ManyToOne(() => Institucion, (institucion) => institucion.operadores)
@JoinColumn({ name: 'id_institucion' })
institucion: Institucion;
@ManyToOne(() => TipoUsuario, (tipoUsuario) => tipoUsuario.operadores, {
eager: true,
})
@ManyToOne(() => TipoUsuario, (tipoUsuario) => tipoUsuario.operadores)
@JoinColumn({ name: 'id_tipo_usuario' })
tipoUsuario: TipoUsuario;

View File

@ -18,7 +18,10 @@ import { TipoUsuario } from '../../../tipo-usuario/entity/tipo-usuario.entity';
.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'),
.innerJoin(TipoUsuario, 'tu', 'tu.id_tipo_usuario = o.id_tipo_usuario')
.orderBy('institucion')
.addOrderBy('tipo_usuario')
.addOrderBy('operador'),
})
export class FullInformacionOperadorView {
@ViewColumn()

View File

@ -130,7 +130,22 @@ export class OperadorController {
const admin: Operador = req.user.operador;
this.validarUsuarioService.validarSuperAdminAdmin(admin);
return this.operadorService.findAll(query);
return this.operadorService.findFullInfoOperadorAll(query);
}
@Serealize(OperadorOutputDto)
@Get('catalogo')
@UseGuards(AuthGuard('jwt'))
@ApiOperation({
description:
'Endpoint que retorna todo el catálogo de operadores de una institucion.',
})
@ApiBearerAuth('jwt')
catalogo(@Request() req) {
const admin: Operador = req.user.operador;
this.validarUsuarioService.validarSuperAdminAdmin(admin);
return this.operadorService.findAllByInstitucion(admin);
}
@Put('update-password')

View File

@ -4,7 +4,7 @@ import {
NotFoundException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Between, Repository } from 'typeorm';
import { Between, FindOptionsWhere, Like, Not, Repository } from 'typeorm';
import { Institucion } from '../institucion/entity/institucion.entity';
import { Operador } from './entity/operador.entity';
import { FullInformacionOperadorView } from './entity/views/full-informacion-operador.view';
@ -44,23 +44,16 @@ export class OperadorService {
throw new ConflictException(
'No se puede asignar un tipo de usuario distinto a admin y operador',
);
// Ver que ningún admin tenga este usuario
return this.repository
.findOne({
select: ['id_operador'],
where: {
operador,
tipoUsuario: { id_tipo_usuario: Between(2, 3) },
},
})
// Ver si existe un admin con ese usaurio
return this.findInfoOperadorAdmin(operador)
.then((existeAdmin) => {
// Error si lo hay
if (existeAdmin)
throw new ConflictException(
'Ya existe un admin con ese nombre, intenta de nuevo con otro.',
);
// Ver que no haya un operador en esta institución con este usuario
return this.repository.findOne({ where: { institucion, operador } });
// Ver que haya un operador en esta institución con este usuario
return this.findInfoOperador(institucion, operador);
})
.then(async (existeOperador) => {
// Error si lo hay
@ -104,7 +97,14 @@ export class OperadorService {
}));
}
async findAll(filtros: {
findAllByInstitucion(operador: Operador) {
return this.repository.find({
select: ['id_operador', 'operador'],
where: { institucion: operador.institucion },
});
}
async findFullInfoOperadorAll(filtros: {
pagina: string;
id_institucion?: string;
id_tipo_usuario?: string;
@ -120,30 +120,74 @@ export class OperadorService {
parseInt(filtros.id_tipo_usuario),
)
: null;
const query = this.repository
.createQueryBuilder('o')
.innerJoinAndSelect('o.institucion', 'i')
.innerJoinAndSelect('o.tipoUsuario', 'tu')
.where('id_operador != 1 AND id_operador != 2')
.orderBy('i.institucion')
.addOrderBy('tu.tipo_usuario')
.addOrderBy('o.operador')
.take(25)
.skip((parseInt(filtros.pagina) - 1) * 25);
const busqueda: FindOptionsWhere<FullInformacionOperadorView> = {};
if (filtros.operador)
query.andWhere('operador LIKE :operador', {
operador: `${filtros.operador}%`,
if (filtros.operador) busqueda.operador = Like(`${filtros.operador}%`);
if (institucion) busqueda.id_institucion = institucion.id_institucion;
if (tipoUsuario) busqueda.id_tipo_usuario = tipoUsuario.id_tipo_usuario;
return this.fullInformacionOperadorView
.findAndCount({
where: [
busqueda,
{ id_tipo_usuario: Not(1) },
{ id_tipo_usuario: Not(2) },
],
take: 25,
skip: (parseInt(filtros.pagina) - 1) * 25,
})
.then((infoOperadores) => {
const operadores: Operador[] = [];
for (let i = 0; i < infoOperadores[0].length; i++)
operadores.push(
this.repository.create({
id_operador: infoOperadores[0][i].id_operador,
activo: infoOperadores[0][i].activo,
nombre: infoOperadores[0][i].nombre,
operador: infoOperadores[0][i].operador,
institucion: {
id_institucion: infoOperadores[0][i].id_operador,
institucion: infoOperadores[0][i].institucion,
},
tipoUsuario: {
id_tipo_usuario: infoOperadores[0][i].id_tipo_usuario,
tipo_usuario: infoOperadores[0][i].tipo_usuario,
},
}),
);
return [operadores];
});
if (institucion)
query.andWhere('i.id_institucion = :id_institucion', {
id_institucion: institucion.id_institucion,
});
if (tipoUsuario)
query.andWhere('tu.id_tipo_usuario = :id_tipo_usuario', {
id_tipo_usuario: tipoUsuario.id_tipo_usuario,
});
return query.getManyAndCount();
}
findInfoOperador(institucion: Institucion, operador: string) {
return this.repository.findOne({
select: {
id_operador: true,
activo: true,
nombre: true,
password: true,
institucion: { id_institucion: true },
tipoUsuario: { id_tipo_usuario: true },
},
where: { operador, institucion },
});
}
findInfoOperadorAdmin(admin: string) {
return this.repository.findOne({
select: {
id_operador: true,
activo: true,
nombre: true,
password: true,
institucion: { id_institucion: true },
tipoUsuario: { id_tipo_usuario: true },
},
where: {
operador: admin,
tipoUsuario: { id_tipo_usuario: Between(2, 3) },
},
});
}
findInfoOperadorById(id_operador: number) {
@ -164,62 +208,6 @@ export class OperadorService {
});
}
informacionAdmin(admin: string) {
return this.fullInformacionOperadorView
.findOne({
where: {
operador: admin,
id_tipo_usuario: Between(2, 3),
},
})
.then((admin) => {
if (!admin) return { operador: null, activo: null, password: null };
return {
operador: {
id_operador: admin.id_operador,
nombre: admin.nombre,
operador: admin.operador,
institucion: admin.id_institucion
? { id_institucion: admin.id_institucion }
: null,
tipoUsuario: { id_tipo_usuario: admin.id_tipo_usuario },
},
activo: admin.activo,
password: admin.password,
};
});
}
informacionOperador(institucion: Institucion, operador: string) {
return this.fullInformacionOperadorView
.findOne({
where: { operador, id_institucion: institucion.id_institucion },
})
.then((operador) => {
if (!operador) return { operador: null, activo: null, password: null };
const o: {
id_operador: number;
nombre: string;
operador: string;
institucion: { id_institucion: number };
tipoUsuario: { id_tipo_usuario: number };
id_modulo?: number;
} = {
id_operador: operador.id_operador,
nombre: operador.nombre,
operador: operador.operador,
institucion: { id_institucion: operador.id_institucion },
tipoUsuario: { id_tipo_usuario: operador.id_tipo_usuario },
};
return {
operador: o,
activo: operador.activo,
password: operador.password,
};
});
}
passwordReset(admin: Operador, id_operador: number, password?: string) {
return this.findInfoOperadorById(id_operador)
.then((operador) => {