2026-02-11 15:27:03 +09:00
|
|
|
import { normalizeTradingEnv, type KisCredentialInput } from "@/lib/kis/config";
|
|
|
|
|
import type { NextRequest } from "next/server";
|
2026-02-26 09:05:17 +09:00
|
|
|
import { z } from "zod";
|
2026-02-11 15:27:03 +09:00
|
|
|
|
2026-02-26 09:05:17 +09:00
|
|
|
const kisCredentialRequestBodySchema = z.object({
|
|
|
|
|
appKey: z.string().trim().optional(),
|
|
|
|
|
appSecret: z.string().trim().optional(),
|
|
|
|
|
tradingEnv: z.string().optional(),
|
|
|
|
|
});
|
2026-02-11 15:27:03 +09:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @description 요청 본문에서 KIS 인증 정보를 파싱합니다.
|
|
|
|
|
* @see app/api/kis/validate/route.ts
|
|
|
|
|
*/
|
|
|
|
|
export async function parseKisCredentialRequest(
|
|
|
|
|
request: NextRequest,
|
|
|
|
|
): Promise<KisCredentialInput> {
|
2026-02-26 09:05:17 +09:00
|
|
|
let rawBody: unknown = {};
|
2026-02-11 15:27:03 +09:00
|
|
|
|
|
|
|
|
try {
|
2026-02-26 09:05:17 +09:00
|
|
|
rawBody = (await request.json()) as unknown;
|
2026-02-11 15:27:03 +09:00
|
|
|
} catch {
|
|
|
|
|
// 빈 본문 또는 JSON 파싱 실패는 아래 필수값 검증에서 처리합니다.
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-26 09:05:17 +09:00
|
|
|
const parsedBody = kisCredentialRequestBodySchema.safeParse(rawBody);
|
|
|
|
|
const body = parsedBody.success ? parsedBody.data : {};
|
|
|
|
|
|
2026-02-11 15:27:03 +09:00
|
|
|
return {
|
|
|
|
|
appKey: body.appKey?.trim(),
|
|
|
|
|
appSecret: body.appSecret?.trim(),
|
|
|
|
|
tradingEnv: normalizeTradingEnv(body.tradingEnv),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @description 인증키 필수값을 검증합니다.
|
|
|
|
|
* @see app/api/kis/revoke/route.ts
|
|
|
|
|
*/
|
|
|
|
|
export function validateKisCredentialInput(credentials: KisCredentialInput) {
|
|
|
|
|
if (!credentials.appKey || !credentials.appSecret) {
|
|
|
|
|
return "앱 키와 앱 시크릿을 모두 입력해 주세요.";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|