From e361ff07b0f27520c3838f89a29621c83086ff93 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 20 Jun 2024 16:56:55 +0530 Subject: [PATCH] sol scan working --- .../src/app/tabs/locales/en/solidity.json | 9 ++ .../src/app/tabs/locales/en/udapp.json | 10 -- .../src/lib/components/universalDappUI.tsx | 103 ------------------ .../src/lib/contract-selection.tsx | 103 +++++++++++++++++- .../src/lib/solScanTable.tsx | 53 +++++++++ 5 files changed, 162 insertions(+), 116 deletions(-) create mode 100644 libs/remix-ui/solidity-compiler/src/lib/solScanTable.tsx diff --git a/apps/remix-ide/src/app/tabs/locales/en/solidity.json b/apps/remix-ide/src/app/tabs/locales/en/solidity.json index fa28d45670..f6c6211fa9 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/solidity.json +++ b/apps/remix-ide/src/app/tabs/locales/en/solidity.json @@ -53,7 +53,16 @@ "solidity._comment_contract-selection.tsx": "libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx", "solidity.publishOn": "Publish on", "solidity.runStaticAnalysis": "Run Static Analysis", + "solidity.runSolidityScan": "Run Solidity Scan", + "solidity.solScan.iconTooltip": "Click to scan this contract for vulnerabilities using SolidityScan, a third-party provider [BETA]", + "solidity.solScan.modalTitle": "Permission to share code", + "solidity.solScan.modalMessage": "To scan and analyze the contract for risks and vulnerabilities, its code will be shared with SolidityScan, a third-party provider. ", + "solidity.solScan.likeToContinue": "Would you like to continue?", + "solidity.solScan.modalOkLabel": "Continue", + "solidity.solScan.modalCancelLabel": "Cancel", + "solidity.solScan.errModalTitle": "Scan error", + "solidity.solScan.successModalTitle": "Scan result", "solidity.flatten": "Flatten contracts before UML generation.", "solidity.generateUML": "Generate a UML diagram of your contract.", "solidity.flattenLabel": "Flatten", diff --git a/apps/remix-ide/src/app/tabs/locales/en/udapp.json b/apps/remix-ide/src/app/tabs/locales/en/udapp.json index bf436e8e94..bd9ff8b6d7 100644 --- a/apps/remix-ide/src/app/tabs/locales/en/udapp.json +++ b/apps/remix-ide/src/app/tabs/locales/en/udapp.json @@ -80,16 +80,6 @@ "udapp.pinnedAt": "Pinned at", "udapp.filePath": "File path", - "udapp.solScan.iconTooltip": "Click to scan this contract for vulnerabilities using SolidityScan, a third-party provider [BETA]", - "udapp.solScan.modalTitle": "Permission to share code", - "udapp.solScan.modalMessage": "To scan and analyze the contract for risks and vulnerabilities, its code will be shared with SolidityScan, a third-party provider. ", - "udapp.solScan.likeToContinue": "Would you like to continue?", - "udapp.solScan.modalOkLabel": "Continue", - "udapp.solScan.modalCancelLabel": "Cancel", - "udapp.solScan.errModalTitle": "Scan error", - "udapp.solScan.successModalTitle": "Scan result", - - "udapp._comment_recorderCardUI.tsx": "libs/remix-ui/run-tab/src/lib/components/recorderCardUI.tsx", "udapp.transactionsRecorded": "Transactions recorded", "udapp.transactionsCountTooltip": "The number of recorded transactions", diff --git a/libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx b/libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx index 4812d794a6..79a0490710 100644 --- a/libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/universalDappUI.tsx @@ -6,10 +6,7 @@ import { FuncABI } from '@remix-project/core-plugin' import { CopyToClipboard } from '@remix-ui/clipboard' import * as remixLib from '@remix-project/remix-lib' import * as ethJSUtil from '@ethereumjs/util' -import axios from 'axios' -import { AppModal } from '@remix-ui/app' import { ContractGUI } from './contractGUI' -import { SolScanTable } from './solScanTable' import { TreeView, TreeViewItem } from '@remix-ui/tree-view' import { BN } from 'bn.js' import { CustomTooltip, is0XPrefixed, isHexadecimal, isNumeric, shortenAddress } from '@remix-ui/helper' @@ -218,103 +215,6 @@ export function UniversalDappUI(props: UdappProps) { setCalldataValue(value) } - const handleScanContinue = async () => { - await props.plugin.call('notification', 'toast', 'Processing data to scan...') - _paq.push(['trackEvent', 'udapp', 'solidityScan', 'initiateScan']) - const workspace = await props.plugin.call('filePanel', 'getCurrentWorkspace') - const fileName = props.instance.filePath || `${workspace.name}/${props.instance.contractData.contract.file}` - const filePath = `.workspaces/${fileName}` - const file = await props.plugin.call('fileManager', 'readFile', filePath) - - const urlResponse = await axios.post(`https://solidityscan.remixproject.org/uploadFile`, { file, fileName }) - - if (urlResponse.data.status === 'success') { - const ws = new WebSocket('wss://solidityscan.remixproject.org/solidityscan') - - ws.addEventListener('error', console.error); - - ws.addEventListener('open', async (event) => { - await props.plugin.call('notification', 'toast', 'Initiating scan...') - }) - - ws.addEventListener('message', async (event) => { - const data = JSON.parse(event.data) - if (data.type === "auth_token_register" && data.payload.message === "Auth token registered.") { - // Message on Bearer token successful registration - const reqToInitScan = { - "action": "message", - "payload": { - "type": "private_project_scan_initiate", - "body": { - "file_urls": [ - urlResponse.data.result.url - ], - "project_name": "RemixProject", - "project_type": "new" - } - } - } - ws.send(JSON.stringify(reqToInitScan)) - } else if (data.type === "scan_status" && data.payload.scan_status === "download_failed") { - // Message on failed scan - _paq.push(['trackEvent', 'udapp', 'solidityScan', 'scanFailed']) - const modal: AppModal = { - id: 'SolidityScanError', - title: , - message: data.payload.scan_status_err_message, - okLabel: 'Close' - } - await props.plugin.call('notification', 'modal', modal) - } else if (data.type === "scan_status" && data.payload.scan_status === "scan_done") { - // Message on successful scan - _paq.push(['trackEvent', 'udapp', 'solidityScan', 'scanSuccess']) - const url = data.payload.scan_details.link - - const { data: scanData } = await axios.post('https://solidityscan.remixproject.org/downloadResult', { url }) - const scanDetails: Record[] = scanData.scan_report.multi_file_scan_details - - let modal: AppModal - - if (scanDetails && scanDetails.length) { - await props.plugin.call('terminal', 'logHtml', ) - } else { - modal = { - id: 'SolidityScanError', - title: , - message: "Some error occurred! Please try again", - okLabel: 'Close' - } - } - await props.plugin.call('notification', 'modal', modal) - } - }) - } - } - - const askPermissionToScan = async () => { - _paq.push(['trackEvent', 'udapp', 'solidityScan', 'askPermissionToScan']) - const modal: AppModal = { - id: 'SolidityScanPermissionHandler', - title: , - message: , - okLabel: , - okFn: handleScanContinue, - cancelLabel: - } - - await props.plugin.call('notification', 'modal', modal) - } - const label = (key: string | number, value: string) => { return (
@@ -407,9 +307,6 @@ export function UniversalDappUI(props: UdappProps) { > )} - }> - -
{ props.isPinnedContract && props.instance.pinnedAt ? ( diff --git a/libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx b/libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx index 53757ae2cb..d274c7e1fc 100644 --- a/libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx +++ b/libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx @@ -5,6 +5,10 @@ import {PublishToStorage} from '@remix-ui/publish-to-storage' // eslint-disable- import {TreeView, TreeViewItem} from '@remix-ui/tree-view' // eslint-disable-line import {CopyToClipboard} from '@remix-ui/clipboard' // eslint-disable-line import { saveAs } from 'file-saver' +import { AppModal } from '@remix-ui/app' +import { SolScanTable } from './solScanTable' +import axios from 'axios' + import './css/style.css' import { CustomTooltip } from '@remix-ui/helper' @@ -249,8 +253,101 @@ export const ContractSelection = (props: ContractSelectionProps) => { console.log('runStaticAnalysis') } - const runSolidityScan = () => { - console.log('runSolidityScan') + const handleScanContinue = async () => { + const plugin = api as any + await plugin.call('notification', 'toast', 'Processing data to scan...') + _paq.push(['trackEvent', 'udapp', 'solidityScan', 'initiateScan']) + const workspace = await plugin.call('filePanel', 'getCurrentWorkspace') + const fileName = `${workspace.name}/${props.compiledFileName}` + const filePath = `.workspaces/${fileName}` + const file = await plugin.call('fileManager', 'readFile', filePath) + + const urlResponse = await axios.post(`https://solidityscan.remixproject.org/uploadFile`, { file, fileName }) + + if (urlResponse.data.status === 'success') { + const ws = new WebSocket('wss://solidityscan.remixproject.org/solidityscan') + + ws.addEventListener('error', console.error); + + ws.addEventListener('open', async (event) => { + await plugin.call('notification', 'toast', 'Fetching result in terminal ...') + }) + + ws.addEventListener('message', async (event) => { + const data = JSON.parse(event.data) + if (data.type === "auth_token_register" && data.payload.message === "Auth token registered.") { + // Message on Bearer token successful registration + const reqToInitScan = { + "action": "message", + "payload": { + "type": "private_project_scan_initiate", + "body": { + "file_urls": [ + urlResponse.data.result.url + ], + "project_name": "RemixProject", + "project_type": "new" + } + } + } + ws.send(JSON.stringify(reqToInitScan)) + } else if (data.type === "scan_status" && data.payload.scan_status === "download_failed") { + // Message on failed scan + _paq.push(['trackEvent', 'udapp', 'solidityScan', 'scanFailed']) + const modal: AppModal = { + id: 'SolidityScanError', + title: , + message: data.payload.scan_status_err_message, + okLabel: 'Close' + } + await plugin.call('notification', 'modal', modal) + } else if (data.type === "scan_status" && data.payload.scan_status === "scan_done") { + // Message on successful scan + _paq.push(['trackEvent', 'udapp', 'solidityScan', 'scanSuccess']) + const url = data.payload.scan_details.link + + const { data: scanData } = await axios.post('https://solidityscan.remixproject.org/downloadResult', { url }) + const scanDetails: Record[] = scanData.scan_report.multi_file_scan_details + + if (scanDetails && scanDetails.length) { + await plugin.call('terminal', 'logHtml', ) + } else { + const modal: AppModal = { + id: 'SolidityScanError', + title: , + message: "Some error occurred! Please try again", + okLabel: 'Close' + } + await plugin.call('notification', 'modal', modal) + } + + } + }) + } + } + + const runSolidityScan = async () => { + _paq.push(['trackEvent', 'udapp', 'solidityScan', 'askPermissionToScan']) + const modal: AppModal = { + id: 'SolidityScanPermissionHandler', + title: , + message: , + okLabel: , + okFn: handleScanContinue, + cancelLabel: + } + + await (api as any).call('notification', 'modal', modal) } return ( @@ -304,7 +401,7 @@ export const ContractSelection = (props: ContractSelectionProps) => { tooltipId="runSolidityScanTooltip" tooltipClasses="text-nowrap" tooltipText={`${intl.formatMessage({ - id: 'solidity.runSolidityScan' + id: 'solidity.solScan.iconTooltip' })}`} > diff --git a/libs/remix-ui/solidity-compiler/src/lib/solScanTable.tsx b/libs/remix-ui/solidity-compiler/src/lib/solScanTable.tsx new file mode 100644 index 0000000000..b5db224c16 --- /dev/null +++ b/libs/remix-ui/solidity-compiler/src/lib/solScanTable.tsx @@ -0,0 +1,53 @@ +// eslint-disable-next-line no-use-before-define +import React from 'react' +import parse from 'html-react-parser' +const _paq = (window._paq = window._paq || []) + +interface SolScanTableProps { + scanDetails: Record[], + fileName: string +} + +export function SolScanTable(props: SolScanTableProps) { + const { scanDetails, fileName } = props + + return ( + <> +

Scanning successful! {scanDetails.length} warnings found for file: {fileName}

+

See the warning details below. For more details,  + _paq.push(['trackEvent', 'udapp', 'solidityScan', 'goToSolidityScan'])}> + go to SolidityScan. + +

+ + + + + + + + + + + + { + Array.from(scanDetails, (template) => { + return ( + + + + + + + + ) + }) + } + + +
NAMESEVERITYCONFIDENCEDESCRIPTIONREMEDIATION
{template.template_details.issue_name}{template.template_details.issue_severity}{template.template_details.issue_confidence}{parse(template.template_details.static_issue_description)}{template.template_details.issue_remediation ? parse(template.template_details.issue_remediation) : 'Not Available' }
+ + ) +}