diff --git a/app/gateway-api/src/auth/kakaoAccountVerification.ts b/app/gateway-api/src/auth/kakaoAccountVerification.ts index 89eb4bdb..e53c8524 100644 --- a/app/gateway-api/src/auth/kakaoAccountVerification.ts +++ b/app/gateway-api/src/auth/kakaoAccountVerification.ts @@ -2,6 +2,8 @@ import { randomInt } from 'node:crypto'; import { addDays, addSeconds, isAfter, isValid, parseISO } from 'date-fns'; +import { formatServerDateTime } from '@sammo-ts/common/time/ServerDateTime'; + import type { KakaoOAuthClient, KakaoOAuthToken, KakaoUserInfo } from './kakaoClient.js'; import type { OAuthSessionStore } from './oauthSessionStore.js'; import type { UserOAuthInfo, UserRecord, UserRepository } from './userRepository.js'; @@ -221,7 +223,7 @@ export const requireKakaoTalkProof = async (options: { try { await options.kakaoClient.sendTalkMessage( options.accessToken, - `인증 코드는 ${challenge.code} 입니다. ${challenge.expiresAt} 이내에 입력해 주세요.`, + `인증 코드는 ${challenge.code} 입니다. ${formatServerDateTime(challenge.expiresAt)} (한국 시간) 이내에 입력해 주세요.`, options.publicBaseUrl ); } catch (error) { @@ -253,7 +255,7 @@ export const verifyKakaoTalkChallenge = async (options: { if (result.status === 'locked') { throw new KakaoVerificationError( 'IDENTITY_MISMATCH', - `인증 실패 횟수를 초과했습니다. ${result.expiresAt}까지 기다려 주세요.` + `인증 실패 횟수를 초과했습니다. ${formatServerDateTime(result.expiresAt)} (한국 시간)까지 기다려 주세요.` ); } if (result.status === 'mismatch') { diff --git a/app/gateway-api/test/authFlow.test.ts b/app/gateway-api/test/authFlow.test.ts index db8ead30..de7195c6 100644 --- a/app/gateway-api/test/authFlow.test.ts +++ b/app/gateway-api/test/authFlow.test.ts @@ -14,6 +14,7 @@ import { InMemoryProfileStatusService } from '../src/lobby/profileStatusService. import { appRouter } from '../src/router.js'; import type { GatewayPrismaClient } from '@sammo-ts/infra'; import { decryptGameSessionToken, type UserSanctions } from '@sammo-ts/common/auth/gameToken'; +import { formatServerDateTime } from '@sammo-ts/common/time/ServerDateTime'; import { createPasswordEnvelopeService } from '../src/auth/passwordEnvelope.js'; import type { GatewayProfileRepository } from '../src/orchestrator/profileRepository.js'; @@ -987,6 +988,9 @@ describe('gateway auth flow', () => { }); const code = sentTalkMessages[0]?.match(/인증 코드는 (\d{4})/)?.[1]; expect(code).toBeTruthy(); + expect(sentTalkMessages[0]).toBe( + `인증 코드는 ${code} 입니다. ${formatServerDateTime(login.expiresAt)} (한국 시간) 이내에 입력해 주세요.` + ); const completed = await caller.auth.kakaoOtp({ challengeId: login.challengeId, code: code! }); expect(completed.validUntil).toBeTruthy(); expect((await users.findById(user.id))?.kakaoTalkVerifiedUntil).toBe(completed.validUntil);