166 lines
4.9 KiB
TypeScript
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',
|
|
};
|
|
}
|
|
}
|
|
}
|