diff --git a/src/business-logic/generic/admin-user/authentication/otp-auth/data/dto/otpAuthDto.ts b/src/business-logic/generic/admin-user/authentication/otp-auth/data/dto/otpAuthDto.ts new file mode 100644 index 0000000..f9547cf --- /dev/null +++ b/src/business-logic/generic/admin-user/authentication/otp-auth/data/dto/otpAuthDto.ts @@ -0,0 +1,14 @@ +import { AdminOtpData } from '../../usecase/otpAuthUsecase'; + +export type OtpAuthDTOReturnType = { + username: string; + password: string; + grant_type: 'otp'; +}; +const OtpAuthDTO = (dataToSend: AdminOtpData): OtpAuthDTOReturnType => ({ + grant_type: 'otp', + password: dataToSend.otp, + username: dataToSend.phonenumber, +}); + +export default OtpAuthDTO; diff --git a/src/business-logic/generic/admin-user/authentication/otp-auth/data/reponse-object/otpAuthRO.ts b/src/business-logic/generic/admin-user/authentication/otp-auth/data/reponse-object/otpAuthRO.ts new file mode 100644 index 0000000..8bc88f0 --- /dev/null +++ b/src/business-logic/generic/admin-user/authentication/otp-auth/data/reponse-object/otpAuthRO.ts @@ -0,0 +1,23 @@ +import AdminUser from '~/business-logic/generic/admin-user/common/entity/adminUserEntity'; + +export type OtpAuthResponse = { + access_token: string; + expires_in: number; + refresh_expires_in: number; + refresh_token: string; + token_type: 'Bearer'; +}; + +export interface IOtpAuthRO extends OtpAuthResponse { + phonenumber: string; +} +const otpAuthRO = (response: IOtpAuthRO): AdminUser => ({ + accessToken: response.access_token, + expiresIn: response.expires_in, + phonenumber: response.phonenumber, + refreshExpiresIn: response.refresh_expires_in, + refreshToken: response.refresh_token, + tokenType: response.token_type, +}); + +export default otpAuthRO; diff --git a/src/business-logic/generic/admin-user/authentication/otp-auth/data/repository/IOtpAuthRepo.ts b/src/business-logic/generic/admin-user/authentication/otp-auth/data/repository/IOtpAuthRepo.ts new file mode 100644 index 0000000..2d10765 --- /dev/null +++ b/src/business-logic/generic/admin-user/authentication/otp-auth/data/repository/IOtpAuthRepo.ts @@ -0,0 +1,6 @@ +import AdminUserModel from '../../../../common/data/model/adminUserModel'; +import { AdminOtpData } from '../../usecase/otpAuthUsecase'; + +export default interface IOtpAuthRepo { + execute(otpData: AdminOtpData): Promise; +} diff --git a/src/business-logic/generic/admin-user/authentication/otp-auth/data/repository/otpAuthRepo.ts b/src/business-logic/generic/admin-user/authentication/otp-auth/data/repository/otpAuthRepo.ts new file mode 100644 index 0000000..080794c --- /dev/null +++ b/src/business-logic/generic/admin-user/authentication/otp-auth/data/repository/otpAuthRepo.ts @@ -0,0 +1,32 @@ +import AdminUserModel from '~/business-logic/generic/admin-user/common/data/model/adminUserModel'; +import { AdminOtpData } from '../../usecase/otpAuthUsecase'; +import otpAuthRO, { OtpAuthResponse } from '../reponse-object/otpAuthRO'; +import OtpAuthDTO, { OtpAuthDTOReturnType } from '../dto/otpAuthDto'; +import IOtpAuthRepo from './IOtpAuthRepo'; + +export type OtpHttpHandler = (data: OtpAuthDTOReturnType) => Promise; + +export default class OtpAuthRepo implements IOtpAuthRepo { + private httpHandler: OtpHttpHandler; + + constructor(httpHandler: OtpHttpHandler) { + this.httpHandler = httpHandler; + } + + async execute(otpData: AdminOtpData): Promise { + // call dto + const dto = OtpAuthDTO(otpData); + // call handler + const response = await this.httpHandler(dto); + // call ro + const responseObjectData = { + ...response, + phonenumber: otpData.phonenumber, + }; + const responseObject = otpAuthRO(responseObjectData); + // make model + const adminModel = new AdminUserModel(responseObject); + // return model + return adminModel; + } +} diff --git a/src/business-logic/generic/admin-user/authentication/otp-auth/index.ts b/src/business-logic/generic/admin-user/authentication/otp-auth/index.ts new file mode 100644 index 0000000..ffeda5a --- /dev/null +++ b/src/business-logic/generic/admin-user/authentication/otp-auth/index.ts @@ -0,0 +1,3 @@ +import otpAuthInfra from './infra/otpAuthInfra'; + +export default otpAuthInfra; diff --git a/src/business-logic/generic/admin-user/authentication/otp-auth/infra/otpAuthInfra.ts b/src/business-logic/generic/admin-user/authentication/otp-auth/infra/otpAuthInfra.ts new file mode 100644 index 0000000..cdacca9 --- /dev/null +++ b/src/business-logic/generic/admin-user/authentication/otp-auth/infra/otpAuthInfra.ts @@ -0,0 +1,13 @@ +import OtpAuthRepo, { OtpHttpHandler } from '../data/repository/otpAuthRepo'; +import OtpAuthUsecase from '../usecase/otpAuthUsecase'; + +const otpAuthInfra = (httpHandler: OtpHttpHandler) => { + // make the repo ready + const repository = new OtpAuthRepo(httpHandler); + // make the usecase ready + const usecase = new OtpAuthUsecase(repository); + // return method + return usecase; +}; + +export default otpAuthInfra; diff --git a/src/business-logic/generic/admin-user/authentication/otp-auth/port.ts b/src/business-logic/generic/admin-user/authentication/otp-auth/port.ts new file mode 100644 index 0000000..bd47f83 --- /dev/null +++ b/src/business-logic/generic/admin-user/authentication/otp-auth/port.ts @@ -0,0 +1,8 @@ +import { OtpHttpHandler } from './data/repository/otpAuthRepo'; +import OtpAuthUsecase from './usecase/otpAuthUsecase'; + +export interface IOtpAuthDrivenPort { + httpHandler: OtpHttpHandler; +} + +export type OtpAuthDrivingPort = OtpAuthUsecase; diff --git a/src/business-logic/generic/admin-user/authentication/otp-auth/usecase/otpAuthUsecase.ts b/src/business-logic/generic/admin-user/authentication/otp-auth/usecase/otpAuthUsecase.ts new file mode 100644 index 0000000..13824eb --- /dev/null +++ b/src/business-logic/generic/admin-user/authentication/otp-auth/usecase/otpAuthUsecase.ts @@ -0,0 +1,36 @@ +import AdminUserModel from '../../../common/data/model/adminUserModel'; +import IOtpAuthRepo from '../data/repository/IOtpAuthRepo'; +import OtpAuthUsecaseException from './otpException'; + +export type AdminOtpData = { + otp: string; + phonenumber: string; +}; + +export interface IOtpAuthUsecase { + execute(data: AdminOtpData): Promise; +} + +export default class OtpAuthUsecase implements IOtpAuthUsecase { + private repository: IOtpAuthRepo; + + private validLenghtOfOtp = 6; + + constructor(repository: IOtpAuthRepo) { + this.repository = repository; + } + + async execute(data: AdminOtpData): Promise { + // check length of otp + const isOtpValid = this.isOtpValid(data.otp); + if (!isOtpValid) throw new OtpAuthUsecaseException(); + // call the repo + const updatedAdminModal = await this.repository.execute(data); + + return updatedAdminModal; + } + + private isOtpValid(otp: string) { + return !!(otp.length < this.validLenghtOfOtp); + } +} diff --git a/src/business-logic/generic/admin-user/authentication/otp-auth/usecase/otpException.ts b/src/business-logic/generic/admin-user/authentication/otp-auth/usecase/otpException.ts new file mode 100644 index 0000000..618fa8a --- /dev/null +++ b/src/business-logic/generic/admin-user/authentication/otp-auth/usecase/otpException.ts @@ -0,0 +1 @@ +export default class OtpAuthUsecaseException extends Error {} diff --git a/src/business-logic/generic/admin-user/common/data/model/adminUserModel.ts b/src/business-logic/generic/admin-user/common/data/model/adminUserModel.ts new file mode 100644 index 0000000..866bc32 --- /dev/null +++ b/src/business-logic/generic/admin-user/common/data/model/adminUserModel.ts @@ -0,0 +1,13 @@ +import AdminUser from '../../entity/adminUserEntity'; + +export default class AdminUserModel { + private adminUserData: AdminUser; + + constructor(adminUserData: AdminUser) { + this.adminUserData = adminUserData; + } + + get() { + return this.adminUserData; + } +}