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

255 lines
7.2 KiB
TypeScript

import {
Injectable,
BadRequestException,
UnauthorizedException,
NotAcceptableException,
} from '@nestjs/common';
import { userSelectValidator } from '@/src/auth/select/dtoValidator';
import { RedisHandlers } from '@/src/utils/auth/redis_handlers';
import {
EmployeeTokenSchema,
OccupantTokenSchema,
TokenDictInterface,
UserType,
} from '@/src/types/auth/token';
import { PrismaService } from '@/src/prisma.service';
@Injectable()
export class SelectService {
constructor(
private readonly redis: RedisHandlers,
private readonly prisma: PrismaService,
) {}
async run(dto: userSelectValidator, req: Request) {
const accessObject = await this.redis.getLoginFromRedis(req);
if (!accessObject) {
throw new UnauthorizedException(
'Authorization failed. Please login to continue',
);
}
const accessToken = accessObject.key.split(':')[1];
const existingSelectToken = await this.redis.callExistingSelectToken(
accessObject.value.users.uu_id,
dto.uuid,
);
if (existingSelectToken) {
return {
message: 'Select successful',
token: existingSelectToken,
};
}
const userType = accessObject.value.users.user_type;
if (userType === 'employee') {
const employee = await this.prisma.employees.findFirstOrThrow({
where: { uu_id: dto.uuid },
omit: {
id: true,
},
});
const staff = await this.prisma.staff.findFirstOrThrow({
where: { id: employee.staff_id },
omit: {
id: true,
},
});
const duties = await this.prisma.duties.findFirstOrThrow({
where: { id: staff.duties_id },
omit: {
id: true,
},
});
const department = await this.prisma.departments.findFirstOrThrow({
where: { id: duties.department_id },
omit: {
id: true,
},
});
const duty = await this.prisma.duty.findFirstOrThrow({
where: { id: duties.duties_id },
omit: {
id: true,
},
});
const company = await this.prisma.companies.findFirstOrThrow({
where: { id: duties.company_id },
omit: {
id: true,
},
});
const employeeToken = EmployeeTokenSchema.parse({
company: company,
department: department,
duty: duty,
employee: employee,
staff: staff,
menu: null,
pages: null,
selection: await this.prisma.employees.findFirstOrThrow({
where: { uu_id: dto.uuid },
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,
},
},
},
},
},
},
},
},
},
},
},
}),
functionsRetriever: staff.function_retriever,
kind: UserType.employee,
});
const tokenSelect = await this.redis.setSelectToRedis(
accessToken,
employeeToken,
accessObject.value.users.uu_id,
dto.uuid,
);
return {
message: 'Select successful',
token: tokenSelect,
};
} else if (userType === 'occupant') {
const livingSpace = await this.prisma.build_living_space.findFirstOrThrow(
{
where: { uu_id: dto.uuid },
omit: {
id: true,
person_id: true,
build_parts_id: true,
occupant_type_id: true,
ref_id: true,
replication_id: true,
cryp_uu_id: true,
},
},
);
const occupantType = await this.prisma.occupant_types.findFirstOrThrow({
where: { uu_id: livingSpace.occupant_type_uu_id },
omit: {
id: true,
cryp_uu_id: true,
ref_id: true,
replication_id: true,
},
});
const part = await this.prisma.build_parts.findFirstOrThrow({
where: { uu_id: livingSpace.build_parts_uu_id },
omit: {
id: true,
cryp_uu_id: true,
ref_id: true,
replication_id: true,
},
});
const build = await this.prisma.build.findFirstOrThrow({
where: { uu_id: part.build_uu_id },
omit: {
id: true,
cryp_uu_id: true,
ref_id: true,
replication_id: true,
},
});
const company = await this.prisma.companies.findFirstOrThrow({
where: { uu_id: accessObject.value.users.related_company },
omit: {
id: true,
cryp_uu_id: true,
ref_id: true,
replication_id: true,
},
});
const occupantToken = OccupantTokenSchema.parse({
livingSpace: livingSpace,
occupant: occupantType,
build: build,
part: part,
company: company,
menu: null,
pages: null,
config: null,
caches: null,
selection: await this.prisma.build_living_space.findFirstOrThrow({
where: { uu_id: dto.uuid },
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,
},
},
},
},
},
}),
functionsRetriever: occupantType.function_retriever,
kind: UserType.occupant,
});
const tokenSelect = await this.redis.setSelectToRedis(
accessToken,
occupantToken,
accessObject.value.users.uu_id,
dto.uuid,
);
return {
message: 'Select successful',
token: tokenSelect,
};
} else {
throw new NotAcceptableException('Invalid user type');
}
}
}