diff --git a/src/pages/Loading/hooks/useLoadingPage.ts b/src/pages/Loading/hooks/useLoadingPage.ts index df02e41..aab3336 100644 --- a/src/pages/Loading/hooks/useLoadingPage.ts +++ b/src/pages/Loading/hooks/useLoadingPage.ts @@ -7,6 +7,7 @@ import { pickString } from '@/shared/api/responseAccess/payloadAccess'; import { resolveResultToneFromSources } from '@/shared/api/risk/resolveResultTone'; import { mapSseStepId } from '@/shared/api/sse/sseStepMapper'; import { ensureScanDetail } from '@/shared/lib/scan-session/ensureScanDetail'; +import { isWebScanTarget } from '@/shared/lib/scan-session/scanClassification'; import { useScanSubscription } from '@/shared/lib/sse/useScanSubscription'; import { useGuestStore } from '@/shared/store/guestStore'; import { useScanProgressStore } from '@/shared/store/scanProgressStore'; @@ -32,10 +33,14 @@ const DEFAULT_LOADING_PAGE_DATA: LoadingPageData = { function openResultRouteForCurrentSession() { const session = getScanSessionSnapshot(); + const currentTargetUrl = session.decodedUrl ?? session.historySelection?.url ?? null; if ( - session.isUrl === false || - (session.schemeType && session.schemeType.trim().toUpperCase() !== 'WEB') + !isWebScanTarget({ + isUrl: session.isUrl, + schemeType: session.schemeType, + url: currentTargetUrl, + }) ) { window.location.assign('/result/non-url'); return; @@ -53,8 +58,8 @@ function openResultRouteForCurrentSession() { } as const; const route = routeByRiskLevel[riskLevel]; - if (session.decodedUrl) { - window.location.assign(`${route}?url=${encodeURIComponent(session.decodedUrl)}`); + if (currentTargetUrl) { + window.location.assign(`${route}?url=${encodeURIComponent(currentTargetUrl)}`); return; } diff --git a/src/pages/QRScan/hooks/useQRScanPage.ts b/src/pages/QRScan/hooks/useQRScanPage.ts index 21bc14f..a5b2173 100644 --- a/src/pages/QRScan/hooks/useQRScanPage.ts +++ b/src/pages/QRScan/hooks/useQRScanPage.ts @@ -5,6 +5,7 @@ import { App } from 'antd'; import { useCallback, useEffect, useRef, useState } from 'react'; import { showApiError } from '@/shared/lib/feedback/showApiError'; +import { isWebScanTarget } from '@/shared/lib/scan-session/scanClassification'; import { useScanProgressStore } from '@/shared/store/scanProgressStore'; import { useScanSessionStore } from '@/shared/store/scanSessionStore'; @@ -141,18 +142,29 @@ function isNonWebScanResponse(scanResponse: Record): boolean { typeof scanResponse.schemeType === 'string' ? scanResponse.schemeType : scanResponse.scheme_type; - const schemeType = typeof rawSchemeType === 'string' ? rawSchemeType.trim().toUpperCase() : ''; + const targetValue = + typeof scanResponse.typeInfo === 'string' + ? scanResponse.typeInfo + : typeof scanResponse.type_info === 'string' + ? scanResponse.type_info + : typeof scanResponse.decodedUrl === 'string' + ? scanResponse.decodedUrl + : typeof scanResponse.decoded_url === 'string' + ? scanResponse.decoded_url + : typeof scanResponse.url === 'string' + ? scanResponse.url + : null; const rawIsUrl = scanResponse.isUrl !== undefined ? scanResponse.isUrl : scanResponse.is_url; - if (typeof rawIsUrl === 'boolean') { - return rawIsUrl === false; - } - - return schemeType.length > 0 && schemeType !== 'WEB'; + return !isWebScanTarget({ + isUrl: typeof rawIsUrl === 'boolean' ? rawIsUrl : null, + schemeType: typeof rawSchemeType === 'string' ? rawSchemeType : null, + url: targetValue, + }); } function isWebHistoryItem(item: ScanHistoryItem): boolean { - return item.isUrl !== false && item.schemeType?.trim().toUpperCase() === 'WEB'; + return isWebScanTarget(item); } function openResultPage(route: ResultRoute, url: string) { diff --git a/src/pages/ScanList/ScanListPage.tsx b/src/pages/ScanList/ScanListPage.tsx index b5309ac..33f3261 100644 --- a/src/pages/ScanList/ScanListPage.tsx +++ b/src/pages/ScanList/ScanListPage.tsx @@ -1,6 +1,7 @@ import { Link } from '@tanstack/react-router'; import { qrIconByTone } from '@/shared/icon/resultIcons'; +import { isWebScanTarget } from '@/shared/lib/scan-session/scanClassification'; import AppHeader from '@/shared/ui/app-header'; import { useScanListPage } from './hooks/useScanListPage'; @@ -8,15 +9,8 @@ import * as styles from './styles/scanListPage.css'; import type { ScanListStatus } from './types/scanListPage.types'; -type ResultRoute = '/result/critical' | '/result/non-url' | '/result/safe' | '/result/warning'; - const nonUrlResultRoute = '/result/non-url'; - -const resultRouteByStatus: Record = { - safe: '/result/safe', - warning: '/result/warning', - critical: '/result/critical', -}; +const reportRoute = '/report'; const statusLabelByTone: Record = { safe: '안전', @@ -91,10 +85,6 @@ function StatusBadgeIcon({ tone }: { tone: ScanListStatus }) { ); } -function isWebScanListItem(item: { isUrl: boolean | null; schemeType: string | null }): boolean { - return item.isUrl !== false && item.schemeType?.trim().toUpperCase() === 'WEB'; -} - export default function ScanListPage() { const { handleSelectScanResult, scanListPageData, scanListUuid } = useScanListPage(); @@ -115,9 +105,7 @@ export default function ScanListPage() { ) : (
    {scanListPageData.items.map((item) => { - const resultRoute = isWebScanListItem(item) - ? resultRouteByStatus[item.status] - : nonUrlResultRoute; + const nextRoute = isWebScanTarget(item) ? reportRoute : nonUrlResultRoute; return (
  • @@ -126,8 +114,8 @@ export default function ScanListPage() { onClick={() => { handleSelectScanResult(item); }} - search={resultRoute === nonUrlResultRoute ? {} : { url: item.url }} - to={resultRoute} + search={nextRoute === reportRoute ? { url: item.url } : {}} + to={nextRoute} >