mirror of
https://github.com/yaklang/yaklang-chrome-extension.git
synced 2026-09-26 21:21:53 +08:00
Compare commits
19
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62cb22d2ab | ||
|
|
2c88e8764a | ||
|
|
70c33af717 | ||
|
|
74c5d4ae2b | ||
|
|
462648a71f | ||
|
|
6b45661fe3 | ||
|
|
fd275d5e7d | ||
|
|
b08a806ce7 | ||
|
|
5104c5b620 | ||
|
|
f3d41a3c6c | ||
|
|
598314a111 | ||
|
|
bb822b2d5b | ||
|
|
3e99ba57ac | ||
|
|
8e2af7a869 | ||
|
|
47ccb37a26 | ||
|
|
5cb1d1fa22 | ||
|
|
391f7292e7 | ||
|
|
5dc3c4c248 | ||
|
|
19c5b6e2ba |
@@ -3,8 +3,9 @@ name: Build and Release
|
|||||||
on: workflow_dispatch
|
on: workflow_dispatch
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-and-publish:
|
build-and-release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -21,18 +22,17 @@ jobs:
|
|||||||
- name: Build project
|
- name: Build project
|
||||||
run: yarn build
|
run: yarn build
|
||||||
|
|
||||||
- name: Get version
|
|
||||||
id: version
|
|
||||||
run: |
|
|
||||||
VERSION=$(jq -r '.version' build/manifest.json)
|
|
||||||
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
|
||||||
echo "build_time=$(date +'%Y-%m-%d %H:%M:%S')" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Zip build artifacts
|
- name: Zip build artifacts
|
||||||
run: |
|
run: |
|
||||||
cd build
|
cd build
|
||||||
zip -r ../extension.zip .
|
zip -r ../extension.zip .
|
||||||
|
|
||||||
|
- name: Generate version number
|
||||||
|
id: version
|
||||||
|
run: |
|
||||||
|
echo "version=1.0.${{ github.run_number }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "build_time=$(date +'%Y-%m-%d %H:%M:%S')" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Create Release
|
- name: Create Release
|
||||||
id: create_release
|
id: create_release
|
||||||
uses: actions/create-release@v1
|
uses: actions/create-release@v1
|
||||||
@@ -57,27 +57,3 @@ jobs:
|
|||||||
asset_path: ./extension.zip
|
asset_path: ./extension.zip
|
||||||
asset_name: yakit-chrome-extension-v${{ steps.version.outputs.version }}.zip
|
asset_name: yakit-chrome-extension-v${{ steps.version.outputs.version }}.zip
|
||||||
asset_content_type: application/zip
|
asset_content_type: application/zip
|
||||||
|
|
||||||
- name: Upload Extension To OSS
|
|
||||||
uses: tvrcgo/upload-to-oss@master
|
|
||||||
with:
|
|
||||||
key-id: ${{ secrets.OSS_KEY_ID }}
|
|
||||||
key-secret: ${{ secrets.OSS_KEY_SECRET }}
|
|
||||||
region: oss-accelerate
|
|
||||||
bucket: yaklang
|
|
||||||
assets: |
|
|
||||||
extension.zip:/chrome-extension/yakit-chrome-extension-v${{ steps.version.outputs.version }}.zip
|
|
||||||
|
|
||||||
- name: Update OSS latest version file
|
|
||||||
run: echo ${{ steps.version.outputs.version }} > ./extension-version.txt
|
|
||||||
|
|
||||||
- name: Upload Version File to OSS
|
|
||||||
uses: tvrcgo/upload-to-oss@master
|
|
||||||
with:
|
|
||||||
key-id: ${{ secrets.OSS_KEY_ID }}
|
|
||||||
key-secret: ${{ secrets.OSS_KEY_SECRET }}
|
|
||||||
region: oss-accelerate
|
|
||||||
bucket: yaklang
|
|
||||||
assets: |
|
|
||||||
./extension-version.txt:/chrome-extension/latest-version.txt
|
|
||||||
|
|
||||||
|
|||||||
+3
-12
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "Yakit Chrome Endpoint",
|
"name": "Yakit Chrome Endpoint",
|
||||||
"version": "0.0.7",
|
"version": "1.0",
|
||||||
"description": "A Endpoint for Yakit MITM or more",
|
"description": "A Endpoint for Yakit MITM or more",
|
||||||
"options_ui": {
|
"options_ui": {
|
||||||
"page": "proxy/options.html",
|
"page": "proxy/options.html",
|
||||||
@@ -24,18 +24,9 @@
|
|||||||
},
|
},
|
||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
{
|
{
|
||||||
"matches": ["<all_urls>","http://mitm/"],
|
"matches": ["http://mitm/"],
|
||||||
"run_at": "document_start",
|
"run_at": "document_start",
|
||||||
"js": [
|
"js": ["proxy/content.js"]
|
||||||
"proxy/links_finder.js"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"matches": ["<all_urls>","http://mitm/"],
|
|
||||||
"run_at": "document_end",
|
|
||||||
"js": [
|
|
||||||
"proxy/content.js"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"permissions": [
|
"permissions": [
|
||||||
|
|||||||
+6
-13
@@ -290,16 +290,6 @@ async function checkAndSetInitialProxy() {
|
|||||||
// 确保默认配置存在
|
// 确保默认配置存在
|
||||||
await ProxySettings.setDefaultConfigs();
|
await ProxySettings.setDefaultConfigs();
|
||||||
|
|
||||||
// 获取上次保存的代理配置
|
|
||||||
const lastProxy = await proxyStore.getCurrentProxy();
|
|
||||||
|
|
||||||
if (lastProxy) {
|
|
||||||
// 如果有上次的配置,恢复它
|
|
||||||
console.log('Restoring last proxy configuration:', lastProxy);
|
|
||||||
await handleSetProxyConfig(lastProxy, () => {});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取当前的代理设置
|
// 获取当前的代理设置
|
||||||
const settings = await getProxySettings();
|
const settings = await getProxySettings();
|
||||||
console.log('Current proxy settings:', settings);
|
console.log('Current proxy settings:', settings);
|
||||||
@@ -348,7 +338,7 @@ async function checkAndSetInitialProxy() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果没有之前的配置也没有检测到代理,才设置为系统代理
|
// 如果没有检测到代理或已存在配置,则设置为系统代理
|
||||||
await handleSetProxyConfig({
|
await handleSetProxyConfig({
|
||||||
id: 'system',
|
id: 'system',
|
||||||
name: '[系统代理]',
|
name: '[系统代理]',
|
||||||
@@ -356,6 +346,9 @@ async function checkAndSetInitialProxy() {
|
|||||||
enabled: true
|
enabled: true
|
||||||
}, () => {});
|
}, () => {});
|
||||||
|
|
||||||
|
// 设置认证监听
|
||||||
|
await ProxyAuth.setupAuthListener();
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error during initialization:', error);
|
console.error('Error during initialization:', error);
|
||||||
}
|
}
|
||||||
@@ -363,10 +356,10 @@ async function checkAndSetInitialProxy() {
|
|||||||
|
|
||||||
// 修改 setupProxyHandlers 函数
|
// 修改 setupProxyHandlers 函数
|
||||||
export function setupProxyHandlers() {
|
export function setupProxyHandlers() {
|
||||||
// 设置代理错误处理
|
// 设置代理错误处理和认证
|
||||||
ProxyAuth.setupErrorHandler();
|
ProxyAuth.setupErrorHandler();
|
||||||
// 设置认证监听
|
|
||||||
ProxyAuth.setupAuthListener();
|
ProxyAuth.setupAuthListener();
|
||||||
|
|
||||||
// 设置代理请求监听器
|
// 设置代理请求监听器
|
||||||
setupProxyRequestListener();
|
setupProxyRequestListener();
|
||||||
|
|
||||||
|
|||||||
+294
-851
File diff suppressed because it is too large
Load Diff
@@ -1,213 +0,0 @@
|
|||||||
// Links Finder Module
|
|
||||||
class LinksFinder {
|
|
||||||
constructor() {
|
|
||||||
this.links = [];
|
|
||||||
this.lastUpdate = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取页面所有链接
|
|
||||||
getAllLinks() {
|
|
||||||
const links = [];
|
|
||||||
const seen = new Set();
|
|
||||||
|
|
||||||
// 获取所有 a 标签
|
|
||||||
document.querySelectorAll('a').forEach(a => {
|
|
||||||
const href = a.href;
|
|
||||||
if (href && !seen.has(href) && href.startsWith('http')) {
|
|
||||||
seen.add(href);
|
|
||||||
links.push({
|
|
||||||
type: 'anchor',
|
|
||||||
url: href,
|
|
||||||
text: a.textContent.trim() || href,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 获取所有图片链接
|
|
||||||
document.querySelectorAll('img').forEach(img => {
|
|
||||||
const src = img.src;
|
|
||||||
if (src && !seen.has(src) && src.startsWith('http')) {
|
|
||||||
seen.add(src);
|
|
||||||
links.push({
|
|
||||||
type: 'image',
|
|
||||||
url: src,
|
|
||||||
alt: img.alt || 'Image',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 获取所有脚本链接
|
|
||||||
document.querySelectorAll('script').forEach(script => {
|
|
||||||
const src = script.src;
|
|
||||||
if (src && !seen.has(src) && src.startsWith('http')) {
|
|
||||||
seen.add(src);
|
|
||||||
links.push({
|
|
||||||
type: 'script',
|
|
||||||
url: src,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 获取所有样式表链接
|
|
||||||
document.querySelectorAll('link[rel="stylesheet"]').forEach(link => {
|
|
||||||
const href = link.href;
|
|
||||||
if (href && !seen.has(href) && href.startsWith('http')) {
|
|
||||||
seen.add(href);
|
|
||||||
links.push({
|
|
||||||
type: 'stylesheet',
|
|
||||||
url: href,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.links = links;
|
|
||||||
this.lastUpdate = new Date();
|
|
||||||
return links;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 按类型过滤链接
|
|
||||||
filterLinksByType(type) {
|
|
||||||
return this.links.filter(link => link.type === type);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取链接统计信息
|
|
||||||
getLinkStats() {
|
|
||||||
const stats = {
|
|
||||||
total: this.links.length,
|
|
||||||
byType: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.links.forEach(link => {
|
|
||||||
if (!stats.byType[link.type]) {
|
|
||||||
stats.byType[link.type] = 0;
|
|
||||||
}
|
|
||||||
stats.byType[link.type]++;
|
|
||||||
});
|
|
||||||
|
|
||||||
return stats;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 构建链接面板的 HTML
|
|
||||||
buildLinksPanel() {
|
|
||||||
const links = this.getAllLinks();
|
|
||||||
const stats = this.getLinkStats();
|
|
||||||
|
|
||||||
let html = `
|
|
||||||
<div class="links-stats">
|
|
||||||
<div class="stats-item">
|
|
||||||
<span>🔗</span>
|
|
||||||
<span>总链接: ${stats.total}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="links-filters">
|
|
||||||
<button class="filter-btn active" data-type="all">
|
|
||||||
<span>🔍</span>
|
|
||||||
<span>全部 (${stats.total})</span>
|
|
||||||
</button>
|
|
||||||
${Object.entries(stats.byType).map(([type, count]) => `
|
|
||||||
<button class="filter-btn" data-type="${type}">
|
|
||||||
<span>${this._getTypeIcon(type)}</span>
|
|
||||||
<span>${this._getTypeName(type)} (${count})</span>
|
|
||||||
</button>
|
|
||||||
`).join('')}
|
|
||||||
</div>
|
|
||||||
<div class="links-list">
|
|
||||||
${links.map(link => this._buildLinkItem(link)).join('')}
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取链接类型图标
|
|
||||||
_getTypeIcon(type) {
|
|
||||||
const icons = {
|
|
||||||
anchor: '🔗',
|
|
||||||
image: '🖼️',
|
|
||||||
script: '📜',
|
|
||||||
stylesheet: '🎨'
|
|
||||||
};
|
|
||||||
return icons[type] || '🔗';
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取链接类型名称
|
|
||||||
_getTypeName(type) {
|
|
||||||
const names = {
|
|
||||||
anchor: '链接',
|
|
||||||
image: '图片',
|
|
||||||
script: '脚本',
|
|
||||||
stylesheet: '样式'
|
|
||||||
};
|
|
||||||
return names[type] || type;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 构建单个链接项的 HTML
|
|
||||||
_buildLinkItem(link) {
|
|
||||||
return `
|
|
||||||
<div class="link-item" data-type="${link.type}">
|
|
||||||
<div class="link-icon">${this._getTypeIcon(link.type)}</div>
|
|
||||||
<div class="link-content">
|
|
||||||
<div class="link-url" title="${link.url}">${link.url}</div>
|
|
||||||
${link.text ? `<div class="link-text" title="${link.text}">${link.text}</div>` : ''}
|
|
||||||
${link.alt ? `<div class="link-alt" title="${link.alt}">${link.alt}</div>` : ''}
|
|
||||||
</div>
|
|
||||||
<button class="copy-btn" data-url="${link.url}" title="复制链接">📋</button>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 绑定事件处理
|
|
||||||
bindEvents(container) {
|
|
||||||
// 过滤按钮点击事件
|
|
||||||
container.querySelectorAll('.filter-btn').forEach(btn => {
|
|
||||||
btn.addEventListener('click', (e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
const type = btn.dataset.type;
|
|
||||||
console.log('Filter clicked:', type);
|
|
||||||
|
|
||||||
// 更新按钮状态
|
|
||||||
container.querySelectorAll('.filter-btn').forEach(b => {
|
|
||||||
b.classList.remove('active');
|
|
||||||
});
|
|
||||||
btn.classList.add('active');
|
|
||||||
|
|
||||||
// 过滤链接显示
|
|
||||||
container.querySelectorAll('.link-item').forEach(item => {
|
|
||||||
if (type === 'all' || item.dataset.type === type) {
|
|
||||||
item.removeAttribute('data-hidden');
|
|
||||||
} else {
|
|
||||||
item.setAttribute('data-hidden', 'true');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 复制按钮点击事件
|
|
||||||
container.querySelectorAll('.copy-btn').forEach(btn => {
|
|
||||||
btn.addEventListener('click', async (e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
const url = btn.dataset.url;
|
|
||||||
try {
|
|
||||||
await navigator.clipboard.writeText(url);
|
|
||||||
const originalText = btn.textContent;
|
|
||||||
btn.textContent = '✓';
|
|
||||||
btn.style.setProperty('color', '#52c41a', 'important');
|
|
||||||
setTimeout(() => {
|
|
||||||
btn.textContent = originalText;
|
|
||||||
btn.style.removeProperty('color');
|
|
||||||
}, 1000);
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Failed to copy:', err);
|
|
||||||
btn.textContent = '❌';
|
|
||||||
setTimeout(() => {
|
|
||||||
btn.textContent = '📋';
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("LinksFinder module loaded");
|
|
||||||
// 导出模块
|
|
||||||
window.LinksFinder = LinksFinder;
|
|
||||||
@@ -43,9 +43,9 @@ export class ProxySettings {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
// 确保日志存储已初始化
|
// 确保日志存储已初始化
|
||||||
const logs = await proxyStore.getLogs();
|
const logs = await proxyStore.getLogs(); // 使用 getLogs 而不是 getProxyLogs
|
||||||
if (!logs || logs.length === 0) {
|
if (!logs || logs.length === 0) {
|
||||||
await proxyStore.clearLogs();
|
await proxyStore.clearLogs(); // 初始化日志存储
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,25 +237,21 @@ export const ProxySwitch: React.FC<ProxySwitchProps> = () => {
|
|||||||
const menuItems: MenuProps['items'] = [
|
const menuItems: MenuProps['items'] = [
|
||||||
...FIXED_MODES.map(mode => ({
|
...FIXED_MODES.map(mode => ({
|
||||||
key: mode.key,
|
key: mode.key,
|
||||||
icon: <span className="menu-icon" style={{
|
icon: <span className="menu-icon" style={{ color: mode.color }}>{mode.icon}</span>,
|
||||||
color: currentMode === mode.key ? 'var(--yakit-primary)' : mode.color
|
label: mode.name,
|
||||||
}}>{mode.icon}</span>,
|
|
||||||
label: `${mode.name}${currentMode === mode.key ? ' ✅' : ''}`,
|
|
||||||
className: `${currentMode === mode.key ? 'menu-item-selected' : ''} ${isLoading ? 'menu-item-loading' : ''}`,
|
className: `${currentMode === mode.key ? 'menu-item-selected' : ''} ${isLoading ? 'menu-item-loading' : ''}`,
|
||||||
title: mode.name.replace(/[\[\]]/g, '')
|
title: mode.name.replace(/[\[\]]/g, '')
|
||||||
})),
|
})),
|
||||||
{ type: 'divider' },
|
{ type: 'divider' },
|
||||||
...customProxies.map(proxy => ({
|
...customProxies.map(proxy => ({
|
||||||
key: proxy.key,
|
key: proxy.key,
|
||||||
icon: <span className="menu-icon" style={{
|
icon: <span className="menu-icon" style={{ color: proxy.color }}>
|
||||||
color: currentMode === proxy.key ? 'var(--yakit-primary)' : proxy.color
|
|
||||||
}}>
|
|
||||||
{proxy.config.proxyType === 'pac_script' ? '📜' : <GlobalOutlined />}
|
{proxy.config.proxyType === 'pac_script' ? '📜' : <GlobalOutlined />}
|
||||||
</span>,
|
</span>,
|
||||||
label: <span style={{
|
label: <span style={{
|
||||||
color: currentMode === proxy.key ? 'var(--yakit-primary)' : 'inherit',
|
color: currentMode === proxy.key ? 'var(--yakit-primary)' : 'inherit',
|
||||||
opacity: isLoading ? 0.7 : 1
|
opacity: isLoading ? 0.7 : 1
|
||||||
}}>{proxy.name}{currentMode === proxy.key ? ' ✅' : ''}</span>,
|
}}>{proxy.name}</span>,
|
||||||
className: `${currentMode === proxy.key ? 'menu-item-selected' : ''} ${isLoading ? 'menu-item-loading' : ''}`,
|
className: `${currentMode === proxy.key ? 'menu-item-selected' : ''} ${isLoading ? 'menu-item-loading' : ''}`,
|
||||||
title: proxy.config.scheme
|
title: proxy.config.scheme
|
||||||
? `${proxy.config.scheme.toUpperCase()} ${proxy.config.host}:${proxy.config.port}`
|
? `${proxy.config.scheme.toUpperCase()} ${proxy.config.host}:${proxy.config.port}`
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ export const ProxySettings: React.FC<ProxySettingsProps> = ({
|
|||||||
// 处理固定代理服务器模式
|
// 处理固定代理服务器模式
|
||||||
const bypassList = values.bypassList
|
const bypassList = values.bypassList
|
||||||
? values.bypassList.split('\n').map(line => line.trim()).filter(line => line.length > 0)
|
? values.bypassList.split('\n').map(line => line.trim()).filter(line => line.length > 0)
|
||||||
: [""];
|
: ["localhost", "127.0.0.1"];
|
||||||
|
|
||||||
updatedConfig = {
|
updatedConfig = {
|
||||||
id: editingConfig.id,
|
id: editingConfig.id,
|
||||||
|
|||||||
Reference in New Issue
Block a user