完善一下

This commit is contained in:
go0p
2024-05-15 14:43:04 +08:00
committed by go0p
parent 26c3bbc570
commit 6358fc720d
14 changed files with 299 additions and 373 deletions
+16 -15
View File
@@ -1,4 +1,4 @@
import { ActionType, WebSocketManager } from './socket.js';
import {ActionType, WebSocketManager} from './socket.js';
console.info("Chrome Extenstion Background is loaded")
@@ -18,7 +18,7 @@ chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
case ActionType.DISCONNECT:
websocketManager.disconnectWebsocket();
break;
case ActionType.SETPROXY:
case ActionType.SET_PROXY:
chrome.proxy.settings.set({
value: {
mode: "fixed_servers",
@@ -33,10 +33,10 @@ chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
scope: 'regular',
});
break;
case ActionType.CLEARPROXY:
case ActionType.CLEAR_PROXY:
chrome.proxy.settings.clear({})
break;
case ActionType.PROXYSTATUS:
case ActionType.PROXY_STATUS:
chrome.proxy.settings.get({}, function (details) {
if (details.value && details.value.mode === "fixed_servers") {
let proxyConfig = details.value.rules.singleProxy;
@@ -45,26 +45,27 @@ chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
proxy: `${proxyConfig.scheme}://${proxyConfig.host}:${proxyConfig.port}`
})
} else {
chrome.runtime.sendMessage({ enable: false, proxy: "" })
chrome.runtime.sendMessage({enable: false, proxy: ""})
}
});
break;
case ActionType.INJECTSCRIPT:
case ActionType.INJECT_SCRIPT:
chrome.scripting.executeScript({
target: { tabId: msg.tabId },
target: {tabId: msg.tabId},
files: ['content.js']
}).then(() => {
chrome.tabs.sendMessage(msg.tabId, { type: 'INJECT_CODE', value: msg.value });
chrome.tabs.sendMessage(msg.tabId,
{type: ActionType.INJECT_SCRIPT, value: msg.value}
).then(response => {
console.log("response", response)
if (response && response.action === ActionType.TO_EXTENSION_PAGE) {
chrome.runtime.sendMessage(response)
}
})
}).catch(err => {
console.error('Script injection failed:', err);
});
break
case ActionType.SENDRESFROMPAGE:
chrome.runtime.sendMessage({
action: ActionType.RESTOEVALINTAB,
result: msg.result
})
break
case ActionType.ECHO:
console.log("Echo ", msg.result)
}
@@ -72,7 +73,7 @@ chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
})
const pageFunction = (code) => {
chrome.runtime.sendMessage({ code }, response => {
chrome.runtime.sendMessage({code}, response => {
if (response && response.success) {
console.log('Result:', response.result);
} else {
+5 -5
View File
@@ -4,12 +4,12 @@
}
window.contentScriptInjected = true;
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.type === 'INJECT_CODE') {
if (request.type === 'yakit_inject_script') {
const injectedScriptURL = chrome.runtime.getURL('inject.js');
const script = document.createElement('script');
script.src = injectedScriptURL;
script.onload = () => {
window.postMessage({ type: 'CALL_FUNCTION', value: request.value }, '*');
window.postMessage({type: request.value.mode, value: request.value}, '*');
script.remove();
};
(document.head || document.documentElement).appendChild(script);
@@ -19,10 +19,10 @@
}
window.removeEventListener('message', onMessage);
// Send the result to the background script
chrome.runtime.sendMessage({ action: 'SEND_RES_FROM_PAGE', result: event.data.result });
sendResponse({ result: event.data.result });
// chrome.runtime.sendMessage({ action: 'yakit_to_extension_page', result: event.data.result });
// 直接向向发送端返回结果
sendResponse({action: 'yakit_to_extension_page', result: event.data.result});
});
// Return true to indicate that the response will be sent asynchronously
return true;
}
});
-1
View File
@@ -8,6 +8,5 @@
</head>
<body>
<div id="root"></div>
<iframe src="./sandbox.html" id="sandbox" style="position: absolute;width:0;height:0;border:0;"></iframe>
</body>
</html>
-18
View File
@@ -1,18 +0,0 @@
document.addEventListener('DOMContentLoaded', function () {
const button = document.getElementById('btn');
button.addEventListener('click', clickHandler);
});
function clickHandler() {
const iframe = document.getElementById('sandbox');
iframe.contentWindow.postMessage( "22 * 33", '*');
function listener(event) {
// 这里处理从 iframe 发送回来的数据
console.log('Received message:', event.data);
}
window.addEventListener('message', listener, {once: true});
}
+27 -12
View File
@@ -1,16 +1,31 @@
(() => {
if (window.injectedMessageListener) {
return;
}
window.injectedMessageListener = true;
window.addEventListener('message', function onMessage(event) {
if (event.source !== window || event.data.type !== 'CALL_FUNCTION') {
return;
if (window.injectedMessageListener) {
return;
}
const value = event.data.value;
const result = window[value.fn_name](value.args);
window.postMessage({ type: 'FROM_PAGE', result: result }, '*');
});
window.injectedMessageListener = true;
window.addEventListener('message', function onMessage(event) {
if (event.source !== window) {
return;
}
let result = "";
switch (event.data.type) {
case 'CONTENT_CALL_FUNCTION':
const fn_name = event.data.value.fn_name;
const args = event.data.value.args;
result = window[fn_name](args);
break;
case 'CONTENT_EVAL_CODE':
const code = event.data.value.code;
result = eval(code);
// console.log("CONTENT_EVAL_CODE result: ", result);
break;
default:
break;
}
if (result && typeof result === 'object' && Object.keys(result).length > 0) {
window.postMessage({type: 'FROM_PAGE', result: result}, '*');
}
});
})();
-5
View File
@@ -15,11 +15,6 @@
"service_worker": "background.js",
"type": "module"
},
"sandbox": {
"pages": [
"sandbox.html"
]
},
"permissions": [
"webNavigation",
"activeTab",
-24
View File
@@ -1,24 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./src/crypto-js.min.js"></script>
</head>
<script>
window.addEventListener('message', async function (event) {
try {
console.log("sandbox event", event)
if (!event.data[0]) {
throw new Error('格式化方法有问题');
}
const func = new Function('obj', event.data[0]);
event.source.window.postMessage(eval(event.data), event.origin);
} catch (e) {
console.error(e);
event.source.window.postMessage(eval(event.data), event.origin);
}
});
</script>
</html>
+5 -8
View File
@@ -2,14 +2,11 @@ export const ActionType = {
CONNECT: 'connect',
DISCONNECT: 'disconnect',
STATUS: 'status',
PROXYSTATUS: 'proxystatus',
SETPROXY: 'setproxy',
CLEARPROXY: 'clearproxy',
INJECTSCRIPT: 'INJECT_SCRIPT',
SENDRESFROMPAGE: "SEND_RES_FROM_PAGE",
RESTOEVALINTAB: "RES_TO_EVALINTAB",
EVAL: 'eval',
ECHO: 'echo',
PROXY_STATUS: 'proxy_status',
SET_PROXY: 'set_proxy',
CLEAR_PROXY: 'clear_proxy',
INJECT_SCRIPT: 'yakit_inject_script',
TO_EXTENSION_PAGE: "yakit_to_extension_page",
}
export class WebSocketManager {
-1
View File
File diff suppressed because one or more lines are too long
+2 -4
View File
@@ -3,7 +3,6 @@ import "./App.css";
import {ConfigProvider} from "antd";
import {Contro} from "@components/Contro";
import {Proxifier} from "@components/Proxifier";
import {Eval} from "@components/Eval";
import {EvalInTab} from "@components/EvalInTab";
function App() {
@@ -16,10 +15,9 @@ function App() {
}}
>
<div className="App">
{/*<Contro/>*/}
{/*<Proxifier/>*/}
<Contro/>
<Proxifier/>
<Eval/>
<EvalInTab/>
</div>
</ConfigProvider>
+169 -167
View File
@@ -1,190 +1,192 @@
import React, { useEffect, useMemo, useRef, useState } from "react";
import { Divider, Tooltip, Input } from "antd";
import React, {useEffect, useMemo, useRef, useState} from "react";
import {Divider, Tooltip, Input} from "antd";
import classNames from "classnames";
import {
CheckIcon,
ExitIcon,
PencilAltIcon,
RefreshIcon,
XIcon,
CheckIcon,
ExitIcon,
PencilAltIcon,
RefreshIcon,
XIcon,
} from "@assets/icon/icon";
import { wsc } from "@network/chrome";
import {wsc} from "@network/chrome";
import "./Contro.css";
import { ActionType } from "../../public/socket";
import {ActionType} from "@network/chrome";
interface ControProps {
}
interface ControProps {}
export const Contro: React.FC<ControProps> = () => {
const [isEdit, setIsEdit] = useState<boolean>(false);
const [connected, setConnected] = useState(false);
const [autoFindFailedReason, setAutoFindFailedReason] = useState<string>("");
const [enginePort, setEnginePort] = useState<string>("");
const [enginePortTemp, setEnginePortTemp] = useState<string>(enginePort);
const enginePortRef = useRef<string>(enginePort);
const [isEdit, setIsEdit] = useState<boolean>(false);
const [connected, setConnected] = useState(false);
const [autoFindFailedReason, setAutoFindFailedReason] = useState<string>("");
const [enginePort, setEnginePort] = useState<string>("");
const [enginePortTemp, setEnginePortTemp] = useState<string>(enginePort);
const enginePortRef = useRef<string>(enginePort);
useEffect(() => {
enginePortRef.current = enginePort;
}, [enginePort]);
useEffect(() => {
enginePortRef.current = enginePort;
}, [enginePort]);
useEffect(() => {
const yakitConnectInfo = localStorage.getItem("yakit-connect");
if (!yakitConnectInfo) {
findPort(11212, 11222);
} else {
const { port, connected } = JSON.parse(yakitConnectInfo);
setConnected(connected);
setEnginePort(port + "");
setAutoFindFailedReason("");
}
wsc.onWSCMessage((message) => {
if (message.action === ActionType.STATUS) {
if (message.connected === false) {
handleConnectFail();
useEffect(() => {
const yakitConnectInfo = localStorage.getItem("yakit-connect");
if (!yakitConnectInfo) {
findPort(11212, 11222);
} else {
localStorage.setItem(
"yakit-connect",
JSON.stringify({ connected: true, port: message.port })
);
setEnginePort(message.port + "");
setConnected(true);
setAutoFindFailedReason("");
const {port, connected} = JSON.parse(yakitConnectInfo);
setConnected(connected);
setEnginePort(port + "");
setAutoFindFailedReason("");
}
}
});
}, []);
const findPort = (port: number, max: number) => {
const ws = new WebSocket(`ws://127.0.0.1:${port}`);
ws.onclose = (e: CloseEvent) => {
if (enginePortRef.current) {
handleConnectFail();
return;
}
if (e.reason !== `FoundYakitWebSocketController` && port + 1 <= max) {
setTimeout(() => findPort(port + 1, max), 200);
}
wsc.onWSCMessage((message) => {
if (message.action === ActionType.STATUS) {
if (message.connected === false) {
handleConnectFail();
} else {
localStorage.setItem(
"yakit-connect",
JSON.stringify({connected: true, port: message.port})
);
setEnginePort(message.port + "");
setConnected(true);
setAutoFindFailedReason("");
}
}
});
}, []);
if (port + 1 > max) {
const findPort = (port: number, max: number) => {
const ws = new WebSocket(`ws://127.0.0.1:${port}`);
ws.onclose = (e: CloseEvent) => {
if (enginePortRef.current) {
handleConnectFail();
return;
}
if (e.reason !== `FoundYakitWebSocketController` && port + 1 <= max) {
setTimeout(() => findPort(port + 1, max), 200);
}
if (port + 1 > max) {
setConnected(false);
setEnginePort("");
setAutoFindFailedReason("Cannot found Yakit");
localStorage.setItem("yakit-connect", "");
}
};
ws.onopen = () => {
setConnected(true);
setEnginePort(port + "");
ws.close(1000, "FoundYakitWebSocketController");
connectPort(port);
};
};
const handleConnectFail = () => {
setConnected(false);
setEnginePort("");
setAutoFindFailedReason("Cannot found Yakit");
setAutoFindFailedReason("Yakit WebSocket Controller Connect Fail");
localStorage.setItem("yakit-connect", "");
}
};
ws.onopen = () => {
setConnected(true);
setEnginePort(port + "");
ws.close(1000, "FoundYakitWebSocketController");
connectPort(port);
const connectPort = (port: number) => {
setAutoFindFailedReason("");
wsc.connect(port);
};
};
const handleConnectFail = () => {
setConnected(false);
setAutoFindFailedReason("Yakit WebSocket Controller Connect Fail");
localStorage.setItem("yakit-connect", "");
};
const safeConnected = useMemo(() => {
return connected && enginePort;
}, [connected, enginePort]);
const connectPort = (port: number) => {
setAutoFindFailedReason("");
wsc.connect(port);
};
const failConnected = useMemo(() => {
return !connected && autoFindFailedReason;
}, [connected, autoFindFailedReason]);
const safeConnected = useMemo(() => {
return connected && enginePort;
}, [connected, enginePort]);
const failConnected = useMemo(() => {
return !connected && autoFindFailedReason;
}, [connected, autoFindFailedReason]);
return (
<>
{safeConnected || failConnected ? (
<div
className={classNames("Contro", {
["Contro-success-bg"]: safeConnected,
["Contro-error-bg"]: failConnected,
})}
>
<div className="Contro-lable">Yakit </div>
<div className="Contro-cont">
{isEdit ? (
<>
<Input
rootClassName="Contro-cont-input"
value={enginePortTemp}
placeholder="输入范围 11212 - 11222"
onChange={(e) => {
const value = e.target.value;
setEnginePortTemp(value);
}}
/>
<div className="Contro-handle-icon">
<XIcon
className="grey-icon icon-p icon-active"
onClick={() => {
setIsEdit(false);
}}
/>
<CheckIcon
className="contro-handle-icon-check icon-p"
onClick={() => {
if (enginePortTemp) {
setIsEdit(false);
setEnginePort(enginePortTemp);
connectPort(Number(enginePortTemp));
}
}}
/>
</div>
</>
) : (
<>
return (
<>
{safeConnected || failConnected ? (
<div
className={classNames("Contro-cont-text", {
["Contro-cont-text-success"]: safeConnected,
["Contro-cont-text-error"]: failConnected,
})}
className={classNames("Contro", {
["Contro-success-bg"]: safeConnected,
["Contro-error-bg"]: failConnected,
})}
>
{safeConnected && "已连接(" + enginePort + ""}
{failConnected &&
(enginePort
? autoFindFailedReason + "" + enginePort + ""
: autoFindFailedReason)}
<div className="Contro-lable">Yakit </div>
<div className="Contro-cont">
{isEdit ? (
<>
<Input
rootClassName="Contro-cont-input"
value={enginePortTemp}
placeholder="输入范围 11212 - 11222"
onChange={(e) => {
const value = e.target.value;
setEnginePortTemp(value);
}}
/>
<div className="Contro-handle-icon">
<XIcon
className="grey-icon icon-p icon-active"
onClick={() => {
setIsEdit(false);
}}
/>
<CheckIcon
className="contro-handle-icon-check icon-p"
onClick={() => {
if (enginePortTemp) {
setIsEdit(false);
setEnginePort(enginePortTemp);
connectPort(Number(enginePortTemp));
}
}}
/>
</div>
</>
) : (
<>
<div
className={classNames("Contro-cont-text", {
["Contro-cont-text-success"]: safeConnected,
["Contro-cont-text-error"]: failConnected,
})}
>
{safeConnected && "已连接(" + enginePort + ""}
{failConnected &&
(enginePort
? autoFindFailedReason + "" + enginePort + ""
: autoFindFailedReason)}
</div>
<div className="Contro-handle-icon">
<Tooltip title="修改监听端口">
<PencilAltIcon
className="grey-icon icon-p icon-active"
onClick={() => {
setIsEdit(true);
setEnginePortTemp(enginePort);
}}
/>
</Tooltip>
<Divider type="vertical" style={{height: 16}}/>
{safeConnected && (
<ExitIcon onClick={() => wsc.disconnect()}/>
)}
{failConnected && (
<RefreshIcon
className="grey-icon icon-active"
onClick={() => {
if (enginePort) {
connectPort(Number(enginePort));
} else {
findPort(11212, 11222);
}
}}
/>
)}
</div>
</>
)}
</div>
</div>
<div className="Contro-handle-icon">
<Tooltip title="修改监听端口">
<PencilAltIcon
className="grey-icon icon-p icon-active"
onClick={() => {
setIsEdit(true);
setEnginePortTemp(enginePort);
}}
/>
</Tooltip>
<Divider type="vertical" style={{ height: 16 }} />
{safeConnected && (
<ExitIcon onClick={() => wsc.disconnect()} />
)}
{failConnected && (
<RefreshIcon
className="grey-icon icon-active"
onClick={() => {
if (enginePort) {
connectPort(Number(enginePort));
} else {
findPort(11212, 11222);
}
}}
/>
)}
</div>
</>
)}
</div>
</div>
) : null}
</>
);
) : null}
</>
);
};
-51
View File
@@ -1,51 +0,0 @@
import React, {useEffect, useState} from "react";
import TextArea from "antd/lib/input/TextArea";
import {Button} from "antd";
interface EvalProps {
}
export const Eval: React.FC<EvalProps> = () => {
const [inputData, setInputData] = useState(""); // 状态用于存储 textarea 输入的数据
useEffect(() => {
const handleMessage = (event: MessageEvent) => {
// 检查消息来源是否安全
// if (event.origin !== "http://example.com") { // 适当替换为你的期望源
// return;
// }
console.log(event.data)
alert(`Received message: ${event.data}`);
}
// 添加事件监听器
window.addEventListener('message', handleMessage);
return () => {
window.removeEventListener('message', handleMessage);
};
}, []);
// 处理按钮点击事件
const handleClick = () => {
const iframe = document.getElementById('sandbox') as HTMLIFrameElement; // 正确的类型断言
if (iframe?.contentWindow) {
iframe.contentWindow.postMessage({fn: 'Encrypt', args: '111111'}, '*'); // 发送用户输入的数据到 iframe
}
};
// 更新 textarea 输入
const handleInputChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setInputData(event.target.value);
};
return (
<div>
<TextArea
value={inputData}
onChange={handleInputChange}
placeholder="Enter your expression (e.g., 22 * 33)"
/>
<Button onClick={handleClick}>Click me</Button>
</div>
);
}
+65 -54
View File
@@ -1,64 +1,75 @@
import React, { useEffect, useState } from "react";
import { Button } from "antd";
import React, {useEffect, useState} from "react";
import {Button, Input} from "antd";
import TextArea from "antd/lib/input/TextArea";
import { wsc } from "@network/chrome";
import { ActionType } from "../../public/socket";
import {wsc} from "@network/chrome";
import {ActionType} from "@network/chrome";
interface EvalInTabProps {}
interface EvalInTabProps {
}
export const EvalInTab: React.FC<EvalInTabProps> = () => {
const [inputData, setInputData] = useState("");
const [funcName, setFuncName] = useState("");
const [inputArgsData, setInputArgsData] = useState("");
const [code, setCode] = useState("");
// useEffect(() => {
// // const onConnectListener = (port: chrome.runtime.Port) => {
// // console.assert(port.name === "content-script");
// // port.onMessage.addListener(function (msg) {
// // console.log("on connect", msg)
// // });
// // port.onDisconnect.addListener(function () {
// // console.error("Disconnected from port.");
// // });
// // port.postMessage({type: "TEST", fn_name: "Encrypt", args: inputData});
// // };
// //
// // chrome.runtime.onConnect.addListener(onConnectListener);
//
// // return () => {
// // chrome.runtime.onConnect.removeListener(onConnectListener);
// // };
// }, [inputData]);
useEffect(() => {
wsc.onWSCMessage((message) => {
if (message.action === ActionType.TO_EXTENSION_PAGE) {
console.log("res:", message.result);
alert("from content script: " + JSON.stringify(message.result));
}
});
}, []);
useEffect(() => {
wsc.onWSCMessage((message) => {
if (message.action === ActionType.RESTOEVALINTAB) {
console.log("res:", message.result);
}
});
}, []);
const handleClick = async () => {
try {
const tabId = await wsc.getTabId();
await chrome.runtime.sendMessage({
action: ActionType.INJECT_SCRIPT,
tabId: tabId,
value: {mode: "CONTENT_CALL_FUNCTION", fn_name: funcName, args: inputArgsData},
});
} catch (error) {
}
};
const handleClick = async () => {
try {
const tabId = await wsc.getTabId();
chrome.runtime.sendMessage({
action: ActionType.INJECTSCRIPT,
tabId: tabId,
value: { fn_name: "Encrypt", args: inputData },
});
} catch (error) {}
};
const handleInputChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setInputArgsData(event.target.value);
};
const handleInputChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setInputData(event.target.value);
};
return (
<div>
<TextArea
value={inputData}
onChange={handleInputChange}
placeholder="Enter your expression (e.g., 22 * 33)"
/>
<Button onClick={handleClick}>eval in tab me</Button>
</div>
);
const handleEvalCodeClick = async () => {
try {
const tabId = await wsc.getTabId();
await chrome.runtime.sendMessage({
action: ActionType.INJECT_SCRIPT,
tabId: tabId,
value: {mode: "CONTENT_EVAL_CODE", code: code},
});
} catch (error) {
}
}
return (
<div>
<Input
value={funcName}
onChange={(e) => setFuncName(e.target.value)}
placeholder="Enter function name"
></Input>
<TextArea
value={inputArgsData}
onChange={handleInputChange}
placeholder="Enter your expression (e.g., 22 * 33)"
/>
<Button onClick={handleClick}>eval func in tab</Button>
<TextArea
value={code}
onChange={(e) => setCode(e.target.value)}
placeholder="Enter your expression (e.g., 22 * 33)"
/>
<Button onClick={handleEvalCodeClick}>eval code in tab</Button>
</div>
);
};
+10 -8
View File
@@ -1,10 +1,12 @@
enum ActionType {
export enum ActionType {
CONNECT = 'connect',
DISCONNECT = 'disconnect',
STATUS = 'status',
PROXYSTATUS = 'proxystatus',
SETPROXY = 'setproxy',
CLEARPROXY = 'clearproxy'
PROXY_STATUS = 'proxy_status',
SET_PROXY = 'set_proxy',
CLEAR_PROXY = 'clear_proxy',
INJECT_SCRIPT = 'yakit_inject_script',
TO_EXTENSION_PAGE = "yakit_to_extension_page",
}
export namespace wsc {
@@ -30,7 +32,7 @@ export namespace wsc {
export function updateProxyStatus() {
chrome.runtime.sendMessage({
action: ActionType.PROXYSTATUS,
action: ActionType.PROXY_STATUS,
});
}
@@ -43,16 +45,16 @@ export namespace wsc {
}
export function setproxy(scheme: string, host: string, port: number) {
chrome.runtime.sendMessage({action: ActionType.SETPROXY, scheme, host, port})
chrome.runtime.sendMessage({action: ActionType.SET_PROXY, scheme, host, port})
}
export function clearproxy() {
chrome.runtime.sendMessage({action: ActionType.CLEARPROXY})
chrome.runtime.sendMessage({action: ActionType.CLEAR_PROXY})
}
export function getTabId() {
return new Promise<number>((resolve, reject) => {
chrome.tabs.query({ active: true, lastFocusedWindow: true }, function (tabs) {
chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
if (tabs.length) {
resolve(tabs[0].id);
} else {