├── .gitignore
├── .vscode
└── extensions.json
├── README.md
├── assets
└── vue.svg
├── components
├── HelloWorld.vue
└── TestDemo.vue
├── entrypoints
├── background.ts
├── content.ts
├── options
│ ├── App.vue
│ ├── Options.vue
│ ├── index.html
│ ├── main.ts
│ └── style.css
├── popup
│ ├── App.vue
│ ├── Popup.vue
│ ├── index.html
│ ├── main.ts
│ └── style.css
└── testpage
│ ├── App.vue
│ ├── index.html
│ ├── main.ts
│ └── style.css
├── package.json
├── pnpm-lock.yaml
├── public
├── _locales
│ ├── en
│ │ └── messages.json
│ └── zh_CN
│ │ └── messages.json
├── icon
│ ├── 128.png
│ ├── 16.png
│ ├── 32.png
│ ├── 48.png
│ └── 96.png
└── wxt.svg
├── screenshot
├── gzh.png
├── screen_1.png
├── screen_2.png
└── weixin.png
├── tsconfig.json
├── utils
├── base.ts
└── storage.ts
└── wxt.config.ts
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | .output
12 | stats.html
13 | stats-*.json
14 | .wxt
15 | web-ext.config.ts
16 |
17 | # Editor directories and files
18 | .vscode/*
19 | !.vscode/extensions.json
20 | .idea
21 | .DS_Store
22 | *.suo
23 | *.ntvs*
24 | *.njsproj
25 | *.sln
26 | *.sw?
27 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["Vue.volar"]
3 | }
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # HiProxy
2 | A proxy extension for Chrome
3 |
4 | ```
5 | Based on Manifest V3 (MV3)
6 |
7 | vue3 + wxt + ts
8 |
9 |
10 | 全新版本,基于谷歌扩展MV3规范开发,适用于Chrome浏览器新版本。
11 |
12 | 代码框架采用 vue3 + wxt + ts
13 |
14 |
15 | 项目代码完全开源,有兴趣的可以自己尝试编译打包,或者省事的师傅可以直接下载我打包好的 zip 文件,直达下载地址:
16 |
17 | https://github.com/hicode0101/HiProxy/releases
18 |
19 |
20 |
21 | 使用方式:
22 | 1、进chrome 浏览器扩展,直达地址 chrome://extensions/
23 | 2、开启开发者模式
24 | 3、把下载的 HiProxy-3.2.10-chrome.zip 文件直接拖进去,就可以了,不用解压。
25 |
26 |
27 | 通过我编写的另外一个 HiLocalProxy 小工具,可以完美解决目前主流浏览器不支持socks5带密码验证的问题。
28 |
29 |
30 | ```
31 |
32 |
33 |
34 |
35 |
36 | ---
37 |
38 | ### 插件安装和使用视频教程:
39 | https://www.bilibili.com/video/BV1tVS4YXEUT
40 |
41 |
42 |
43 |
44 | ### 支持socks5用户名密码代理的视频教程:
45 |
46 | https://www.bilibili.com/video/BV18rPsedEXs
47 |
48 |
49 | 点击链接跳转至视频播放页面。
50 |
51 |
52 |
53 |
54 |
55 |
56 | # Screenshot(UI截图)
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | ## 作者申明
65 |
66 | 本系列工具软件仅供白帽子安全研究和技术交流使用,禁止用于商业用途。
67 |
68 | 👨💻我的白帽昵称:犀利的远哥
69 |
70 | ✉️我的微信:hicode0101
71 |
72 | 💞️微信公众号:远哥说安全
73 |
74 | 如果你在我分享的工具中,遇到了问题,请联系我,我会及时回复。
75 |
76 | 如果你在我分享的工具上,有其它功能需求,也请告知我,我非常乐意尝试满足你的需求。
77 |
78 |
79 |
80 |
81 | ---
82 |
83 |
84 |
85 | ### 我的微信:
86 |
87 |
88 |
89 |
90 | ---
91 |
92 | ### 微信公众号:
93 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/assets/vue.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/components/HelloWorld.vue:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 | {{ msg }}
13 |
14 |
15 |
16 |
17 | Edit
18 | components/HelloWorld.vue
to test HMR
19 |
20 |
21 |
22 |
23 | Install
24 | Volar
25 | in your IDE for a better DX
26 |
27 | Click on the WXT and Vue logos to learn more
28 |
29 |
30 |
35 |
--------------------------------------------------------------------------------
/components/TestDemo.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Default
6 |
7 | Tertiary
8 |
9 |
10 | Primary
11 |
12 |
13 | Info
14 |
15 |
16 | Success
17 |
18 |
19 | Warning
20 |
21 |
22 | Error
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
35 |
36 |
37 |
40 |
41 |
--------------------------------------------------------------------------------
/entrypoints/background.ts:
--------------------------------------------------------------------------------
1 | //import { directProxy } from "@/utils/base";
2 |
3 | export default defineBackground(() => {
4 | console.log('Hello background!', { id: browser.runtime.id });
5 |
6 |
7 | browser.runtime.onInstalled.addListener((e: any) => {
8 | console.log("onInstalled");
9 | //console.info("onInstalled");
10 | console.debug(JSON.stringify(e));
11 |
12 | if (e.reason === 'install') {
13 | proxyConfigsInit();
14 | //browser.tabs.create({ url: "/options.html" });
15 | }
16 |
17 | directProxy(()=>{});
18 |
19 | });
20 |
21 | browser.runtime.onStartup.addListener((event: any) => {
22 | console.log("onStartup", new Date().toLocaleTimeString());
23 |
24 | //directProxy(()=>{});
25 |
26 | browser.storage.local.get(["useLastProxy"]).then((result : any)=> {
27 | console.log("useLastProxy is ", result.useLastProxy);
28 |
29 | if(result.useLastProxy == true){
30 | console.log("openCurrProxy");
31 | openCurrProxy(()=>{});
32 | }else{
33 | directProxy(()=>{});
34 | }
35 |
36 | });
37 |
38 | });
39 |
40 |
41 | /*
42 | browser.runtime.openOptionsPage((event: any) => {
43 | console.log("openOptionsPage", new Date().toLocaleTimeString());
44 | });
45 | */
46 |
47 | });
48 |
--------------------------------------------------------------------------------
/entrypoints/content.ts:
--------------------------------------------------------------------------------
1 | export default defineContentScript({
2 | matches: ['*://*.google.com/*'],
3 | main() {
4 | console.log('Hello content.ts.');
5 | },
6 | });
7 |
--------------------------------------------------------------------------------
/entrypoints/options/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
27 |
28 |
31 |
--------------------------------------------------------------------------------
/entrypoints/options/Options.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
{{ browser.i18n.getMessage('plugin_name') }}
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | {{ browser.i18n.getMessage('options_btn_addNew') }}
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | {{ browser.i18n.getMessage('options_btn_save_all') }}
51 |
52 |
53 | {{ browser.i18n.getMessage('options_btn_reset') }}
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | {{ browser.i18n.getMessage('options_msg_export_tips') }}
69 |
70 | |
71 |
72 |
73 |
74 | {{ browser.i18n.getMessage('options_msg_export_lbl') }}: |
75 |
76 |
77 |
78 | {{ browser.i18n.getMessage('options_msg_export_btn') }}
79 |
80 | |
81 |
82 |
83 | {{ browser.i18n.getMessage('options_msg_import_lbl') }}: |
84 |
85 |
86 |
87 |
88 | {{ browser.i18n.getMessage('options_msg_import_btn') }}
89 |
90 | |
91 |
92 |
93 | {{ browser.i18n.getMessage('options_msg_import_reset_lbl') }}: |
94 |
95 |
96 |
97 | {{ browser.i18n.getMessage('options_msg_import_reset_btn') }}
98 |
99 | |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 | {{ browser.i18n.getMessage('options_msg_others_uselastproxy_lbl') }}: |
113 |
114 |
115 | {{ browser.i18n.getMessage('options_msg_others_uselastproxy_switch') }}
116 | |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 | 表达式 |
129 | 说明 |
130 |
131 |
132 |
133 |
134 | 127.0.0.1 |
135 |
136 | http://127.0.0.1 的访问不会走代理
137 | |
138 |
139 |
140 | localhost |
141 |
142 | http://localhost 的访问不会走代理
143 | |
144 |
145 |
146 | ::1 |
147 |
148 | http://::1 的访问不会走代理("::1"代表ipv6的本地回环地址)
149 | |
150 |
151 |
152 | 192.168.1.0/24 |
153 |
154 | 对主机范围 192.168.1.0~192.168.1.255 的访问不会走代理
155 | |
156 |
157 |
158 | qq.com |
159 |
160 | 仅 http://qq.com 的访问不会走代理,其它二级域名的访问会走代理,例如 http://www.qq.com 的访问会走代理
161 | |
162 |
163 |
164 | .qq.com |
165 |
166 | qq.com 域名下所有二级域名不走代理,例如 http://aaa.qq.com 或 http://bbb.qq.com 的访问都不会走代理
167 | |
168 |
169 |
170 | *.qq.com |
171 |
172 | qq.com 域名下所有二级域名不走代理,例如 http://aaa.qq.com 或 http://bbb.qq.com 的访问都不会走代理(推荐)
173 | |
174 |
175 |
176 | *qq.com |
177 |
178 | http://abc.qq.com 或 http://abcqq.com 的访问不会走代理
179 | |
180 |
181 |
182 | login.qq.com |
183 |
184 | http://login.qq.com 的访问不会走代理
185 | |
186 |
187 |
188 | h.trace.qq.com |
189 |
190 | http://h.trace.qq.com 的访问不会走代理
191 | |
192 |
193 |
194 | 官方文档 |
195 |
196 |
197 | https://developer.chrome.com/docs/extensions/reference/api/proxy?hl=zh-cn#bypass_list
198 |
199 | |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 | {{ browser.i18n.getMessage('options_about_project') }}: |
215 |
216 | https://github.com/hicode0101/HiProxy
218 | |
219 |
220 |
221 | {{ browser.i18n.getMessage('options_about_version') }}: |
222 | v{{ browser.runtime.getManifest().version }} |
223 |
224 |
225 | {{ browser.i18n.getMessage('options_about_author') }}: |
226 | hicode0101 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 | {{ detailItem.name }}
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 | {{ browser.i18n.getMessage('options_msg_input_detail_bypass') }}
264 |
265 | |
266 |
267 |
268 |
269 | ByPassHost: |
270 |
271 |
272 |
281 | |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 | {{ browser.i18n.getMessage('options_msg_input_detail_auth') }}
292 |
293 | |
294 |
295 |
296 |
297 |
298 | UserName: |
299 |
300 |
301 | |
302 |
303 |
304 | PassWord: |
305 |
306 |
307 | |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 | {{ browser.i18n.getMessage('options_btn_detail_ok') }}
320 |
321 |
322 | {{ browser.i18n.getMessage('options_btn_detail_ok_tips') }}
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
675 |
676 |
--------------------------------------------------------------------------------
/entrypoints/options/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | HiProxy Options
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/entrypoints/options/main.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue';
2 | import './style.css';
3 | import App from './App.vue';
4 | import naive from "naive-ui";
5 |
6 | //createApp(App).mount('#app');
7 |
8 | const app = createApp(App);
9 | app.use(naive);
10 | app.mount("#app");
11 |
--------------------------------------------------------------------------------
/entrypoints/options/style.css:
--------------------------------------------------------------------------------
1 | :root {
2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3 | line-height: 1.5;
4 | font-weight: 400;
5 |
6 | color-scheme: light dark;
7 | color: rgba(255, 255, 255, 0.87);
8 | background-color: #242424;
9 |
10 | font-synthesis: none;
11 | text-rendering: optimizeLegibility;
12 | -webkit-font-smoothing: antialiased;
13 | -moz-osx-font-smoothing: grayscale;
14 | -webkit-text-size-adjust: 100%;
15 | }
16 |
17 | a {
18 | font-weight: 500;
19 | color: #646cff;
20 | text-decoration: inherit;
21 | }
22 | a:hover {
23 | color: #535bf2;
24 | }
25 |
26 | a {
27 | font-weight: 500;
28 | color: #646cff;
29 | text-decoration: inherit;
30 | }
31 | a:hover {
32 | color: #535bf2;
33 | }
34 |
35 | body {
36 | margin: 0;
37 | min-width: 320px;
38 | min-height: 100vh;
39 | }
40 |
41 | h1 {
42 | font-size: 3.2em;
43 | line-height: 1.1;
44 | }
45 |
46 | button {
47 | border-radius: 8px;
48 | border: 1px solid transparent;
49 | padding: 0.6em 1.2em;
50 | font-size: 1em;
51 | font-weight: 500;
52 | font-family: inherit;
53 | background-color: #1a1a1a;
54 | cursor: pointer;
55 | transition: border-color 0.25s;
56 | }
57 | button:hover {
58 | border-color: #646cff;
59 | }
60 | button:focus,
61 | button:focus-visible {
62 | outline: 4px auto -webkit-focus-ring-color;
63 | }
64 |
65 | .card {
66 | padding: 2em;
67 | }
68 |
69 | #app {
70 | max-width: 1280px;
71 | }
72 |
73 | @media (prefers-color-scheme: light) {
74 | :root {
75 | color: #213547;
76 | background-color: #ffffff;
77 | }
78 | a:hover {
79 | color: #747bff;
80 | }
81 | button {
82 | background-color: #f9f9f9;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/entrypoints/popup/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
25 |
26 |
29 |
--------------------------------------------------------------------------------
/entrypoints/popup/Popup.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
192 |
193 |
--------------------------------------------------------------------------------
/entrypoints/popup/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | HiProxy Popup
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/entrypoints/popup/main.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue';
2 | import './style.css';
3 | import App from './App.vue';
4 | import naive from "naive-ui";
5 |
6 | //createApp(App).mount('#app');
7 |
8 | const app = createApp(App);
9 | app.use(naive);
10 | app.mount("#app");
11 |
--------------------------------------------------------------------------------
/entrypoints/popup/style.css:
--------------------------------------------------------------------------------
1 | :root {
2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3 | line-height: 1.5;
4 | font-weight: 400;
5 |
6 | color-scheme: light dark;
7 | color: rgba(255, 255, 255, 0.87);
8 | background-color: #242424;
9 |
10 | font-synthesis: none;
11 | text-rendering: optimizeLegibility;
12 | -webkit-font-smoothing: antialiased;
13 | -moz-osx-font-smoothing: grayscale;
14 | -webkit-text-size-adjust: 100%;
15 | }
16 |
17 | a {
18 | font-weight: 500;
19 | color: #646cff;
20 | text-decoration: inherit;
21 | }
22 | a:hover {
23 | color: #535bf2;
24 | }
25 |
26 | a {
27 | font-weight: 500;
28 | color: #646cff;
29 | text-decoration: inherit;
30 | }
31 | a:hover {
32 | color: #535bf2;
33 | }
34 |
35 | body {
36 | margin: 0;
37 | display: flex;
38 | place-items: center;
39 | min-width: 210px;
40 | background-color: #fdfdfd;
41 | }
42 |
43 | h1 {
44 | font-size: 3.2em;
45 | line-height: 1.1;
46 | }
47 |
48 | button {
49 | border-radius: 8px;
50 | border: 1px solid transparent;
51 | padding: 0.6em 1.2em;
52 | font-size: 1em;
53 | font-weight: 500;
54 | font-family: inherit;
55 | background-color: #1a1a1a;
56 | cursor: pointer;
57 | transition: border-color 0.25s;
58 | }
59 | button:hover {
60 | border-color: #646cff;
61 | }
62 | button:focus,
63 | button:focus-visible {
64 | outline: 4px auto -webkit-focus-ring-color;
65 | }
66 |
67 | .card {
68 | padding: 2em;
69 | }
70 |
71 | #app {
72 | min-width: 210px;
73 | }
74 |
75 | @media (prefers-color-scheme: light) {
76 | :root {
77 | color: #213547;
78 | background-color: #ffffff;
79 | }
80 | a:hover {
81 | color: #747bff;
82 | }
83 | button {
84 | background-color: #f9f9f9;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/entrypoints/testpage/App.vue:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
--------------------------------------------------------------------------------
/entrypoints/testpage/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Test Page
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/entrypoints/testpage/main.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue';
2 | import './style.css';
3 | import App from './App.vue';
4 | import naive from "naive-ui";
5 |
6 | //createApp(App).mount('#app');
7 |
8 | const app = createApp(App);
9 | app.use(naive);
10 | app.mount("#app");
11 |
--------------------------------------------------------------------------------
/entrypoints/testpage/style.css:
--------------------------------------------------------------------------------
1 | :root {
2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3 | line-height: 1.5;
4 | font-weight: 400;
5 |
6 | color-scheme: light dark;
7 | color: rgba(255, 255, 255, 0.87);
8 | background-color: #242424;
9 |
10 | font-synthesis: none;
11 | text-rendering: optimizeLegibility;
12 | -webkit-font-smoothing: antialiased;
13 | -moz-osx-font-smoothing: grayscale;
14 | -webkit-text-size-adjust: 100%;
15 | }
16 |
17 | a {
18 | font-weight: 500;
19 | color: #646cff;
20 | text-decoration: inherit;
21 | }
22 | a:hover {
23 | color: #535bf2;
24 | }
25 |
26 | a {
27 | font-weight: 500;
28 | color: #646cff;
29 | text-decoration: inherit;
30 | }
31 | a:hover {
32 | color: #535bf2;
33 | }
34 |
35 | body {
36 | margin: 0;
37 | display: flex;
38 | place-items: center;
39 | min-width: 320px;
40 | min-height: 100vh;
41 | }
42 |
43 | h1 {
44 | font-size: 3.2em;
45 | line-height: 1.1;
46 | }
47 |
48 | button {
49 | border-radius: 8px;
50 | border: 1px solid transparent;
51 | padding: 0.6em 1.2em;
52 | font-size: 1em;
53 | font-weight: 500;
54 | font-family: inherit;
55 | background-color: #1a1a1a;
56 | cursor: pointer;
57 | transition: border-color 0.25s;
58 | }
59 | button:hover {
60 | border-color: #646cff;
61 | }
62 | button:focus,
63 | button:focus-visible {
64 | outline: 4px auto -webkit-focus-ring-color;
65 | }
66 |
67 | .card {
68 | padding: 2em;
69 | }
70 |
71 | #app {
72 | max-width: 1280px;
73 | margin: 0 auto;
74 | padding: 2rem;
75 | text-align: center;
76 | }
77 |
78 | @media (prefers-color-scheme: light) {
79 | :root {
80 | color: #213547;
81 | background-color: #ffffff;
82 | }
83 | a:hover {
84 | color: #747bff;
85 | }
86 | button {
87 | background-color: #f9f9f9;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wxt-vue-starter",
3 | "description": "manifest.json description",
4 | "private": true,
5 | "version": "0.0.0",
6 | "type": "module",
7 | "scripts": {
8 | "dev": "wxt",
9 | "dev:firefox": "wxt -b firefox",
10 | "build": "wxt build",
11 | "build:firefox": "wxt build -b firefox",
12 | "zip": "wxt zip",
13 | "zip:firefox": "wxt zip -b firefox",
14 | "compile": "vue-tsc --noEmit",
15 | "postinstall": "wxt prepare"
16 | },
17 | "dependencies": {
18 | "@vicons/ionicons4": "^0.12.0",
19 | "@vicons/ionicons5": "^0.12.0",
20 | "vue": "^3.5.11"
21 | },
22 | "devDependencies": {
23 | "@vicons/fluent": "^0.12.0",
24 | "@wxt-dev/module-vue": "^1.0.1",
25 | "naive-ui": "^2.40.1",
26 | "typescript": "^5.6.2",
27 | "vfonts": "^0.0.3",
28 | "vue-router": "^4.4.5",
29 | "vue-tsc": "^2.1.6",
30 | "wxt": "^0.19.13"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/public/_locales/en/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugin_name": {
3 | "message": "HiProxy"
4 | },
5 | "plugin_desc": {
6 | "message": "A proxy extension for Chrome"
7 | },
8 | "pop_menu_direct": {
9 | "message": "Direct"
10 | },
11 | "pop_menu_system": {
12 | "message": "System"
13 | },
14 | "pop_menu_options": {
15 | "message": "Options"
16 | },
17 | "pop_menu_myip": {
18 | "message": "Query My IP"
19 | },
20 | "options_tab_proxy_config": {
21 | "message": "Proxy Configs"
22 | },
23 | "options_tab_bypass_doc": {
24 | "message": "Bypass Doc"
25 | },
26 | "options_tab_export": {
27 | "message": "Export/Import"
28 | },
29 | "options_tab_others": {
30 | "message": "Others"
31 | },
32 | "options_tab_about": {
33 | "message": "About"
34 | },
35 | "options_btn_addNew": {
36 | "message": "Add New Config"
37 | },
38 | "options_msg_input_proxy_name_ph": {
39 | "message": "a name for config"
40 | },
41 | "options_btn_save_all": {
42 | "message": "Save All"
43 | },
44 | "options_btn_reset": {
45 | "message": "Reset"
46 | },
47 | "options_btn_detail_ok": {
48 | "message": "OK"
49 | },
50 | "options_btn_detail_ok_tips": {
51 | "message": "After modification, click the batch save button on the list interface to take effect"
52 | },
53 | "options_about_project": {
54 | "message": "Project"
55 | },
56 | "options_about_version": {
57 | "message": "Version"
58 | },
59 | "options_about_author": {
60 | "message": "Author"
61 | },
62 | "options_msg_repeat_name": {
63 | "message": "There are duplicate configuration names, please check!"
64 | },
65 | "options_msg_save_success": {
66 | "message": "Saved successfully! "
67 | },
68 | "options_msg_reset_dialog_title": {
69 | "message": "Operation warning"
70 | },
71 | "options_msg_reset_dialog_content": {
72 | "message": "Are you sure you want to reset all configurations?"
73 | },
74 | "options_msg_reset_dialog_positiveText": {
75 | "message": "Confirm"
76 | },
77 | "options_msg_reset_dialog_negativeText": {
78 | "message": "Cancel"
79 | },
80 | "options_msg_input_name": {
81 | "message": "The configuration name parameter is incorrect, please check"
82 | },
83 | "options_msg_input_host": {
84 | "message": "The host address parameters are incorrect, please check"
85 | },
86 | "options_msg_input_port": {
87 | "message": "The port parameters are incorrect (port range 0~65535), please check"
88 | },
89 | "options_msg_input_detail_bypass": {
90 | "message": "List of hosts connected without proxy: (one host per row)"
91 | },
92 | "options_msg_input_detail_bypass_host_ph": {
93 | "message": "host IP or domain wildcard"
94 | },
95 | "options_msg_input_detail_auth": {
96 | "message": "Proxy login: (If password login is not required, leave all options below blank)"
97 | },
98 | "options_msg_input_detail_auth_username": {
99 | "message": "UserName"
100 | },
101 | "options_msg_input_detail_auth_password": {
102 | "message": "PassWord"
103 | },
104 | "options_msg_export_tips": {
105 | "message": "Here, you can export the current configuration for backup or sharing, or directly restore personalized configuration parameters by importing files."
106 | },
107 | "options_msg_export_lbl": {
108 | "message": "Export"
109 | },
110 | "options_msg_export_btn": {
111 | "message": "Export Config"
112 | },
113 | "options_msg_import_lbl": {
114 | "message": "Import"
115 | },
116 | "options_msg_import_btn": {
117 | "message": "Import Config"
118 | },
119 | "options_msg_import_reset_lbl": {
120 | "message": "Reset"
121 | },
122 | "options_msg_import_reset_btn": {
123 | "message": "Reset (restore to initial configuration)"
124 | },
125 | "options_msg_others_uselastproxy_lbl": {
126 | "message": "Default Proxy"
127 | },
128 | "options_msg_others_uselastproxy_switch": {
129 | "message": "(Use the last proxy)"
130 | },
131 | "options_msg_xxxxxxxxx": {
132 | "message": "xxxxxxxxxxxx"
133 | },
134 | "test_note": {
135 | "message": ""
136 | }
137 | }
--------------------------------------------------------------------------------
/public/_locales/zh_CN/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugin_name": {
3 | "message": "HiProxy"
4 | },
5 | "plugin_desc": {
6 | "message": "HiProxy 一个代理设置插件"
7 | },
8 | "pop_menu_direct": {
9 | "message": "直接连接"
10 | },
11 | "pop_menu_system": {
12 | "message": "系统代理"
13 | },
14 | "pop_menu_options": {
15 | "message": "配置选项"
16 | },
17 | "pop_menu_myip": {
18 | "message": "查询当前IP"
19 | },
20 | "options_tab_proxy_config": {
21 | "message": "代理配置"
22 | },
23 | "options_tab_bypass_doc": {
24 | "message": "通配符说明文档"
25 | },
26 | "options_tab_export": {
27 | "message": "导入导出"
28 | },
29 | "options_tab_others": {
30 | "message": "其它配置"
31 | },
32 | "options_tab_about": {
33 | "message": "关于"
34 | },
35 | "options_btn_addNew": {
36 | "message": "新增代理配置"
37 | },
38 | "options_msg_input_proxy_name_ph": {
39 | "message": "代理配置的名称,例如:http-8080,方便自己区分"
40 | },
41 | "options_btn_save_all": {
42 | "message": "批量保存"
43 | },
44 | "options_btn_reset": {
45 | "message": "重置"
46 | },
47 | "options_btn_detail_ok": {
48 | "message": "确定修改,并返回到列表"
49 | },
50 | "options_btn_detail_ok_tips": {
51 | "message": "修改后在列表界面,点批量保存按钮生效"
52 | },
53 | "options_about_project": {
54 | "message": "项目地址"
55 | },
56 | "options_about_version": {
57 | "message": "版本号"
58 | },
59 | "options_about_author": {
60 | "message": "作者"
61 | },
62 | "options_msg_repeat_name": {
63 | "message": "存在重复的配置名,请检查!"
64 | },
65 | "options_msg_save_success": {
66 | "message": "保存成功!"
67 | },
68 | "options_msg_reset_dialog_title": {
69 | "message": "操作警告"
70 | },
71 | "options_msg_reset_dialog_content": {
72 | "message": "您确定要重置全部配置吗?"
73 | },
74 | "options_msg_reset_dialog_positiveText": {
75 | "message": "确定重置"
76 | },
77 | "options_msg_reset_dialog_negativeText": {
78 | "message": "取消"
79 | },
80 | "options_msg_input_name": {
81 | "message": "配置名参数不正确,请检查"
82 | },
83 | "options_msg_input_host": {
84 | "message": "主机地址参数不正确,请检查"
85 | },
86 | "options_msg_input_port": {
87 | "message": "端口参数不正确(端口范围 0~ 65535),请检查"
88 | },
89 | "options_msg_input_detail_bypass": {
90 | "message": "不经过代理连接的主机列表: (每行一个主机,支持通配符)"
91 | },
92 | "options_msg_input_detail_bypass_host_ph": {
93 | "message": "请输入 主机IP 或 域名通配符"
94 | },
95 | "options_msg_input_detail_auth": {
96 | "message": "代理登录: (如无需密码登录,则下面选项全部留空)"
97 | },
98 | "options_msg_input_detail_auth_username": {
99 | "message": "用户名"
100 | },
101 | "options_msg_input_detail_auth_password": {
102 | "message": "密码"
103 | },
104 | "options_msg_export_tips": {
105 | "message": "在这里您可以将当前的配置导出进行备份或分享,也可以在这里通过导入文件直接还原个性化的配置参数。"
106 | },
107 | "options_msg_export_lbl": {
108 | "message": "导出"
109 | },
110 | "options_msg_export_btn": {
111 | "message": "导出当前配置"
112 | },
113 | "options_msg_import_lbl": {
114 | "message": "导入"
115 | },
116 | "options_msg_import_btn": {
117 | "message": "导入配置"
118 | },
119 | "options_msg_import_reset_lbl": {
120 | "message": "重置"
121 | },
122 | "options_msg_import_reset_btn": {
123 | "message": "重置(还原到初始配置)"
124 | },
125 | "options_msg_others_uselastproxy_lbl": {
126 | "message": "默认上一次代理"
127 | },
128 | "options_msg_others_uselastproxy_switch": {
129 | "message": "(每次重新启动浏览器时,自动使用上一次使用的代理)"
130 | },
131 | "options_msg_xxxxxxxxx": {
132 | "message": "xxxxxxxxxxxx"
133 | },
134 | "test_note": {
135 | "message": ""
136 | }
137 | }
--------------------------------------------------------------------------------
/public/icon/128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hicode0101/HiProxy/4272c620cde614a446476e99b159b9ed86f27be4/public/icon/128.png
--------------------------------------------------------------------------------
/public/icon/16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hicode0101/HiProxy/4272c620cde614a446476e99b159b9ed86f27be4/public/icon/16.png
--------------------------------------------------------------------------------
/public/icon/32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hicode0101/HiProxy/4272c620cde614a446476e99b159b9ed86f27be4/public/icon/32.png
--------------------------------------------------------------------------------
/public/icon/48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hicode0101/HiProxy/4272c620cde614a446476e99b159b9ed86f27be4/public/icon/48.png
--------------------------------------------------------------------------------
/public/icon/96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hicode0101/HiProxy/4272c620cde614a446476e99b159b9ed86f27be4/public/icon/96.png
--------------------------------------------------------------------------------
/public/wxt.svg:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/screenshot/gzh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hicode0101/HiProxy/4272c620cde614a446476e99b159b9ed86f27be4/screenshot/gzh.png
--------------------------------------------------------------------------------
/screenshot/screen_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hicode0101/HiProxy/4272c620cde614a446476e99b159b9ed86f27be4/screenshot/screen_1.png
--------------------------------------------------------------------------------
/screenshot/screen_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hicode0101/HiProxy/4272c620cde614a446476e99b159b9ed86f27be4/screenshot/screen_2.png
--------------------------------------------------------------------------------
/screenshot/weixin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hicode0101/HiProxy/4272c620cde614a446476e99b159b9ed86f27be4/screenshot/weixin.png
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.wxt/tsconfig.json"
3 | }
4 |
--------------------------------------------------------------------------------
/utils/base.ts:
--------------------------------------------------------------------------------
1 |
2 | export function everywherefunc(){
3 | console.log("every-where-func");
4 | }
5 |
6 |
7 |
8 | export async function directProxy(callback:Function) {
9 |
10 | browser.proxy.settings.set({ value: { mode: "direct" }, scope: "regular" }).then(() => {
11 | callback();
12 | });
13 |
14 |
15 | showCurrProxy();
16 | reDrawIcon("#9b9b9b", "");
17 | //currProxyPidRemove();
18 |
19 | let currProxyPid = await currProxyPidGet();
20 | console.log("directProxy currProxyPid", currProxyPid);
21 |
22 | }
23 |
24 | export function systemProxy(callback:Function) {
25 |
26 | browser.proxy.settings.set({ value: { mode: "system" }, scope: "regular" }).then(() => {
27 | callback();
28 | });
29 |
30 | showCurrProxy();
31 | reDrawIcon("#000000", "");
32 | //currProxyPidRemove();
33 |
34 | }
35 |
36 |
37 |
38 |
39 | export function showCurrProxy() {
40 | browser.proxy.settings.get({ 'incognito': false }, function (config: any) {
41 | console.log(JSON.stringify(config));
42 | });
43 | }
44 |
45 | export async function proxyConfigsInit() {
46 | console.log("proxyConfigsInit", new Date().toLocaleTimeString());
47 |
48 | let currProxyPid = await currProxyPidGet();
49 | console.log("proxyConfigsInit currProxyPid", currProxyPid);
50 |
51 | //storageClear();
52 |
53 |
54 | let proxyConfigsMap = getDefaultConfigs();
55 |
56 | await proxyConfigsSet(proxyConfigsMap);
57 |
58 | //proxyConfigsMap = await proxyConfigsGet();
59 | ///console.log(proxyConfigsMap);
60 |
61 | currProxyPidSet("direct");
62 | directProxy(()=>{});
63 |
64 | }
65 |
66 |
67 | export async function openCurrProxy(callback: Function) {
68 | let currProxyPid = await currProxyPidGet();
69 | console.log("openCurrProxy currProxyPid", currProxyPid);
70 |
71 | proxyConfigsGetByCallback((result: Map)=>{
72 | let proxyConfigs = result;
73 | if(proxyConfigs instanceof Map){
74 | if (currProxyPid != undefined && proxyConfigs.has(currProxyPid) == true) {
75 | let proxyConfig = proxyConfigs.get(currProxyPid);
76 | changeProxy(proxyConfig, callback);
77 | }else if(currProxyPid == "system"){
78 | systemProxy(callback);
79 | } else {
80 | directProxy(callback);
81 | }
82 | }else{
83 | console.error("proxyConfigs is not a map");
84 | directProxy(callback);
85 | }
86 |
87 | });
88 |
89 |
90 | }
91 |
92 | export function changeProxy(proxyConfig: any, callback: Function) {
93 | console.log("changeProxy", proxyConfig);
94 |
95 | var _config = {
96 | mode: proxyConfig.mode,
97 | rules: proxyConfig.rules
98 | };
99 |
100 | console.log("proxy.settings.set", _config);
101 | browser.proxy.settings.set({ value: _config, scope: 'regular' }, console.log("porxy switched")).then(() => {
102 | callback();
103 | });
104 |
105 |
106 | reDrawIcon(proxyConfig.color, "");
107 | currProxyPidSet(proxyConfig.pid);
108 | showCurrProxy();
109 | }
110 |
111 |
112 |
113 | export function reDrawIcon(outColor: string, innerColor: string) {
114 | console.log(outColor, innerColor);
115 |
116 | const canvas = new OffscreenCanvas(16, 16);
117 | const context = canvas.getContext('2d');
118 | if (!context) {
119 | console.error('Failed to get 2D rendering context');
120 | return;
121 | }
122 | context.scale(16, 16);
123 | context.clearRect(0, 0, 1, 1);
124 | //context.fillStyle = '#00FF00';
125 | //circleDraw(context, "#4477bb");
126 | //circleDraw(context, "#4477bb","#00FF00");
127 | circleDraw(context, outColor, innerColor);
128 | context.setTransform(1, 0, 0, 1, 0, 0);
129 | const imageData = context.getImageData(0, 0, 16, 16);
130 | //chrome.action.setIcon({ imageData: imageData }, () => { /* ... */ });
131 | browser.action.setIcon({ imageData: imageData }, () => { /* ... */ });
132 |
133 | }
134 |
135 | export function circleDraw(ctx: OffscreenCanvasRenderingContext2D, outerCircleColor: string, innerCircleColor: string) {
136 | ctx.globalCompositeOperation = "source-over";
137 | ctx.fillStyle = outerCircleColor;
138 | ctx.beginPath();
139 | ctx.arc(0.5, 0.5, 0.5, 0, Math.PI * 2, true);
140 | ctx.closePath();
141 | ctx.fill();
142 |
143 | if (innerCircleColor != null && innerCircleColor != "") {
144 | ctx.fillStyle = innerCircleColor;
145 | } else {
146 | ctx.globalCompositeOperation = "destination-out";
147 | }
148 |
149 | ctx.beginPath();
150 | ctx.arc(0.5, 0.5, 0.25, 0, Math.PI * 2, true);
151 | ctx.closePath();
152 | ctx.fill();
153 | }
154 |
155 |
--------------------------------------------------------------------------------
/utils/storage.ts:
--------------------------------------------------------------------------------
1 |
2 |
3 | export async function currProxyPidGet() {
4 | //localStorage.getItem('currProxyPid');
5 | //chrome.storage.local.get(["currProxyPid"]).then((result)=> {console.log("Value is ",result.currProxyPid);});
6 |
7 | const _result = await browser.storage.local.get("currProxyPid");
8 | console.log(_result);
9 | //console.log(_result.currProxyPid);
10 | return _result.currProxyPid;
11 | }
12 |
13 |
14 | export async function currProxyPidSet(currProxyPid: string) {
15 | //localStorage.setItem('currProxyPid', 'taven2');
16 | //chrome.storage.local.set({"currProxyPid":"system"}).then(()=> {console.log("Value is set");})
17 |
18 | await browser.storage.local.set({ "currProxyPid": currProxyPid });
19 |
20 | }
21 |
22 | export function currProxyPidRemove() {
23 | browser.storage.local.remove("currProxyPid");
24 | }
25 |
26 | export async function useLastProxyGet() {
27 |
28 | const _result = await browser.storage.local.get("useLastProxy");
29 | console.log(_result);
30 | //console.log(_result.useLastProxy);
31 | return _result.useLastProxy;
32 | }
33 |
34 |
35 | export async function useLastProxySet(useLastProxy: boolean) {
36 |
37 | await browser.storage.local.set({ "useLastProxy": useLastProxy });
38 |
39 | }
40 |
41 | export async function saveProxyConfigs(proxyConfigsMap : Map){
42 |
43 | let json = JSON.stringify(Array.from(proxyConfigsMap));
44 | console.log(json);
45 |
46 | //localStorage.setItem("proxyConfigs", json);
47 | await browser.storage.local.set({"proxyConfigs": json});
48 |
49 | }
50 |
51 | export function getAllKeys() {
52 | //chrome.storage.local.getKeys().then((result)=> {console.log("Value is ",result);});
53 | browser.storage.local.getKeys().then((result : any)=> {console.log("Value is ",result);});
54 | }
55 |
56 | async function storageSet(jsonData : string) {
57 | console.log("storageSet", jsonData);
58 | //chrome.storage.local.set(jsonData).then(() => {
59 | // console.log("Value is set");
60 | //});
61 |
62 | await browser.storage.local.set(jsonData);
63 |
64 | }
65 |
66 | async function storageGet(keyName : string) {
67 |
68 | //_result = {};
69 | //await chrome.storage.local.get(keyName).then((result) => {
70 | // console.log("storageGet is ", keyName, JSON.stringify(result));
71 | // _result = result;
72 | //});
73 |
74 | const _result = await browser.storage.local.get(keyName);
75 | console.log(_result);
76 | //console.log(_result.currProxyPid);
77 |
78 | return _result;
79 | }
80 | export function clearStorage() {
81 | //localStorage.clear();
82 | //chrome.storage.local.clear();
83 | browser.storage.local.clear();
84 | console.log("storageClear");
85 | }
86 |
87 | export function storageRemove(keyName : string) {
88 | browser.storage.local.remove(keyName).then(() => {
89 | console.log("Value removed");
90 | });
91 | }
92 |
93 |
94 |
95 |
96 | export async function proxyConfigsSet(proxyConfigsMap: Map) {
97 | //proxyConfigsMap = new Map();
98 | let json = JSON.stringify(Array.from(proxyConfigsMap));
99 | await browser.storage.local.set({ "proxyConfigs": json });
100 | console.log(proxyConfigsMap);
101 | console.log(JSON.stringify(Array.from(proxyConfigsMap)));
102 | }
103 |
104 |
105 | async function proxyConfigsGet() {
106 | const _result = await browser.storage.local.get("proxyConfigs");
107 | console.log(_result);
108 | console.log(_result.proxyConfigs);
109 | let map = new Map(JSON.parse(_result.proxyConfigs));
110 | return map;
111 |
112 | }
113 |
114 | export function proxyConfigsGetByCallback(callback: Function) {
115 | browser.storage.local.get(["proxyConfigs"]).then((result: any) => {
116 | console.log("GetValue is ", result);
117 | if (result.proxyConfigs == undefined) {
118 | console.log("GetValue is undefined");
119 | callback(new Map());
120 | } else {
121 | let map = new Map(JSON.parse(result.proxyConfigs));
122 | console.log("map is ", map);
123 | callback(map);
124 | }
125 |
126 | });
127 |
128 | }
129 |
130 |
131 |
132 |
133 | export function getDefaultConfigs() {
134 | let proxyConfigsMap = new Map();
135 |
136 | let proxyConfig = {
137 | pid: "http-8080",
138 | name: "http-8080",
139 | color: "#4477bb",
140 | mode: "fixed_servers",
141 | rules: {
142 | singleProxy: {
143 | scheme: "http",
144 | host: "127.0.0.1",
145 | port: 8080,
146 | },
147 | bypassList: [
148 | "127.0.0.1",
149 | "::1",
150 | "localhost"
151 | ]
152 | }
153 | };
154 |
155 | proxyConfigsMap.set(proxyConfig.pid, proxyConfig);
156 |
157 | proxyConfig = {
158 | pid: "socks5-1080",
159 | name: "socks5-1080",
160 | color: "#8169ff",
161 | mode: "fixed_servers",
162 | rules: {
163 | singleProxy: {
164 | scheme: "socks5",
165 | host: "127.0.0.1",
166 | port: 1080,
167 | },
168 | bypassList: [
169 | "127.0.0.1",
170 | "::1",
171 | "localhost"
172 | ]
173 | }
174 | };
175 |
176 | proxyConfigsMap.set(proxyConfig.pid, proxyConfig);
177 |
178 | proxyConfig = {
179 | pid: "socks5-10808",
180 | name: "socks5-10808",
181 | color: "#d497ee",
182 | mode: "fixed_servers",
183 | rules: {
184 | singleProxy: {
185 | scheme: "socks5",
186 | host: "127.0.0.1",
187 | port: 10808,
188 | },
189 | bypassList: [
190 | "127.0.0.1",
191 | "::1",
192 | "localhost"
193 | ]
194 | }
195 | };
196 |
197 | proxyConfigsMap.set(proxyConfig.pid, proxyConfig);
198 |
199 | proxyConfig = {
200 | pid: "socks5-7891",
201 | name: "socks5-7891",
202 | color: "#9117c5",
203 | mode: "fixed_servers",
204 | rules: {
205 | singleProxy: {
206 | scheme: "socks5",
207 | host: "127.0.0.1",
208 | port: 7891,
209 | },
210 | bypassList: [
211 | "127.0.0.1",
212 | "::1",
213 | "localhost"
214 | ]
215 | }
216 | };
217 |
218 | proxyConfigsMap.set(proxyConfig.pid, proxyConfig);
219 |
220 | proxyConfig = {
221 | pid: "http-7890",
222 | name: "http-7890",
223 | color: "#0b4da4",
224 | mode: "fixed_servers",
225 | rules: {
226 | singleProxy: {
227 | scheme: "http",
228 | host: "127.0.0.1",
229 | port: 7890,
230 | },
231 | bypassList: [
232 | "127.0.0.1",
233 | "::1",
234 | "localhost"
235 | ]
236 | }
237 | };
238 |
239 | proxyConfigsMap.set(proxyConfig.pid, proxyConfig);
240 |
241 | proxyConfig = {
242 | pid: "burp-8080",
243 | name: "burp-8080",
244 | color: "#55bb55",
245 | mode: "fixed_servers",
246 | rules: {
247 | singleProxy: {
248 | scheme: "http",
249 | host: "127.0.0.1",
250 | port: 8080,
251 | },
252 | bypassList: [
253 | "127.0.0.1",
254 | "::1",
255 | ".google.com",
256 | ".google-analytics.com",
257 | ".googleapis.com",
258 | "mcs.volceapplog.com",
259 | "mssdk.bytedance.com",
260 | "mcs.zijieapi.com",
261 | "mon.zijieapi.com"
262 | ]
263 | }
264 | };
265 |
266 | proxyConfigsMap.set(proxyConfig.pid, proxyConfig);
267 |
268 | proxyConfig = {
269 | pid: "loop-8080",
270 | name: "loop-8080",
271 | color: "#8892AB",
272 | mode: "fixed_servers",
273 | rules: {
274 | singleProxy: {
275 | scheme: "http",
276 | host: "127.0.0.1",
277 | port: 8080,
278 | },
279 | bypassList: [
280 | "<-loopback>"
281 | ]
282 | }
283 | };
284 |
285 | proxyConfigsMap.set(proxyConfig.pid, proxyConfig);
286 |
287 | return proxyConfigsMap;
288 | }
289 |
290 |
--------------------------------------------------------------------------------
/wxt.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'wxt';
2 |
3 | // See https://wxt.dev/api/config.html
4 | export default defineConfig({
5 | extensionApi: 'chrome',
6 | modules: ['@wxt-dev/module-vue'],
7 | manifest: {
8 | manifest_version: 3,
9 | name: "__MSG_plugin_name__",
10 | description: "__MSG_plugin_desc__",
11 | default_locale: "en",
12 | version: "3.2.10",
13 | minimum_chrome_version: "88.0.0",
14 | author: "hicode0101@gmail.com",
15 | action: {
16 | default_popup: "popup.html",
17 | default_title: "__MSG_plugin_desc__"
18 | },
19 | options_page: "options.html",
20 | permissions: [
21 | "notifications",
22 | "proxy",
23 | "storage",
24 | "webRequest",
25 | "webRequestAuthProvider"
26 | ],
27 | },
28 | });
29 |
--------------------------------------------------------------------------------