forked from yaklang/yakit
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
733 additions
and
538 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
197 changes: 197 additions & 0 deletions
197
app/renderer/src/main/src/pages/mitm/MITMPluginList.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
import React, {useEffect, useState} from "react"; | ||
import {AutoCard} from "../../components/AutoCard"; | ||
import {Button, Empty, Form, List, Popconfirm, Space} from "antd"; | ||
import {SelectOne} from "../../utils/inputUtil"; | ||
import {PoweroffOutlined, ReloadOutlined} from "@ant-design/icons"; | ||
import {getValue, saveValue} from "../../utils/kv"; | ||
import {EditorProps, YakCodeEditor} from "../../utils/editors"; | ||
import {YakModuleList} from "../yakitStore/YakitStorePage"; | ||
import {YakScript, YakScriptHooks} from "../invoker/schema"; | ||
import {useMap, useMemoizedFn} from "ahooks"; | ||
import {ExecResultLog} from "../invoker/batch/ExecMessageViewer"; | ||
import {YakExecutorParam} from "../invoker/YakExecutorParams"; | ||
import {MITMPluginTemplateShort} from "../invoker/data/MITMPluginTamplate"; | ||
import {MITMYakScriptLoader} from "./MITMYakScriptLoader"; | ||
import {failed} from "../../utils/notification"; | ||
|
||
export const MITM_HOTPATCH_CODE = `MITM_HOTPATCH_CODE` | ||
|
||
export interface MITMPluginListProp { | ||
proxy?: string | ||
downloadCertNode?: () => React.ReactNode | ||
setFilterNode?: () => React.ReactNode | ||
onSubmitScriptContent?: (script: string) => any | ||
onSubmitYakScriptId?: (id: number, params: YakExecutorParam[]) => any | ||
onSendToWebFuzzer?: (isHttps: boolean, request: string) => any | ||
onExit?: () => any | ||
} | ||
|
||
const {ipcRenderer} = window.require("electron"); | ||
|
||
const updateHooks = () => { | ||
ipcRenderer.invoke("mitm-get-current-hook").catch(e => { | ||
failed(`更新 MITM 插件状态失败: ${e}`) | ||
}) | ||
} | ||
|
||
export const MITMPluginList: React.FC<MITMPluginListProp> = (props) => { | ||
const [initialed, setInitialed] = useState(false); | ||
const [script, setScript] = useState(MITMPluginTemplateShort); | ||
// const [userDefined, setUserDefined] = useState(false); | ||
const [hooks, handlers] = useMap<string, boolean>(new Map<string, boolean>()); | ||
const [mode, setMode] = useState<"hot-patch" | "loaded" | "all">("all"); | ||
const [refreshTrigger, setRefreshTrigger] = useState(false); | ||
const refresh = useMemoizedFn(() => { | ||
setRefreshTrigger(!refreshTrigger) | ||
}) | ||
|
||
useEffect(() => { | ||
getValue(MITM_HOTPATCH_CODE).then(e => { | ||
if (!e) { | ||
return | ||
} | ||
setScript(`${e}`) | ||
}) | ||
}, []) | ||
|
||
// 设置用户模式 | ||
const userDefined = mode === "hot-patch"; | ||
let hooksItem: { name: string }[] = []; | ||
hooks.forEach((value, key) => { | ||
if (value) { | ||
hooksItem.push({name: key}) | ||
} | ||
}); | ||
hooksItem = hooksItem.sort((a, b) => a.name.localeCompare(b.name)) | ||
|
||
useEffect(() => { | ||
// 用于 MITM 的 查看当前 Hooks | ||
ipcRenderer.on("client-mitm-hooks", (e, data: YakScriptHooks[]) => { | ||
const tmp = new Map<string, boolean>() | ||
data.forEach(i => { | ||
i.Hooks.map(hook => { | ||
tmp.set(hook.YakScriptName, true) | ||
}) | ||
}) | ||
handlers.setAll(tmp) | ||
}) | ||
updateHooks() | ||
setTimeout(() => { | ||
setInitialed(true) | ||
}, 300) | ||
return () => { | ||
ipcRenderer.removeAllListeners("client-mitm-hooks"); | ||
} | ||
}, []); | ||
|
||
return <AutoCard | ||
bordered={false} | ||
bodyStyle={{padding: 0}} | ||
loading={!initialed} | ||
title={<Space> | ||
<Form size={"small"} onSubmitCapture={e => e.preventDefault()}> | ||
<SelectOne | ||
data={[ | ||
{text: "热加载", value: "hot-patch"}, | ||
{text: "已启用", value: "loaded"}, | ||
{text: "全部", value: "all"}, | ||
]} | ||
value={mode} | ||
formItemStyle={{marginBottom: 0}} | ||
setValue={setMode} | ||
/> | ||
</Form> | ||
{mode === "hot-patch" && <Popconfirm | ||
title={"确认重置热加载代码?"} | ||
onConfirm={() => { | ||
setScript(MITMPluginTemplateShort) | ||
refresh() | ||
}} | ||
> | ||
<Button | ||
type={"link"} icon={<ReloadOutlined/>} size={"small"} | ||
/> | ||
</Popconfirm>} | ||
</Space>} size={"small"} | ||
extra={<> | ||
<Space> | ||
{userDefined && <Button | ||
size={"small"} type={"primary"} | ||
onClick={() => { | ||
if (!!script) { | ||
saveValue(MITM_HOTPATCH_CODE, script) | ||
} | ||
props.onSubmitScriptContent && props.onSubmitScriptContent(script) | ||
}} | ||
>加载当前代码</Button>} | ||
{/*: <Button*/} | ||
{/* size={"small"} type={"primary"}*/} | ||
{/* onClick={() => {*/} | ||
{/* enablePlugin()*/} | ||
{/* }}*/} | ||
{/*>加载插件</Button>}*/} | ||
<Button | ||
danger={true} | ||
size={"small"} type={"primary"} | ||
onClick={() => { | ||
props.onExit && props.onExit() | ||
}} | ||
icon={<PoweroffOutlined/>} | ||
>停止</Button> | ||
</Space> | ||
</>} | ||
> | ||
{mode === "hot-patch" && <> | ||
{/* 用户热加载代码 */} | ||
<YakCodeEditor | ||
refreshTrigger={refreshTrigger} | ||
noHeader={true} noPacketModifier={true} | ||
originValue={Buffer.from(script || "")} | ||
onChange={e => setScript(e.toString())} | ||
language={"yak"} | ||
extraEditorProps={{ | ||
noMiniMap: true, noWordWrap: true, | ||
} as EditorProps} | ||
/> | ||
</>} | ||
{mode === "all" && <> | ||
<YakModuleList | ||
Type={"mitm"} | ||
onClicked={(script: YakScript) => { | ||
|
||
}} | ||
Keyword={""} | ||
onYakScriptRender={(i: YakScript) => { | ||
return <MITMYakScriptLoader | ||
script={i} hooks={hooks} | ||
onSendToPatch={code => { | ||
setScript(code) | ||
setMode("hot-patch") | ||
}} | ||
onSubmitYakScriptId={props.onSubmitYakScriptId} | ||
/> | ||
}} | ||
/> | ||
</>} | ||
{mode === "loaded" && <> | ||
{hooks.size > 0 ? <> | ||
<List pagination={false}> | ||
{hooksItem.map(i => { | ||
return <> | ||
<MITMYakScriptLoader | ||
onSendToPatch={code => { | ||
setScript(code) | ||
setMode("hot-patch") | ||
}} | ||
script={{ScriptName: i.name} as YakScript} hooks={hooks} | ||
onSubmitYakScriptId={props.onSubmitYakScriptId} | ||
/> | ||
</> | ||
})} | ||
</List> | ||
</> : <> | ||
<Empty description={"未启用 MITM 插件"}/> | ||
</>} | ||
</>} | ||
</AutoCard> | ||
}; |
32 changes: 32 additions & 0 deletions
32
app/renderer/src/main/src/pages/mitm/MITMPluginLogViewer.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import React from "react"; | ||
import {AutoCard} from "../../components/AutoCard"; | ||
import {Divider, Space, Tag} from "antd"; | ||
import {formatDate} from "../../utils/timeUtil"; | ||
import {StatusCardViewer} from "./MITMYakScriptLoader"; | ||
import {YakitLogViewers} from "../invoker/YakitLogFormatter"; | ||
import {ExecResultLog} from "../invoker/batch/ExecMessageViewer"; | ||
import moment from "moment"; | ||
import {StatusCardProps} from "../yakitStore/viewers/base"; | ||
|
||
export interface MITMPluginLogViewerProp { | ||
messages: ExecResultLog[] | ||
status: StatusCardProps[] | ||
} | ||
|
||
|
||
export const MITMPluginLogViewer: React.FC<MITMPluginLogViewerProp> = React.memo((props) => { | ||
const {status} = props; | ||
const currentTimestamp: number = (props?.messages || []).length > 0 ? props.messages[0].timestamp : moment().unix() | ||
|
||
return <AutoCard | ||
title={<Space> | ||
<Tag color={"geekblue"}>{formatDate(currentTimestamp)}</Tag> | ||
</Space>} | ||
size={"small"} | ||
bodyStyle={{overflowY: "auto"}} | ||
> | ||
<StatusCardViewer status={status}/> | ||
<Divider style={{marginTop: 8}}/> | ||
<YakitLogViewers data={props.messages} onlyTime={true}/> | ||
</AutoCard> | ||
}); |
Oops, something went wrong.