From d68209879b45c4b579c9fed56e9a091d240fdcc4 Mon Sep 17 00:00:00 2001 From: hided62 Date: Sun, 30 Aug 2026 01:37:18 +0000 Subject: [PATCH] =?UTF-8?q?=EC=B9=B4=EC=B9=B4=EC=98=A4=20OTP=20=EB=A7=8C?= =?UTF-8?q?=EB=A3=8C=20=EC=8B=9C=EA=B0=81=EC=9D=84=20=ED=95=9C=EA=B5=AD=20?= =?UTF-8?q?=EC=8B=9C=EA=B0=84=EC=9C=BC=EB=A1=9C=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/gateway-api/src/auth/kakaoAccountVerification.ts | 6 ++++-- app/gateway-api/test/authFlow.test.ts | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-) 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);