✨ Refacto login
This commit is contained in:
parent
fc8b86b7ca
commit
d3f9527f85
@ -3,7 +3,13 @@ import { Controller, Post } from "@ControllerPattern/index";
|
||||
import ApiController from "@Common/system/controller-pattern/ApiController";
|
||||
import { Service } from "typedi";
|
||||
import { EnrollmentResponse } from "@Services/common/Id360Service/Id360Service";
|
||||
import CustomersService, { SmsNotExpiredError } from "@Services/customer/CustomersService/CustomersService";
|
||||
import CustomersService, {
|
||||
InvalidPasswordError,
|
||||
InvalidTotpCodeError,
|
||||
NotRegisteredCustomerError,
|
||||
SmsNotExpiredError,
|
||||
TotpCodeExpiredError,
|
||||
} from "@Services/customer/CustomersService/CustomersService";
|
||||
import AuthService, { ICustomerJwtPayload } from "@Services/common/AuthService/AuthService";
|
||||
import { Customer } from "le-coffre-resources/dist/SuperAdmin";
|
||||
|
||||
@ -28,7 +34,7 @@ export default class AuthController extends ApiController {
|
||||
this.httpNotFoundRequest(response, "Customer not found");
|
||||
return;
|
||||
}
|
||||
this.httpSuccess(response, { partialPhoneNumber: customer.contact?.cell_phone_number.slice(-4) });
|
||||
this.httpSuccess(response, { partialPhoneNumber: customer.contact?.cell_phone_number.replace(/\s/g, "").slice(-4) });
|
||||
} catch (error) {
|
||||
if (error instanceof SmsNotExpiredError) {
|
||||
this.httpTooEarlyRequest(response, error.message);
|
||||
@ -60,56 +66,28 @@ export default class AuthController extends ApiController {
|
||||
return;
|
||||
}
|
||||
|
||||
let customer = await this.customerService.getOne({
|
||||
where: {
|
||||
contact: {
|
||||
email,
|
||||
},
|
||||
},
|
||||
include: {
|
||||
contact: true,
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
const customer = await this.customerService.login(email, smsCode, password);
|
||||
if (!customer) {
|
||||
this.httpNotFoundRequest(response, "Customer not found");
|
||||
this.httpBadRequest(response, "Customer not found");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!customer.smsCode) {
|
||||
this.httpBadRequest(response, "No sms code found");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!customer.smsCodeExpire || new Date().getTime() > customer.smsCodeExpire.getTime()) {
|
||||
this.httpBadRequest(response, "Sms code expired");
|
||||
return;
|
||||
}
|
||||
|
||||
if (customer.smsCode !== smsCode) {
|
||||
this.httpBadRequest(response, "Invalid sms code");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!customer.password) {
|
||||
this.httpBadRequest(response, "Customer not registered");
|
||||
return;
|
||||
}
|
||||
|
||||
// compare password to the hash
|
||||
const isPasswordValid = await this.authService.comparePassword(password, customer.password);
|
||||
if (!isPasswordValid) {
|
||||
this.httpBadRequest(response, "Invalid password");
|
||||
return;
|
||||
}
|
||||
|
||||
const customerHydrated = Customer.hydrate<Customer>(customer);
|
||||
const payload = await this.authService.getCustomerJwtPayload([customerHydrated]);
|
||||
const accessToken = this.authService.generateAccessToken(payload);
|
||||
const refreshToken = this.authService.generateRefreshToken(payload);
|
||||
try {
|
||||
this.httpSuccess(response, { accessToken, refreshToken });
|
||||
} catch (error) {
|
||||
if (error instanceof TotpCodeExpiredError || error instanceof NotRegisteredCustomerError) {
|
||||
this.httpBadRequest(response, error.message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (error instanceof InvalidTotpCodeError || error instanceof InvalidPasswordError) {
|
||||
this.httpUnauthorized(response, error.message);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(error);
|
||||
this.httpInternalError(response);
|
||||
return;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Customers, Prisma } from "@prisma/client";
|
||||
import CustomersRepository from "@Repositories/CustomersRepository";
|
||||
import BaseService from "@Services/BaseService";
|
||||
import AuthService from "@Services/common/AuthService/AuthService";
|
||||
import { Customer } from "le-coffre-resources/dist/Notary";
|
||||
import { Service } from "typedi";
|
||||
|
||||
@ -9,9 +10,33 @@ export class SmsNotExpiredError extends Error {
|
||||
super("SMS code not expired");
|
||||
}
|
||||
}
|
||||
|
||||
export class TotpCodeExpiredError extends Error {
|
||||
constructor() {
|
||||
super("Totp code not found or expired");
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidTotpCodeError extends Error {
|
||||
constructor() {
|
||||
super("Invalid Totp code");
|
||||
}
|
||||
}
|
||||
|
||||
export class NotRegisteredCustomerError extends Error {
|
||||
constructor() {
|
||||
super("Customer not registered");
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidPasswordError extends Error {
|
||||
constructor() {
|
||||
super("Invalid password");
|
||||
}
|
||||
}
|
||||
@Service()
|
||||
export default class CustomersService extends BaseService {
|
||||
constructor(private customerRepository: CustomersRepository) {
|
||||
constructor(private customerRepository: CustomersRepository, private authService: AuthService) {
|
||||
super();
|
||||
}
|
||||
|
||||
@ -111,4 +136,41 @@ export default class CustomersService extends BaseService {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @description : Login a customer
|
||||
* 1: Check if the customer exists
|
||||
* 2: Check if the SMS code is existing and is not expired
|
||||
* 3: Check if the SMS code is valid
|
||||
* 4: Check if the user has a password or it's their first login
|
||||
* 5: Check if the password is valid
|
||||
* 6: Return the customer
|
||||
* @param email
|
||||
* @param smsCode
|
||||
* @param password
|
||||
* @returns Customer | null
|
||||
*/
|
||||
public async login(email: string, smsCode: string, password: string): Promise<Customer | null> {
|
||||
// 1: Check if the customer exists
|
||||
const customer = await this.getByEmail(email);
|
||||
if (!customer) return null;
|
||||
|
||||
// 2: Check if the SMS code is existing and is not expired
|
||||
if (!customer.smsCode || !customer.smsCodeExpire || new Date().getTime() > customer.smsCodeExpire.getTime())
|
||||
throw new TotpCodeExpiredError();
|
||||
|
||||
// 3: Check if the SMS code is valid
|
||||
if (customer.smsCode !== smsCode) throw new InvalidTotpCodeError();
|
||||
|
||||
// 4: Check if the user has a password or it's their first login
|
||||
if (!customer.password) throw new NotRegisteredCustomerError();
|
||||
|
||||
// 5: Check if the password is valid
|
||||
const isPasswordValid = await this.authService.comparePassword(password, customer.password);
|
||||
if (!isPasswordValid) throw new InvalidPasswordError();
|
||||
|
||||
// 6: Return the customer
|
||||
return customer;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user