Merge branch 'dev' into create-vistor-password

This commit is contained in:
faris Aljohari
2024-08-12 12:57:29 +03:00
108 changed files with 2031 additions and 681 deletions

View File

@ -1,5 +1,5 @@
import { RoleTypeRepository } from './../../../libs/common/src/modules/role-type/repositories/role.type.repository';
import { UserRoleRepository } from './../../../libs/common/src/modules/user-role/repositories/user.role.repository';
import { UserRoleRepository } from './../../../libs/common/src/modules/user/repositories/user.repository';
import { UserRepository } from '../../../libs/common/src/modules/user/repositories';
import {
BadRequestException,
@ -12,12 +12,14 @@ import { HelperHashService } from '../../../libs/common/src/helper/services';
import { UserLoginDto } from '../dtos/user-login.dto';
import { AuthService } from '../../../libs/common/src/auth/services/auth.service';
import { UserSessionRepository } from '../../../libs/common/src/modules/session/repositories/session.repository';
import { UserOtpRepository } from '../../../libs/common/src/modules/user-otp/repositories/user-otp.repository';
import { UserOtpRepository } from '../../../libs/common/src/modules/user/repositories/user.repository';
import { ForgetPasswordDto, UserOtpDto, VerifyOtpDto } from '../dtos';
import { EmailService } from '../../../libs/common/src/util/email.service';
import { OtpType } from '../../../libs/common/src/constants/otp-type.enum';
import { UserEntity } from '../../../libs/common/src/modules/user/entities/user.entity';
import * as argon2 from 'argon2';
import { differenceInSeconds } from '@app/common/helper/differenceInSeconds';
import { LessThan, MoreThan } from 'typeorm';
@Injectable()
export class UserAuthService {
@ -44,9 +46,17 @@ export class UserAuthService {
);
try {
const { regionUuid, ...rest } = userSignUpDto;
const user = await this.userRepository.save({
...userSignUpDto,
...rest,
password: hashedPassword,
region: regionUuid
? {
uuid: regionUuid,
}
: {
regionName: 'United Arab Emirates',
},
});
return user;
@ -80,41 +90,49 @@ export class UserAuthService {
}
async userLogin(data: UserLoginDto) {
const user = await this.authService.validateUser(data.email, data.password);
try {
const user = await this.authService.validateUser(
data.email,
data.password,
data.regionUuid,
);
if (!user) {
throw new UnauthorizedException('Invalid login credentials.');
}
if (!user) {
throw new UnauthorizedException('Invalid login credentials.');
}
const session = await Promise.all([
await this.sessionRepository.update(
{ userId: user.id },
{
isLoggedOut: true,
},
),
await this.authService.createSession({
const session = await Promise.all([
await this.sessionRepository.update(
{ userId: user.id },
{
isLoggedOut: true,
},
),
await this.authService.createSession({
userId: user.uuid,
loginTime: new Date(),
isLoggedOut: false,
}),
]);
return await this.authService.login({
email: user.email,
userId: user.uuid,
loginTime: new Date(),
isLoggedOut: false,
}),
]);
return await this.authService.login({
email: user.email,
userId: user.uuid,
uuid: user.uuid,
roles: user?.roles?.map((role) => {
return { uuid: role.uuid, type: role.roleType.type };
}),
sessionId: session[1].uuid,
});
uuid: user.uuid,
roles: user?.roles?.map((role) => {
return { uuid: role.uuid, type: role.roleType.type };
}),
sessionId: session[1].uuid,
});
} catch (error) {
throw new BadRequestException('Invalid credentials');
}
}
async deleteUser(uuid: string) {
const user = await this.findOneById(uuid);
if (!user) {
throw new BadRequestException('User does not found');
throw new BadRequestException('User not found');
}
return await this.userRepository.update({ uuid }, { isActive: false });
}
@ -124,7 +142,55 @@ export class UserAuthService {
}
async generateOTP(data: UserOtpDto): Promise<string> {
await this.otpRepository.delete({ email: data.email, type: data.type });
const threeDaysAgo = new Date();
threeDaysAgo.setDate(threeDaysAgo.getDate() - 3);
const userExists = await this.userRepository.exists({
where: {
region: data.regionUuid
? {
uuid: data.regionUuid,
}
: undefined,
email: data.email,
isUserVerified: data.type === OtpType.PASSWORD ? true : undefined,
},
});
if (!userExists) {
throw new BadRequestException('User not found');
}
await this.otpRepository.softDelete({ email: data.email, type: data.type });
await this.otpRepository.delete({
email: data.email,
type: data.type,
createdAt: LessThan(threeDaysAgo),
});
const countOfOtp = await this.otpRepository.count({
withDeleted: true,
where: {
email: data.email,
type: data.type,
createdAt: MoreThan(threeDaysAgo),
},
});
const lastOtp = await this.otpRepository.findOne({
where: { email: data.email, type: data.type },
order: { createdAt: 'DESC' },
withDeleted: true,
});
const cooldown = 30 * Math.pow(2, countOfOtp - 1);
if (lastOtp) {
const now = new Date();
const timeSinceLastOtp = differenceInSeconds(now, lastOtp.createdAt);
if (timeSinceLastOtp < cooldown) {
throw new BadRequestException({
message: `Please wait ${cooldown - timeSinceLastOtp} more seconds before requesting a new OTP.`,
data: {
cooldown: cooldown - timeSinceLastOtp,
},
});
}
}
const otpCode = Math.floor(100000 + Math.random() * 900000).toString();
const expiryTime = new Date();
expiryTime.setMinutes(expiryTime.getMinutes() + 1);