sales-frontend-server-side-helper 0.0.120 → 0.0.122
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
|
@@ -253,7 +253,8 @@ var participantCertificationsVerification = async (request, fetchOption) => {
|
|
|
253
253
|
isSuccess: data.isSuccess,
|
|
254
254
|
code: data.code,
|
|
255
255
|
message: data.message,
|
|
256
|
-
data: "fail"
|
|
256
|
+
data: "fail",
|
|
257
|
+
exceptionId: data.exceptionId
|
|
257
258
|
});
|
|
258
259
|
}
|
|
259
260
|
const response = server.NextResponse.json({
|
|
@@ -285,7 +286,59 @@ var participantCertificationsVerification = async (request, fetchOption) => {
|
|
|
285
286
|
}
|
|
286
287
|
return response;
|
|
287
288
|
};
|
|
289
|
+
async function dudInternalDownload(req) {
|
|
290
|
+
try {
|
|
291
|
+
const fileId = req.nextUrl.searchParams.get("fileid") || "";
|
|
292
|
+
const fileName = req.nextUrl.searchParams.get("filename") || "file.pdf";
|
|
293
|
+
if (!fileId || !fileName) {
|
|
294
|
+
throw new Error("fileid or filename is required");
|
|
295
|
+
}
|
|
296
|
+
const params = {
|
|
297
|
+
fileMgmtId: fileId,
|
|
298
|
+
outputType: "BINARY"
|
|
299
|
+
};
|
|
300
|
+
const apiUrl = `${salesFrontendUtils.getDudApiBasePathFromEnvironment()}/v1/get/file`;
|
|
301
|
+
const httpClient = new server$1.HttpServerAxios({
|
|
302
|
+
responseType: "blob",
|
|
303
|
+
headers: {
|
|
304
|
+
...Object.fromEntries(req.headers.entries()),
|
|
305
|
+
"Authorization": `Bearer ${req.cookies.get("accessToken")}`
|
|
306
|
+
}
|
|
307
|
+
//필요시 사용
|
|
308
|
+
// params: Object.fromEntries(req.nextUrl.searchParams.entries()),
|
|
309
|
+
});
|
|
310
|
+
httpClient.api.interceptors.request.use((config) => {
|
|
311
|
+
console.log("dud-serverside-interceptor request");
|
|
312
|
+
return config;
|
|
313
|
+
}, (error) => {
|
|
314
|
+
console.log("dud-serverside-interceptor request error");
|
|
315
|
+
return Promise.reject(error);
|
|
316
|
+
});
|
|
317
|
+
httpClient.api.interceptors.response.use((response) => {
|
|
318
|
+
console.log("dud-serverside-interceptor response");
|
|
319
|
+
const { data } = response;
|
|
320
|
+
if (!(data instanceof Blob)) {
|
|
321
|
+
return Promise.reject(response);
|
|
322
|
+
}
|
|
323
|
+
return response;
|
|
324
|
+
}, (error) => {
|
|
325
|
+
console.log("dud-serverside-interceptor response error");
|
|
326
|
+
return Promise.reject(error);
|
|
327
|
+
});
|
|
328
|
+
const res = await httpClient.api.post(apiUrl, params);
|
|
329
|
+
return new server.NextResponse(res.data, {
|
|
330
|
+
headers: {
|
|
331
|
+
"Content-Type": "application/octet-stream",
|
|
332
|
+
"Content-Disposition": res.headers["content-disposition"] || `attachment; filename="${encodeURIComponent(fileName)}"`
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
} catch (error) {
|
|
336
|
+
console.error("Dud Axios Internal Server Error", error);
|
|
337
|
+
return new server.NextResponse(`[Dud Axios Internal Server Error] : ${error instanceof Error ? error.message : "unknown error"}`, { status: 500 });
|
|
338
|
+
}
|
|
339
|
+
}
|
|
288
340
|
|
|
341
|
+
exports.dudInternalDownload = dudInternalDownload;
|
|
289
342
|
exports.getServerTime = getServerTime;
|
|
290
343
|
exports.participantCertificationsVerification = participantCertificationsVerification;
|
|
291
344
|
exports.refreshTokens = refreshTokens;
|
|
@@ -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 { 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
|
+
{"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","../../src/api-route/dud-download.ts"],"names":["getFormFactorFromUserAgent","getEnvironmentFromHostname","NextResponse","requestRefreshToken","getApiHostNameFromEnvironment","HttpClientFetch","getDudApiBasePathFromEnvironment","HttpServerAxios"],"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 { 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 exceptionId?: string;\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 /**\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\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 exceptionId: data.exceptionId\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","\n\nimport { NextRequest, NextResponse } from 'next/server';\n\nimport { HttpServerAxios } from 'sales-frontend-api/server';\nimport { getDudApiBasePathFromEnvironment } from 'sales-frontend-utils';\n\n/**\n * @description\n * 비정형의 fileId 를 파라미터로 받아서 서버사이드에서 대신 호출하여 응답을 리턴한다.\n * 링크(앵커태그), location.href 등을 이용해서 get방식으로 호출될경우 기기에서 다운받기 기능이 동작되도록 한다.\n */\nexport async function dudInternalDownload(req: NextRequest): Promise<NextResponse<Blob>> {\n try {\n\n const fileId = req.nextUrl.searchParams.get('fileid') || '';\n const fileName = req.nextUrl.searchParams.get('filename') || 'file.pdf';\n\n //fileid , filename 이 없으면 에러 리턴\n if (!fileId || !fileName) {\n throw new Error('fileid or filename is required');\n }\n\n const params = {\n fileMgmtId: fileId,\n outputType: 'BINARY'\n }\n\n const apiUrl = `${getDudApiBasePathFromEnvironment()}/v1/get/file`;\n\n const httpClient = new HttpServerAxios({\n responseType: 'blob',\n headers: {\n ...Object.fromEntries(req.headers.entries()),\n 'Authorization': `Bearer ${req.cookies.get('accessToken')}`\n },\n //필요시 사용\n // params: Object.fromEntries(req.nextUrl.searchParams.entries()),\n });\n\n httpClient.api.interceptors.request.use((config) => {\n console.log('dud-serverside-interceptor request')\n\n return config;\n }, (error) => {\n console.log('dud-serverside-interceptor request error')\n\n return Promise.reject(error);\n });\n httpClient.api.interceptors.response.use((response) => {\n console.log('dud-serverside-interceptor response')\n const { data } = response;\n\n if (!(data instanceof Blob)) {\n return Promise.reject(response);\n }\n\n return response;\n }, (error) => {\n console.log('dud-serverside-interceptor response error')\n\n return Promise.reject(error);\n });\n\n\n /**\n * FileExternalRequestDto 의 outputType 에 따라 returnType이 상이\n * outputType = 'BASE64' 이면 returnType 이 FileExternalResponseDto\n * outputType = 'BINARY' 이면 File\n */\n const res = await httpClient.api.post<Blob>(apiUrl, params);\n\n\n return new NextResponse(res.data, {\n headers: {\n 'Content-Type': 'application/octet-stream',\n 'Content-Disposition': res.headers['content-disposition'] || `attachment; filename=\"${encodeURIComponent(fileName)}\"`,\n },\n\n });\n } catch (error: any) {\n console.error('Dud Axios Internal Server Error', error);\n\n return new NextResponse(`[Dud Axios Internal Server Error] : ${error instanceof Error ? error.message : 'unknown error'}`, { status: 500 });\n }\n} "]}
|
|
@@ -43,6 +43,7 @@ interface DspResponseVerificationResponseDto {
|
|
|
43
43
|
code: string;
|
|
44
44
|
message: string;
|
|
45
45
|
data: VerificationResponseDto;
|
|
46
|
+
exceptionId?: string;
|
|
46
47
|
}
|
|
47
48
|
interface VerificationResponseDto {
|
|
48
49
|
/**
|
|
@@ -63,10 +64,6 @@ interface VerificationRequestDto {
|
|
|
63
64
|
* 티켓
|
|
64
65
|
*/
|
|
65
66
|
ticket: string;
|
|
66
|
-
/**
|
|
67
|
-
* @example 1234567890 사용자 ID (고객 ID 또는 FP사원번호)
|
|
68
|
-
*/
|
|
69
|
-
userId: string;
|
|
70
67
|
/**
|
|
71
68
|
* @example rxoBpkaMHU 넥스트랩 인증 ID
|
|
72
69
|
*/
|
|
@@ -77,6 +74,7 @@ declare const participantCertificationsVerification: (request: NextRequest, fetc
|
|
|
77
74
|
code: string;
|
|
78
75
|
message: string;
|
|
79
76
|
data: string;
|
|
77
|
+
exceptionId: string | undefined;
|
|
80
78
|
}> | NextResponse<{
|
|
81
79
|
isSuccess: true;
|
|
82
80
|
code: string;
|
|
@@ -84,4 +82,11 @@ declare const participantCertificationsVerification: (request: NextRequest, fetc
|
|
|
84
82
|
data: string;
|
|
85
83
|
}>>;
|
|
86
84
|
|
|
87
|
-
|
|
85
|
+
/**
|
|
86
|
+
* @description
|
|
87
|
+
* 비정형의 fileId 를 파라미터로 받아서 서버사이드에서 대신 호출하여 응답을 리턴한다.
|
|
88
|
+
* 링크(앵커태그), location.href 등을 이용해서 get방식으로 호출될경우 기기에서 다운받기 기능이 동작되도록 한다.
|
|
89
|
+
*/
|
|
90
|
+
declare function dudInternalDownload(req: NextRequest): Promise<NextResponse<Blob>>;
|
|
91
|
+
|
|
92
|
+
export { type DspResponseVerificationResponseDto, type VerificationRequestDto, type VerificationResponseDto, dudInternalDownload, getServerTime, participantCertificationsVerification, refreshTokens };
|
|
@@ -43,6 +43,7 @@ interface DspResponseVerificationResponseDto {
|
|
|
43
43
|
code: string;
|
|
44
44
|
message: string;
|
|
45
45
|
data: VerificationResponseDto;
|
|
46
|
+
exceptionId?: string;
|
|
46
47
|
}
|
|
47
48
|
interface VerificationResponseDto {
|
|
48
49
|
/**
|
|
@@ -63,10 +64,6 @@ interface VerificationRequestDto {
|
|
|
63
64
|
* 티켓
|
|
64
65
|
*/
|
|
65
66
|
ticket: string;
|
|
66
|
-
/**
|
|
67
|
-
* @example 1234567890 사용자 ID (고객 ID 또는 FP사원번호)
|
|
68
|
-
*/
|
|
69
|
-
userId: string;
|
|
70
67
|
/**
|
|
71
68
|
* @example rxoBpkaMHU 넥스트랩 인증 ID
|
|
72
69
|
*/
|
|
@@ -77,6 +74,7 @@ declare const participantCertificationsVerification: (request: NextRequest, fetc
|
|
|
77
74
|
code: string;
|
|
78
75
|
message: string;
|
|
79
76
|
data: string;
|
|
77
|
+
exceptionId: string | undefined;
|
|
80
78
|
}> | NextResponse<{
|
|
81
79
|
isSuccess: true;
|
|
82
80
|
code: string;
|
|
@@ -84,4 +82,11 @@ declare const participantCertificationsVerification: (request: NextRequest, fetc
|
|
|
84
82
|
data: string;
|
|
85
83
|
}>>;
|
|
86
84
|
|
|
87
|
-
|
|
85
|
+
/**
|
|
86
|
+
* @description
|
|
87
|
+
* 비정형의 fileId 를 파라미터로 받아서 서버사이드에서 대신 호출하여 응답을 리턴한다.
|
|
88
|
+
* 링크(앵커태그), location.href 등을 이용해서 get방식으로 호출될경우 기기에서 다운받기 기능이 동작되도록 한다.
|
|
89
|
+
*/
|
|
90
|
+
declare function dudInternalDownload(req: NextRequest): Promise<NextResponse<Blob>>;
|
|
91
|
+
|
|
92
|
+
export { type DspResponseVerificationResponseDto, type VerificationRequestDto, type VerificationResponseDto, dudInternalDownload, getServerTime, participantCertificationsVerification, refreshTokens };
|
package/dist/api-route/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { NextResponse } from 'next/server';
|
|
2
2
|
import { requestRefreshToken } from 'sales-frontend-api/middleware';
|
|
3
|
-
import { getApiHostNameFromEnvironment, getEnvironmentFromHostname, getFormFactorFromUserAgent } from 'sales-frontend-utils';
|
|
4
|
-
import { HttpClientFetch } from 'sales-frontend-api/server';
|
|
3
|
+
import { getApiHostNameFromEnvironment, getDudApiBasePathFromEnvironment, getEnvironmentFromHostname, getFormFactorFromUserAgent } from 'sales-frontend-utils';
|
|
4
|
+
import { HttpClientFetch, HttpServerAxios } from 'sales-frontend-api/server';
|
|
5
5
|
|
|
6
6
|
// src/api-route/refresh-token.ts
|
|
7
7
|
|
|
@@ -251,7 +251,8 @@ var participantCertificationsVerification = async (request, fetchOption) => {
|
|
|
251
251
|
isSuccess: data.isSuccess,
|
|
252
252
|
code: data.code,
|
|
253
253
|
message: data.message,
|
|
254
|
-
data: "fail"
|
|
254
|
+
data: "fail",
|
|
255
|
+
exceptionId: data.exceptionId
|
|
255
256
|
});
|
|
256
257
|
}
|
|
257
258
|
const response = NextResponse.json({
|
|
@@ -283,7 +284,58 @@ var participantCertificationsVerification = async (request, fetchOption) => {
|
|
|
283
284
|
}
|
|
284
285
|
return response;
|
|
285
286
|
};
|
|
287
|
+
async function dudInternalDownload(req) {
|
|
288
|
+
try {
|
|
289
|
+
const fileId = req.nextUrl.searchParams.get("fileid") || "";
|
|
290
|
+
const fileName = req.nextUrl.searchParams.get("filename") || "file.pdf";
|
|
291
|
+
if (!fileId || !fileName) {
|
|
292
|
+
throw new Error("fileid or filename is required");
|
|
293
|
+
}
|
|
294
|
+
const params = {
|
|
295
|
+
fileMgmtId: fileId,
|
|
296
|
+
outputType: "BINARY"
|
|
297
|
+
};
|
|
298
|
+
const apiUrl = `${getDudApiBasePathFromEnvironment()}/v1/get/file`;
|
|
299
|
+
const httpClient = new HttpServerAxios({
|
|
300
|
+
responseType: "blob",
|
|
301
|
+
headers: {
|
|
302
|
+
...Object.fromEntries(req.headers.entries()),
|
|
303
|
+
"Authorization": `Bearer ${req.cookies.get("accessToken")}`
|
|
304
|
+
}
|
|
305
|
+
//필요시 사용
|
|
306
|
+
// params: Object.fromEntries(req.nextUrl.searchParams.entries()),
|
|
307
|
+
});
|
|
308
|
+
httpClient.api.interceptors.request.use((config) => {
|
|
309
|
+
console.log("dud-serverside-interceptor request");
|
|
310
|
+
return config;
|
|
311
|
+
}, (error) => {
|
|
312
|
+
console.log("dud-serverside-interceptor request error");
|
|
313
|
+
return Promise.reject(error);
|
|
314
|
+
});
|
|
315
|
+
httpClient.api.interceptors.response.use((response) => {
|
|
316
|
+
console.log("dud-serverside-interceptor response");
|
|
317
|
+
const { data } = response;
|
|
318
|
+
if (!(data instanceof Blob)) {
|
|
319
|
+
return Promise.reject(response);
|
|
320
|
+
}
|
|
321
|
+
return response;
|
|
322
|
+
}, (error) => {
|
|
323
|
+
console.log("dud-serverside-interceptor response error");
|
|
324
|
+
return Promise.reject(error);
|
|
325
|
+
});
|
|
326
|
+
const res = await httpClient.api.post(apiUrl, params);
|
|
327
|
+
return new NextResponse(res.data, {
|
|
328
|
+
headers: {
|
|
329
|
+
"Content-Type": "application/octet-stream",
|
|
330
|
+
"Content-Disposition": res.headers["content-disposition"] || `attachment; filename="${encodeURIComponent(fileName)}"`
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
} catch (error) {
|
|
334
|
+
console.error("Dud Axios Internal Server Error", error);
|
|
335
|
+
return new NextResponse(`[Dud Axios Internal Server Error] : ${error instanceof Error ? error.message : "unknown error"}`, { status: 500 });
|
|
336
|
+
}
|
|
337
|
+
}
|
|
286
338
|
|
|
287
|
-
export { getServerTime, participantCertificationsVerification, refreshTokens };
|
|
339
|
+
export { dudInternalDownload, getServerTime, participantCertificationsVerification, refreshTokens };
|
|
288
340
|
//# sourceMappingURL=index.js.map
|
|
289
341
|
//# sourceMappingURL=index.js.map
|
|
@@ -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 { 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
|
+
{"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","../../src/api-route/dud-download.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 exceptionId?: string;\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 /**\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\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 exceptionId: data.exceptionId\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","\n\nimport { NextRequest, NextResponse } from 'next/server';\n\nimport { HttpServerAxios } from 'sales-frontend-api/server';\nimport { getDudApiBasePathFromEnvironment } from 'sales-frontend-utils';\n\n/**\n * @description\n * 비정형의 fileId 를 파라미터로 받아서 서버사이드에서 대신 호출하여 응답을 리턴한다.\n * 링크(앵커태그), location.href 등을 이용해서 get방식으로 호출될경우 기기에서 다운받기 기능이 동작되도록 한다.\n */\nexport async function dudInternalDownload(req: NextRequest): Promise<NextResponse<Blob>> {\n try {\n\n const fileId = req.nextUrl.searchParams.get('fileid') || '';\n const fileName = req.nextUrl.searchParams.get('filename') || 'file.pdf';\n\n //fileid , filename 이 없으면 에러 리턴\n if (!fileId || !fileName) {\n throw new Error('fileid or filename is required');\n }\n\n const params = {\n fileMgmtId: fileId,\n outputType: 'BINARY'\n }\n\n const apiUrl = `${getDudApiBasePathFromEnvironment()}/v1/get/file`;\n\n const httpClient = new HttpServerAxios({\n responseType: 'blob',\n headers: {\n ...Object.fromEntries(req.headers.entries()),\n 'Authorization': `Bearer ${req.cookies.get('accessToken')}`\n },\n //필요시 사용\n // params: Object.fromEntries(req.nextUrl.searchParams.entries()),\n });\n\n httpClient.api.interceptors.request.use((config) => {\n console.log('dud-serverside-interceptor request')\n\n return config;\n }, (error) => {\n console.log('dud-serverside-interceptor request error')\n\n return Promise.reject(error);\n });\n httpClient.api.interceptors.response.use((response) => {\n console.log('dud-serverside-interceptor response')\n const { data } = response;\n\n if (!(data instanceof Blob)) {\n return Promise.reject(response);\n }\n\n return response;\n }, (error) => {\n console.log('dud-serverside-interceptor response error')\n\n return Promise.reject(error);\n });\n\n\n /**\n * FileExternalRequestDto 의 outputType 에 따라 returnType이 상이\n * outputType = 'BASE64' 이면 returnType 이 FileExternalResponseDto\n * outputType = 'BINARY' 이면 File\n */\n const res = await httpClient.api.post<Blob>(apiUrl, params);\n\n\n return new NextResponse(res.data, {\n headers: {\n 'Content-Type': 'application/octet-stream',\n 'Content-Disposition': res.headers['content-disposition'] || `attachment; filename=\"${encodeURIComponent(fileName)}\"`,\n },\n\n });\n } catch (error: any) {\n console.error('Dud Axios Internal Server Error', error);\n\n return new NextResponse(`[Dud Axios Internal Server Error] : ${error instanceof Error ? error.message : 'unknown error'}`, { status: 500 });\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.122",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -44,15 +44,15 @@
|
|
|
44
44
|
"tsup": "^8.4.0",
|
|
45
45
|
"typescript": "5.8.2",
|
|
46
46
|
"eslint-config-sales-frontend-eslint-config-v8": "^0.0.7",
|
|
47
|
-
"sales-frontend-
|
|
48
|
-
"sales-frontend-
|
|
47
|
+
"sales-frontend-api": "0.0.138",
|
|
48
|
+
"sales-frontend-typescript-config": "0.0.2"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"next": ">=15.3.0",
|
|
52
|
-
"sales-frontend-api": "0.0.
|
|
52
|
+
"sales-frontend-api": "0.0.138"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"sales-frontend-utils": "0.0.
|
|
55
|
+
"sales-frontend-utils": "0.0.49"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"lint": "eslint . --max-warnings 0",
|