diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-07-25 07:51:15 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-07-25 07:51:15 +0000 |
| commit | 2650b7c0bb0ea12b68a58c0439f72d61df04b2f1 (patch) | |
| tree | 17156183fd74b69d78178065388ac61a18ac07b4 /middleware.ts | |
| parent | d32acea05915bd6c1ed4b95e56c41ef9204347bc (diff) | |
(대표님) 정기평가 대상, 미들웨어 수정, nextauth 토큰 처리 개선, GTC 등
(최겸) 기술영업
Diffstat (limited to 'middleware.ts')
| -rw-r--r-- | middleware.ts | 68 |
1 files changed, 35 insertions, 33 deletions
diff --git a/middleware.ts b/middleware.ts index cbe78067..595f87e1 100644 --- a/middleware.ts +++ b/middleware.ts @@ -23,7 +23,6 @@ const publicPaths = [ '/api/auth', '/spreadTest', '/auth/reset-password', - ]; const landingPages = [ @@ -49,7 +48,6 @@ function isPublicPath(path: string, lng: string) { // 3. publicPaths 배열의 경로들과 매칭 if (publicPaths.some(publicPath => { - // return path === `/${lng}${publicPath}` || path.startsWith(`/${lng}${publicPath}/`); return path === `/${lng}${publicPath}`; })) { return true; @@ -104,20 +102,22 @@ function getDomainRedirectPath(path: string, domain: string, lng: string) { // 도메인이 없는 경우 리다이렉트 없음 if (!domain) return null; - // 각 도메인 경로 패턴 확인 + // 각 도메인 경로 패턴 확인 (trailing slash 문제 해결) const domainPatterns = { - pending: `/pending/`, - evcp: `/evcp/`, - procurement: `/procurement/`, - sales: `/sales/`, - engineering: `/engineering/`, - partners: `/partners/` + pending: `/pending`, + evcp: `/evcp`, + procurement: `/procurement`, + sales: `/sales`, + engineering: `/engineering`, + partners: `/partners` }; // 현재 경로가 어떤 도메인 패턴에 속하는지 확인 let currentPathDomain = null; for (const [domainName, pattern] of Object.entries(domainPatterns)) { - if (path.includes(pattern)) { + // 정확한 매칭을 위해 언어 코드를 포함한 전체 패턴으로 확인 + const fullPattern = `/${lng}${pattern}`; + if (path === fullPattern || path.startsWith(`${fullPattern}/`)) { currentPathDomain = domainName; break; } @@ -139,7 +139,7 @@ function getDomainRedirectPath(path: string, domain: string, lng: string) { const targetPattern = domainPatterns[domain as keyof typeof domainPatterns]; if (targetPattern && currentPathDomain) { const sourcePattern = domainPatterns[currentPathDomain as keyof typeof domainPatterns]; - return path.replace(sourcePattern, targetPattern); + return path.replace(`/${lng}${sourcePattern}`, `/${lng}${targetPattern}`); } } @@ -164,6 +164,20 @@ function checkSessionTimeout(token: any): { isExpired: boolean; isExpiringSoon: }; } +// 실제 로그인 페이지인지 확인하는 함수 (pending 페이지 제외) +function isActualLoginPage(pathname: string, detectedLng: string): boolean { + const actualLoginPages = [ + `/${detectedLng}/evcp`, + `/${detectedLng}/procurement`, + `/${detectedLng}/sales`, + `/${detectedLng}/engineering`, + `/${detectedLng}/partners`, + // pending은 로그인 페이지가 아니라 실제 대시보드이므로 제외 + ]; + + return actualLoginPages.includes(pathname); +} + // 로그인 페이지 URL 생성 함수 (세션 만료 정보 포함) function createLoginUrl(pathname: string, detectedLng: string, origin: string, request: NextRequest, reason?: string) { let loginPath; @@ -171,10 +185,9 @@ function createLoginUrl(pathname: string, detectedLng: string, origin: string, r // 경로에 따라 적절한 로그인 페이지 선택 if (pathname.includes('/partners') || pathname.startsWith(`/${detectedLng}/vendor`)) { loginPath = `/${detectedLng}/partners`; - } else if (pathname.includes('/pending')) { - loginPath = `/${detectedLng}/pending`; } else { - // evcp, procurement, sales, engineering은 모두 evcp 로그인 사용 + // evcp, procurement, sales, engineering, pending 모두 evcp 로그인 사용 + // pending 페이지는 로그인 페이지가 아니라 실제 대시보드이므로 evcp 로그인으로 보냄 loginPath = `/${detectedLng}/evcp`; } @@ -273,30 +286,19 @@ export async function middleware(request: NextRequest) { } /** - * 8. 이미 로그인한 사용자가 로그인 페이지에 접근할 경우 대시보드로 리다이렉트 + * 8. 이미 로그인한 사용자가 실제 로그인 페이지에 접근할 경우 대시보드로 리다이렉트 + * (pending 페이지는 실제 대시보드이므로 제외) */ if (token) { // 세션이 만료되지 않은 경우에만 대시보드로 리다이렉트 const { isExpired } = checkSessionTimeout(token); - if (!isExpired) { - // 모든 도메인의 로그인 페이지 확인 - const loginPages = [ - `/${detectedLng}/evcp`, - `/${detectedLng}/procurement`, - `/${detectedLng}/sales`, - `/${detectedLng}/engineering`, - `/${detectedLng}/partners`, - `/${detectedLng}/pending` - ]; - - if (loginPages.includes(pathname)) { - // 사용자의 도메인에 맞는 대시보드로 리다이렉트 - const dashboardPath = getDashboardPath(token.domain as string, detectedLng); - const redirectUrl = new URL(dashboardPath, origin); - redirectUrl.search = searchParams.toString(); - return NextResponse.redirect(redirectUrl); - } + if (!isExpired && isActualLoginPage(pathname, detectedLng)) { + // 사용자의 도메인에 맞는 대시보드로 리다이렉트 + const dashboardPath = getDashboardPath(token.domain as string, detectedLng); + const redirectUrl = new URL(dashboardPath, origin); + redirectUrl.search = searchParams.toString(); + return NextResponse.redirect(redirectUrl); } } |
