production-evyos-systems-an.../ServicesApi/src/auth/login/login.service.ts

166 lines
4.9 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import { userLoginValidator } from '@/src/auth/login/dtoValidator';
import { RedisHandlers } from '@/src/utils/auth/redis_handlers';
import { PasswordHandlers } from '@/src/utils/auth/login_handler';
import { PrismaService } from '@/src/prisma.service';
import { AuthTokenSchema } from '@/src/types/auth/token';
@Injectable()
export class LoginService {
constructor(
private readonly redis: RedisHandlers,
private readonly passHandlers: PasswordHandlers,
private readonly prisma: PrismaService,
) {}
async run(dto: userLoginValidator) {
const foundUser = await this.prisma.users.findFirstOrThrow({
where: { email: dto.accessKey },
});
if (foundUser.password_token) {
throw new Error('Password need to be set first');
}
const isPasswordValid = this.passHandlers.check_password(
foundUser.uu_id,
dto.password,
foundUser.hash_password,
);
if (!isPasswordValid) {
throw new Error('Invalid password');
}
const foundPerson = await this.prisma.people.findFirstOrThrow({
where: { id: foundUser.id },
});
const alreadyExists = await this.redis.callExistingLoginToken(
foundUser.uu_id,
);
if (alreadyExists) {
return {
token: alreadyExists,
message: 'User already logged in',
};
} else {
let selectList: any[] = [];
if (foundUser.user_type === 'occupant') {
const livingSpaces = await this.prisma.build_living_space.findMany({
where: { people: { id: foundPerson.id } },
orderBy: {
build_parts: {
build: {
id: 'asc',
},
},
},
select: {
uu_id: true,
occupant_types: {
select: {
uu_id: true,
occupant_code: true,
occupant_type: true,
function_retriever: true,
},
},
build_parts: {
select: {
uu_id: true,
part_code: true,
part_no: true,
part_level: true,
human_livable: true,
api_enum_dropdown_build_parts_part_type_idToapi_enum_dropdown: {
select: {
uu_id: true,
enum_class: true,
value: true,
},
},
build: {
select: {
uu_id: true,
build_name: true,
},
},
},
},
},
});
selectList = livingSpaces;
} else if (foundUser.user_type === 'employee') {
const employees = await this.prisma.employees.findMany({
where: { people: { id: foundPerson.id } },
orderBy: {
staff: {
duties: {
departments: {
companies: {
formal_name: 'asc',
},
},
},
},
},
select: {
uu_id: true,
staff: {
select: {
uu_id: true,
staff_code: true,
function_retriever: true,
duties: {
select: {
uu_id: true,
departments: {
select: {
uu_id: true,
department_code: true,
department_name: true,
companies: {
select: {
uu_id: true,
formal_name: true,
public_name: true,
addresses: {
select: {
comment_address: true,
},
},
},
},
},
},
},
},
},
},
},
});
selectList = employees;
}
const redisData = AuthTokenSchema.parse({
people: foundPerson,
users: foundUser,
credentials: {
person_uu_id: foundPerson.uu_id,
person_name: foundPerson.firstname,
person_full_name: `${foundPerson.firstname} ${foundPerson.middle_name || ''} | ${foundPerson.birthname || ''} | ${foundPerson.surname}`,
},
selectionList: {
type: foundUser.user_type,
list: selectList,
},
});
const accessToken = await this.redis.setLoginToRedis(
redisData,
foundUser.uu_id,
);
return {
token: accessToken,
message: 'Login successful',
};
}
}
}