diff --git a/app/main/handlers/listenPort.js b/app/main/handlers/listenPort.js index 47f8d7817d..dd03599e2b 100644 --- a/app/main/handlers/listenPort.js +++ b/app/main/handlers/listenPort.js @@ -58,11 +58,6 @@ module.exports = (win, getClient) => { streams[addr] = stream; }) - - ipcMain.handle("copy-clipboard", (e, text) => { - clipboard.writeText(text); - }); - const asyncGetReverseShellProgramList = (params) => { return new Promise((resolve, reject) => { getClient().GetReverseShellProgramList(params, (err, data) => { diff --git a/app/main/uiOperate/other.js b/app/main/uiOperate/other.js index 00cfc0137c..359ba8681b 100644 --- a/app/main/uiOperate/other.js +++ b/app/main/uiOperate/other.js @@ -21,15 +21,6 @@ module.exports = (win, getClient) => { if (flag) shell.openExternal(url) }) - // 将渲染进程传入内容复制进系统剪切板内 - ipcMain.handle("set-copy-clipboard", (e, text) => { - clipboard.writeText(text) - }) - /** 将剪贴板中的内容传递进渲染进程 */ - ipcMain.handle("get-copy-clipboard", (e, text) => { - return clipboard.readText() - }) - // 将绝对路径里的文件名(不带文件后缀)提取出来 ipcMain.handle("fetch-path-file-name", (e, path) => { const extension = Path.extname(path) diff --git a/app/main/utils/clipboard.js b/app/main/utils/clipboard.js index e539a22647..51e1931a58 100644 --- a/app/main/utils/clipboard.js +++ b/app/main/utils/clipboard.js @@ -13,6 +13,11 @@ module.exports = (win, getClient) => { return {size: image.getSize(), blob: image.toDataURL()} }) + // 设置剪切板文本信息 + ipcMain.handle("set-clipboard-text", (e, text) => { + clipboard.writeText(text) + return + }) // 获取剪切板文本信息 ipcMain.handle("get-clipboard-text", (e) => { return clipboard.readText() diff --git a/app/renderer/src/main/src/components/CVXterm.tsx b/app/renderer/src/main/src/components/CVXterm.tsx index cc0352ce50..e6e90f6d12 100644 --- a/app/renderer/src/main/src/components/CVXterm.tsx +++ b/app/renderer/src/main/src/components/CVXterm.tsx @@ -4,8 +4,7 @@ import {XTerm} from "xterm-for-react" import ReactResizeDetector from "react-resize-detector" import {xtermFit} from "../utils/xtermUtils" import {TERMINAL_INPUT_KEY} from "./yakitUI/YakitCVXterm/YakitCVXterm" - -const {ipcRenderer} = window.require("electron") +import {setClipboardText} from "@/utils/clipboard" export interface CVXtermProps extends IProps { isWrite?: boolean @@ -92,9 +91,12 @@ export const CVXterm = forwardRef((props: CVXtermProps, ref) => { timer.current = null } timer.current = setTimeout(() => { - ipcRenderer.invoke("copy-clipboard", str).finally(() => { - timer.current = null - setLoading(false) + setClipboardText(str, { + hiddenHint: true, + finalCallback: () => { + timer.current = null + setLoading(false) + } }) }, 300) } diff --git a/app/renderer/src/main/src/components/HTTPFlowDetail.tsx b/app/renderer/src/main/src/components/HTTPFlowDetail.tsx index 5d5c0a5d3a..623da8a584 100644 --- a/app/renderer/src/main/src/components/HTTPFlowDetail.tsx +++ b/app/renderer/src/main/src/components/HTTPFlowDetail.tsx @@ -1,5 +1,5 @@ -import React, {useEffect, useState, useMemo, useRef, ReactNode, ReactElement, useImperativeHandle} from "react" -import {Button, Card, Col, Descriptions, Empty, PageHeader, Row, Space, Spin, Tag, Tooltip, Typography} from "antd" +import React, {useEffect, useState, useMemo, useRef, ReactNode, ReactElement} from "react" +import {Button, Card, Col, Descriptions, Empty, PageHeader, Row, Space, Tag, Tooltip, Typography} from "antd" import {LeftOutlined, RightOutlined} from "@ant-design/icons" import {HTTPFlow} from "./HTTPFlowTable/HTTPFlowTable" import {IMonacoEditor, NewHTTPPacketEditor, RenderTypeOptionVal} from "../utils/editors" @@ -8,17 +8,14 @@ import {FuzzableParamList} from "./FuzzableParamList" import {FuzzerResponse} from "../pages/fuzzer/HTTPFuzzerPage" import {HTTPHistorySourcePageType, HTTPPacketFuzzable} from "./HTTPHistory" import {Buffer} from "buffer" -import {StringToUint8Array, Uint8ArrayToString} from "@/utils/str" +import {Uint8ArrayToString} from "@/utils/str" import {HTTPFlowForWebsocketViewer, WebSocketEditor} from "@/pages/websocket/HTTPFlowForWebsocketViewer" import {WebsocketFrameHistory} from "@/pages/websocket/WebsocketFrameHistory" import styles from "./hTTPFlowDetail.module.scss" -import {callCopyToClipboard} from "@/utils/basic" import {useDebounceEffect, useMemoizedFn, useUpdateEffect} from "ahooks" import {HTTPFlowExtractedData, HTTPFlowExtractedDataTable} from "@/components/HTTPFlowExtractedDataTable" -import {showResponseViaResponseRaw} from "@/components/ShowInBrowser" import {ChevronDownIcon, ChevronUpIcon, ChromeSvgIcon, SideBarCloseIcon, SideBarOpenIcon} from "@/assets/newIcon" -import {OtherMenuListProps} from "./yakitUI/YakitEditor/YakitEditorType" import {YakitEmpty} from "./yakitUI/YakitEmpty/YakitEmpty" import classNames from "classnames" import {getRemoteValue, setRemoteValue} from "@/utils/kv" diff --git a/app/renderer/src/main/src/components/HTTPFlowTable/HTTPFlowTable.tsx b/app/renderer/src/main/src/components/HTTPFlowTable/HTTPFlowTable.tsx index 7f56257463..bf268c80a5 100644 --- a/app/renderer/src/main/src/components/HTTPFlowTable/HTTPFlowTable.tsx +++ b/app/renderer/src/main/src/components/HTTPFlowTable/HTTPFlowTable.tsx @@ -1,5 +1,5 @@ import React, {ReactNode, Ref, useEffect, useMemo, useRef, useState} from "react" -import {Button, Divider, Empty, Form, Input, Select, Space, Tooltip, Badge} from "antd" +import {Button, Divider, Empty, Form, Input, Space, Tooltip, Badge} from "antd" import {YakQueryHTTPFlowRequest} from "../../utils/yakQueryHTTPFlow" import {showDrawer} from "../../utils/showModal" import {PaginationSchema, YakScript} from "../../pages/invoker/schema" @@ -11,7 +11,6 @@ import {formatTime, formatTimestamp} from "../../utils/timeUtil" import {useHotkeys} from "react-hotkeys-hook" import {useDebounceEffect, useDebounceFn, useGetState, useMemoizedFn, useUpdateEffect, useVirtualList} from "ahooks" import ReactResizeDetector from "react-resize-detector" -import {callCopyToClipboard} from "../../utils/basic" import { generateCSRFPocByRequest, generateYakCodeByRequest, @@ -73,16 +72,11 @@ import {IconSolidAIIcon, IconSolidAIWhiteIcon} from "@/assets/icon/colors" import {YakitRoute} from "@/enums/yakitRoute" import {PluginSwitchToTag} from "@/pages/pluginEditor/defaultconstants" import {Uint8ArrayToString} from "@/utils/str" -import {WEB_FUZZ_PROXY} from "@/defaultConstants/HTTPFuzzerPage" -import {onSetRemoteValuesBase} from "../yakitUI/utils" -import {CacheDropDownGV} from "@/yakitGV" import {newWebsocketFuzzerTab} from "@/pages/websocket/WebsocketFuzzer" import cloneDeep from "lodash/cloneDeep" -import {parseStatusCodes} from "@/pages/fuzzer/components/HTTPFuzzerPageTable/HTTPFuzzerPageTable" +import {setClipboardText} from "@/utils/clipboard" const {ipcRenderer} = window.require("electron") -const {Option} = Select - export interface codecHistoryPluginProps { key: string label: string @@ -2721,14 +2715,14 @@ export const HTTPFlowTable = React.memo((props) => { webSocket: true, default: true, toWebFuzzer: true, - onClickSingle: (v) => callCopyToClipboard(v.Url), + onClickSingle: (v) => setClipboardText(v.Url), onClickBatch: (v, number) => { if (v.length === 0) { yakitNotify("warning", "请选择数据") return } if (v.length < number) { - callCopyToClipboard(v.map((ele) => `${ele.Url}`).join("\r\n")) + setClipboardText(v.map((ele) => `${ele.Url}`).join("\r\n")) setSelectedRowKeys([]) setSelectedRows([]) } else { @@ -2778,7 +2772,7 @@ export const HTTPFlowTable = React.memo((props) => { const flow = v as HTTPFlow if (!flow) return generateCSRFPocByRequest(flow.Request, flow.IsHTTPS, (e) => { - callCopyToClipboard(e) + setClipboardText(e) }) } }, @@ -3129,7 +3123,7 @@ export const HTTPFlowTable = React.memo((props) => { flow.IsHTTPS, flow.Request, (code) => { - callCopyToClipboard(code) + setClipboardText(code) }, RequestToYakCodeTemplate.Ordinary ) @@ -3144,7 +3138,7 @@ export const HTTPFlowTable = React.memo((props) => { flow.IsHTTPS, flow.Request, (code) => { - callCopyToClipboard(code) + setClipboardText(code) }, RequestToYakCodeTemplate.Batch ) diff --git a/app/renderer/src/main/src/components/baseConsole/BaseConsole.tsx b/app/renderer/src/main/src/components/baseConsole/BaseConsole.tsx index 3bc96643c9..814c200d1c 100644 --- a/app/renderer/src/main/src/components/baseConsole/BaseConsole.tsx +++ b/app/renderer/src/main/src/components/baseConsole/BaseConsole.tsx @@ -20,6 +20,7 @@ import {WindowPositionType} from "../yakitUI/YakitWindow/YakitWindowType" import {YakitButton} from "../yakitUI/YakitButton/YakitButton" import {OutlineXIcon} from "@/assets/icon/outline" import emiter from "@/utils/eventBus/eventBus" +import {setClipboardText} from "@/utils/clipboard" const {ipcRenderer} = window.require("electron") @@ -118,7 +119,7 @@ export const EngineConsole: React.FC = (props) => { const setCopy = useDebounceFn( useMemoizedFn((content: string) => { - ipcRenderer.invoke("set-copy-clipboard", content) + setClipboardText(content) }), {wait: 10} ).run diff --git a/app/renderer/src/main/src/components/layout/update/InstallEngine.tsx b/app/renderer/src/main/src/components/layout/update/InstallEngine.tsx index fe30782479..7e411b4ec5 100644 --- a/app/renderer/src/main/src/components/layout/update/InstallEngine.tsx +++ b/app/renderer/src/main/src/components/layout/update/InstallEngine.tsx @@ -18,6 +18,7 @@ import {OutlineQuestionmarkcircleIcon} from "@/assets/icon/outline" import {grpcFetchLatestYakVersion} from "@/apiUtils/grpc" import emiter from "@/utils/eventBus/eventBus" import {WebsiteGV} from "@/enums/website" +import {setClipboardText} from "@/utils/clipboard" import classNames from "classnames" import styles from "./InstallEngine.module.scss" @@ -651,8 +652,7 @@ export const QuestionModal: React.FC = React.memo((props) => link = `https://${WebsiteGV.OSSSourceAddress}/yak/${latestVersion || "latest"}/yak_windows_amd64.exe` break } - ipcRenderer.invoke("set-copy-clipboard", link) - success("复制成功") + setClipboardText(link) }) useEffect(() => { diff --git a/app/renderer/src/main/src/components/yakitUI/YakitCVXterm/YakitCVXterm.tsx b/app/renderer/src/main/src/components/yakitUI/YakitCVXterm/YakitCVXterm.tsx index 37ee798722..5ba4dddfd9 100644 --- a/app/renderer/src/main/src/components/yakitUI/YakitCVXterm/YakitCVXterm.tsx +++ b/app/renderer/src/main/src/components/yakitUI/YakitCVXterm/YakitCVXterm.tsx @@ -1,12 +1,9 @@ -import {forwardRef, useEffect, useImperativeHandle, useRef, useState} from "react" +import {forwardRef, useImperativeHandle, useRef, useState} from "react" import {IProps} from "xterm-for-react/dist/src/XTerm" import {XTerm} from "xterm-for-react" -import ReactResizeDetector from "react-resize-detector" import {xtermFit} from "@/utils/xtermUtils" import styles from "./YakitCVXterm.module.scss" -import {Terminal as ITerminal} from "xterm" - -const {ipcRenderer} = window.require("electron") +import {setClipboardText} from "@/utils/clipboard" export interface CVXtermProps extends IProps { isWrite?: boolean @@ -105,9 +102,11 @@ export const YakitCVXterm = forwardRef((props: CVXtermProps, ref) => { timer.current = null } timer.current = setTimeout(() => { - ipcRenderer.invoke("copy-clipboard", str).finally(() => { - timer.current = null - setLoading(false) + setClipboardText(str, { + finalCallback: () => { + timer.current = null + setLoading(false) + } }) }, 300) } diff --git a/app/renderer/src/main/src/components/yakitUI/YakitEditor/contextMenus.tsx b/app/renderer/src/main/src/components/yakitUI/YakitEditor/contextMenus.tsx index 92c8ec47ec..bb009544e8 100644 --- a/app/renderer/src/main/src/components/yakitUI/YakitEditor/contextMenus.tsx +++ b/app/renderer/src/main/src/components/yakitUI/YakitEditor/contextMenus.tsx @@ -6,15 +6,12 @@ import {AutoCard} from "../../AutoCard" import {YakitEditor} from "./YakitEditor" import {YakitButton} from "../YakitButton/YakitButton" import {monacoEditorClear, monacoEditorWrite} from "@/pages/fuzzer/fuzzerTemplates" -import {failed, yakitNotify} from "@/utils/notification" +import {failed} from "@/utils/notification" import {fetchCursorContent, fetchSelectionRange} from "./editorUtils" -import {useEffect, useRef, useState} from "react" -import {AutoSpin} from "@/components/AutoSpin" -import {YakitSpin} from "../YakitSpin/YakitSpin" -import {showYakitModal} from "../YakitModal/YakitModalConfirm" import emiter from "@/utils/eventBus/eventBus" import {IconSolidAIIcon, IconSolidAIWhiteIcon} from "@/assets/icon/colors" import {CodecResponseProps, CodecWorkProps} from "@/pages/codec/NewCodec" +import {getClipboardText, setClipboardText} from "@/utils/clipboard" const {ipcRenderer} = window.require("electron") @@ -52,7 +49,7 @@ export const baseMenuLists: OtherMenuListProps = { } ]) if (flag) { - ipcRenderer.invoke("set-copy-clipboard", `${content}`) + setClipboardText(`${content}`) editor.focus() } } @@ -62,7 +59,7 @@ export const baseMenuLists: OtherMenuListProps = { copy: { menu: [{key: "copy", label: "复制"}], onRun: (editor: YakitIMonacoEditor, key: string) => { - if (editor) ipcRenderer.invoke("set-copy-clipboard", `${fetchCursorContent(editor, true)}`) + if (editor) setClipboardText(`${fetchCursorContent(editor, true)}`) return } }, @@ -75,8 +72,7 @@ export const baseMenuLists: OtherMenuListProps = { const position = fetchSelectionRange(editor, false) if (!position) return - ipcRenderer - .invoke("get-copy-clipboard") + getClipboardText() .then((str: string) => { if (editor?.executeEdits) { editor.executeEdits("", [ diff --git a/app/renderer/src/main/src/components/yakitUI/YakitEditor/extraYakitEditor.tsx b/app/renderer/src/main/src/components/yakitUI/YakitEditor/extraYakitEditor.tsx index 79f565be3e..f3d426d9b3 100644 --- a/app/renderer/src/main/src/components/yakitUI/YakitEditor/extraYakitEditor.tsx +++ b/app/renderer/src/main/src/components/yakitUI/YakitEditor/extraYakitEditor.tsx @@ -11,7 +11,6 @@ import {failed, info, yakitNotify} from "@/utils/notification" import {ShareValueProps, newWebFuzzerTab} from "@/pages/fuzzer/HTTPFuzzerPage" import {generateCSRFPocByRequest} from "@/pages/invoker/fromPacketToYakCode" import {StringToUint8Array} from "@/utils/str" -import {callCopyToClipboard} from "@/utils/basic" import {showResponseViaResponseRaw} from "@/components/ShowInBrowser" import {openExternalWebsite, saveABSFileToOpen} from "@/utils/openWebsite" import {Modal} from "antd" @@ -26,7 +25,7 @@ import {newWebsocketFuzzerTab} from "@/pages/websocket/WebsocketFuzzer" import {getRemoteValue} from "@/utils/kv" import {RemoteGV} from "@/yakitGV" import {HTTPFlowBodyByIdRequest} from "@/components/HTTPHistory" -import emiter from "@/utils/eventBus/eventBus" +import {setClipboardText} from "@/utils/clipboard" const {ipcRenderer} = window.require("electron") interface HTTPPacketYakitEditor extends Omit { @@ -109,7 +108,7 @@ export const HTTPPacketYakitEditor: React.FC = React.memo if (onClickUrlMenu) { onClickUrlMenu() } else { - callCopyToClipboard(url || "") + setClipboardText(url || "") } } }, @@ -128,7 +127,7 @@ export const HTTPPacketYakitEditor: React.FC = React.memo return } generateCSRFPocByRequest(StringToUint8Array(text, "utf8"), defaultHttps, (code) => { - callCopyToClipboard(code) + setClipboardText(code) }) } catch (e) { failed("自动生成 CSRF 失败") @@ -344,7 +343,7 @@ export const HTTPPacketYakitEditor: React.FC = React.memo Bytes: bytes.Raw }) .then((res: {Base64: string}) => { - callCopyToClipboard(res.Base64) + setClipboardText(res.Base64) }) .catch((err) => { yakitNotify("error", `${err}`) diff --git a/app/renderer/src/main/src/components/yakitUI/YakitTag/YakitTag.tsx b/app/renderer/src/main/src/components/yakitUI/YakitTag/YakitTag.tsx index 6f0e4b6119..4744922285 100644 --- a/app/renderer/src/main/src/components/yakitUI/YakitTag/YakitTag.tsx +++ b/app/renderer/src/main/src/components/yakitUI/YakitTag/YakitTag.tsx @@ -8,6 +8,7 @@ import {useMemoizedFn} from "ahooks" import {CheckOutlined, LoadingOutlined} from "@ant-design/icons" import {success} from "@/utils/notification" import {OutlineXIcon} from "@/assets/icon/outline" +import {setClipboardText} from "@/utils/clipboard" const {ipcRenderer} = window.require("electron") @@ -79,15 +80,19 @@ export const CopyComponents: React.FC = (props) => { e.stopPropagation() if (!props.copyText) return setLoading(true) - ipcRenderer.invoke("set-copy-clipboard", props.copyText) - setTimeout(() => { - setLoading(false) - setIsShowSure(true) - setTimeout(() => { - setIsShowSure(false) - }, 2000) - success("复制成功") - }, 1000) + setClipboardText(props.copyText, { + hiddenHint: true, + finalCallback: () => { + setTimeout(() => { + setLoading(false) + setIsShowSure(true) + setTimeout(() => { + setIsShowSure(false) + }, 2000) + success("复制成功") + }, 1000) + } + }) if (props.onAfterCopy) props.onAfterCopy(e) }) return ( diff --git a/app/renderer/src/main/src/components/yakitUI/YakitXterm/YakitXterm.tsx b/app/renderer/src/main/src/components/yakitUI/YakitXterm/YakitXterm.tsx index 5d44b5074c..be3dfe5e7c 100644 --- a/app/renderer/src/main/src/components/yakitUI/YakitXterm/YakitXterm.tsx +++ b/app/renderer/src/main/src/components/yakitUI/YakitXterm/YakitXterm.tsx @@ -12,11 +12,11 @@ import styles from "./YakitXterm.module.scss" import classNames from "classnames" import {useMemoizedFn, useThrottleFn} from "ahooks" import {warn} from "@/utils/notification" -import {callCopyToClipboard, getCallCopyToClipboard} from "@/utils/basic" import {YakitMenuItemType} from "../YakitMenu/YakitMenu" import {showByRightContext} from "../YakitMenu/showByRightContext" import useListenWidth from "@/pages/pluginHub/hooks/useListenWidth" import {System, SystemInfo, handleFetchSystem} from "@/constants/hardware" +import {getClipboardText, setClipboardText} from "@/utils/clipboard" export interface YakitXtermRefProps { terminal: Terminal @@ -306,7 +306,12 @@ const YakitXterm: React.FC = forwardRef((props, ref) => { return } loading.current = true - callCopyToClipboard(selectedText, false).finally(() => (loading.current = false)) + setClipboardText(selectedText, { + hiddenHint: true, + finalCallback: () => { + loading.current = false + } + }) }), {wait: 200} ).run @@ -315,7 +320,7 @@ const YakitXterm: React.FC = forwardRef((props, ref) => { useMemoizedFn(() => { if (isWrite) { loading.current = true - getCallCopyToClipboard() + getClipboardText() .then((str: string) => { if (terminalRef.current) { terminalRef.current.paste(str) diff --git a/app/renderer/src/main/src/pages/codec/NewCodec.tsx b/app/renderer/src/main/src/pages/codec/NewCodec.tsx index 70a2fdbc4f..679c3f9a4f 100644 --- a/app/renderer/src/main/src/pages/codec/NewCodec.tsx +++ b/app/renderer/src/main/src/pages/codec/NewCodec.tsx @@ -57,6 +57,7 @@ import {YakitCheckableTag} from "@/components/yakitUI/YakitTag/YakitCheckableTag import {YakitModal} from "@/components/yakitUI/YakitModal/YakitModal" import HexEditor from "react-hex-editor" import {HexEditorHandle} from "react-hex-editor/dist/types" +import {setClipboardText} from "@/utils/clipboard" const {ipcRenderer} = window.require("electron") const {YakitPanel} = YakitCollapse @@ -212,8 +213,7 @@ export const NewCodecRightEditorBox: React.FC = (pr // 复制 const onCopy = useMemoizedFn(() => { - ipcRenderer.invoke("set-copy-clipboard", outputResponse?.Result || "") - success("复制成功") + setClipboardText(outputResponse?.Result || "") }) const suffixFun = (file_name: string) => { @@ -404,19 +404,21 @@ export const NewCodecRightEditorBox: React.FC = (pr
Output - {outputResponse && { - if (checked) { - setOutputShowType("hex") - } else { - setOutputShowType("editor") - } - }} - > - hex原文 - } + {outputResponse && ( + { + if (checked) { + setOutputShowType("hex") + } else { + setOutputShowType("editor") + } + }} + > + hex原文 + + )} {outPutObj.hidden && ( 450 ? null : "超大输出,请点击保存下载文件查看"} @@ -2054,7 +2056,9 @@ export const NewCodec: React.FC = (props) => { useDebounceEffect( () => { if (searchValue && searchValue.length) { - const filterCodec = cacheCodecRef.current.filter((item) => item.CodecName.toLocaleLowerCase().includes(searchValue.toLocaleLowerCase())) + const filterCodec = cacheCodecRef.current.filter((item) => + item.CodecName.toLocaleLowerCase().includes(searchValue.toLocaleLowerCase()) + ) setLeftSearchData(filterCodec) setShowSearchList(true) } else { diff --git a/app/renderer/src/main/src/pages/dynamicControl/DynamicControl.tsx b/app/renderer/src/main/src/pages/dynamicControl/DynamicControl.tsx index 12e54b85c6..c56c9b4488 100644 --- a/app/renderer/src/main/src/pages/dynamicControl/DynamicControl.tsx +++ b/app/renderer/src/main/src/pages/dynamicControl/DynamicControl.tsx @@ -1,11 +1,10 @@ -import React, {ReactNode, useEffect, useRef, useState} from "react" -import {Table, Space, Button, Input, Modal, Radio, Avatar, Spin, DatePicker, Menu} from "antd" +import React, {ReactNode, useEffect, useState} from "react" +import {Button, Input, Radio, Avatar, Spin} from "antd" import locale from "antd/es/date-picker/locale/zh_CN" import {API} from "@/services/swagger/resposeType" -import {callCopyToClipboard} from "@/utils/basic" -import {useDebounceFn, useGetState, useMemoizedFn} from "ahooks" +import {useDebounceFn, useGetState} from "ahooks" import moment from "moment" -import {failed, success, warn} from "@/utils/notification" +import {failed, warn} from "@/utils/notification" import {NetWorkApi} from "@/services/fetch" import {PaginationSchema} from "@/pages/invoker/schema" import {ControlMyselfIcon, ControlOtherIcon} from "@/assets/icons" @@ -14,7 +13,6 @@ import {YakitButton} from "@/components/yakitUI/YakitButton/YakitButton" import {ContentUploadInput} from "@/components/functionTemplate/ContentUploadTextArea" import {YakitInput} from "@/components/yakitUI/YakitInput/YakitInput" import {VirtualTable} from "./VirtualTable" -import {QueryYakScriptsResponse} from "../invoker/schema" import {VirtualColumns} from "./VirtualTable" import {DynamicStatusProps, UserInfoProps, useStore, yakitDynamicStatus} from "@/store" import {getRemoteValue, setRemoteValue} from "@/utils/kv" @@ -23,7 +21,8 @@ import {YakitMenu} from "@/components/yakitUI/YakitMenu/YakitMenu" import {getReleaseEditionName} from "@/utils/envfile" import {YakitSpin} from "@/components/yakitUI/YakitSpin/YakitSpin" import {YakitDatePicker} from "@/components/yakitUI/YakitDatePicker/YakitDatePicker" -import { YakitModal } from "@/components/yakitUI/YakitModal/YakitModal" +import {YakitModal} from "@/components/yakitUI/YakitModal/YakitModal" +import {setClipboardText} from "@/utils/clipboard" const {TextArea} = Input const {ipcRenderer} = window.require("electron") export interface ControlOperationProps { @@ -55,8 +54,8 @@ export const ControlOperation: React.FC = (props) => { 退出远程 @@ -208,8 +207,7 @@ export const ControlMyself: React.FC = (props) => { { - ipcRenderer.invoke("set-copy-clipboard", textArea) - success("复制成功") + setClipboardText(textArea) }} > 复制密钥 @@ -233,8 +231,8 @@ export const ControlOther: React.FC = (props) => { const [loading, setLoading] = useState(false) const onFinish = () => { - const resultObj: ResultObjProps|undefined = readable(textAreaValue) - if (resultObj&&resultObj?.id) { + const resultObj: ResultObjProps | undefined = readable(textAreaValue) + if (resultObj && resultObj?.id) { NetWorkApi({ method: "get", url: "remote/status", @@ -353,7 +351,7 @@ export interface DynamicControlProps { onCancle: () => void mainTitle: string secondTitle: string - children?: React.ReactNode + children?: ReactNode width?: number } @@ -372,9 +370,7 @@ export const DynamicControl: React.FC = (props) => { title={mainTitle} subTitle={secondTitle} > -
- {children} -
+
{children}
) } @@ -385,7 +381,7 @@ export interface ShowUserInfoProps extends API.NewUrmResponse { const ShowUserInfo: React.FC = (props) => { const {user_name, password, onClose} = props const copyUserInfo = () => { - callCopyToClipboard(`用户名:${user_name}\n密码:${password}`) + setClipboardText(`用户名:${user_name}\n密码:${password}`) } return (
@@ -653,25 +649,26 @@ export const remoteOperation = (status: boolean, dynamicStatus: DynamicStatusPro const {id, host, port, secret, note} = dynamicStatus return new Promise(async (resolve, reject) => { NetWorkApi({ - url: "remote/operation", - method: "post", - data: { - tunnel: id, - addr: `${host}:${port}`, - auth: secret, - note, - status - } - }) - .then((data) => { - if (data.ok) {} - }) - .catch((err) => { - failed(`连接远程/取消失败:${err}`) - }) - .finally(() => { - resolve(true) + url: "remote/operation", + method: "post", + data: { + tunnel: id, + addr: `${host}:${port}`, + auth: secret, + note, + status + } }) + .then((data) => { + if (data.ok) { + } + }) + .catch((err) => { + failed(`连接远程/取消失败:${err}`) + }) + .finally(() => { + resolve(true) + }) }) } diff --git a/app/renderer/src/main/src/pages/fuzzer/HTTPFuzzerEditorMenu.tsx b/app/renderer/src/main/src/pages/fuzzer/HTTPFuzzerEditorMenu.tsx index c7e682460f..d01eaa2bd7 100644 --- a/app/renderer/src/main/src/pages/fuzzer/HTTPFuzzerEditorMenu.tsx +++ b/app/renderer/src/main/src/pages/fuzzer/HTTPFuzzerEditorMenu.tsx @@ -1,8 +1,8 @@ -import React, {useEffect, useMemo, useRef, useState} from "react" -import {Avatar, Space, Spin, Timeline} from "antd" +import React, {useEffect, useRef, useState} from "react" +import {Avatar, Timeline} from "antd" import {PlusOutlined} from "@ant-design/icons" import styles from "./HTTPFuzzerEditorMenu.module.scss" -import {failed, success, warn, info} from "@/utils/notification" +import {failed} from "@/utils/notification" import classNames from "classnames" import {YakitButton} from "@/components/yakitUI/YakitButton/YakitButton" import { @@ -18,7 +18,6 @@ import { } from "@/assets/newIcon" import {DragDropContext, Droppable, Draggable, DraggingStyle} from "@hello-pangea/dnd" import {AutoDecodeResult} from "@/utils/encodec" -import {callCopyToClipboard} from "@/utils/basic" import {YakitInput} from "@/components/yakitUI/YakitInput/YakitInput" import {QueryFuzzerLabelResponseProps} from "./StringFuzzer" import {setRemoteValue} from "@/utils/kv" @@ -30,6 +29,7 @@ import {IconSolidAIIcon} from "@/assets/icon/colors" import {YakitSpin} from "@/components/yakitUI/YakitSpin/YakitSpin" import {defaultLabel} from "@/defaultConstants/HTTPFuzzerPage" import {PluginSwitchToTag} from "../pluginEditor/defaultconstants" +import {setClipboardText} from "@/utils/clipboard" const {ipcRenderer} = window.require("electron") export interface CountDirectionProps { @@ -714,7 +714,7 @@ export const DecodeCopyReplace: React.FC = (props) => {
{ - callCopyToClipboard(itemStr) + setClipboardText(itemStr) }} > diff --git a/app/renderer/src/main/src/pages/fuzzer/HTTPFuzzerHotPatch.tsx b/app/renderer/src/main/src/pages/fuzzer/HTTPFuzzerHotPatch.tsx index 53882aeb4b..29a9fbb5cb 100644 --- a/app/renderer/src/main/src/pages/fuzzer/HTTPFuzzerHotPatch.tsx +++ b/app/renderer/src/main/src/pages/fuzzer/HTTPFuzzerHotPatch.tsx @@ -1,7 +1,6 @@ import React, {useEffect, useState} from "react" import {Form, Space} from "antd" import {YakEditor} from "../../utils/editors" -import {callCopyToClipboard} from "../../utils/basic" import {AutoCard} from "../../components/AutoCard" import {getRemoteValue, setRemoteValue} from "@/utils/kv" import {useGetState, useMemoizedFn} from "ahooks" @@ -17,6 +16,7 @@ import {yakitNotify} from "@/utils/notification" import {OutlineXIcon} from "@/assets/icon/outline" import {YakitModalConfirm} from "@/components/yakitUI/YakitModal/YakitModalConfirm" import {WEB_FUZZ_HOTPATCH_CODE} from "@/defaultConstants/HTTPFuzzerPage" +import {setClipboardText} from "@/utils/clipboard" export interface HTTPFuzzerHotPatchProp { onInsert?: (s: string) => any @@ -164,7 +164,7 @@ export const HTTPFuzzerHotPatch: React.FC = (props) => { { - callCopyToClipboard(data.join("\n")) + setClipboardText(data.join("\n")) }} > 复制 Fuzz 结果 @@ -172,7 +172,7 @@ export const HTTPFuzzerHotPatch: React.FC = (props) => { { - callCopyToClipboard(params.Template) + setClipboardText(params.Template) }} > {" "} @@ -198,7 +198,7 @@ export const HTTPFuzzerHotPatch: React.FC = (props) => { { - callCopyToClipboard(params.Template) + setClipboardText(params.Template) }} > 点击复制 diff --git a/app/renderer/src/main/src/pages/fuzzer/HTTPFuzzerPage.tsx b/app/renderer/src/main/src/pages/fuzzer/HTTPFuzzerPage.tsx index e7a7635a25..cd3c3abfdc 100644 --- a/app/renderer/src/main/src/pages/fuzzer/HTTPFuzzerPage.tsx +++ b/app/renderer/src/main/src/pages/fuzzer/HTTPFuzzerPage.tsx @@ -27,7 +27,6 @@ import { import {getRemoteValue, setRemoteValue} from "../../utils/kv" import {HTTPFuzzerHistorySelector, HTTPFuzzerTaskDetail} from "./HTTPFuzzerHistory" import {HTTPFuzzerHotPatch} from "./HTTPFuzzerHotPatch" -import {callCopyToClipboard} from "../../utils/basic" import {exportHTTPFuzzerResponse, exportPayloadResponse} from "./HTTPFuzzerPageExport" import {StringToUint8Array, Uint8ArrayToString} from "../../utils/str" import {PacketScanButton} from "@/pages/packetScanner/DefaultPacketScanGroup" @@ -151,6 +150,7 @@ import { apiSaveFuzzerConfig } from "../layout/mainOperatorContent/utils" import {GetSystemProxyResult, apiGetSystemProxy} from "@/utils/ConfigSystemProxy" +import {setClipboardText} from "@/utils/clipboard" const ResponseAllDataCard = React.lazy(() => import("./FuzzerSequence/ResponseAllDataCard")) const PluginDebugDrawer = React.lazy(() => import("./components/PluginDebugDrawer/PluginDebugDrawer")) @@ -359,7 +359,7 @@ export function copyAsUrl(f: {Request: string; IsHTTPS: boolean}) { ipcRenderer .invoke("ExtractUrl", f) .then((data: {Url: string}) => { - callCopyToClipboard(data.Url) + setClipboardText(data.Url) }) .catch((e) => { failed("复制 URL 失败:包含 Fuzz 标签可能会导致 URL 不完整") diff --git a/app/renderer/src/main/src/pages/fuzzer/WebFuzzerNewEditor/WebFuzzerNewEditor.tsx b/app/renderer/src/main/src/pages/fuzzer/WebFuzzerNewEditor/WebFuzzerNewEditor.tsx index 9977e89794..06a89c0108 100644 --- a/app/renderer/src/main/src/pages/fuzzer/WebFuzzerNewEditor/WebFuzzerNewEditor.tsx +++ b/app/renderer/src/main/src/pages/fuzzer/WebFuzzerNewEditor/WebFuzzerNewEditor.tsx @@ -1,21 +1,19 @@ -import React, {ReactElement, useEffect, useImperativeHandle, useMemo, useRef, useState} from "react" -import {IMonacoEditor, NewHTTPPacketEditor, NewHTTPPacketEditorProp} from "@/utils/editors" -import {StringToUint8Array, Uint8ArrayToString} from "@/utils/str" +import React, {useEffect, useImperativeHandle, useMemo, useRef, useState} from "react" +import {IMonacoEditor, NewHTTPPacketEditor} from "@/utils/editors" import {insertFileFuzzTag, insertTemporaryFileFuzzTag} from "../InsertFileFuzzTag" import {monacoEditorWrite} from "../fuzzerTemplates" import {OtherMenuListProps} from "@/components/yakitUI/YakitEditor/YakitEditorType" -import {callCopyToClipboard} from "@/utils/basic" import {execCodec} from "@/utils/encodec" import {copyAsUrl, showDictsAndSelect} from "../HTTPFuzzerPage" import styles from "./WebFuzzerNewEditor.module.scss" import {showYakitModal} from "@/components/yakitUI/YakitModal/YakitModalConfirm" import {setRemoteValue} from "@/utils/kv" -import {useDebounceEffect, useMemoizedFn} from "ahooks" +import {useMemoizedFn} from "ahooks" import {HTTPFuzzerHotPatch} from "../HTTPFuzzerHotPatch" import {yakitNotify} from "@/utils/notification" import {WEB_FUZZ_HOTPATCH_CODE, WEB_FUZZ_HOTPATCH_WITH_PARAM_CODE} from "@/defaultConstants/HTTPFuzzerPage" -import emiter from "@/utils/eventBus/eventBus" -import { openExternalWebsite } from "@/utils/openWebsite" +import {openExternalWebsite} from "@/utils/openWebsite" +import {setClipboardText} from "@/utils/clipboard" const {ipcRenderer} = window.require("electron") export interface WebFuzzerNewEditorProps { @@ -152,8 +150,7 @@ export const WebFuzzerNewEditor: React.FC = React.memo( execCodec("packet-to-curl", newRequest, undefined, undefined, undefined, [ {Key: "https", Value: isHttps ? "true" : ""} ]).then((data) => { - callCopyToClipboard(data) - yakitNotify("info", "复制到剪贴板") + setClipboardText(data, {hintText: "复制到剪贴板"}) }) return default: diff --git a/app/renderer/src/main/src/pages/invoker/YakitLogFormatter.tsx b/app/renderer/src/main/src/pages/invoker/YakitLogFormatter.tsx index 1dc7617ce2..411512591c 100644 --- a/app/renderer/src/main/src/pages/invoker/YakitLogFormatter.tsx +++ b/app/renderer/src/main/src/pages/invoker/YakitLogFormatter.tsx @@ -9,7 +9,6 @@ import {HTTPFlowRiskViewer, YakitHTTPFlowRisk} from "../../components/HTTPFlowRi import {AutoCard} from "../../components/AutoCard" import MDEditor from "@uiw/react-md-editor" import {openABSFileLocated} from "../../utils/openWebsite" -import {callCopyToClipboard} from "../../utils/basic" import styles from "./YakitLogFormatter.module.scss" import classNames from "classnames" import {YakitButton} from "@/components/yakitUI/YakitButton/YakitButton" @@ -27,6 +26,7 @@ import {YakitEditor} from "@/components/yakitUI/YakitEditor/YakitEditor" import {YakEditor} from "@/utils/editors" import {showYakitModal} from "@/components/yakitUI/YakitModal/YakitModalConfirm" import {SolidCalendarIcon} from "@/assets/icon/solid" +import {setClipboardText} from "@/utils/clipboard" const LogCharts = React.lazy(() => import("./LogCharts/LogCharts")) const WordCloudCharts = React.lazy(() => import("./LogCharts/WordCloudCharts")) @@ -219,7 +219,7 @@ const FileLogShow: React.FC = React.memo((props) => { const {title, is_dir, is_existed, file_size, description, path, timestamp, showTime = true} = props const [expand, setExpand] = useState(true) const onCopy = useMemoizedFn(() => { - callCopyToClipboard(path) + setClipboardText(path) }) const onOpen = useMemoizedFn(() => { openABSFileLocated(path) diff --git a/app/renderer/src/main/src/pages/loginOperationMenu/AccountAdminPage.tsx b/app/renderer/src/main/src/pages/loginOperationMenu/AccountAdminPage.tsx index 88f5fcfd6b..d102735e86 100644 --- a/app/renderer/src/main/src/pages/loginOperationMenu/AccountAdminPage.tsx +++ b/app/renderer/src/main/src/pages/loginOperationMenu/AccountAdminPage.tsx @@ -28,13 +28,12 @@ import {ColumnsTypeProps} from "@/components/TableVirtualResize/TableVirtualResi import moment from "moment" import {useCampare} from "@/hook/useCompare/useCompare" import {YakitModal} from "@/components/yakitUI/YakitModal/YakitModal" -import {callCopyToClipboard} from "@/utils/basic" import {unReadable} from "../dynamicControl/DynamicControl" import YakitCascader from "@/components/yakitUI/YakitCascader/YakitCascader" import {YakitSelect} from "@/components/yakitUI/YakitSelect/YakitSelect" import {DefaultOptionType} from "antd/lib/cascader" import styles from "./AccountAdminPage.module.scss" -const {ipcRenderer} = window.require("electron") +import {setClipboardText} from "@/utils/clipboard" interface QueryAccountAdminRequest { departmentId?: number keywords: string @@ -993,7 +992,7 @@ const AccountList: React.FC = (props) => {
callCopyToClipboard(`用户名:${user_name}\n密码:${password}`)} + onClick={() => setClipboardText(`用户名:${user_name}\n密码:${password}`)} > 复制 @@ -1031,8 +1030,7 @@ const AccountList: React.FC = (props) => { secret } const showData = unReadable(resultObj) - ipcRenderer.invoke("set-copy-clipboard", showData) - yakitNotify("success", "复制远程连接成功") + setClipboardText(showData, {hintText: "复制远程连接成功"}) } else { yakitNotify("error", `暂无最新连接信息,请该用户发起远程连接后再操作`) } @@ -1490,7 +1488,7 @@ const AccountForm: React.FC = (props) => {
callCopyToClipboard(`用户名:${user_name}\n密码:${password}`)} + onClick={() => setClipboardText(`用户名:${user_name}\n密码:${password}`)} > 复制 diff --git a/app/renderer/src/main/src/pages/payloadGenerater/NewJavaPayloadPage.tsx b/app/renderer/src/main/src/pages/payloadGenerater/NewJavaPayloadPage.tsx index 3ccdbb0daf..ce5977f0ab 100644 --- a/app/renderer/src/main/src/pages/payloadGenerater/NewJavaPayloadPage.tsx +++ b/app/renderer/src/main/src/pages/payloadGenerater/NewJavaPayloadPage.tsx @@ -18,7 +18,6 @@ import { SettingReverseParamsInfo } from "../reverseServer/NewReverseServerPage" import {randomString} from "@/utils/randomUtil" -import {callCopyToClipboard} from "@/utils/basic" import {ReverseNotification, ReverseTable} from "../reverseServer/ReverseTable" import {getRemoteValue} from "@/utils/kv" import {ExtractExecResultMessage} from "@/components/yakitLogSchema" @@ -40,6 +39,7 @@ import {YakitRadioButtons} from "@/components/yakitUI/YakitRadioButtons/YakitRad import {YakitEditor} from "@/components/yakitUI/YakitEditor/YakitEditor" import {YakitCopyText} from "@/components/yakitUI/YakitCopyText/YakitCopyText" import {YakitTag} from "@/components/yakitUI/YakitTag/YakitTag" +import {setClipboardText} from "@/utils/clipboard" const {ipcRenderer} = window.require("electron") @@ -1150,7 +1150,7 @@ export const PayloadCode: React.FC = React.memo((props) => { saveABSFileToOpen(`${type}-${data.Class}-${data.Gadget}`, type === "hex" ? hex : code) } - if (value === "copy") callCopyToClipboard(code) + if (value === "copy") setClipboardText(code) if (value === "extra") onExtra() }) diff --git a/app/renderer/src/main/src/pages/payloadManager/newPayload.tsx b/app/renderer/src/main/src/pages/payloadManager/newPayload.tsx index 6ebe880d93..539173313b 100644 --- a/app/renderer/src/main/src/pages/payloadManager/newPayload.tsx +++ b/app/renderer/src/main/src/pages/payloadManager/newPayload.tsx @@ -60,7 +60,6 @@ import {YakitInput} from "@/components/yakitUI/YakitInput/YakitInput" import Dragger from "antd/lib/upload/Dragger" import {v4 as uuidv4} from "uuid" import {DeletePayloadProps, NewPayloadTable, Payload, QueryPayloadParams} from "./newPayloadTable" -import {callCopyToClipboard} from "@/utils/basic" import {PaginationSchema, QueryGeneralResponse} from "../invoker/schema" import {randomString} from "@/utils/randomUtil" import _isEqual from "lodash/isEqual" @@ -78,6 +77,7 @@ import {getRemoteValue, setRemoteValue} from "@/utils/kv" import {YakitMenuItemProps} from "@/components/yakitUI/YakitMenu/YakitMenu" import {YakitRadioButtons} from "@/components/yakitUI/YakitRadioButtons/YakitRadioButtons" import {YakitCheckableTag} from "@/components/yakitUI/YakitTag/YakitCheckableTag" +import {setClipboardText} from "@/utils/clipboard" const {ipcRenderer} = window.require("electron") interface UploadStatusInfoProps { @@ -1845,7 +1845,7 @@ export const FolderComponent: React.FC = (props) => { setMenuOpen(false) switch (key) { case "copyFuzztag": - callCopyToClipboard(`{{payload(${inputName}/*)}}`) + setClipboardText(`{{payload(${inputName}/*)}}`) break case "addChildPayload": // 注: 此处需注意文件夹 @@ -2521,7 +2521,7 @@ export const FileComponent: React.FC = (props) => { setMenuOpen(false) switch (key) { case "copyFuzztag": - callCopyToClipboard(`{{payload(${inputName})}}`) + setClipboardText(`{{payload(${inputName})}}`) break case "importPayload": const m = showYakitModal({ diff --git a/app/renderer/src/main/src/pages/pluginEditor/pluginEditor/PluginEditor.tsx b/app/renderer/src/main/src/pages/pluginEditor/pluginEditor/PluginEditor.tsx index 25736cf2cf..628caa6919 100644 --- a/app/renderer/src/main/src/pages/pluginEditor/pluginEditor/PluginEditor.tsx +++ b/app/renderer/src/main/src/pages/pluginEditor/pluginEditor/PluginEditor.tsx @@ -57,6 +57,7 @@ import {APIFunc} from "@/apiUtils/type" import {PluginUploadModal} from "@/pages/pluginHub/pluginUploadModal/PluginUploadModal" import {YakitModal} from "@/components/yakitUI/YakitModal/YakitModal" import {YakitInput} from "@/components/yakitUI/YakitInput/YakitInput" +import {setClipboardText} from "@/utils/clipboard" import classNames from "classnames" import "../../plugins/plugins.scss" @@ -136,12 +137,14 @@ export const PluginEditor: React.FC = memo( }) const onOldDataOk = useMemoizedFn(() => { if (!copyLoading) setCopyLoading(true) - ipcRenderer.invoke("set-copy-clipboard", oldParamsRef.current) - setTimeout(() => { - onOldDataCancel() - yakitNotify("success", "复制成功") - setCopyLoading(false) - }, 500) + setClipboardText(oldParamsRef.current, { + finalCallback: () => { + setTimeout(() => { + onOldDataCancel() + setCopyLoading(false) + }, 200) + } + }) }) const onOldDataCancel = useMemoizedFn(() => { if (oldShow) setOldShow(false) diff --git a/app/renderer/src/main/src/pages/pluginHub/hubExtraOperate/HubExtraOperate.tsx b/app/renderer/src/main/src/pages/pluginHub/hubExtraOperate/HubExtraOperate.tsx index 8d16595787..8b326fc245 100644 --- a/app/renderer/src/main/src/pages/pluginHub/hubExtraOperate/HubExtraOperate.tsx +++ b/app/renderer/src/main/src/pages/pluginHub/hubExtraOperate/HubExtraOperate.tsx @@ -39,12 +39,11 @@ import {ExportYakScriptStreamRequest} from "@/pages/plugins/local/PluginsLocalTy import {defaultSearch} from "@/pages/plugins/builtInData" import cloneDeep from "lodash/cloneDeep" import {PluginUploadModal} from "../pluginUploadModal/PluginUploadModal" +import {setClipboardText} from "@/utils/clipboard" import classNames from "classnames" import styles from "./HubExtraOperate.module.scss" -const {ipcRenderer} = window.require("electron") - export interface HubExtraOperateRef { downloadedNext: (flag: boolean) => void } @@ -341,12 +340,7 @@ export const HubExtraOperate: React.FC = memo( const handleShare = useMemoizedFn(() => { activeOperate.current = "" if (!online) return - ipcRenderer - .invoke("copy-clipboard", online.uuid || "") - .then(() => { - yakitNotify("success", "分享ID已复制到剪切板") - }) - .catch(() => {}) + setClipboardText(online.uuid || "", {hintText: "分享ID已复制到剪切板"}) }) const [uploadHint, setUploadHint] = useState(false) diff --git a/app/renderer/src/main/src/pages/pluginHub/pluginHubList/funcTemplate.tsx b/app/renderer/src/main/src/pages/pluginHub/pluginHubList/funcTemplate.tsx index 0a82aefd0e..cdde6d158d 100644 --- a/app/renderer/src/main/src/pages/pluginHub/pluginHubList/funcTemplate.tsx +++ b/app/renderer/src/main/src/pages/pluginHub/pluginHubList/funcTemplate.tsx @@ -54,6 +54,7 @@ import {YakScript} from "@/pages/invoker/schema" import {YakitMenuItemType} from "@/components/yakitUI/YakitMenu/YakitMenu" import {YakitHint} from "@/components/yakitUI/YakitHint/YakitHint" import {PluginUpload} from "@/pages/plugins/local/PluginLocalUpload" +import {setClipboardText} from "@/utils/clipboard" import YakitLogo from "@/assets/yakitLogo.png" import UnLogin from "@/assets/unLogin.png" @@ -1061,9 +1062,7 @@ export const OwnOptFooterExtra: React.FC = memo((props) yakitNotify("error", "分享插件的UUID不存在") return } - ipcRenderer.invoke("copy-clipboard", info.uuid).then(() => { - yakitNotify("success", "插件UUID已粘贴到剪切板") - }) + setClipboardText(info.uuid, {hintText: "插件UUID已粘贴到剪切板"}) }) const delLoading = useMemo(() => { diff --git a/app/renderer/src/main/src/pages/portscan/PortTable.tsx b/app/renderer/src/main/src/pages/portscan/PortTable.tsx index c7ffed5430..27a2fd534d 100644 --- a/app/renderer/src/main/src/pages/portscan/PortTable.tsx +++ b/app/renderer/src/main/src/pages/portscan/PortTable.tsx @@ -6,11 +6,11 @@ import {formatTimestamp} from "../../utils/timeUtil" import {failed} from "../../utils/notification" import {DropdownMenu} from "../../components/baseTemplate/DropdownMenu" import {LineMenunIcon} from "../../assets/icons" -import {callCopyToClipboard} from "../../utils/basic" import {ExportExcel} from "@/components/DataExport/DataExport" import {useMemoizedFn} from "ahooks" import {YakitRoute} from "@/enums/yakitRoute" import emiter from "@/utils/eventBus/eventBus" +import {setClipboardText} from "@/utils/clipboard" export interface PortTableProp { data: YakitPort[] isSimple?: boolean @@ -175,7 +175,7 @@ export const OpenPortTableViewer: React.FC = (props) => { { - callCopyToClipboard(addr) + setClipboardText(addr) }} > {addr} diff --git a/app/renderer/src/main/src/pages/reverseShellReceiver/shellReceiver.tsx b/app/renderer/src/main/src/pages/reverseShellReceiver/shellReceiver.tsx index 65582d45a9..4bbbb82311 100644 --- a/app/renderer/src/main/src/pages/reverseShellReceiver/shellReceiver.tsx +++ b/app/renderer/src/main/src/pages/reverseShellReceiver/shellReceiver.tsx @@ -30,10 +30,10 @@ import { import {YakitSpin} from "@/components/yakitUI/YakitSpin/YakitSpin" import {defaultGenerateReverseShellCommand} from "./constants" import {ReverseShellTerminal, XTermSizeProps} from "./ReverseShellTerminal/ReverseShellTerminal" -import {callCopyToClipboard} from "@/utils/basic" import {CopyComponents, YakitTag} from "@/components/yakitUI/YakitTag/YakitTag" import {YakitPopover} from "@/components/yakitUI/YakitPopover/YakitPopover" import {OutlineCogIcon} from "@/assets/icon/outline" +import {setClipboardText} from "@/utils/clipboard" const {ipcRenderer} = window.require("electron") export interface ShellReceiverLeftListProps { @@ -238,7 +238,7 @@ export const ShellReceiverMiddleItem: React.FC = ( }) }) const onCopy = useMemoizedFn(() => { - if (reverseShellCommand?.Result) callCopyToClipboard(reverseShellCommand?.Result) + if (reverseShellCommand?.Result) setClipboardText(reverseShellCommand?.Result) }) const onIPChange = useMemoizedFn((e) => { setIP(e.target.value) diff --git a/app/renderer/src/main/src/pages/softwareSettings/ProjectManage.tsx b/app/renderer/src/main/src/pages/softwareSettings/ProjectManage.tsx index 95be495c86..db30106b48 100644 --- a/app/renderer/src/main/src/pages/softwareSettings/ProjectManage.tsx +++ b/app/renderer/src/main/src/pages/softwareSettings/ProjectManage.tsx @@ -55,6 +55,7 @@ import emiter from "@/utils/eventBus/eventBus" import YakitCollapse from "@/components/yakitUI/YakitCollapse/YakitCollapse" import {AutoTextarea} from "../fuzzer/components/AutoTextarea/AutoTextarea" import {isCommunityEdition} from "@/utils/envfile" +import {setClipboardText} from "@/utils/clipboard" const {ipcRenderer} = window.require("electron") const {YakitPanel} = YakitCollapse @@ -665,8 +666,7 @@ const ProjectManage: React.FC = memo((props) => { failed("该条项目无数据或无关键信息,复制失败!") return } - ipcRenderer.invoke("set-copy-clipboard", data.DatabasePath) - info("复制成功") + setClipboardText(data.DatabasePath) return case "setCurrent": if (!data || !data.Id) { diff --git a/app/renderer/src/main/src/pages/webShell/WebShellTable.tsx b/app/renderer/src/main/src/pages/webShell/WebShellTable.tsx index 53afaacc06..e40c5f0de2 100644 --- a/app/renderer/src/main/src/pages/webShell/WebShellTable.tsx +++ b/app/renderer/src/main/src/pages/webShell/WebShellTable.tsx @@ -6,7 +6,6 @@ import cveStyles from "@/pages/cve/CVETable.module.scss"; import mitmStyles from "@/pages/mitm/MITMServerHijacking/MITMServerHijacking.module.scss"; import {YakitSwitch} from "@/components/yakitUI/YakitSwitch/YakitSwitch"; import {formatTimestamp} from "@/utils/timeUtil"; -import {YakitCombinationSearch} from "@/components/YakitCombinationSearch/YakitCombinationSearch"; import {YakitButton} from "@/components/yakitUI/YakitButton/YakitButton"; import { ArrowCircleRightSvgIcon, @@ -16,28 +15,15 @@ import { SMViewGridAddIcon, TrashIcon } from "@/assets/newIcon"; import {TableVirtualResize} from "@/components/TableVirtualResize/TableVirtualResize"; -import {Button, Divider, Space, Tooltip} from 'antd'; +import {Button, Space, Tooltip} from 'antd'; import {ColumnsTypeProps, SortProps} from "@/components/TableVirtualResize/TableVirtualResizeType"; import {YakitTag} from "@/components/yakitUI/YakitTag/YakitTag"; import {useDebounceEffect, useDebounceFn, useInViewport, useMemoizedFn, useUpdateEffect} from 'ahooks'; import {genDefaultPagination, PaginationSchema, QueryGeneralResponse} from "@/pages/invoker/schema"; import style from "@/components/HTTPFlowTable/HTTPFlowTable.module.scss"; -import {showDrawer, showModal} from "@/utils/showModal"; +import {showModal} from "@/utils/showModal"; import {RemarkDetail, WebShellCreatorForm} from "@/pages/webShell/WebShellComp"; import {YakitMenu, YakitMenuItemProps} from "@/components/yakitUI/YakitMenu/YakitMenu"; -import { - availableColors, - CalloutColor, - onRemoveCalloutColor, - onSendToTab -} from "@/components/HTTPFlowTable/HTTPFlowTable"; -import {execPacketScan} from "@/pages/packetScanner/PacketScanner"; -import {packetScanDefaultValue} from "@/pages/packetScanner/DefaultPacketScanGroup"; -import {callCopyToClipboard} from "@/utils/basic"; -import {showResponseViaHTTPFlowID} from "@/components/ShowInBrowser"; -import {failed, success} from "@/utils/notification"; -import {YakitModalConfirm} from "@/components/yakitUI/YakitModal/YakitModalConfirm"; -import {ExclamationCircleOutlined} from '@ant-design/icons'; import {deleteWebShell, featurePing} from "@/pages/webShell/WebShellManager"; import {addToTab} from "@/pages/MainTabs"; import { diff --git a/app/renderer/src/main/src/pages/yakRunner/BottomEditorDetails/BottomEditorDetails.tsx b/app/renderer/src/main/src/pages/yakRunner/BottomEditorDetails/BottomEditorDetails.tsx index 6ff0628665..74baaef1db 100644 --- a/app/renderer/src/main/src/pages/yakRunner/BottomEditorDetails/BottomEditorDetails.tsx +++ b/app/renderer/src/main/src/pages/yakRunner/BottomEditorDetails/BottomEditorDetails.tsx @@ -44,6 +44,7 @@ import {RemoteGV} from "@/yakitGV" import {YakitInputNumber} from "@/components/yakitUI/YakitInputNumber/YakitInputNumber" import {YakitResizeBox} from "@/components/yakitUI/YakitResizeBox/YakitResizeBox" import {Uint8ArrayToString} from "@/utils/str" +import {setClipboardText} from "@/utils/clipboard" const {ipcRenderer} = window.require("electron") // 编辑器区域 展示详情(输出/语法检查/终端/帮助信息) @@ -726,7 +727,7 @@ export const OutputInfo: React.FC = (props) => { const setCopy = useDebounceFn( useMemoizedFn((content: string) => { - ipcRenderer.invoke("set-copy-clipboard", content) + setClipboardText(content) }), {wait: 10} ).run diff --git a/app/renderer/src/main/src/pages/yakRunner/FileTree/FileTree.tsx b/app/renderer/src/main/src/pages/yakRunner/FileTree/FileTree.tsx index cc0b71d5ae..5b1c5dd832 100644 --- a/app/renderer/src/main/src/pages/yakRunner/FileTree/FileTree.tsx +++ b/app/renderer/src/main/src/pages/yakRunner/FileTree/FileTree.tsx @@ -45,8 +45,8 @@ import { import {failed, success, warn} from "@/utils/notification" import {YakitHint} from "@/components/yakitUI/YakitHint/YakitHint" import cloneDeep from "lodash/cloneDeep" -import {callCopyToClipboard} from "@/utils/basic" import {OpenFileByPathProps} from "../YakRunnerType" +import {setClipboardText} from "@/utils/clipboard" const {ipcRenderer} = window.require("electron") @@ -350,7 +350,7 @@ const FileTreeNode: React.FC = (props) => { // 复制绝对路径 const onCopyAbsolutePath = useMemoizedFn(() => { - callCopyToClipboard(info.path) + setClipboardText(info.path) }) // 复制相对路径 @@ -361,7 +361,7 @@ const FileTreeNode: React.FC = (props) => { } const basePath = fileTree[0].path const relativePath = await getRelativePath(basePath, info.path) - callCopyToClipboard(relativePath) + setClipboardText(relativePath) }) // 粘贴 diff --git a/app/renderer/src/main/src/utils/basic.tsx b/app/renderer/src/main/src/utils/basic.tsx index 6d56577888..ded8959883 100644 --- a/app/renderer/src/main/src/utils/basic.tsx +++ b/app/renderer/src/main/src/utils/basic.tsx @@ -24,24 +24,6 @@ import {RefreshIcon} from "@/assets/newIcon" const {ipcRenderer} = window.require("electron") -export const callCopyToClipboard: (str: string, isShow?: boolean) => Promise = (str: string, isShow = true) => { - return new Promise((resolve, reject) => { - ipcRenderer - .invoke("copy-clipboard", str) - .then(() => { - isShow && info("Copy Finished") - resolve(null) - }) - .catch(reject) - }) -} - -export const getCallCopyToClipboard: () => Promise = () => { - return new Promise((resolve, reject) => { - ipcRenderer.invoke("get-copy-clipboard").then(resolve).catch(reject) - }) -} - export const ConfigGlobalReverse = React.memo(() => { const [addr, setAddr, getAddr] = useGetState("") const [password, setPassword, getPassword] = useGetState("") diff --git a/app/renderer/src/main/src/utils/clipboard.ts b/app/renderer/src/main/src/utils/clipboard.ts new file mode 100644 index 0000000000..bfb7c0c333 --- /dev/null +++ b/app/renderer/src/main/src/utils/clipboard.ts @@ -0,0 +1,49 @@ +import {yakitNotify} from "./notification" + +const {ipcRenderer} = window.require("electron") + +interface SetClipboardTextExtraParams { + /** 是否隐藏复制成功提示 */ + hiddenHint?: boolean + /** 复制成功提示信息(默认: 复制成功) */ + hintText?: string + /** 复制成功后的回调 */ + successCallback?: () => void + /** 复制失败后的回调 */ + failedCallback?: () => void + /** 执行完后的回调 */ + finalCallback?: () => void +} +/** + * @name 设置剪切板文本信息 + * @param text 复制到剪切板的文本信息 + * @param extra 复制功能的额外配置 + */ +export const setClipboardText = (text?: string, extra?: SetClipboardTextExtraParams) => { + const {hiddenHint, hintText, successCallback, failedCallback, finalCallback} = extra || {} + if (text) { + ipcRenderer + .invoke("set-clipboard-text", text) + .then(() => { + if (!hiddenHint) yakitNotify("success", hintText || "复制成功") + successCallback && successCallback() + }) + .catch(() => { + failedCallback && failedCallback() + }) + .finally(() => { + finalCallback && finalCallback() + }) + } else { + finalCallback && finalCallback() + } +} + +/** 获取剪切板文本信息 */ +export const getClipboardText = async () => { + try { + return ((await ipcRenderer.invoke("get-clipboard-text")) || "") as string + } catch (error) { + return "" + } +}