sales-frontend-server-side-helper 0.0.71 → 0.0.73
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api-route/index.cjs
CHANGED
|
@@ -237,12 +237,13 @@ var getServerTime = () => {
|
|
|
237
237
|
data: { serverTime }
|
|
238
238
|
});
|
|
239
239
|
};
|
|
240
|
-
var participantCertificationsVerification = async (request) => {
|
|
240
|
+
var participantCertificationsVerification = async (request, fetchOption) => {
|
|
241
241
|
const params = await request.json();
|
|
242
242
|
console.log("[participantCertificationsVerification] parameter::", params);
|
|
243
243
|
const apiUrl = `/api/dea/v1/post/participant/certifications/verification`;
|
|
244
244
|
const httpClientServer = new server$1.HttpClientFetch({
|
|
245
|
-
baseURL: `${salesFrontendUtils.getApiHostNameFromEnvironment(request.nextUrl.hostname)}
|
|
245
|
+
baseURL: `${salesFrontendUtils.getApiHostNameFromEnvironment(request.nextUrl.hostname)}`,
|
|
246
|
+
...fetchOption
|
|
246
247
|
});
|
|
247
248
|
const { data } = await httpClientServer.post(apiUrl, params);
|
|
248
249
|
console.log("[participantCertificationsVerification] \uC751\uB2F5:", data);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config/cookie-config.ts","../../src/utils/parse-utils.ts","../../src/utils/middleware-utils.ts","../../src/utils/cookie-utils.ts","../../src/api-route/refresh-token.ts","../../src/api-route/server-time.ts","../../src/api-route/participant-certifications-verification.ts"],"names":["getFormFactorFromUserAgent","getEnvironmentFromHostname","NextResponse","requestRefreshToken","getApiHostNameFromEnvironment","HttpClientFetch"],"mappings":"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","file":"index.cjs","sourcesContent":["export const COOKIE_DEFAULT_CONFIG = {\n httpOnly: false,\n sameSite: 'strict' as const,\n secure: true\n};\n","import { NextRequest } from 'next/server';\n\n/**\n * 요청 헤더에 값 파싱\n * @param request\n * @returns\n */\nexport const parseRequestHeaders = (request: NextRequest) => {\n return {\n acceptLanguage: request.headers.get('Accept-Language'),\n deviceId: request.headers.get('X-Channel-DeviceId'),\n loginType: request.headers.get('X-Channel-LoginType'),\n platformName: request.headers.get('X-Channel-PlatformName'),\n platformVersion: request.headers.get('X-Channel-PlatformVersion'),\n appVersion: request.headers.get('X-Channel-AppVersion'),\n deviceModel: request.headers.get('X-Channel-DeviceModel'),\n loginChannel: request.headers.get('X-Channel-LoginChannel'),\n formFactor: request.headers.get('X-Channel-FormFactor')\n };\n};\n\n/**\n * 쿼리 스트링 값 파싱\n * @param request\n * @returns\n */\nexport const parseQueryParameters = (request: NextRequest) => {\n const { searchParams } = request.nextUrl;\n\n return {\n tempToken: searchParams.get('tempToken')\n };\n};\n\n/**\n * 요청 쿠키에 값 파싱\n * @param request\n * @returns\n */\nexport const parseCookies = (request: NextRequest) => {\n return {\n formFactor: request.cookies.get('formFactor')?.value,\n accessToken: request.cookies.get('accessToken')?.value\n };\n};\n","import { NextRequest } from 'next/server';\n\nimport { getFormFactorFromUserAgent } from 'sales-frontend-utils';\n\nimport { parseCookies, parseRequestHeaders } from './parse-utils';\n\n/**\n * FormFactor에 따른 적응형 경로 변환\n * @param pathname\n * @param formFactor\n * @returns\n */\nexport const convertAdaptiveTargetPath = (pathname: string, formFactor: string) => {\n if (pathname === '/') {\n return pathname;\n }\n\n switch (formFactor.toLowerCase()) {\n case 'tablet':\n return `/tablet${pathname}`;\n case 'phone':\n case 'smartphone':\n return `/mobile${pathname}`;\n case 'desktop':\n case 'pc':\n return `/pc${pathname}`;\n default:\n return pathname;\n }\n};\n\n/**\n * FormFactor 구하기\n * @param request\n * @returns\n */\nexport const getFormFactor = (request: NextRequest) => {\n const userAgent = request.headers.get('user-agent') || '';\n\n // 1순위: Custom Header\n const headerValue = parseRequestHeaders(request).formFactor;\n if (headerValue) {\n return headerValue;\n }\n\n // 2순위: Cookie\n const cookieValue = parseCookies(request).formFactor;\n if (cookieValue) {\n return cookieValue;\n }\n\n // 3순위: User-Agent 판단\n return getFormFactorFromUserAgent(userAgent);\n};\n\n/**\n * 반응형 전용 pathname 판단\n * @param pathname\n * @param responsivePaths\n * @returns\n */\nexport const isResponsivePath = (pathname: string, responsivePaths: string[] = []): boolean => {\n return responsivePaths.some((path) => pathname.startsWith(path));\n};\n\n/**\n * 정적 자원 체크 함수\n * @param pathname\n * @returns\n */\nexport const isStaticAsset = (pathname: string): boolean => {\n // API 라우트는 제외\n if (pathname.startsWith('/api')) {\n return false;\n }\n\n // _next 관련 파일들\n if (pathname.startsWith('/_next') || pathname === '/favicon.ico') {\n return true;\n }\n\n // 확장자가 있으면 정적 자원\n return /\\.[a-zA-Z0-9]+$/.test(pathname);\n};\n","import { NextRequest, NextResponse } from 'next/server';\n\nimport { getEnvironmentFromHostname } from 'sales-frontend-utils';\n\nimport { COOKIE_DEFAULT_CONFIG } from '../config/cookie-config';\nimport { CookieData } from '../server-side-helper.types';\n\nimport { getFormFactor } from './middleware-utils';\nimport { parseRequestHeaders } from './parse-utils';\n\n/**\n * 쿠키 생성\n * @param response\n * @param cookieData\n * @returns\n */\nexport const createResponseWithCookies = (\n response: NextResponse,\n request: NextRequest,\n cookieData?: CookieData\n): NextResponse => {\n const { hostname } = new URL(request.url);\n const formFactor = getFormFactor(request);\n\n // 헤더에 있는 데이터 > 쿠키 > 초기 셋업\n const { acceptLanguage, appVersion, deviceId, deviceModel, loginChannel, loginType, platformName, platformVersion } =\n parseRequestHeaders(request);\n\n // 토큰타입\n if (cookieData?.tokens?.tokenType) {\n response.cookies.set({\n name: 'tokenType',\n value: cookieData.tokens.tokenType,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // expiresIn\n if (cookieData?.tokens?.expiresIn) {\n response.cookies.set({\n name: 'expiresIn',\n value: String(cookieData.tokens.expiresIn),\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // 액세스 토큰 쿠키\n if (cookieData?.tokens?.accessToken) {\n response.cookies.set({\n name: 'accessToken',\n value: cookieData.tokens.accessToken,\n ...getDefaultCookieConfig(hostname),\n //! middleware 커스텀헤더 세팅 불가로 우선 풀어 넣음\n httpOnly: false\n });\n }\n\n // 리프레시 토큰 쿠키\n if (cookieData?.tokens?.refreshToken) {\n response.cookies.set({\n name: 'refreshToken',\n value: cookieData.tokens.refreshToken,\n ...getDefaultCookieConfig(hostname),\n httpOnly: true\n });\n }\n\n // FormFactor 쿠키\n if (formFactor) {\n response.cookies.set({\n name: 'formFactor',\n value: formFactor,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Accept Language 쿠키\n if (acceptLanguage) {\n response.cookies.set({\n name: 'acceptLanguage',\n value: acceptLanguage,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // App Version 쿠키\n if (appVersion) {\n response.cookies.set({\n name: 'appVersion',\n value: appVersion,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Device ID 쿠키\n if (deviceId) {\n response.cookies.set({\n name: 'deviceId',\n value: deviceId,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Device Model 쿠키\n if (deviceModel) {\n response.cookies.set({\n name: 'deviceModel',\n value: deviceModel,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Login Channel 쿠키\n if (loginChannel) {\n response.cookies.set({\n name: 'loginChannel',\n value: loginChannel,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Login Type 쿠키\n if (loginType) {\n response.cookies.set({\n name: 'loginType',\n value: loginType,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Platform Name 쿠키\n if (platformName) {\n response.cookies.set({\n name: 'platformName',\n value: platformName,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Platform Version 쿠키\n if (platformVersion) {\n response.cookies.set({\n name: 'platformVersion',\n value: platformVersion,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n return response;\n};\n\n/**\n * 환경에 따른 기본 쿠키 설정값 반환\n * @param hostname\n * @returns\n */\nexport const getDefaultCookieConfig = (hostname: string) => {\n const environment = getEnvironmentFromHostname(hostname);\n\n if (environment !== 'prd') {\n return {\n ...COOKIE_DEFAULT_CONFIG,\n sameSite: 'lax' as const\n };\n }\n\n return COOKIE_DEFAULT_CONFIG;\n};\n","import { NextRequest, NextResponse } from 'next/server';\n\nimport { requestRefreshToken } from 'sales-frontend-api/middleware';\nimport { getApiHostNameFromEnvironment } from 'sales-frontend-utils';\n\nimport { ApiErrorResponse, RefreshTokensOptions } from '../server-side-helper.types';\nimport { createResponseWithCookies } from '../utils/cookie-utils';\n\n/**\n * 리프레시 토큰을 사용하여 새로운 액세스 토큰과 리프레시 토큰을 쿠키로 발급 받습니다.\n * API Route에서 사용될 수 있습니다.\n * 각 프로젝트 API Route 생성 경로: /app/internal/api/auth/refresh/route.ts\n * Method: POST\n * @returns 새로운 AT, RT 발급 후 새 AT 반환\n */\nexport const refreshTokens = async (request: NextRequest, refreshTokensOptions?: RefreshTokensOptions) => {\n const refreshToken = request.cookies.get('refreshToken')?.value;\n\n // 기본 밸리데이션\n if (!refreshToken) {\n return NextResponse.json(\n {\n isSuccess: false,\n code: 'REFRESH_TOKEN_MISSING',\n message: '[ServerSideHelper-Api-Route] Refresh Token이 존재하지 않습니다.)',\n data: null\n } as ApiErrorResponse,\n { status: 401 }\n );\n }\n\n try {\n const tokenData = await requestRefreshToken(\n { refreshToken },\n {\n baseURL: getApiHostNameFromEnvironment(new URL(request.url).hostname, refreshTokensOptions?.forceApiHostName),\n ...Object.fromEntries(\n Array.from(request.headers.entries()).filter(([key]) => key.toLowerCase().startsWith('x-channel'))\n )\n }\n );\n\n console.log('[ServerSideHelper-Api-Route] tokenData', tokenData);\n\n if (tokenData.isSuccess === false) {\n return NextResponse.json(\n {\n isSuccess: false,\n code: tokenData.code || 'TOKEN_REFRESH_FAILED',\n message: `[ServerSideHelper-Api-Route] ${tokenData.message || '토큰 갱신에 실패했습니다.'}`,\n data: null\n } as ApiErrorResponse,\n { status: 401 }\n );\n }\n\n // 응답 유효성 체크\n if (!tokenData.data?.accessToken || !tokenData.data?.refreshToken) {\n throw new Error('[ServerSideHelper-Api-Route] Invalid token data structure');\n }\n\n const { accessToken: newAccessToken, refreshToken: newRefreshToken, expiresIn, tokenType } = tokenData.data;\n\n // 응답 생성\n const response = NextResponse.json(\n {\n isSuccess: true,\n code: '',\n message: '[ServerSideHelper-Api-Route] Token 갱신 성공',\n data: { accessToken: newAccessToken, refreshToken: newRefreshToken, expiresIn, tokenType }\n },\n { status: 200 }\n );\n\n // 새 토큰들을 쿠키에 저장\n createResponseWithCookies(response, request, {\n tokens: { accessToken: newAccessToken, refreshToken: newRefreshToken, expiresIn, tokenType }\n });\n\n return response;\n } catch (error) {\n console.error('Token refresh error:', error);\n\n return NextResponse.json(\n {\n isSuccess: false,\n code: 'REFRESH_TOKEN_MISSING',\n message: '[ServerSideHelper-Api-Route] 토큰 재발급 중 오류가 발생했습니다.',\n data: null\n } as ApiErrorResponse,\n { status: 401 }\n );\n }\n};\n","import { NextResponse } from 'next/server';\n\n/**\n * 서버의 현재 시간을 밀리초 단위로 반환합니다.\n * API Route에서 사용될 수 있습니다.\n * 권장경로: /app/internal/api/time/route.ts\n * Method: GET\n * @returns\n */\nexport const getServerTime = () => {\n const now = new Date();\n const serverTime = now.getTime();\n\n return NextResponse.json({\n isSuccess: true,\n code: '',\n message: 'Current server time fetched successfully',\n data: { serverTime }\n });\n};\n","import { NextRequest, NextResponse } from 'next/server';\n\nimport { HttpClientFetch } from 'sales-frontend-api/server';\nimport { getApiHostNameFromEnvironment } from 'sales-frontend-utils';\n\nimport { getDefaultCookieConfig } from '../utils';\n\nexport interface DspResponseVerificationResponseDto {\n isSuccess: boolean;\n code: string;\n message: string;\n data: VerificationResponseDto;\n}\n\nexport interface VerificationResponseDto {\n /**\n * 토큰타입\n * @example Bearer\n */\n tokenType: string;\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n}\n\n/**\n * @description 고객인증검증 요청\n */\nexport interface VerificationRequestDto {\n /**\n * example: 63165824132905202oa4\n * 티켓\n */\n ticket: string;\n /**\n * @example 1234567890 사용자 ID (고객 ID 또는 FP사원번호)\n */\n userId: string;\n /**\n * @example rxoBpkaMHU 넥스트랩 인증 ID\n */\n nlcCtfnId: string;\n}\n\nexport const participantCertificationsVerification = async (request: NextRequest) => {\n const params: VerificationRequestDto = await request.json();\n console.log('[participantCertificationsVerification] parameter::', params);\n\n const apiUrl = `/api/dea/v1/post/participant/certifications/verification`;\n const httpClientServer = new HttpClientFetch({\n baseURL: `${getApiHostNameFromEnvironment(request.nextUrl.hostname)}`\n });\n\n const { data } = await httpClientServer.post<DspResponseVerificationResponseDto>(apiUrl, params);\n\n console.log('[participantCertificationsVerification] 응답:', data);\n\n // 인증검증 실패\n if (data.isSuccess === false) {\n console.error('[participantCertificationsVerification] 인증검증 실패');\n\n return NextResponse.json({\n isSuccess: data.isSuccess,\n code: data.code,\n message: data.message,\n data: 'fail'\n });\n }\n // 인증성공 응답 생성\n const response = NextResponse.json({\n isSuccess: data.isSuccess,\n code: data.code,\n message: data.message,\n data: 'ok'\n });\n\n const { accessToken, refreshToken } = data.data;\n const { hostname } = new URL(request.url);\n if (data.isSuccess) {\n // 액세스 토큰 쿠키\n if (accessToken) {\n response.cookies.set({\n name: 'accessToken',\n value: accessToken,\n ...getDefaultCookieConfig(hostname),\n //! middleware 커스텀헤더 세팅 불가로 우선 풀어 넣음\n httpOnly: false\n });\n }\n // 리프레시 토큰 쿠키\n if (refreshToken) {\n response.cookies.set({\n name: 'refreshToken',\n value: refreshToken,\n ...getDefaultCookieConfig(hostname),\n httpOnly: true\n });\n }\n }\n\n return response;\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/config/cookie-config.ts","../../src/utils/parse-utils.ts","../../src/utils/middleware-utils.ts","../../src/utils/cookie-utils.ts","../../src/api-route/refresh-token.ts","../../src/api-route/server-time.ts","../../src/api-route/participant-certifications-verification.ts"],"names":["getFormFactorFromUserAgent","getEnvironmentFromHostname","NextResponse","requestRefreshToken","getApiHostNameFromEnvironment","HttpClientFetch"],"mappings":";;;;;;;;;;AAAO,IAAM,qBAAwB,GAAA;AAAA,EACnC,QAAU,EAAA,KAAA;AAAA,EACV,QAAU,EAAA,QAAA;AAAA,EACV,MAAQ,EAAA;AACV,CAAA;;;ACGO,IAAM,mBAAA,GAAsB,CAAC,OAAyB,KAAA;AAC3D,EAAO,OAAA;AAAA,IACL,cAAgB,EAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,iBAAiB,CAAA;AAAA,IACrD,QAAU,EAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,oBAAoB,CAAA;AAAA,IAClD,SAAW,EAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,qBAAqB,CAAA;AAAA,IACpD,YAAc,EAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,wBAAwB,CAAA;AAAA,IAC1D,eAAiB,EAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,2BAA2B,CAAA;AAAA,IAChE,UAAY,EAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,sBAAsB,CAAA;AAAA,IACtD,WAAa,EAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,uBAAuB,CAAA;AAAA,IACxD,YAAc,EAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,wBAAwB,CAAA;AAAA,IAC1D,UAAY,EAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,sBAAsB;AAAA,GACxD;AACF,CAAA;AAoBO,IAAM,YAAA,GAAe,CAAC,OAAyB,KAAA;AACpD,EAAO,OAAA;AAAA,IACL,UAAY,EAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,YAAY,CAAG,EAAA,KAAA;AAAA,IAC/C,WAAa,EAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,aAAa,CAAG,EAAA;AAAA,GACnD;AACF,CAAA;;;ACRO,IAAM,aAAA,GAAgB,CAAC,OAAyB,KAAA;AACrD,EAAA,MAAM,SAAY,GAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,YAAY,CAAK,IAAA,EAAA;AAGvD,EAAM,MAAA,WAAA,GAAc,mBAAoB,CAAA,OAAO,CAAE,CAAA,UAAA;AACjD,EAAA,IAAI,WAAa,EAAA;AACf,IAAO,OAAA,WAAA;AAAA;AAIT,EAAM,MAAA,WAAA,GAAc,YAAa,CAAA,OAAO,CAAE,CAAA,UAAA;AAC1C,EAAA,IAAI,WAAa,EAAA;AACf,IAAO,OAAA,WAAA;AAAA;AAIT,EAAA,OAAOA,8CAA2B,SAAS,CAAA;AAC7C,CAAA;;;ACrCO,IAAM,yBAA4B,GAAA,CACvC,QACA,EAAA,OAAA,EACA,UACiB,KAAA;AACjB,EAAA,MAAM,EAAE,QAAS,EAAA,GAAI,IAAI,GAAA,CAAI,QAAQ,GAAG,CAAA;AACxC,EAAM,MAAA,UAAA,GAAa,cAAc,OAAO,CAAA;AAGxC,EAAM,MAAA,EAAE,cAAgB,EAAA,UAAA,EAAY,QAAU,EAAA,WAAA,EAAa,YAAc,EAAA,SAAA,EAAW,YAAc,EAAA,eAAA,EAChG,GAAA,mBAAA,CAAoB,OAAO,CAAA;AAG7B,EAAI,IAAA,UAAA,EAAY,QAAQ,SAAW,EAAA;AACjC,IAAA,QAAA,CAAS,QAAQ,GAAI,CAAA;AAAA,MACnB,IAAM,EAAA,WAAA;AAAA,MACN,KAAA,EAAO,WAAW,MAAO,CAAA,SAAA;AAAA,MACzB,GAAG,uBAAuB,QAAQ;AAAA,KACnC,CAAA;AAAA;AAIH,EAAI,IAAA,UAAA,EAAY,QAAQ,SAAW,EAAA;AACjC,IAAA,QAAA,CAAS,QAAQ,GAAI,CAAA;AAAA,MACnB,IAAM,EAAA,WAAA;AAAA,MACN,KAAO,EAAA,MAAA,CAAO,UAAW,CAAA,MAAA,CAAO,SAAS,CAAA;AAAA,MACzC,GAAG,uBAAuB,QAAQ;AAAA,KACnC,CAAA;AAAA;AAIH,EAAI,IAAA,UAAA,EAAY,QAAQ,WAAa,EAAA;AACnC,IAAA,QAAA,CAAS,QAAQ,GAAI,CAAA;AAAA,MACnB,IAAM,EAAA,aAAA;AAAA,MACN,KAAA,EAAO,WAAW,MAAO,CAAA,WAAA;AAAA,MACzB,GAAG,uBAAuB,QAAQ,CAAA;AAAA;AAAA,MAElC,QAAU,EAAA;AAAA,KACX,CAAA;AAAA;AAIH,EAAI,IAAA,UAAA,EAAY,QAAQ,YAAc,EAAA;AACpC,IAAA,QAAA,CAAS,QAAQ,GAAI,CAAA;AAAA,MACnB,IAAM,EAAA,cAAA;AAAA,MACN,KAAA,EAAO,WAAW,MAAO,CAAA,YAAA;AAAA,MACzB,GAAG,uBAAuB,QAAQ,CAAA;AAAA,MAClC,QAAU,EAAA;AAAA,KACX,CAAA;AAAA;AAIH,EAAA,IAAI,UAAY,EAAA;AACd,IAAA,QAAA,CAAS,QAAQ,GAAI,CAAA;AAAA,MACnB,IAAM,EAAA,YAAA;AAAA,MACN,KAAO,EAAA,UAAA;AAAA,MACP,GAAG,uBAAuB,QAAQ;AAAA,KACnC,CAAA;AAAA;AAIH,EAAA,IAAI,cAAgB,EAAA;AAClB,IAAA,QAAA,CAAS,QAAQ,GAAI,CAAA;AAAA,MACnB,IAAM,EAAA,gBAAA;AAAA,MACN,KAAO,EAAA,cAAA;AAAA,MACP,GAAG,uBAAuB,QAAQ;AAAA,KACnC,CAAA;AAAA;AAIH,EAAA,IAAI,UAAY,EAAA;AACd,IAAA,QAAA,CAAS,QAAQ,GAAI,CAAA;AAAA,MACnB,IAAM,EAAA,YAAA;AAAA,MACN,KAAO,EAAA,UAAA;AAAA,MACP,GAAG,uBAAuB,QAAQ;AAAA,KACnC,CAAA;AAAA;AAIH,EAAA,IAAI,QAAU,EAAA;AACZ,IAAA,QAAA,CAAS,QAAQ,GAAI,CAAA;AAAA,MACnB,IAAM,EAAA,UAAA;AAAA,MACN,KAAO,EAAA,QAAA;AAAA,MACP,GAAG,uBAAuB,QAAQ;AAAA,KACnC,CAAA;AAAA;AAIH,EAAA,IAAI,WAAa,EAAA;AACf,IAAA,QAAA,CAAS,QAAQ,GAAI,CAAA;AAAA,MACnB,IAAM,EAAA,aAAA;AAAA,MACN,KAAO,EAAA,WAAA;AAAA,MACP,GAAG,uBAAuB,QAAQ;AAAA,KACnC,CAAA;AAAA;AAIH,EAAA,IAAI,YAAc,EAAA;AAChB,IAAA,QAAA,CAAS,QAAQ,GAAI,CAAA;AAAA,MACnB,IAAM,EAAA,cAAA;AAAA,MACN,KAAO,EAAA,YAAA;AAAA,MACP,GAAG,uBAAuB,QAAQ;AAAA,KACnC,CAAA;AAAA;AAIH,EAAA,IAAI,SAAW,EAAA;AACb,IAAA,QAAA,CAAS,QAAQ,GAAI,CAAA;AAAA,MACnB,IAAM,EAAA,WAAA;AAAA,MACN,KAAO,EAAA,SAAA;AAAA,MACP,GAAG,uBAAuB,QAAQ;AAAA,KACnC,CAAA;AAAA;AAIH,EAAA,IAAI,YAAc,EAAA;AAChB,IAAA,QAAA,CAAS,QAAQ,GAAI,CAAA;AAAA,MACnB,IAAM,EAAA,cAAA;AAAA,MACN,KAAO,EAAA,YAAA;AAAA,MACP,GAAG,uBAAuB,QAAQ;AAAA,KACnC,CAAA;AAAA;AAIH,EAAA,IAAI,eAAiB,EAAA;AACnB,IAAA,QAAA,CAAS,QAAQ,GAAI,CAAA;AAAA,MACnB,IAAM,EAAA,iBAAA;AAAA,MACN,KAAO,EAAA,eAAA;AAAA,MACP,GAAG,uBAAuB,QAAQ;AAAA,KACnC,CAAA;AAAA;AAGH,EAAO,OAAA,QAAA;AACT,CAAA;AAOO,IAAM,sBAAA,GAAyB,CAAC,QAAqB,KAAA;AAC1D,EAAM,MAAA,WAAA,GAAcC,8CAA2B,QAAQ,CAAA;AAEvD,EAAA,IAAI,gBAAgB,KAAO,EAAA;AACzB,IAAO,OAAA;AAAA,MACL,GAAG,qBAAA;AAAA,MACH,QAAU,EAAA;AAAA,KACZ;AAAA;AAGF,EAAO,OAAA,qBAAA;AACT,CAAA;;;ACxJa,IAAA,aAAA,GAAgB,OAAO,OAAA,EAAsB,oBAAgD,KAAA;AACxG,EAAA,MAAM,YAAe,GAAA,OAAA,CAAQ,OAAQ,CAAA,GAAA,CAAI,cAAc,CAAG,EAAA,KAAA;AAG1D,EAAA,IAAI,CAAC,YAAc,EAAA;AACjB,IAAA,OAAOC,mBAAa,CAAA,IAAA;AAAA,MAClB;AAAA,QACE,SAAW,EAAA,KAAA;AAAA,QACX,IAAM,EAAA,uBAAA;AAAA,QACN,OAAS,EAAA,sGAAA;AAAA,QACT,IAAM,EAAA;AAAA,OACR;AAAA,MACA,EAAE,QAAQ,GAAI;AAAA,KAChB;AAAA;AAGF,EAAI,IAAA;AACF,IAAA,MAAM,YAAY,MAAMC,8BAAA;AAAA,MACtB,EAAE,YAAa,EAAA;AAAA,MACf;AAAA,QACE,OAAA,EAASC,iDAA8B,IAAI,GAAA,CAAI,QAAQ,GAAG,CAAA,CAAE,QAAU,EAAA,oBAAA,EAAsB,gBAAgB,CAAA;AAAA,QAC5G,GAAG,MAAO,CAAA,WAAA;AAAA,UACR,MAAM,IAAK,CAAA,OAAA,CAAQ,OAAQ,CAAA,OAAA,EAAS,CAAE,CAAA,MAAA,CAAO,CAAC,CAAC,GAAG,CAAM,KAAA,GAAA,CAAI,aAAc,CAAA,UAAA,CAAW,WAAW,CAAC;AAAA;AACnG;AACF,KACF;AAEA,IAAQ,OAAA,CAAA,GAAA,CAAI,0CAA0C,SAAS,CAAA;AAE/D,IAAI,IAAA,SAAA,CAAU,cAAc,KAAO,EAAA;AACjC,MAAA,OAAOF,mBAAa,CAAA,IAAA;AAAA,QAClB;AAAA,UACE,SAAW,EAAA,KAAA;AAAA,UACX,IAAA,EAAM,UAAU,IAAQ,IAAA,sBAAA;AAAA,UACxB,OAAS,EAAA,CAAA,6BAAA,EAAgC,SAAU,CAAA,OAAA,IAAW,uEAAgB,CAAA,CAAA;AAAA,UAC9E,IAAM,EAAA;AAAA,SACR;AAAA,QACA,EAAE,QAAQ,GAAI;AAAA,OAChB;AAAA;AAIF,IAAA,IAAI,CAAC,SAAU,CAAA,IAAA,EAAM,eAAe,CAAC,SAAA,CAAU,MAAM,YAAc,EAAA;AACjE,MAAM,MAAA,IAAI,MAAM,2DAA2D,CAAA;AAAA;AAG7E,IAAM,MAAA,EAAE,aAAa,cAAgB,EAAA,YAAA,EAAc,iBAAiB,SAAW,EAAA,SAAA,KAAc,SAAU,CAAA,IAAA;AAGvG,IAAA,MAAM,WAAWA,mBAAa,CAAA,IAAA;AAAA,MAC5B;AAAA,QACE,SAAW,EAAA,IAAA;AAAA,QACX,IAAM,EAAA,EAAA;AAAA,QACN,OAAS,EAAA,8DAAA;AAAA,QACT,MAAM,EAAE,WAAA,EAAa,gBAAgB,YAAc,EAAA,eAAA,EAAiB,WAAW,SAAU;AAAA,OAC3F;AAAA,MACA,EAAE,QAAQ,GAAI;AAAA,KAChB;AAGA,IAAA,yBAAA,CAA0B,UAAU,OAAS,EAAA;AAAA,MAC3C,QAAQ,EAAE,WAAA,EAAa,gBAAgB,YAAc,EAAA,eAAA,EAAiB,WAAW,SAAU;AAAA,KAC5F,CAAA;AAED,IAAO,OAAA,QAAA;AAAA,WACA,KAAO,EAAA;AACd,IAAQ,OAAA,CAAA,KAAA,CAAM,wBAAwB,KAAK,CAAA;AAE3C,IAAA,OAAOA,mBAAa,CAAA,IAAA;AAAA,MAClB;AAAA,QACE,SAAW,EAAA,KAAA;AAAA,QACX,IAAM,EAAA,uBAAA;AAAA,QACN,OAAS,EAAA,8HAAA;AAAA,QACT,IAAM,EAAA;AAAA,OACR;AAAA,MACA,EAAE,QAAQ,GAAI;AAAA,KAChB;AAAA;AAEJ;ACpFO,IAAM,gBAAgB,MAAM;AACjC,EAAM,MAAA,GAAA,uBAAU,IAAK,EAAA;AACrB,EAAM,MAAA,UAAA,GAAa,IAAI,OAAQ,EAAA;AAE/B,EAAA,OAAOA,oBAAa,IAAK,CAAA;AAAA,IACvB,SAAW,EAAA,IAAA;AAAA,IACX,IAAM,EAAA,EAAA;AAAA,IACN,OAAS,EAAA,0CAAA;AAAA,IACT,IAAA,EAAM,EAAE,UAAW;AAAA,GACpB,CAAA;AACH;ACyBa,IAAA,qCAAA,GAAwC,OAAO,OAAA,EAAsB,WAAmC,KAAA;AACnH,EAAM,MAAA,MAAA,GAAiC,MAAM,OAAA,CAAQ,IAAK,EAAA;AAC1D,EAAQ,OAAA,CAAA,GAAA,CAAI,uDAAuD,MAAM,CAAA;AAEzE,EAAA,MAAM,MAAS,GAAA,CAAA,wDAAA,CAAA;AACf,EAAM,MAAA,gBAAA,GAAmB,IAAIG,wBAAgB,CAAA;AAAA,IAC3C,SAAS,CAAGD,EAAAA,gDAAAA,CAA8B,OAAQ,CAAA,OAAA,CAAQ,QAAQ,CAAC,CAAA,CAAA;AAAA,IACnE,GAAG;AAAA,GACJ,CAAA;AAED,EAAA,MAAM,EAAE,IAAK,EAAA,GAAI,MAAM,gBAAiB,CAAA,IAAA,CAAyC,QAAQ,MAAM,CAAA;AAE/F,EAAQ,OAAA,CAAA,GAAA,CAAI,yDAA+C,IAAI,CAAA;AAG/D,EAAI,IAAA,IAAA,CAAK,cAAc,KAAO,EAAA;AAC5B,IAAA,OAAA,CAAQ,MAAM,+EAAiD,CAAA;AAE/D,IAAA,OAAOF,oBAAa,IAAK,CAAA;AAAA,MACvB,WAAW,IAAK,CAAA,SAAA;AAAA,MAChB,MAAM,IAAK,CAAA,IAAA;AAAA,MACX,SAAS,IAAK,CAAA,OAAA;AAAA,MACd,IAAM,EAAA;AAAA,KACP,CAAA;AAAA;AAGH,EAAM,MAAA,QAAA,GAAWA,oBAAa,IAAK,CAAA;AAAA,IACjC,WAAW,IAAK,CAAA,SAAA;AAAA,IAChB,MAAM,IAAK,CAAA,IAAA;AAAA,IACX,SAAS,IAAK,CAAA,OAAA;AAAA,IACd,IAAM,EAAA;AAAA,GACP,CAAA;AAED,EAAA,MAAM,EAAE,WAAA,EAAa,YAAa,EAAA,GAAI,IAAK,CAAA,IAAA;AAC3C,EAAA,MAAM,EAAE,QAAS,EAAA,GAAI,IAAI,GAAA,CAAI,QAAQ,GAAG,CAAA;AACxC,EAAA,IAAI,KAAK,SAAW,EAAA;AAElB,IAAA,IAAI,WAAa,EAAA;AACf,MAAA,QAAA,CAAS,QAAQ,GAAI,CAAA;AAAA,QACnB,IAAM,EAAA,aAAA;AAAA,QACN,KAAO,EAAA,WAAA;AAAA,QACP,GAAG,uBAAuB,QAAQ,CAAA;AAAA;AAAA,QAElC,QAAU,EAAA;AAAA,OACX,CAAA;AAAA;AAGH,IAAA,IAAI,YAAc,EAAA;AAChB,MAAA,QAAA,CAAS,QAAQ,GAAI,CAAA;AAAA,QACnB,IAAM,EAAA,cAAA;AAAA,QACN,KAAO,EAAA,YAAA;AAAA,QACP,GAAG,uBAAuB,QAAQ,CAAA;AAAA,QAClC,QAAU,EAAA;AAAA,OACX,CAAA;AAAA;AACH;AAGF,EAAO,OAAA,QAAA;AACT","file":"index.cjs","sourcesContent":["export const COOKIE_DEFAULT_CONFIG = {\n httpOnly: false,\n sameSite: 'strict' as const,\n secure: true\n};\n","import { NextRequest } from 'next/server';\n\n/**\n * 요청 헤더에 값 파싱\n * @param request\n * @returns\n */\nexport const parseRequestHeaders = (request: NextRequest) => {\n return {\n acceptLanguage: request.headers.get('Accept-Language'),\n deviceId: request.headers.get('X-Channel-DeviceId'),\n loginType: request.headers.get('X-Channel-LoginType'),\n platformName: request.headers.get('X-Channel-PlatformName'),\n platformVersion: request.headers.get('X-Channel-PlatformVersion'),\n appVersion: request.headers.get('X-Channel-AppVersion'),\n deviceModel: request.headers.get('X-Channel-DeviceModel'),\n loginChannel: request.headers.get('X-Channel-LoginChannel'),\n formFactor: request.headers.get('X-Channel-FormFactor')\n };\n};\n\n/**\n * 쿼리 스트링 값 파싱\n * @param request\n * @returns\n */\nexport const parseQueryParameters = (request: NextRequest) => {\n const { searchParams } = request.nextUrl;\n\n return {\n tempToken: searchParams.get('tempToken')\n };\n};\n\n/**\n * 요청 쿠키에 값 파싱\n * @param request\n * @returns\n */\nexport const parseCookies = (request: NextRequest) => {\n return {\n formFactor: request.cookies.get('formFactor')?.value,\n accessToken: request.cookies.get('accessToken')?.value\n };\n};\n","import { NextRequest } from 'next/server';\n\nimport { getFormFactorFromUserAgent } from 'sales-frontend-utils';\n\nimport { parseCookies, parseRequestHeaders } from './parse-utils';\n\n/**\n * FormFactor에 따른 적응형 경로 변환\n * @param pathname\n * @param formFactor\n * @returns\n */\nexport const convertAdaptiveTargetPath = (pathname: string, formFactor: string) => {\n if (pathname === '/') {\n return pathname;\n }\n\n switch (formFactor.toLowerCase()) {\n case 'tablet':\n return `/tablet${pathname}`;\n case 'phone':\n case 'smartphone':\n return `/mobile${pathname}`;\n case 'desktop':\n case 'pc':\n return `/pc${pathname}`;\n default:\n return pathname;\n }\n};\n\n/**\n * FormFactor 구하기\n * @param request\n * @returns\n */\nexport const getFormFactor = (request: NextRequest) => {\n const userAgent = request.headers.get('user-agent') || '';\n\n // 1순위: Custom Header\n const headerValue = parseRequestHeaders(request).formFactor;\n if (headerValue) {\n return headerValue;\n }\n\n // 2순위: Cookie\n const cookieValue = parseCookies(request).formFactor;\n if (cookieValue) {\n return cookieValue;\n }\n\n // 3순위: User-Agent 판단\n return getFormFactorFromUserAgent(userAgent);\n};\n\n/**\n * 반응형 전용 pathname 판단\n * @param pathname\n * @param responsivePaths\n * @returns\n */\nexport const isResponsivePath = (pathname: string, responsivePaths: string[] = []): boolean => {\n return responsivePaths.some((path) => pathname.startsWith(path));\n};\n\n/**\n * 정적 자원 체크 함수\n * @param pathname\n * @returns\n */\nexport const isStaticAsset = (pathname: string): boolean => {\n // API 라우트는 제외\n if (pathname.startsWith('/api')) {\n return false;\n }\n\n // _next 관련 파일들\n if (pathname.startsWith('/_next') || pathname === '/favicon.ico') {\n return true;\n }\n\n // 확장자가 있으면 정적 자원\n return /\\.[a-zA-Z0-9]+$/.test(pathname);\n};\n","import { NextRequest, NextResponse } from 'next/server';\n\nimport { getEnvironmentFromHostname } from 'sales-frontend-utils';\n\nimport { COOKIE_DEFAULT_CONFIG } from '../config/cookie-config';\nimport { CookieData } from '../server-side-helper.types';\n\nimport { getFormFactor } from './middleware-utils';\nimport { parseRequestHeaders } from './parse-utils';\n\n/**\n * 쿠키 생성\n * @param response\n * @param cookieData\n * @returns\n */\nexport const createResponseWithCookies = (\n response: NextResponse,\n request: NextRequest,\n cookieData?: CookieData\n): NextResponse => {\n const { hostname } = new URL(request.url);\n const formFactor = getFormFactor(request);\n\n // 헤더에 있는 데이터 > 쿠키 > 초기 셋업\n const { acceptLanguage, appVersion, deviceId, deviceModel, loginChannel, loginType, platformName, platformVersion } =\n parseRequestHeaders(request);\n\n // 토큰타입\n if (cookieData?.tokens?.tokenType) {\n response.cookies.set({\n name: 'tokenType',\n value: cookieData.tokens.tokenType,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // expiresIn\n if (cookieData?.tokens?.expiresIn) {\n response.cookies.set({\n name: 'expiresIn',\n value: String(cookieData.tokens.expiresIn),\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // 액세스 토큰 쿠키\n if (cookieData?.tokens?.accessToken) {\n response.cookies.set({\n name: 'accessToken',\n value: cookieData.tokens.accessToken,\n ...getDefaultCookieConfig(hostname),\n //! middleware 커스텀헤더 세팅 불가로 우선 풀어 넣음\n httpOnly: false\n });\n }\n\n // 리프레시 토큰 쿠키\n if (cookieData?.tokens?.refreshToken) {\n response.cookies.set({\n name: 'refreshToken',\n value: cookieData.tokens.refreshToken,\n ...getDefaultCookieConfig(hostname),\n httpOnly: true\n });\n }\n\n // FormFactor 쿠키\n if (formFactor) {\n response.cookies.set({\n name: 'formFactor',\n value: formFactor,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Accept Language 쿠키\n if (acceptLanguage) {\n response.cookies.set({\n name: 'acceptLanguage',\n value: acceptLanguage,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // App Version 쿠키\n if (appVersion) {\n response.cookies.set({\n name: 'appVersion',\n value: appVersion,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Device ID 쿠키\n if (deviceId) {\n response.cookies.set({\n name: 'deviceId',\n value: deviceId,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Device Model 쿠키\n if (deviceModel) {\n response.cookies.set({\n name: 'deviceModel',\n value: deviceModel,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Login Channel 쿠키\n if (loginChannel) {\n response.cookies.set({\n name: 'loginChannel',\n value: loginChannel,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Login Type 쿠키\n if (loginType) {\n response.cookies.set({\n name: 'loginType',\n value: loginType,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Platform Name 쿠키\n if (platformName) {\n response.cookies.set({\n name: 'platformName',\n value: platformName,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Platform Version 쿠키\n if (platformVersion) {\n response.cookies.set({\n name: 'platformVersion',\n value: platformVersion,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n return response;\n};\n\n/**\n * 환경에 따른 기본 쿠키 설정값 반환\n * @param hostname\n * @returns\n */\nexport const getDefaultCookieConfig = (hostname: string) => {\n const environment = getEnvironmentFromHostname(hostname);\n\n if (environment !== 'prd') {\n return {\n ...COOKIE_DEFAULT_CONFIG,\n sameSite: 'lax' as const\n };\n }\n\n return COOKIE_DEFAULT_CONFIG;\n};\n","import { NextRequest, NextResponse } from 'next/server';\n\nimport { requestRefreshToken } from 'sales-frontend-api/middleware';\nimport { getApiHostNameFromEnvironment } from 'sales-frontend-utils';\n\nimport { ApiErrorResponse, RefreshTokensOptions } from '../server-side-helper.types';\nimport { createResponseWithCookies } from '../utils/cookie-utils';\n\n/**\n * 리프레시 토큰을 사용하여 새로운 액세스 토큰과 리프레시 토큰을 쿠키로 발급 받습니다.\n * API Route에서 사용될 수 있습니다.\n * 각 프로젝트 API Route 생성 경로: /app/internal/api/auth/refresh/route.ts\n * Method: POST\n * @returns 새로운 AT, RT 발급 후 새 AT 반환\n */\nexport const refreshTokens = async (request: NextRequest, refreshTokensOptions?: RefreshTokensOptions) => {\n const refreshToken = request.cookies.get('refreshToken')?.value;\n\n // 기본 밸리데이션\n if (!refreshToken) {\n return NextResponse.json(\n {\n isSuccess: false,\n code: 'REFRESH_TOKEN_MISSING',\n message: '[ServerSideHelper-Api-Route] Refresh Token이 존재하지 않습니다.)',\n data: null\n } as ApiErrorResponse,\n { status: 401 }\n );\n }\n\n try {\n const tokenData = await requestRefreshToken(\n { refreshToken },\n {\n baseURL: getApiHostNameFromEnvironment(new URL(request.url).hostname, refreshTokensOptions?.forceApiHostName),\n ...Object.fromEntries(\n Array.from(request.headers.entries()).filter(([key]) => key.toLowerCase().startsWith('x-channel'))\n )\n }\n );\n\n console.log('[ServerSideHelper-Api-Route] tokenData', tokenData);\n\n if (tokenData.isSuccess === false) {\n return NextResponse.json(\n {\n isSuccess: false,\n code: tokenData.code || 'TOKEN_REFRESH_FAILED',\n message: `[ServerSideHelper-Api-Route] ${tokenData.message || '토큰 갱신에 실패했습니다.'}`,\n data: null\n } as ApiErrorResponse,\n { status: 401 }\n );\n }\n\n // 응답 유효성 체크\n if (!tokenData.data?.accessToken || !tokenData.data?.refreshToken) {\n throw new Error('[ServerSideHelper-Api-Route] Invalid token data structure');\n }\n\n const { accessToken: newAccessToken, refreshToken: newRefreshToken, expiresIn, tokenType } = tokenData.data;\n\n // 응답 생성\n const response = NextResponse.json(\n {\n isSuccess: true,\n code: '',\n message: '[ServerSideHelper-Api-Route] Token 갱신 성공',\n data: { accessToken: newAccessToken, refreshToken: newRefreshToken, expiresIn, tokenType }\n },\n { status: 200 }\n );\n\n // 새 토큰들을 쿠키에 저장\n createResponseWithCookies(response, request, {\n tokens: { accessToken: newAccessToken, refreshToken: newRefreshToken, expiresIn, tokenType }\n });\n\n return response;\n } catch (error) {\n console.error('Token refresh error:', error);\n\n return NextResponse.json(\n {\n isSuccess: false,\n code: 'REFRESH_TOKEN_MISSING',\n message: '[ServerSideHelper-Api-Route] 토큰 재발급 중 오류가 발생했습니다.',\n data: null\n } as ApiErrorResponse,\n { status: 401 }\n );\n }\n};\n","import { NextResponse } from 'next/server';\n\n/**\n * 서버의 현재 시간을 밀리초 단위로 반환합니다.\n * API Route에서 사용될 수 있습니다.\n * 권장경로: /app/internal/api/time/route.ts\n * Method: GET\n * @returns\n */\nexport const getServerTime = () => {\n const now = new Date();\n const serverTime = now.getTime();\n\n return NextResponse.json({\n isSuccess: true,\n code: '',\n message: 'Current server time fetched successfully',\n data: { serverTime }\n });\n};\n","import { NextRequest, NextResponse } from 'next/server';\n\nimport { type HttpClientConfig, HttpClientFetch } from 'sales-frontend-api/server';\nimport { getApiHostNameFromEnvironment } from 'sales-frontend-utils';\n\nimport { getDefaultCookieConfig } from '../utils';\n\nexport interface DspResponseVerificationResponseDto {\n isSuccess: boolean;\n code: string;\n message: string;\n data: VerificationResponseDto;\n}\n\nexport interface VerificationResponseDto {\n /**\n * 토큰타입\n * @example Bearer\n */\n tokenType: string;\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n}\n\n/**\n * @description 고객인증검증 요청\n */\nexport interface VerificationRequestDto {\n /**\n * example: 63165824132905202oa4\n * 티켓\n */\n ticket: string;\n /**\n * @example 1234567890 사용자 ID (고객 ID 또는 FP사원번호)\n */\n userId: string;\n /**\n * @example rxoBpkaMHU 넥스트랩 인증 ID\n */\n nlcCtfnId: string;\n}\n\nexport const participantCertificationsVerification = async (request: NextRequest, fetchOption?: HttpClientConfig) => {\n const params: VerificationRequestDto = await request.json();\n console.log('[participantCertificationsVerification] parameter::', params);\n\n const apiUrl = `/api/dea/v1/post/participant/certifications/verification`;\n const httpClientServer = new HttpClientFetch({\n baseURL: `${getApiHostNameFromEnvironment(request.nextUrl.hostname)}`,\n ...fetchOption\n });\n\n const { data } = await httpClientServer.post<DspResponseVerificationResponseDto>(apiUrl, params);\n\n console.log('[participantCertificationsVerification] 응답:', data);\n\n // 인증검증 실패\n if (data.isSuccess === false) {\n console.error('[participantCertificationsVerification] 인증검증 실패');\n\n return NextResponse.json({\n isSuccess: data.isSuccess,\n code: data.code,\n message: data.message,\n data: 'fail'\n });\n }\n // 인증성공 응답 생성\n const response = NextResponse.json({\n isSuccess: data.isSuccess,\n code: data.code,\n message: data.message,\n data: 'ok'\n });\n\n const { accessToken, refreshToken } = data.data;\n const { hostname } = new URL(request.url);\n if (data.isSuccess) {\n // 액세스 토큰 쿠키\n if (accessToken) {\n response.cookies.set({\n name: 'accessToken',\n value: accessToken,\n ...getDefaultCookieConfig(hostname),\n //! middleware 커스텀헤더 세팅 불가로 우선 풀어 넣음\n httpOnly: false\n });\n }\n // 리프레시 토큰 쿠키\n if (refreshToken) {\n response.cookies.set({\n name: 'refreshToken',\n value: refreshToken,\n ...getDefaultCookieConfig(hostname),\n httpOnly: true\n });\n }\n }\n\n return response;\n};\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextRequest, NextResponse } from 'next/server';
|
|
2
2
|
import { R as RefreshTokensOptions, A as ApiErrorResponse } from '../server-side-helper.types-tKQj3B1_.cjs';
|
|
3
|
+
import { HttpClientConfig } from 'sales-frontend-api/server';
|
|
3
4
|
import 'sales-frontend-api/middleware';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -71,7 +72,7 @@ interface VerificationRequestDto {
|
|
|
71
72
|
*/
|
|
72
73
|
nlcCtfnId: string;
|
|
73
74
|
}
|
|
74
|
-
declare const participantCertificationsVerification: (request: NextRequest) => Promise<NextResponse<{
|
|
75
|
+
declare const participantCertificationsVerification: (request: NextRequest, fetchOption?: HttpClientConfig) => Promise<NextResponse<{
|
|
75
76
|
isSuccess: false;
|
|
76
77
|
code: string;
|
|
77
78
|
message: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NextRequest, NextResponse } from 'next/server';
|
|
2
2
|
import { R as RefreshTokensOptions, A as ApiErrorResponse } from '../server-side-helper.types-tKQj3B1_.js';
|
|
3
|
+
import { HttpClientConfig } from 'sales-frontend-api/server';
|
|
3
4
|
import 'sales-frontend-api/middleware';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -71,7 +72,7 @@ interface VerificationRequestDto {
|
|
|
71
72
|
*/
|
|
72
73
|
nlcCtfnId: string;
|
|
73
74
|
}
|
|
74
|
-
declare const participantCertificationsVerification: (request: NextRequest) => Promise<NextResponse<{
|
|
75
|
+
declare const participantCertificationsVerification: (request: NextRequest, fetchOption?: HttpClientConfig) => Promise<NextResponse<{
|
|
75
76
|
isSuccess: false;
|
|
76
77
|
code: string;
|
|
77
78
|
message: string;
|
package/dist/api-route/index.js
CHANGED
|
@@ -235,12 +235,13 @@ var getServerTime = () => {
|
|
|
235
235
|
data: { serverTime }
|
|
236
236
|
});
|
|
237
237
|
};
|
|
238
|
-
var participantCertificationsVerification = async (request) => {
|
|
238
|
+
var participantCertificationsVerification = async (request, fetchOption) => {
|
|
239
239
|
const params = await request.json();
|
|
240
240
|
console.log("[participantCertificationsVerification] parameter::", params);
|
|
241
241
|
const apiUrl = `/api/dea/v1/post/participant/certifications/verification`;
|
|
242
242
|
const httpClientServer = new HttpClientFetch({
|
|
243
|
-
baseURL: `${getApiHostNameFromEnvironment(request.nextUrl.hostname)}
|
|
243
|
+
baseURL: `${getApiHostNameFromEnvironment(request.nextUrl.hostname)}`,
|
|
244
|
+
...fetchOption
|
|
244
245
|
});
|
|
245
246
|
const { data } = await httpClientServer.post(apiUrl, params);
|
|
246
247
|
console.log("[participantCertificationsVerification] \uC751\uB2F5:", data);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/config/cookie-config.ts","../../src/utils/parse-utils.ts","../../src/utils/middleware-utils.ts","../../src/utils/cookie-utils.ts","../../src/api-route/refresh-token.ts","../../src/api-route/server-time.ts","../../src/api-route/participant-certifications-verification.ts"],"names":["NextResponse","getApiHostNameFromEnvironment"],"mappings":"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","file":"index.js","sourcesContent":["export const COOKIE_DEFAULT_CONFIG = {\n httpOnly: false,\n sameSite: 'strict' as const,\n secure: true\n};\n","import { NextRequest } from 'next/server';\n\n/**\n * 요청 헤더에 값 파싱\n * @param request\n * @returns\n */\nexport const parseRequestHeaders = (request: NextRequest) => {\n return {\n acceptLanguage: request.headers.get('Accept-Language'),\n deviceId: request.headers.get('X-Channel-DeviceId'),\n loginType: request.headers.get('X-Channel-LoginType'),\n platformName: request.headers.get('X-Channel-PlatformName'),\n platformVersion: request.headers.get('X-Channel-PlatformVersion'),\n appVersion: request.headers.get('X-Channel-AppVersion'),\n deviceModel: request.headers.get('X-Channel-DeviceModel'),\n loginChannel: request.headers.get('X-Channel-LoginChannel'),\n formFactor: request.headers.get('X-Channel-FormFactor')\n };\n};\n\n/**\n * 쿼리 스트링 값 파싱\n * @param request\n * @returns\n */\nexport const parseQueryParameters = (request: NextRequest) => {\n const { searchParams } = request.nextUrl;\n\n return {\n tempToken: searchParams.get('tempToken')\n };\n};\n\n/**\n * 요청 쿠키에 값 파싱\n * @param request\n * @returns\n */\nexport const parseCookies = (request: NextRequest) => {\n return {\n formFactor: request.cookies.get('formFactor')?.value,\n accessToken: request.cookies.get('accessToken')?.value\n };\n};\n","import { NextRequest } from 'next/server';\n\nimport { getFormFactorFromUserAgent } from 'sales-frontend-utils';\n\nimport { parseCookies, parseRequestHeaders } from './parse-utils';\n\n/**\n * FormFactor에 따른 적응형 경로 변환\n * @param pathname\n * @param formFactor\n * @returns\n */\nexport const convertAdaptiveTargetPath = (pathname: string, formFactor: string) => {\n if (pathname === '/') {\n return pathname;\n }\n\n switch (formFactor.toLowerCase()) {\n case 'tablet':\n return `/tablet${pathname}`;\n case 'phone':\n case 'smartphone':\n return `/mobile${pathname}`;\n case 'desktop':\n case 'pc':\n return `/pc${pathname}`;\n default:\n return pathname;\n }\n};\n\n/**\n * FormFactor 구하기\n * @param request\n * @returns\n */\nexport const getFormFactor = (request: NextRequest) => {\n const userAgent = request.headers.get('user-agent') || '';\n\n // 1순위: Custom Header\n const headerValue = parseRequestHeaders(request).formFactor;\n if (headerValue) {\n return headerValue;\n }\n\n // 2순위: Cookie\n const cookieValue = parseCookies(request).formFactor;\n if (cookieValue) {\n return cookieValue;\n }\n\n // 3순위: User-Agent 판단\n return getFormFactorFromUserAgent(userAgent);\n};\n\n/**\n * 반응형 전용 pathname 판단\n * @param pathname\n * @param responsivePaths\n * @returns\n */\nexport const isResponsivePath = (pathname: string, responsivePaths: string[] = []): boolean => {\n return responsivePaths.some((path) => pathname.startsWith(path));\n};\n\n/**\n * 정적 자원 체크 함수\n * @param pathname\n * @returns\n */\nexport const isStaticAsset = (pathname: string): boolean => {\n // API 라우트는 제외\n if (pathname.startsWith('/api')) {\n return false;\n }\n\n // _next 관련 파일들\n if (pathname.startsWith('/_next') || pathname === '/favicon.ico') {\n return true;\n }\n\n // 확장자가 있으면 정적 자원\n return /\\.[a-zA-Z0-9]+$/.test(pathname);\n};\n","import { NextRequest, NextResponse } from 'next/server';\n\nimport { getEnvironmentFromHostname } from 'sales-frontend-utils';\n\nimport { COOKIE_DEFAULT_CONFIG } from '../config/cookie-config';\nimport { CookieData } from '../server-side-helper.types';\n\nimport { getFormFactor } from './middleware-utils';\nimport { parseRequestHeaders } from './parse-utils';\n\n/**\n * 쿠키 생성\n * @param response\n * @param cookieData\n * @returns\n */\nexport const createResponseWithCookies = (\n response: NextResponse,\n request: NextRequest,\n cookieData?: CookieData\n): NextResponse => {\n const { hostname } = new URL(request.url);\n const formFactor = getFormFactor(request);\n\n // 헤더에 있는 데이터 > 쿠키 > 초기 셋업\n const { acceptLanguage, appVersion, deviceId, deviceModel, loginChannel, loginType, platformName, platformVersion } =\n parseRequestHeaders(request);\n\n // 토큰타입\n if (cookieData?.tokens?.tokenType) {\n response.cookies.set({\n name: 'tokenType',\n value: cookieData.tokens.tokenType,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // expiresIn\n if (cookieData?.tokens?.expiresIn) {\n response.cookies.set({\n name: 'expiresIn',\n value: String(cookieData.tokens.expiresIn),\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // 액세스 토큰 쿠키\n if (cookieData?.tokens?.accessToken) {\n response.cookies.set({\n name: 'accessToken',\n value: cookieData.tokens.accessToken,\n ...getDefaultCookieConfig(hostname),\n //! middleware 커스텀헤더 세팅 불가로 우선 풀어 넣음\n httpOnly: false\n });\n }\n\n // 리프레시 토큰 쿠키\n if (cookieData?.tokens?.refreshToken) {\n response.cookies.set({\n name: 'refreshToken',\n value: cookieData.tokens.refreshToken,\n ...getDefaultCookieConfig(hostname),\n httpOnly: true\n });\n }\n\n // FormFactor 쿠키\n if (formFactor) {\n response.cookies.set({\n name: 'formFactor',\n value: formFactor,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Accept Language 쿠키\n if (acceptLanguage) {\n response.cookies.set({\n name: 'acceptLanguage',\n value: acceptLanguage,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // App Version 쿠키\n if (appVersion) {\n response.cookies.set({\n name: 'appVersion',\n value: appVersion,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Device ID 쿠키\n if (deviceId) {\n response.cookies.set({\n name: 'deviceId',\n value: deviceId,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Device Model 쿠키\n if (deviceModel) {\n response.cookies.set({\n name: 'deviceModel',\n value: deviceModel,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Login Channel 쿠키\n if (loginChannel) {\n response.cookies.set({\n name: 'loginChannel',\n value: loginChannel,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Login Type 쿠키\n if (loginType) {\n response.cookies.set({\n name: 'loginType',\n value: loginType,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Platform Name 쿠키\n if (platformName) {\n response.cookies.set({\n name: 'platformName',\n value: platformName,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Platform Version 쿠키\n if (platformVersion) {\n response.cookies.set({\n name: 'platformVersion',\n value: platformVersion,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n return response;\n};\n\n/**\n * 환경에 따른 기본 쿠키 설정값 반환\n * @param hostname\n * @returns\n */\nexport const getDefaultCookieConfig = (hostname: string) => {\n const environment = getEnvironmentFromHostname(hostname);\n\n if (environment !== 'prd') {\n return {\n ...COOKIE_DEFAULT_CONFIG,\n sameSite: 'lax' as const\n };\n }\n\n return COOKIE_DEFAULT_CONFIG;\n};\n","import { NextRequest, NextResponse } from 'next/server';\n\nimport { requestRefreshToken } from 'sales-frontend-api/middleware';\nimport { getApiHostNameFromEnvironment } from 'sales-frontend-utils';\n\nimport { ApiErrorResponse, RefreshTokensOptions } from '../server-side-helper.types';\nimport { createResponseWithCookies } from '../utils/cookie-utils';\n\n/**\n * 리프레시 토큰을 사용하여 새로운 액세스 토큰과 리프레시 토큰을 쿠키로 발급 받습니다.\n * API Route에서 사용될 수 있습니다.\n * 각 프로젝트 API Route 생성 경로: /app/internal/api/auth/refresh/route.ts\n * Method: POST\n * @returns 새로운 AT, RT 발급 후 새 AT 반환\n */\nexport const refreshTokens = async (request: NextRequest, refreshTokensOptions?: RefreshTokensOptions) => {\n const refreshToken = request.cookies.get('refreshToken')?.value;\n\n // 기본 밸리데이션\n if (!refreshToken) {\n return NextResponse.json(\n {\n isSuccess: false,\n code: 'REFRESH_TOKEN_MISSING',\n message: '[ServerSideHelper-Api-Route] Refresh Token이 존재하지 않습니다.)',\n data: null\n } as ApiErrorResponse,\n { status: 401 }\n );\n }\n\n try {\n const tokenData = await requestRefreshToken(\n { refreshToken },\n {\n baseURL: getApiHostNameFromEnvironment(new URL(request.url).hostname, refreshTokensOptions?.forceApiHostName),\n ...Object.fromEntries(\n Array.from(request.headers.entries()).filter(([key]) => key.toLowerCase().startsWith('x-channel'))\n )\n }\n );\n\n console.log('[ServerSideHelper-Api-Route] tokenData', tokenData);\n\n if (tokenData.isSuccess === false) {\n return NextResponse.json(\n {\n isSuccess: false,\n code: tokenData.code || 'TOKEN_REFRESH_FAILED',\n message: `[ServerSideHelper-Api-Route] ${tokenData.message || '토큰 갱신에 실패했습니다.'}`,\n data: null\n } as ApiErrorResponse,\n { status: 401 }\n );\n }\n\n // 응답 유효성 체크\n if (!tokenData.data?.accessToken || !tokenData.data?.refreshToken) {\n throw new Error('[ServerSideHelper-Api-Route] Invalid token data structure');\n }\n\n const { accessToken: newAccessToken, refreshToken: newRefreshToken, expiresIn, tokenType } = tokenData.data;\n\n // 응답 생성\n const response = NextResponse.json(\n {\n isSuccess: true,\n code: '',\n message: '[ServerSideHelper-Api-Route] Token 갱신 성공',\n data: { accessToken: newAccessToken, refreshToken: newRefreshToken, expiresIn, tokenType }\n },\n { status: 200 }\n );\n\n // 새 토큰들을 쿠키에 저장\n createResponseWithCookies(response, request, {\n tokens: { accessToken: newAccessToken, refreshToken: newRefreshToken, expiresIn, tokenType }\n });\n\n return response;\n } catch (error) {\n console.error('Token refresh error:', error);\n\n return NextResponse.json(\n {\n isSuccess: false,\n code: 'REFRESH_TOKEN_MISSING',\n message: '[ServerSideHelper-Api-Route] 토큰 재발급 중 오류가 발생했습니다.',\n data: null\n } as ApiErrorResponse,\n { status: 401 }\n );\n }\n};\n","import { NextResponse } from 'next/server';\n\n/**\n * 서버의 현재 시간을 밀리초 단위로 반환합니다.\n * API Route에서 사용될 수 있습니다.\n * 권장경로: /app/internal/api/time/route.ts\n * Method: GET\n * @returns\n */\nexport const getServerTime = () => {\n const now = new Date();\n const serverTime = now.getTime();\n\n return NextResponse.json({\n isSuccess: true,\n code: '',\n message: 'Current server time fetched successfully',\n data: { serverTime }\n });\n};\n","import { NextRequest, NextResponse } from 'next/server';\n\nimport { HttpClientFetch } from 'sales-frontend-api/server';\nimport { getApiHostNameFromEnvironment } from 'sales-frontend-utils';\n\nimport { getDefaultCookieConfig } from '../utils';\n\nexport interface DspResponseVerificationResponseDto {\n isSuccess: boolean;\n code: string;\n message: string;\n data: VerificationResponseDto;\n}\n\nexport interface VerificationResponseDto {\n /**\n * 토큰타입\n * @example Bearer\n */\n tokenType: string;\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n}\n\n/**\n * @description 고객인증검증 요청\n */\nexport interface VerificationRequestDto {\n /**\n * example: 63165824132905202oa4\n * 티켓\n */\n ticket: string;\n /**\n * @example 1234567890 사용자 ID (고객 ID 또는 FP사원번호)\n */\n userId: string;\n /**\n * @example rxoBpkaMHU 넥스트랩 인증 ID\n */\n nlcCtfnId: string;\n}\n\nexport const participantCertificationsVerification = async (request: NextRequest) => {\n const params: VerificationRequestDto = await request.json();\n console.log('[participantCertificationsVerification] parameter::', params);\n\n const apiUrl = `/api/dea/v1/post/participant/certifications/verification`;\n const httpClientServer = new HttpClientFetch({\n baseURL: `${getApiHostNameFromEnvironment(request.nextUrl.hostname)}`\n });\n\n const { data } = await httpClientServer.post<DspResponseVerificationResponseDto>(apiUrl, params);\n\n console.log('[participantCertificationsVerification] 응답:', data);\n\n // 인증검증 실패\n if (data.isSuccess === false) {\n console.error('[participantCertificationsVerification] 인증검증 실패');\n\n return NextResponse.json({\n isSuccess: data.isSuccess,\n code: data.code,\n message: data.message,\n data: 'fail'\n });\n }\n // 인증성공 응답 생성\n const response = NextResponse.json({\n isSuccess: data.isSuccess,\n code: data.code,\n message: data.message,\n data: 'ok'\n });\n\n const { accessToken, refreshToken } = data.data;\n const { hostname } = new URL(request.url);\n if (data.isSuccess) {\n // 액세스 토큰 쿠키\n if (accessToken) {\n response.cookies.set({\n name: 'accessToken',\n value: accessToken,\n ...getDefaultCookieConfig(hostname),\n //! middleware 커스텀헤더 세팅 불가로 우선 풀어 넣음\n httpOnly: false\n });\n }\n // 리프레시 토큰 쿠키\n if (refreshToken) {\n response.cookies.set({\n name: 'refreshToken',\n value: refreshToken,\n ...getDefaultCookieConfig(hostname),\n httpOnly: true\n });\n }\n }\n\n return response;\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/config/cookie-config.ts","../../src/utils/parse-utils.ts","../../src/utils/middleware-utils.ts","../../src/utils/cookie-utils.ts","../../src/api-route/refresh-token.ts","../../src/api-route/server-time.ts","../../src/api-route/participant-certifications-verification.ts"],"names":["NextResponse","getApiHostNameFromEnvironment"],"mappings":"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","file":"index.js","sourcesContent":["export const COOKIE_DEFAULT_CONFIG = {\n httpOnly: false,\n sameSite: 'strict' as const,\n secure: true\n};\n","import { NextRequest } from 'next/server';\n\n/**\n * 요청 헤더에 값 파싱\n * @param request\n * @returns\n */\nexport const parseRequestHeaders = (request: NextRequest) => {\n return {\n acceptLanguage: request.headers.get('Accept-Language'),\n deviceId: request.headers.get('X-Channel-DeviceId'),\n loginType: request.headers.get('X-Channel-LoginType'),\n platformName: request.headers.get('X-Channel-PlatformName'),\n platformVersion: request.headers.get('X-Channel-PlatformVersion'),\n appVersion: request.headers.get('X-Channel-AppVersion'),\n deviceModel: request.headers.get('X-Channel-DeviceModel'),\n loginChannel: request.headers.get('X-Channel-LoginChannel'),\n formFactor: request.headers.get('X-Channel-FormFactor')\n };\n};\n\n/**\n * 쿼리 스트링 값 파싱\n * @param request\n * @returns\n */\nexport const parseQueryParameters = (request: NextRequest) => {\n const { searchParams } = request.nextUrl;\n\n return {\n tempToken: searchParams.get('tempToken')\n };\n};\n\n/**\n * 요청 쿠키에 값 파싱\n * @param request\n * @returns\n */\nexport const parseCookies = (request: NextRequest) => {\n return {\n formFactor: request.cookies.get('formFactor')?.value,\n accessToken: request.cookies.get('accessToken')?.value\n };\n};\n","import { NextRequest } from 'next/server';\n\nimport { getFormFactorFromUserAgent } from 'sales-frontend-utils';\n\nimport { parseCookies, parseRequestHeaders } from './parse-utils';\n\n/**\n * FormFactor에 따른 적응형 경로 변환\n * @param pathname\n * @param formFactor\n * @returns\n */\nexport const convertAdaptiveTargetPath = (pathname: string, formFactor: string) => {\n if (pathname === '/') {\n return pathname;\n }\n\n switch (formFactor.toLowerCase()) {\n case 'tablet':\n return `/tablet${pathname}`;\n case 'phone':\n case 'smartphone':\n return `/mobile${pathname}`;\n case 'desktop':\n case 'pc':\n return `/pc${pathname}`;\n default:\n return pathname;\n }\n};\n\n/**\n * FormFactor 구하기\n * @param request\n * @returns\n */\nexport const getFormFactor = (request: NextRequest) => {\n const userAgent = request.headers.get('user-agent') || '';\n\n // 1순위: Custom Header\n const headerValue = parseRequestHeaders(request).formFactor;\n if (headerValue) {\n return headerValue;\n }\n\n // 2순위: Cookie\n const cookieValue = parseCookies(request).formFactor;\n if (cookieValue) {\n return cookieValue;\n }\n\n // 3순위: User-Agent 판단\n return getFormFactorFromUserAgent(userAgent);\n};\n\n/**\n * 반응형 전용 pathname 판단\n * @param pathname\n * @param responsivePaths\n * @returns\n */\nexport const isResponsivePath = (pathname: string, responsivePaths: string[] = []): boolean => {\n return responsivePaths.some((path) => pathname.startsWith(path));\n};\n\n/**\n * 정적 자원 체크 함수\n * @param pathname\n * @returns\n */\nexport const isStaticAsset = (pathname: string): boolean => {\n // API 라우트는 제외\n if (pathname.startsWith('/api')) {\n return false;\n }\n\n // _next 관련 파일들\n if (pathname.startsWith('/_next') || pathname === '/favicon.ico') {\n return true;\n }\n\n // 확장자가 있으면 정적 자원\n return /\\.[a-zA-Z0-9]+$/.test(pathname);\n};\n","import { NextRequest, NextResponse } from 'next/server';\n\nimport { getEnvironmentFromHostname } from 'sales-frontend-utils';\n\nimport { COOKIE_DEFAULT_CONFIG } from '../config/cookie-config';\nimport { CookieData } from '../server-side-helper.types';\n\nimport { getFormFactor } from './middleware-utils';\nimport { parseRequestHeaders } from './parse-utils';\n\n/**\n * 쿠키 생성\n * @param response\n * @param cookieData\n * @returns\n */\nexport const createResponseWithCookies = (\n response: NextResponse,\n request: NextRequest,\n cookieData?: CookieData\n): NextResponse => {\n const { hostname } = new URL(request.url);\n const formFactor = getFormFactor(request);\n\n // 헤더에 있는 데이터 > 쿠키 > 초기 셋업\n const { acceptLanguage, appVersion, deviceId, deviceModel, loginChannel, loginType, platformName, platformVersion } =\n parseRequestHeaders(request);\n\n // 토큰타입\n if (cookieData?.tokens?.tokenType) {\n response.cookies.set({\n name: 'tokenType',\n value: cookieData.tokens.tokenType,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // expiresIn\n if (cookieData?.tokens?.expiresIn) {\n response.cookies.set({\n name: 'expiresIn',\n value: String(cookieData.tokens.expiresIn),\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // 액세스 토큰 쿠키\n if (cookieData?.tokens?.accessToken) {\n response.cookies.set({\n name: 'accessToken',\n value: cookieData.tokens.accessToken,\n ...getDefaultCookieConfig(hostname),\n //! middleware 커스텀헤더 세팅 불가로 우선 풀어 넣음\n httpOnly: false\n });\n }\n\n // 리프레시 토큰 쿠키\n if (cookieData?.tokens?.refreshToken) {\n response.cookies.set({\n name: 'refreshToken',\n value: cookieData.tokens.refreshToken,\n ...getDefaultCookieConfig(hostname),\n httpOnly: true\n });\n }\n\n // FormFactor 쿠키\n if (formFactor) {\n response.cookies.set({\n name: 'formFactor',\n value: formFactor,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Accept Language 쿠키\n if (acceptLanguage) {\n response.cookies.set({\n name: 'acceptLanguage',\n value: acceptLanguage,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // App Version 쿠키\n if (appVersion) {\n response.cookies.set({\n name: 'appVersion',\n value: appVersion,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Device ID 쿠키\n if (deviceId) {\n response.cookies.set({\n name: 'deviceId',\n value: deviceId,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Device Model 쿠키\n if (deviceModel) {\n response.cookies.set({\n name: 'deviceModel',\n value: deviceModel,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Login Channel 쿠키\n if (loginChannel) {\n response.cookies.set({\n name: 'loginChannel',\n value: loginChannel,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Login Type 쿠키\n if (loginType) {\n response.cookies.set({\n name: 'loginType',\n value: loginType,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Platform Name 쿠키\n if (platformName) {\n response.cookies.set({\n name: 'platformName',\n value: platformName,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n // Platform Version 쿠키\n if (platformVersion) {\n response.cookies.set({\n name: 'platformVersion',\n value: platformVersion,\n ...getDefaultCookieConfig(hostname)\n });\n }\n\n return response;\n};\n\n/**\n * 환경에 따른 기본 쿠키 설정값 반환\n * @param hostname\n * @returns\n */\nexport const getDefaultCookieConfig = (hostname: string) => {\n const environment = getEnvironmentFromHostname(hostname);\n\n if (environment !== 'prd') {\n return {\n ...COOKIE_DEFAULT_CONFIG,\n sameSite: 'lax' as const\n };\n }\n\n return COOKIE_DEFAULT_CONFIG;\n};\n","import { NextRequest, NextResponse } from 'next/server';\n\nimport { requestRefreshToken } from 'sales-frontend-api/middleware';\nimport { getApiHostNameFromEnvironment } from 'sales-frontend-utils';\n\nimport { ApiErrorResponse, RefreshTokensOptions } from '../server-side-helper.types';\nimport { createResponseWithCookies } from '../utils/cookie-utils';\n\n/**\n * 리프레시 토큰을 사용하여 새로운 액세스 토큰과 리프레시 토큰을 쿠키로 발급 받습니다.\n * API Route에서 사용될 수 있습니다.\n * 각 프로젝트 API Route 생성 경로: /app/internal/api/auth/refresh/route.ts\n * Method: POST\n * @returns 새로운 AT, RT 발급 후 새 AT 반환\n */\nexport const refreshTokens = async (request: NextRequest, refreshTokensOptions?: RefreshTokensOptions) => {\n const refreshToken = request.cookies.get('refreshToken')?.value;\n\n // 기본 밸리데이션\n if (!refreshToken) {\n return NextResponse.json(\n {\n isSuccess: false,\n code: 'REFRESH_TOKEN_MISSING',\n message: '[ServerSideHelper-Api-Route] Refresh Token이 존재하지 않습니다.)',\n data: null\n } as ApiErrorResponse,\n { status: 401 }\n );\n }\n\n try {\n const tokenData = await requestRefreshToken(\n { refreshToken },\n {\n baseURL: getApiHostNameFromEnvironment(new URL(request.url).hostname, refreshTokensOptions?.forceApiHostName),\n ...Object.fromEntries(\n Array.from(request.headers.entries()).filter(([key]) => key.toLowerCase().startsWith('x-channel'))\n )\n }\n );\n\n console.log('[ServerSideHelper-Api-Route] tokenData', tokenData);\n\n if (tokenData.isSuccess === false) {\n return NextResponse.json(\n {\n isSuccess: false,\n code: tokenData.code || 'TOKEN_REFRESH_FAILED',\n message: `[ServerSideHelper-Api-Route] ${tokenData.message || '토큰 갱신에 실패했습니다.'}`,\n data: null\n } as ApiErrorResponse,\n { status: 401 }\n );\n }\n\n // 응답 유효성 체크\n if (!tokenData.data?.accessToken || !tokenData.data?.refreshToken) {\n throw new Error('[ServerSideHelper-Api-Route] Invalid token data structure');\n }\n\n const { accessToken: newAccessToken, refreshToken: newRefreshToken, expiresIn, tokenType } = tokenData.data;\n\n // 응답 생성\n const response = NextResponse.json(\n {\n isSuccess: true,\n code: '',\n message: '[ServerSideHelper-Api-Route] Token 갱신 성공',\n data: { accessToken: newAccessToken, refreshToken: newRefreshToken, expiresIn, tokenType }\n },\n { status: 200 }\n );\n\n // 새 토큰들을 쿠키에 저장\n createResponseWithCookies(response, request, {\n tokens: { accessToken: newAccessToken, refreshToken: newRefreshToken, expiresIn, tokenType }\n });\n\n return response;\n } catch (error) {\n console.error('Token refresh error:', error);\n\n return NextResponse.json(\n {\n isSuccess: false,\n code: 'REFRESH_TOKEN_MISSING',\n message: '[ServerSideHelper-Api-Route] 토큰 재발급 중 오류가 발생했습니다.',\n data: null\n } as ApiErrorResponse,\n { status: 401 }\n );\n }\n};\n","import { NextResponse } from 'next/server';\n\n/**\n * 서버의 현재 시간을 밀리초 단위로 반환합니다.\n * API Route에서 사용될 수 있습니다.\n * 권장경로: /app/internal/api/time/route.ts\n * Method: GET\n * @returns\n */\nexport const getServerTime = () => {\n const now = new Date();\n const serverTime = now.getTime();\n\n return NextResponse.json({\n isSuccess: true,\n code: '',\n message: 'Current server time fetched successfully',\n data: { serverTime }\n });\n};\n","import { NextRequest, NextResponse } from 'next/server';\n\nimport { type HttpClientConfig, HttpClientFetch } from 'sales-frontend-api/server';\nimport { getApiHostNameFromEnvironment } from 'sales-frontend-utils';\n\nimport { getDefaultCookieConfig } from '../utils';\n\nexport interface DspResponseVerificationResponseDto {\n isSuccess: boolean;\n code: string;\n message: string;\n data: VerificationResponseDto;\n}\n\nexport interface VerificationResponseDto {\n /**\n * 토큰타입\n * @example Bearer\n */\n tokenType: string;\n accessToken: string;\n refreshToken: string;\n expiresIn: number;\n}\n\n/**\n * @description 고객인증검증 요청\n */\nexport interface VerificationRequestDto {\n /**\n * example: 63165824132905202oa4\n * 티켓\n */\n ticket: string;\n /**\n * @example 1234567890 사용자 ID (고객 ID 또는 FP사원번호)\n */\n userId: string;\n /**\n * @example rxoBpkaMHU 넥스트랩 인증 ID\n */\n nlcCtfnId: string;\n}\n\nexport const participantCertificationsVerification = async (request: NextRequest, fetchOption?: HttpClientConfig) => {\n const params: VerificationRequestDto = await request.json();\n console.log('[participantCertificationsVerification] parameter::', params);\n\n const apiUrl = `/api/dea/v1/post/participant/certifications/verification`;\n const httpClientServer = new HttpClientFetch({\n baseURL: `${getApiHostNameFromEnvironment(request.nextUrl.hostname)}`,\n ...fetchOption\n });\n\n const { data } = await httpClientServer.post<DspResponseVerificationResponseDto>(apiUrl, params);\n\n console.log('[participantCertificationsVerification] 응답:', data);\n\n // 인증검증 실패\n if (data.isSuccess === false) {\n console.error('[participantCertificationsVerification] 인증검증 실패');\n\n return NextResponse.json({\n isSuccess: data.isSuccess,\n code: data.code,\n message: data.message,\n data: 'fail'\n });\n }\n // 인증성공 응답 생성\n const response = NextResponse.json({\n isSuccess: data.isSuccess,\n code: data.code,\n message: data.message,\n data: 'ok'\n });\n\n const { accessToken, refreshToken } = data.data;\n const { hostname } = new URL(request.url);\n if (data.isSuccess) {\n // 액세스 토큰 쿠키\n if (accessToken) {\n response.cookies.set({\n name: 'accessToken',\n value: accessToken,\n ...getDefaultCookieConfig(hostname),\n //! middleware 커스텀헤더 세팅 불가로 우선 풀어 넣음\n httpOnly: false\n });\n }\n // 리프레시 토큰 쿠키\n if (refreshToken) {\n response.cookies.set({\n name: 'refreshToken',\n value: refreshToken,\n ...getDefaultCookieConfig(hostname),\n httpOnly: true\n });\n }\n }\n\n return response;\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sales-frontend-server-side-helper",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.73",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -43,15 +43,15 @@
|
|
|
43
43
|
"next": "^15.3.0",
|
|
44
44
|
"tsup": "^8.4.0",
|
|
45
45
|
"typescript": "5.8.2",
|
|
46
|
-
"sales-frontend-
|
|
47
|
-
"
|
|
46
|
+
"eslint-config-sales-frontend-eslint-config-v8": "^0.0.6",
|
|
47
|
+
"sales-frontend-typescript-config": "0.0.2"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"next": ">=15.3.0"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"sales-frontend-utils": "0.0.25",
|
|
54
|
-
"sales-frontend-api": "0.0.
|
|
54
|
+
"sales-frontend-api": "0.0.90"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"lint": "eslint . --max-warnings 0",
|