From 6fdaa93362abb8d0821911355ec0bdac77b5ce52 Mon Sep 17 00:00:00 2001 From: HyungJu Date: Mon, 6 May 2024 01:30:32 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20SMSState=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../request-reset-password/mapper.ts | 22 ++++++++++++ .../reset-password/reset-password.request.ts | 6 ++++ .../nip/strategies/resetPassword/request.ts | 8 ++++- .../src/password-reset/context.factory.ts | 5 ++- .../password-reset/password-reset.module.ts | 2 ++ .../password-reset/password-reset.state.ts | 1 + .../src/password-reset/states/SMSState.ts | 36 +++++++++++++++++++ .../password-reset/states/SecureNoState.ts | 2 +- 8 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 apps/server/src/password-reset/states/SMSState.ts diff --git a/apps/server/src/codef/strategies/request-reset-password/mapper.ts b/apps/server/src/codef/strategies/request-reset-password/mapper.ts index fa15029..015eea6 100644 --- a/apps/server/src/codef/strategies/request-reset-password/mapper.ts +++ b/apps/server/src/codef/strategies/request-reset-password/mapper.ts @@ -5,6 +5,7 @@ import { NipResetPasswordResponse } from '../../../nip/strategies/resetPassword/ import { CodefResetPasswordRequest, CodefTwoWaySecureNoInputRequest, + CodefTwoWaySMSInputRequest, } from '../../types/reset-password/reset-password.request'; export class Mapper { @@ -43,6 +44,27 @@ export class Mapper { is2Way: true, }; + return codefRequest; + } else if (request.type == 'InputSMS') { + const codefRequest: CodefTwoWaySMSInputRequest = { + organization: '0011', + authMethod: '0', + timeout: '170', + userName: request.name, + identity: request.identity.to9DigitRnnString(), + userPassword: request.newPassword, + telecom: request.telecom.getValue().toString(), + phoneNo: request.phoneNumber, + twoWayInfo: { + jobIndex: request.twoWayInfo.jobIndex, + threadIndex: request.twoWayInfo.threadIndex, + jti: request.twoWayInfo.jti, + twoWayTimestamp: request.twoWayInfo.twoWayTimestamp, + }, + smsAuthNo: request.smsAuthNo, + is2Way: true, + }; + return codefRequest; } } diff --git a/apps/server/src/codef/types/reset-password/reset-password.request.ts b/apps/server/src/codef/types/reset-password/reset-password.request.ts index bb30a3a..073e4fd 100644 --- a/apps/server/src/codef/types/reset-password/reset-password.request.ts +++ b/apps/server/src/codef/types/reset-password/reset-password.request.ts @@ -23,6 +23,12 @@ export type CodefTwoWaySecureNoInputRequest = CodefResetPasswordRequest & { is2Way: true; }; +export type CodefTwoWaySMSInputRequest = CodefResetPasswordRequest & { + twoWayInfo: TwoWayInfo; + smsAuthNo: string; + is2Way: true; +}; + export type CodefRequests = | CodefResetPasswordRequest | CodefTwoWaySecureNoInputRequest; diff --git a/apps/server/src/nip/strategies/resetPassword/request.ts b/apps/server/src/nip/strategies/resetPassword/request.ts index cea5ab9..4108c32 100644 --- a/apps/server/src/nip/strategies/resetPassword/request.ts +++ b/apps/server/src/nip/strategies/resetPassword/request.ts @@ -27,6 +27,12 @@ export type NipInputSecureNoRequest = { } & NipResetPasswordBaseRequest<'InputSecureNo'> & TwoWayRequest; +export type NipInputSMSRequest = { + smsAuthNo: string; +} & NipResetPasswordBaseRequest<'InputSMS'> & + TwoWayRequest; + export type NipResetPasswordRequest = | NipRequestResetPasswordRequest - | NipInputSecureNoRequest; + | NipInputSecureNoRequest + | NipInputSMSRequest; diff --git a/apps/server/src/password-reset/context.factory.ts b/apps/server/src/password-reset/context.factory.ts index ea37842..229ca8e 100644 --- a/apps/server/src/password-reset/context.factory.ts +++ b/apps/server/src/password-reset/context.factory.ts @@ -7,6 +7,7 @@ import { RequestPasswordReset } from './states/RequestPasswordReset'; import { States } from './types/state'; import { ContextRepository } from './context.repository'; import { Context } from './types/context'; +import { SMSState } from './states/SMSState'; @Injectable() export class ContextFactory { @@ -17,12 +18,14 @@ export class ContextFactory { private repository: ContextRepository, private initialState: InitialState, private requestPasswordReset: RequestPasswordReset, - private secureNoState: SecureNoState + private secureNoState: SecureNoState, + private smsState: SMSState ) { this.states = { [StateType.INITIAL]: this.initialState, [StateType.REQUEST_PASSWORD_RESET]: this.requestPasswordReset, [StateType.SECURE_NO]: this.secureNoState, + [StateType.SMS]: this.smsState, }; } diff --git a/apps/server/src/password-reset/password-reset.module.ts b/apps/server/src/password-reset/password-reset.module.ts index 776411c..928d748 100644 --- a/apps/server/src/password-reset/password-reset.module.ts +++ b/apps/server/src/password-reset/password-reset.module.ts @@ -7,6 +7,7 @@ import { NipModule } from '../nip/nip.module'; import { ContextMapper } from './mapper/mapper'; import { ContextFactory } from './context.factory'; import { RedisContextRepositoryImpl } from './redis-context.repository'; +import { SMSState } from './states/SMSState'; @Module({ imports: [NipModule], @@ -19,6 +20,7 @@ import { RedisContextRepositoryImpl } from './redis-context.repository'; SecureNoState, RedisContextRepositoryImpl, ContextFactory, + SMSState, { provide: 'ContextRepository', useClass: RedisContextRepositoryImpl, diff --git a/apps/server/src/password-reset/password-reset.state.ts b/apps/server/src/password-reset/password-reset.state.ts index f5ee99c..75b6be3 100644 --- a/apps/server/src/password-reset/password-reset.state.ts +++ b/apps/server/src/password-reset/password-reset.state.ts @@ -7,6 +7,7 @@ export enum StateType { INITIAL = 'initial', REQUEST_PASSWORD_RESET = 'requestPasswordReset', SECURE_NO = 'secureNo', + SMS = 'sms', } export abstract class PasswordResetState { diff --git a/apps/server/src/password-reset/states/SMSState.ts b/apps/server/src/password-reset/states/SMSState.ts new file mode 100644 index 0000000..f2ffff1 --- /dev/null +++ b/apps/server/src/password-reset/states/SMSState.ts @@ -0,0 +1,36 @@ +import { PasswordResetState, StateType } from '../password-reset.state'; +import { Injectable } from '@nestjs/common'; + +import { NipService } from '../../nip/nip.service'; +import { ResetPasswordRequest } from '../types/reset-password.request'; + +@Injectable() +export class SMSState extends PasswordResetState { + constructor(private nipService: NipService) { + super(); + } + + public async requestPasswordChange( + request: ResetPasswordRequest + ): Promise { + this.context.changeState(StateType.INITIAL); + return this.context.state.requestPasswordChange(request); + } + + public async inputSMSCode(smsCode: string): Promise { + const savedRequest = this.context.data.requestInfo; + + const response = await this.nipService.requestPasswordReset({ + type: 'InputSMS', + smsAuthNo: smsCode, + name: savedRequest.name, + identity: savedRequest.identity, + newPassword: savedRequest.newPassword, + telecom: savedRequest.telecom, + phoneNumber: savedRequest.phoneNumber, + twoWayInfo: this.context.data.twoWayInfo, + }); + + return true; + } +} diff --git a/apps/server/src/password-reset/states/SecureNoState.ts b/apps/server/src/password-reset/states/SecureNoState.ts index e15af75..801404a 100644 --- a/apps/server/src/password-reset/states/SecureNoState.ts +++ b/apps/server/src/password-reset/states/SecureNoState.ts @@ -45,7 +45,7 @@ export class SecureNoState extends PasswordResetState { throw new DomainException(ErrorCode.SECURE_NO_ERROR_REFRESHED); } else if (response.type == 'SMS') { - console.log('SMS State로 전환 !!'); + this.context.changeState(StateType.SMS); return true; } } catch (e) {