From 15d7b8571299d8be3e5b71bf4e9a488c9c779cf9 Mon Sep 17 00:00:00 2001 From: behnamrhp Date: Mon, 22 May 2023 16:34:02 +0300 Subject: [PATCH] [FEAT]: implement phonenumber auth logics --- .../data/dto/phonenumberDto.ts | 10 ++++++ .../data/repository/IPhoneNumberAuthRepo.ts | 5 +++ .../data/repository/phonenumberAuthRepo.ts | 20 +++++++++++ .../authentication/phonnumber-auth/index.ts | 3 ++ .../infra/phonenumberAuthInfra.ts | 21 +++++++++++ .../authentication/phonnumber-auth/port.ts | 5 +++ .../phonnumber-auth/usecase/exception.ts | 1 + .../usecase/phonenumberAuthUsecase.ts | 36 +++++++++++++++++++ .../common/entity/adminUserEntity.ts | 13 +++++++ .../otp-code-inputs/view/OtpCodeView.tsx | 2 +- 10 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 src/business-logic/generic/admin-user/authentication/phonnumber-auth/data/dto/phonenumberDto.ts create mode 100644 src/business-logic/generic/admin-user/authentication/phonnumber-auth/data/repository/IPhoneNumberAuthRepo.ts create mode 100644 src/business-logic/generic/admin-user/authentication/phonnumber-auth/data/repository/phonenumberAuthRepo.ts create mode 100644 src/business-logic/generic/admin-user/authentication/phonnumber-auth/index.ts create mode 100644 src/business-logic/generic/admin-user/authentication/phonnumber-auth/infra/phonenumberAuthInfra.ts create mode 100644 src/business-logic/generic/admin-user/authentication/phonnumber-auth/port.ts create mode 100644 src/business-logic/generic/admin-user/authentication/phonnumber-auth/usecase/exception.ts create mode 100644 src/business-logic/generic/admin-user/authentication/phonnumber-auth/usecase/phonenumberAuthUsecase.ts create mode 100644 src/business-logic/generic/admin-user/common/entity/adminUserEntity.ts diff --git a/src/business-logic/generic/admin-user/authentication/phonnumber-auth/data/dto/phonenumberDto.ts b/src/business-logic/generic/admin-user/authentication/phonnumber-auth/data/dto/phonenumberDto.ts new file mode 100644 index 0000000..3b76455 --- /dev/null +++ b/src/business-logic/generic/admin-user/authentication/phonnumber-auth/data/dto/phonenumberDto.ts @@ -0,0 +1,10 @@ +import { AdminData } from '../../usecase/phonenumberAuthUsecase'; + +export type PhonenumberAuthDTOReturnType = { + username: string; +}; +const phonenumberAuthDTO = (adminData: AdminData): PhonenumberAuthDTOReturnType => ({ + username: adminData.phonenumber, +}); + +export default phonenumberAuthDTO; diff --git a/src/business-logic/generic/admin-user/authentication/phonnumber-auth/data/repository/IPhoneNumberAuthRepo.ts b/src/business-logic/generic/admin-user/authentication/phonnumber-auth/data/repository/IPhoneNumberAuthRepo.ts new file mode 100644 index 0000000..48e0864 --- /dev/null +++ b/src/business-logic/generic/admin-user/authentication/phonnumber-auth/data/repository/IPhoneNumberAuthRepo.ts @@ -0,0 +1,5 @@ +import { AdminData } from '../../usecase/phonenumberAuthUsecase'; + +export default interface IPhoneNumberAuthRepo { + execute(adminData: AdminData): Promise; +} diff --git a/src/business-logic/generic/admin-user/authentication/phonnumber-auth/data/repository/phonenumberAuthRepo.ts b/src/business-logic/generic/admin-user/authentication/phonnumber-auth/data/repository/phonenumberAuthRepo.ts new file mode 100644 index 0000000..5746d99 --- /dev/null +++ b/src/business-logic/generic/admin-user/authentication/phonnumber-auth/data/repository/phonenumberAuthRepo.ts @@ -0,0 +1,20 @@ +import { AdminData } from '../../usecase/phonenumberAuthUsecase'; +import phonenumberAuthDTO, { PhonenumberAuthDTOReturnType } from '../dto/phonenumberDto'; +import IPhoneNumberAuthRepo from './IPhoneNumberAuthRepo'; + +export type RepoHttpHandler = (dtoData: PhonenumberAuthDTOReturnType) => Promise; +export default class PhoneNumberAuthRepo implements IPhoneNumberAuthRepo { + private httpHandler: RepoHttpHandler; + + constructor(httpHandler: RepoHttpHandler) { + this.httpHandler = httpHandler; + } + + async execute(adminData: AdminData): Promise { + // make dto + const data = phonenumberAuthDTO(adminData); + // call http handler + const response = await this.httpHandler(data); + return response; + } +} diff --git a/src/business-logic/generic/admin-user/authentication/phonnumber-auth/index.ts b/src/business-logic/generic/admin-user/authentication/phonnumber-auth/index.ts new file mode 100644 index 0000000..c5526dc --- /dev/null +++ b/src/business-logic/generic/admin-user/authentication/phonnumber-auth/index.ts @@ -0,0 +1,3 @@ +import phonenumberAuthInfra from './infra/phonenumberAuthInfra'; + +export default phonenumberAuthInfra; diff --git a/src/business-logic/generic/admin-user/authentication/phonnumber-auth/infra/phonenumberAuthInfra.ts b/src/business-logic/generic/admin-user/authentication/phonnumber-auth/infra/phonenumberAuthInfra.ts new file mode 100644 index 0000000..ce1f4e2 --- /dev/null +++ b/src/business-logic/generic/admin-user/authentication/phonnumber-auth/infra/phonenumberAuthInfra.ts @@ -0,0 +1,21 @@ +import PhoneNumberAuthRepo, { RepoHttpHandler } from '../data/repository/phonenumberAuthRepo'; +import PhonenumberAuthUsecase from '../usecase/phonenumberAuthUsecase'; + +export interface IPhonenumberAuthInfra { + httpHandler: RepoHttpHandler; + wrongPhoneNumberMessage: string; +} + +const phonenumberAuthInfra = async ( + httpHandler: RepoHttpHandler, + wrongPhoneNumberMessage: string, +): Promise => { + // prepare repo + const repository = new PhoneNumberAuthRepo(httpHandler); + // prepare usecase + const usecase = new PhonenumberAuthUsecase(repository, wrongPhoneNumberMessage); + // return main method + return usecase; +}; + +export default phonenumberAuthInfra; diff --git a/src/business-logic/generic/admin-user/authentication/phonnumber-auth/port.ts b/src/business-logic/generic/admin-user/authentication/phonnumber-auth/port.ts new file mode 100644 index 0000000..c4c8abf --- /dev/null +++ b/src/business-logic/generic/admin-user/authentication/phonnumber-auth/port.ts @@ -0,0 +1,5 @@ +import { IPhonenumberAuthInfra } from './infra/phonenumberAuthInfra'; +import PhonenumberAuthUsecase from './usecase/phonenumberAuthUsecase'; + +export type IPhonenumberAuthPort = IPhonenumberAuthInfra; +export type PhonenumberReturnTypePort = Promise; diff --git a/src/business-logic/generic/admin-user/authentication/phonnumber-auth/usecase/exception.ts b/src/business-logic/generic/admin-user/authentication/phonnumber-auth/usecase/exception.ts new file mode 100644 index 0000000..ee325b4 --- /dev/null +++ b/src/business-logic/generic/admin-user/authentication/phonnumber-auth/usecase/exception.ts @@ -0,0 +1 @@ +export default class PhonenumberException extends Error {} diff --git a/src/business-logic/generic/admin-user/authentication/phonnumber-auth/usecase/phonenumberAuthUsecase.ts b/src/business-logic/generic/admin-user/authentication/phonnumber-auth/usecase/phonenumberAuthUsecase.ts new file mode 100644 index 0000000..97b16e3 --- /dev/null +++ b/src/business-logic/generic/admin-user/authentication/phonnumber-auth/usecase/phonenumberAuthUsecase.ts @@ -0,0 +1,36 @@ +import IPhoneNumberAuthRepo from '../data/repository/IPhoneNumberAuthRepo'; +import PhonenumberException from './exception'; + +export type AdminData = { + phonenumber: string; +}; + +interface IPhoneNumberAuthUsecase { + execute(adminData: AdminData): Promise; +} + +export default class PhonenumberAuthUsecase implements IPhoneNumberAuthUsecase { + private repository: IPhoneNumberAuthRepo; + + private wrongPhoneNumberMessage: string; + + constructor(repository: IPhoneNumberAuthRepo, wrongPhoneNumberMessage: string) { + this.repository = repository; + this.wrongPhoneNumberMessage = wrongPhoneNumberMessage; + } + + async execute(adminData: AdminData): Promise { + // check phone number regex + const isPhoenumberValid = this.isPhoneNumberValid(adminData.phonenumber); + if (!isPhoenumberValid) throw new PhonenumberException(this.wrongPhoneNumberMessage); + + const response = await this.repository.execute(adminData); + + return response; + } + + private isPhoneNumberValid(phonenumber: string) { + const regex = /\(?([0-9]{3})\)?([ .-]?)([0-9]{3})\2([0-9]{4})/; + return regex.test(phonenumber); + } +} diff --git a/src/business-logic/generic/admin-user/common/entity/adminUserEntity.ts b/src/business-logic/generic/admin-user/common/entity/adminUserEntity.ts new file mode 100644 index 0000000..1b1a6d0 --- /dev/null +++ b/src/business-logic/generic/admin-user/common/entity/adminUserEntity.ts @@ -0,0 +1,13 @@ +export default abstract class AdminUser { + abstract phonenumber: string; + + abstract accessToken: string; + + abstract refreshToken: string; + + abstract expiresIn: number; + + abstract refreshExpiresIn: number; + + abstract tokenType: 'Bearer'; +} diff --git a/src/driving/application/generic/authentication/otp-code-inputs/view/OtpCodeView.tsx b/src/driving/application/generic/authentication/otp-code-inputs/view/OtpCodeView.tsx index e8596a0..3d2d947 100644 --- a/src/driving/application/generic/authentication/otp-code-inputs/view/OtpCodeView.tsx +++ b/src/driving/application/generic/authentication/otp-code-inputs/view/OtpCodeView.tsx @@ -20,7 +20,7 @@ export default function OtpCodeView(props: IOtpCodeView) { tabIndex={i + 1} ref={(el: HTMLInputElement) => (otpChar.current[i] = el)} key={`otp_char_${i}`} - className='font-bold inline-block w-5 bg-transparent text-center focus:outline-none' + className='font-bold text-base inline-block w-5 md:w-10 bg-transparent text-center focus:outline-none' maxLength={1} defaultValue='_' placeholder='_'