mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-08-26 06:09:41 +00:00
feat: add login and forget password and refactor code
This commit is contained in:
@ -3,7 +3,6 @@ import { ConfigService } from '@nestjs/config';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import * as bcrypt from 'bcrypt';
|
||||
import { Request } from 'express';
|
||||
import { ArrayContains } from 'typeorm';
|
||||
import { CacheService } from '~/common/modules/cache/services';
|
||||
import { OtpScope, OtpType } from '~/common/modules/otp/enums';
|
||||
import { OtpService } from '~/common/modules/otp/services';
|
||||
@ -12,23 +11,15 @@ import { DeviceService, UserService, UserTokenService } from '~/user/services';
|
||||
import { User } from '../../user/entities';
|
||||
import { PASSCODE_REGEX } from '../constants';
|
||||
import {
|
||||
AppleLoginRequestDto,
|
||||
CreateUnverifiedUserRequestDto,
|
||||
CreateUnverifiedUserV2RequestDto,
|
||||
DisableBiometricRequestDto,
|
||||
EnableBiometricRequestDto,
|
||||
ForgetPasswordRequestDto,
|
||||
GoogleLoginRequestDto,
|
||||
LoginRequestDto,
|
||||
SendForgetPasswordOtpRequestDto,
|
||||
SendLoginOtpRequestDto,
|
||||
SetEmailRequestDto,
|
||||
setJuniorPasswordRequestDto,
|
||||
VerifyLoginOtpRequestDto,
|
||||
VerifyUserRequestDto,
|
||||
VerifyUserV2RequestDto,
|
||||
} from '../dtos/request';
|
||||
import { Roles } from '../enums';
|
||||
import { IJwtPayload, ILoginResponse } from '../interfaces';
|
||||
import { removePadding, verifySignature } from '../utils';
|
||||
import { Oauth2Service } from './oauth2.service';
|
||||
@ -49,19 +40,8 @@ export class AuthService {
|
||||
private readonly cacheService: CacheService,
|
||||
private readonly oauth2Service: Oauth2Service,
|
||||
) {}
|
||||
|
||||
async sendRegisterOtp(body: CreateUnverifiedUserRequestDto) {
|
||||
this.logger.log(`Sending OTP to ${body.email}`);
|
||||
const user = await this.userService.findOrCreateUser(body);
|
||||
|
||||
return this.otpService.generateAndSendOtp({
|
||||
userId: user.id,
|
||||
recipient: user.email,
|
||||
scope: OtpScope.VERIFY_EMAIL,
|
||||
otpType: OtpType.EMAIL,
|
||||
});
|
||||
}
|
||||
|
||||
async sendPhoneRegisterOtp(body: CreateUnverifiedUserV2RequestDto) {
|
||||
if (body.email) {
|
||||
const isEmailUsed = await this.userService.findUser({ email: body.email, isEmailVerified: true });
|
||||
if (isEmailUsed) {
|
||||
@ -70,8 +50,13 @@ export class AuthService {
|
||||
}
|
||||
}
|
||||
|
||||
if (body.password !== body.confirmPassword) {
|
||||
this.logger.error('Password and confirm password do not match');
|
||||
throw new BadRequestException('AUTH.PASSWORD_MISMATCH');
|
||||
}
|
||||
|
||||
this.logger.log(`Sending OTP to ${body.countryCode + body.phoneNumber}`);
|
||||
const user = await this.userService.findOrCreateByPhoneNumber(body);
|
||||
const user = await this.userService.findOrCreateUser(body);
|
||||
return this.otpService.generateAndSendOtp({
|
||||
userId: user.id,
|
||||
recipient: user.fullPhoneNumber,
|
||||
@ -81,36 +66,6 @@ export class AuthService {
|
||||
}
|
||||
|
||||
async verifyUser(verifyUserDto: VerifyUserRequestDto): Promise<[ILoginResponse, User]> {
|
||||
this.logger.log(`Verifying user with email ${verifyUserDto.email}`);
|
||||
const user = await this.userService.findUserOrThrow({ email: verifyUserDto.email });
|
||||
|
||||
if (user.isEmailVerified) {
|
||||
this.logger.error(`User with email ${verifyUserDto.email} already verified`);
|
||||
throw new BadRequestException('USER.EMAIL_ALREADY_VERIFIED');
|
||||
}
|
||||
|
||||
const isOtpValid = await this.otpService.verifyOtp({
|
||||
userId: user.id,
|
||||
scope: OtpScope.VERIFY_EMAIL,
|
||||
otpType: OtpType.EMAIL,
|
||||
value: verifyUserDto.otp,
|
||||
});
|
||||
|
||||
if (!isOtpValid) {
|
||||
this.logger.error(`Invalid OTP for user with email ${verifyUserDto.email}`);
|
||||
throw new BadRequestException('OTP.INVALID_OTP');
|
||||
}
|
||||
|
||||
await this.userService.verifyUser(user.id, verifyUserDto);
|
||||
|
||||
await user.reload();
|
||||
|
||||
const tokens = await this.generateAuthToken(user);
|
||||
this.logger.log(`User with email ${verifyUserDto.email} verified successfully`);
|
||||
return [tokens, user];
|
||||
}
|
||||
|
||||
async verifyUserV2(verifyUserDto: VerifyUserV2RequestDto): Promise<[ILoginResponse, User]> {
|
||||
this.logger.log(`Verifying user with phone number ${verifyUserDto.countryCode + verifyUserDto.phoneNumber}`);
|
||||
const user = await this.userService.findUserOrThrow({
|
||||
phoneNumber: verifyUserDto.phoneNumber,
|
||||
@ -134,7 +89,7 @@ export class AuthService {
|
||||
throw new BadRequestException('OTP.INVALID_OTP');
|
||||
}
|
||||
|
||||
await this.userService.verifyUserV2(user.id, verifyUserDto);
|
||||
await this.userService.verifyUser(user.id, verifyUserDto);
|
||||
|
||||
await user.reload();
|
||||
|
||||
@ -143,81 +98,6 @@ export class AuthService {
|
||||
return [tokens, user];
|
||||
}
|
||||
|
||||
async setEmail(userId: string, { email }: SetEmailRequestDto) {
|
||||
this.logger.log(`Setting email for user with id ${userId}`);
|
||||
const user = await this.userService.findUserOrThrow({ id: userId });
|
||||
|
||||
if (user.email) {
|
||||
this.logger.error(`Email already set for user with id ${userId}`);
|
||||
throw new BadRequestException('USER.EMAIL_ALREADY_SET');
|
||||
}
|
||||
|
||||
const existingUser = await this.userService.findUser({ email });
|
||||
|
||||
if (existingUser) {
|
||||
this.logger.error(`Email ${email} already taken`);
|
||||
throw new BadRequestException('USER.EMAIL_ALREADY_TAKEN');
|
||||
}
|
||||
|
||||
return this.userService.setEmail(userId, email);
|
||||
}
|
||||
|
||||
async setPasscode(userId: string, passcode: string) {
|
||||
this.logger.log(`Setting passcode for user with id ${userId}`);
|
||||
const user = await this.userService.findUserOrThrow({ id: userId });
|
||||
|
||||
if (user.password) {
|
||||
this.logger.error(`Passcode already set for user with id ${userId}`);
|
||||
throw new BadRequestException('AUTH.PASSCODE_ALREADY_SET');
|
||||
}
|
||||
const salt = bcrypt.genSaltSync(SALT_ROUNDS);
|
||||
const hashedPasscode = bcrypt.hashSync(passcode, salt);
|
||||
|
||||
await this.userService.setPasscode(userId, hashedPasscode, salt);
|
||||
this.logger.log(`Passcode set successfully for user with id ${userId}`);
|
||||
}
|
||||
|
||||
// async setPhoneNumber(userId: string, { phoneNumber, countryCode }: CreateUnverifiedUserRequestDto) {
|
||||
// const user = await this.userService.findUserOrThrow({ id: userId });
|
||||
|
||||
// if (user.phoneNumber || user.countryCode) {
|
||||
// this.logger.error(`Phone number already set for user with id ${userId}`);
|
||||
// throw new BadRequestException('USER.PHONE_NUMBER_ALREADY_SET');
|
||||
// }
|
||||
|
||||
// const existingUser = await this.userService.findUser({ phoneNumber, countryCode });
|
||||
|
||||
// if (existingUser) {
|
||||
// this.logger.error(`Phone number ${countryCode + phoneNumber} already taken`);
|
||||
// throw new BadRequestException('USER.PHONE_NUMBER_ALREADY_TAKEN');
|
||||
// }
|
||||
|
||||
// await this.userService.setPhoneNumber(userId, phoneNumber, countryCode);
|
||||
|
||||
// return this.otpService.generateAndSendOtp({
|
||||
// userId,
|
||||
// recipient: countryCode + phoneNumber,
|
||||
// scope: OtpScope.VERIFY_PHONE,
|
||||
// otpType: OtpType.SMS,
|
||||
// });
|
||||
// }
|
||||
|
||||
// async verifyPhoneNumber(userId: string, otp: string) {
|
||||
// const isOtpValid = await this.otpService.verifyOtp({
|
||||
// otpType: OtpType.SMS,
|
||||
// scope: OtpScope.VERIFY_PHONE,
|
||||
// userId,
|
||||
// value: otp,
|
||||
// });
|
||||
|
||||
// if (!isOtpValid) {
|
||||
// this.logger.error(`Invalid OTP for user with id ${userId}`);
|
||||
// throw new BadRequestException('OTP.INVALID_OTP');
|
||||
// }
|
||||
|
||||
// return this.userService.verifyPhoneNumber(userId);
|
||||
// }
|
||||
|
||||
async enableBiometric(userId: string, { deviceId, publicKey }: EnableBiometricRequestDto) {
|
||||
this.logger.log(`Enabling biometric for user with id ${userId}`);
|
||||
const device = await this.deviceService.findUserDeviceById(deviceId, userId);
|
||||
@ -255,48 +135,49 @@ export class AuthService {
|
||||
return this.deviceService.updateDevice(deviceId, { publicKey: null });
|
||||
}
|
||||
|
||||
async sendForgetPasswordOtp({ email }: SendForgetPasswordOtpRequestDto) {
|
||||
this.logger.log(`Sending forget password OTP to ${email}`);
|
||||
const user = await this.userService.findUserOrThrow({ email });
|
||||
|
||||
if (!user.isProfileCompleted) {
|
||||
this.logger.error(`Profile not completed for user with email ${email}`);
|
||||
throw new BadRequestException('USER.PROFILE_NOT_COMPLETED');
|
||||
}
|
||||
async sendForgetPasswordOtp({ countryCode, phoneNumber }: SendForgetPasswordOtpRequestDto) {
|
||||
this.logger.log(`Sending forget password OTP to ${countryCode + phoneNumber}`);
|
||||
const user = await this.userService.findUserOrThrow({ countryCode, phoneNumber });
|
||||
|
||||
return this.otpService.generateAndSendOtp({
|
||||
userId: user.id,
|
||||
recipient: user.email,
|
||||
recipient: user.fullPhoneNumber,
|
||||
scope: OtpScope.FORGET_PASSWORD,
|
||||
otpType: OtpType.EMAIL,
|
||||
otpType: OtpType.SMS,
|
||||
});
|
||||
}
|
||||
|
||||
async verifyForgetPasswordOtp({ email, otp, password, confirmPassword }: ForgetPasswordRequestDto) {
|
||||
this.logger.log(`Verifying forget password OTP for ${email}`);
|
||||
const user = await this.userService.findUserOrThrow({ email });
|
||||
if (!user.isProfileCompleted) {
|
||||
this.logger.error(`Profile not completed for user with email ${email}`);
|
||||
throw new BadRequestException('USER.PROFILE_NOT_COMPLETED');
|
||||
}
|
||||
async verifyForgetPasswordOtp({
|
||||
countryCode,
|
||||
phoneNumber,
|
||||
otp,
|
||||
password,
|
||||
confirmPassword,
|
||||
}: ForgetPasswordRequestDto) {
|
||||
this.logger.log(`Verifying forget password OTP for ${countryCode + phoneNumber}`);
|
||||
const user = await this.userService.findUserOrThrow({ countryCode, phoneNumber });
|
||||
|
||||
const isOtpValid = await this.otpService.verifyOtp({
|
||||
userId: user.id,
|
||||
scope: OtpScope.FORGET_PASSWORD,
|
||||
otpType: OtpType.EMAIL,
|
||||
otpType: OtpType.SMS,
|
||||
value: otp,
|
||||
});
|
||||
|
||||
if (!isOtpValid) {
|
||||
this.logger.error(`Invalid OTP for user with email ${email}`);
|
||||
this.logger.error(`Invalid OTP for user with phone number ${user.fullPhoneNumber}`);
|
||||
throw new BadRequestException('OTP.INVALID_OTP');
|
||||
}
|
||||
|
||||
this.validatePassword(password, confirmPassword, user);
|
||||
if (password !== confirmPassword) {
|
||||
this.logger.error('Password and confirm password do not match');
|
||||
throw new BadRequestException('AUTH.PASSWORD_MISMATCH');
|
||||
}
|
||||
|
||||
const hashedPassword = bcrypt.hashSync(password, user.salt);
|
||||
|
||||
await this.userService.setPasscode(user.id, hashedPassword, user.salt);
|
||||
this.logger.log(`Passcode updated successfully for user with email ${email}`);
|
||||
await this.userService.setPassword(user.id, hashedPassword, user.salt);
|
||||
this.logger.log(`Passcode updated successfully for user with phone number ${user.fullPhoneNumber}`);
|
||||
}
|
||||
|
||||
async setJuniorPasscode(body: setJuniorPasswordRequestDto) {
|
||||
@ -304,7 +185,7 @@ export class AuthService {
|
||||
const juniorId = await this.userTokenService.validateToken(body.qrToken, UserType.JUNIOR);
|
||||
const salt = bcrypt.genSaltSync(SALT_ROUNDS);
|
||||
const hashedPasscode = bcrypt.hashSync(body.passcode, salt);
|
||||
await this.userService.setPasscode(juniorId!, hashedPasscode, salt);
|
||||
await this.userService.setPassword(juniorId!, hashedPasscode, salt);
|
||||
await this.userTokenService.invalidateToken(body.qrToken);
|
||||
this.logger.log(`Passcode set successfully for junior with id ${juniorId}`);
|
||||
}
|
||||
@ -345,40 +226,6 @@ export class AuthService {
|
||||
}
|
||||
}
|
||||
|
||||
async sendLoginOtp({ email }: SendLoginOtpRequestDto) {
|
||||
const user = await this.userService.findUserOrThrow({ email });
|
||||
|
||||
this.logger.log(`Sending login OTP to ${email}`);
|
||||
return this.otpService.generateAndSendOtp({
|
||||
recipient: email,
|
||||
scope: OtpScope.LOGIN,
|
||||
otpType: OtpType.EMAIL,
|
||||
userId: user.id,
|
||||
});
|
||||
}
|
||||
|
||||
async verifyLoginOtp({ email, otp }: VerifyLoginOtpRequestDto): Promise<[ILoginResponse, User]> {
|
||||
const user = await this.userService.findUserOrThrow({ email });
|
||||
|
||||
this.logger.log(`Verifying login OTP for ${email}`);
|
||||
const isOtpValid = await this.otpService.verifyOtp({
|
||||
otpType: OtpType.EMAIL,
|
||||
scope: OtpScope.LOGIN,
|
||||
userId: user.id,
|
||||
value: otp,
|
||||
});
|
||||
|
||||
if (!isOtpValid) {
|
||||
this.logger.error(`Invalid OTP for user with email ${email}`);
|
||||
throw new BadRequestException('OTP.INVALID_OTP');
|
||||
}
|
||||
|
||||
this.logger.log(`Login OTP verified successfully for ${email}`);
|
||||
|
||||
const token = await this.generateAuthToken(user);
|
||||
return [token, user];
|
||||
}
|
||||
|
||||
logout(req: Request) {
|
||||
this.logger.log('Logging out');
|
||||
const accessToken = req.headers.authorization?.split(' ')[1] as string;
|
||||
@ -386,147 +233,68 @@ export class AuthService {
|
||||
return this.cacheService.set(accessToken, 'BLACKLISTED', expiryInTtl);
|
||||
}
|
||||
|
||||
private async loginWithPassword(loginDto: LoginRequestDto): Promise<[ILoginResponse, User]> {
|
||||
const user = await this.userService.findUserOrThrow({ email: loginDto.email });
|
||||
async loginWithPassword(loginDto: LoginRequestDto): Promise<[ILoginResponse, User]> {
|
||||
const user = await this.userService.findUser({
|
||||
countryCode: loginDto.countryCode,
|
||||
phoneNumber: loginDto.phoneNumber,
|
||||
});
|
||||
|
||||
this.logger.log(`validating password for user with email ${loginDto.email}`);
|
||||
if (!user) {
|
||||
this.logger.error(`User not found with phone number ${loginDto.countryCode + loginDto.phoneNumber}`);
|
||||
throw new UnauthorizedException('AUTH.INVALID_CREDENTIALS');
|
||||
}
|
||||
|
||||
if (!user.password) {
|
||||
this.logger.error(`Password not set for user with phone number ${loginDto.countryCode + loginDto.phoneNumber}`);
|
||||
throw new UnauthorizedException('AUTH.PHONE_NUMBER_NOT_VERIFIED');
|
||||
}
|
||||
|
||||
this.logger.log(`validating password for user with phone ${loginDto.countryCode + loginDto.phoneNumber}`);
|
||||
const isPasswordValid = bcrypt.compareSync(loginDto.password, user.password);
|
||||
|
||||
if (!isPasswordValid) {
|
||||
this.logger.error(`Invalid password for user with email ${loginDto.email}`);
|
||||
this.logger.error(`Invalid password for user with phone ${loginDto.countryCode + loginDto.phoneNumber}`);
|
||||
throw new UnauthorizedException('AUTH.INVALID_CREDENTIALS');
|
||||
}
|
||||
|
||||
const tokens = await this.generateAuthToken(user);
|
||||
this.logger.log(`Password validated successfully for user with email ${loginDto.email}`);
|
||||
this.logger.log(`Password validated successfully for user`);
|
||||
return [tokens, user];
|
||||
}
|
||||
|
||||
private async loginWithBiometric(loginDto: LoginRequestDto, deviceId: string): Promise<[ILoginResponse, User]> {
|
||||
const user = await this.userService.findUserOrThrow({ email: loginDto.email });
|
||||
// private async loginWithBiometric(loginDto: LoginRequestDto, deviceId: string): Promise<[ILoginResponse, User]> {
|
||||
// const user = await this.userService.findUserOrThrow({ email: loginDto.email });
|
||||
|
||||
this.logger.log(`validating biometric for user with email ${loginDto.email}`);
|
||||
const device = await this.deviceService.findUserDeviceById(deviceId, user.id);
|
||||
// this.logger.log(`validating biometric for user with email ${loginDto.email}`);
|
||||
// const device = await this.deviceService.findUserDeviceById(deviceId, user.id);
|
||||
|
||||
if (!device) {
|
||||
this.logger.error(`Device not found for user with email ${loginDto.email} and device id ${deviceId}`);
|
||||
throw new UnauthorizedException('AUTH.DEVICE_NOT_FOUND');
|
||||
}
|
||||
// if (!device) {
|
||||
// this.logger.error(`Device not found for user with email ${loginDto.email} and device id ${deviceId}`);
|
||||
// throw new UnauthorizedException('AUTH.DEVICE_NOT_FOUND');
|
||||
// }
|
||||
|
||||
if (!device.publicKey) {
|
||||
this.logger.error(`Biometric not enabled for user with email ${loginDto.email}`);
|
||||
throw new UnauthorizedException('AUTH.BIOMETRIC_NOT_ENABLED');
|
||||
}
|
||||
// if (!device.publicKey) {
|
||||
// this.logger.error(`Biometric not enabled for user with email ${loginDto.email}`);
|
||||
// throw new UnauthorizedException('AUTH.BIOMETRIC_NOT_ENABLED');
|
||||
// }
|
||||
|
||||
const cleanToken = removePadding(loginDto.signature);
|
||||
const isValidToken = await verifySignature(
|
||||
device.publicKey,
|
||||
cleanToken,
|
||||
`${user.email} - ${device.deviceId}`,
|
||||
'SHA1',
|
||||
);
|
||||
// const cleanToken = removePadding(loginDto.signature);
|
||||
// const isValidToken = await verifySignature(
|
||||
// device.publicKey,
|
||||
// cleanToken,
|
||||
// `${user.email} - ${device.deviceId}`,
|
||||
// 'SHA1',
|
||||
// );
|
||||
|
||||
if (!isValidToken) {
|
||||
this.logger.error(`Invalid biometric for user with email ${loginDto.email}`);
|
||||
throw new UnauthorizedException('AUTH.INVALID_BIOMETRIC');
|
||||
}
|
||||
// if (!isValidToken) {
|
||||
// this.logger.error(`Invalid biometric for user with email ${loginDto.email}`);
|
||||
// throw new UnauthorizedException('AUTH.INVALID_BIOMETRIC');
|
||||
// }
|
||||
|
||||
const tokens = await this.generateAuthToken(user);
|
||||
this.logger.log(`Biometric validated successfully for user with email ${loginDto.email}`);
|
||||
return [tokens, user];
|
||||
}
|
||||
|
||||
async loginWithGoogle(loginDto: GoogleLoginRequestDto): Promise<[ILoginResponse, User]> {
|
||||
const {
|
||||
email,
|
||||
sub,
|
||||
given_name: firstName,
|
||||
family_name: lastName,
|
||||
} = await this.oauth2Service.verifyGoogleToken(loginDto.googleToken);
|
||||
const [existingUser, isJunior, existingUserWithEmail] = await Promise.all([
|
||||
this.userService.findUser({ googleId: sub }),
|
||||
this.userService.findUser({ email, roles: ArrayContains([Roles.JUNIOR]) }),
|
||||
this.userService.findUser({ email }),
|
||||
]);
|
||||
|
||||
if (isJunior) {
|
||||
this.logger.error(`User with email ${email} is an already registered junior`);
|
||||
throw new BadRequestException('USER.JUNIOR_UPGRADE_NOT_SUPPORTED_YET');
|
||||
}
|
||||
|
||||
if (!existingUser && existingUserWithEmail) {
|
||||
this.logger.error(`User with email ${email} already exists adding google id to existing user`);
|
||||
await this.userService.updateUser(existingUserWithEmail.id, { googleId: sub });
|
||||
const tokens = await this.generateAuthToken(existingUserWithEmail);
|
||||
return [tokens, existingUserWithEmail];
|
||||
}
|
||||
|
||||
if (!existingUser && !existingUserWithEmail) {
|
||||
this.logger.debug(`User with google id ${sub} or email ${email} not found, creating new user`);
|
||||
const user = await this.userService.createGoogleUser(sub, email, firstName, lastName);
|
||||
|
||||
const tokens = await this.generateAuthToken(user);
|
||||
|
||||
return [tokens, user];
|
||||
}
|
||||
|
||||
const tokens = await this.generateAuthToken(existingUser!);
|
||||
|
||||
return [tokens, existingUser!];
|
||||
}
|
||||
|
||||
async loginWithApple(loginDto: AppleLoginRequestDto): Promise<[ILoginResponse, User]> {
|
||||
const { sub, email } = await this.oauth2Service.verifyAppleToken(loginDto.appleToken);
|
||||
|
||||
const [existingUserWithSub, isJunior] = await Promise.all([
|
||||
this.userService.findUser({ appleId: sub }),
|
||||
this.userService.findUser({ email, roles: ArrayContains([Roles.JUNIOR]) }),
|
||||
]);
|
||||
|
||||
if (isJunior) {
|
||||
this.logger.error(`User with apple id ${sub} is an already registered junior`);
|
||||
throw new BadRequestException('USER.JUNIOR_UPGRADE_NOT_SUPPORTED_YET');
|
||||
}
|
||||
|
||||
if (email) {
|
||||
const existingUserWithEmail = await this.userService.findUser({ email });
|
||||
|
||||
if (existingUserWithEmail && !existingUserWithSub) {
|
||||
{
|
||||
this.logger.error(`User with email ${email} already exists adding apple id to existing user`);
|
||||
await this.userService.updateUser(existingUserWithEmail.id, { appleId: sub });
|
||||
const tokens = await this.generateAuthToken(existingUserWithEmail);
|
||||
return [tokens, existingUserWithEmail];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!existingUserWithSub) {
|
||||
// Apple only provides email if user authorized zod for the first time
|
||||
if (!email || !loginDto.additionalData) {
|
||||
this.logger.error(`User authorized zod before but his email is not stored in the database`);
|
||||
throw new BadRequestException('AUTH.APPLE_RE-CONSENT_REQUIRED');
|
||||
}
|
||||
|
||||
this.logger.debug(`User with apple id ${sub} not found, creating new user`);
|
||||
const user = await this.userService.createAppleUser(
|
||||
sub,
|
||||
email,
|
||||
loginDto.additionalData.firstName,
|
||||
loginDto.additionalData.lastName,
|
||||
);
|
||||
|
||||
const tokens = await this.generateAuthToken(user);
|
||||
|
||||
return [tokens, user];
|
||||
}
|
||||
|
||||
const tokens = await this.generateAuthToken(existingUserWithSub);
|
||||
|
||||
this.logger.log(`User with apple id ${sub} logged in successfully`);
|
||||
|
||||
return [tokens, existingUserWithSub];
|
||||
}
|
||||
// const tokens = await this.generateAuthToken(user);
|
||||
// this.logger.log(`Biometric validated successfully for user with email ${loginDto.email}`);
|
||||
// return [tokens, user];
|
||||
// }
|
||||
|
||||
private async generateAuthToken(user: User) {
|
||||
this.logger.log(`Generating auth token for user with id ${user.id}`);
|
||||
@ -550,19 +318,4 @@ export class AuthService {
|
||||
this.logger.log(`Auth token generated successfully for user with id ${user.id}`);
|
||||
return { accessToken, refreshToken, expiresAt: new Date(this.jwtService.decode(accessToken).exp * ONE_THOUSAND) };
|
||||
}
|
||||
|
||||
private validatePassword(password: string, confirmPassword: string, user: User) {
|
||||
this.logger.log(`Validating password for user with id ${user.id}`);
|
||||
if (password !== confirmPassword) {
|
||||
this.logger.error(`Password mismatch for user with id ${user.id}`);
|
||||
throw new BadRequestException('AUTH.PASSWORD_MISMATCH');
|
||||
}
|
||||
|
||||
if (!PASSCODE_REGEX.test(password)) {
|
||||
this.logger.error(`Invalid password for user with id ${user.id}`);
|
||||
throw new BadRequestException('AUTH.INVALID_PASSCODE');
|
||||
}
|
||||
}
|
||||
|
||||
private validateGoogleToken(googleToken: string) {}
|
||||
}
|
||||
|
Reference in New Issue
Block a user