Skip to content

Commit de034a2

Browse files
SYM01dependabot[bot]transifex-integration[bot]
authored
v1.2.3: Support Auto Switch Authentication (#46)
* update github action * minor change to System profile * Build(deps): Bump nanoid from 3.3.7 to 3.3.8 (#21) Bumps [nanoid](https://github.com/ai/nanoid) from 3.3.7 to 3.3.8. - [Release notes](https://github.com/ai/nanoid/releases) - [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md) - [Commits](ai/nanoid@3.3.7...3.3.8) --- updated-dependencies: - dependency-name: nanoid dependency-type: indirect ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Avoid blocking 401 authentication request (#22) (#23) * fix 401 issue (#22) * enablle github action on develop branch * Support Firefox (#18) * Adapt firefox * support firefore auto publish * support firefox, and optimized UX * [i18n] Updates for file public/_locales/en/messages.json (#25) * [i18n] Translate messages.json in pt_BR 100% reviewed source file: 'messages.json' on 'pt_BR'. * [i18n] Translate messages.json in zh_CN 100% reviewed source file: 'messages.json' on 'zh_CN'. * [i18n] Translate messages.json in zh_TW 100% reviewed source file: 'messages.json' on 'zh_TW'. * [i18n] Translate messages.json in pt_BR 100% reviewed source file: 'messages.json' on 'pt_BR'. * update English i18n msg --------- Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> Co-authored-by: SYM01 <[email protected]> * sentry integration (#29) * [WIP] support exporting * [WIP] support import/export settings (#7) * Support import/export profiles and close #7 (#30) * implemented an utility to export/import settings * optimized description * [i18n] Updates for file public/_locales/en/messages.json (#32) * [i18n] Translate messages.json in pt_BR 100% reviewed source file: 'messages.json' on 'pt_BR'. * [i18n] Translate messages.json in zh_TW 100% reviewed source file: 'messages.json' on 'zh_TW'. * [i18n] Translate messages.json in zh_CN 100% reviewed source file: 'messages.json' on 'zh_CN'. --------- Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> * fix an import issue (#33) (#35) * optimized sentry release * Optimize Development Flow (#37) * [WIP] support chrome auto deploy * finalize Chrome auto deploy * npm audit fix * npm audit fix * UX improvement and close #28 (#38) * minor bug fixed * improve UX and close #28 * use the same CIDR validator as PAC script * [i18n] Updates for file public/_locales/en/messages.json (#40) * [i18n] Translate messages.json in pt_BR 100% reviewed source file: 'messages.json' on 'pt_BR'. * [i18n] Translate messages.json in zh_TW 100% reviewed source file: 'messages.json' on 'zh_TW'. * [i18n] Translate messages.json in zh_CN 100% reviewed source file: 'messages.json' on 'zh_CN'. --------- Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> * Support Authentication in Auto Switch Profiles, fixing #34 (#45) * update deps * fix the auth issue in auto switch profiles * fix typo --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
1 parent 82ea90e commit de034a2

File tree

10 files changed

+881
-551
lines changed

10 files changed

+881
-551
lines changed

package-lock.json

Lines changed: 593 additions & 498 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,33 +17,33 @@
1717
},
1818
"dependencies": {
1919
"@highlightjs/vue-plugin": "^2.1.0",
20-
"@sentry/vue": "^8.51.0",
21-
"@vueuse/core": "^12.4.0",
22-
"acorn": "^8.14.0",
20+
"@sentry/vue": "^8.55.0",
21+
"@vueuse/core": "^12.8.2",
22+
"acorn": "^8.14.1",
2323
"escodegen": "^2.1.0",
2424
"espree": "^10.3.0",
2525
"io-ts": "^2.2.22",
2626
"ipaddr.js": "^2.2.0",
27-
"vue": "^3.5.13",
28-
"vue-router": "^4.5.0"
27+
"vue": "^3.5.16",
28+
"vue-router": "^4.5.1"
2929
},
3030
"devDependencies": {
31-
"@arco-design/web-vue": "^2.56.3",
32-
"@sentry/vite-plugin": "^3.0.0",
31+
"@arco-design/web-vue": "^2.57.0",
32+
"@sentry/vite-plugin": "^3.5.0",
3333
"@types/chrome": "^0.0.266",
3434
"@types/escodegen": "^0.0.10",
3535
"@types/espree": "^10.1.0",
3636
"@types/firefox-webext-browser": "^120.0.4",
3737
"@types/node": "^22.10.6",
38-
"@vitejs/plugin-vue": "^5.2.1",
39-
"@vitest/coverage-v8": "^3.0.6",
38+
"@vitejs/plugin-vue": "^5.2.4",
39+
"@vitest/coverage-v8": "^3.2.2",
4040
"rollup-plugin-visualizer": "^5.14.0",
4141
"sass-embedded": "^1.83.3",
42-
"typescript": "^5.7.3",
42+
"typescript": "^5.8.3",
4343
"unplugin-auto-import": "^19.0.0",
4444
"unplugin-vue-components": "^28.0.0",
45-
"vite": "^6.1.0",
46-
"vitest": "^3.0.6",
47-
"vue-tsc": "^2.2.2"
45+
"vite": "^6.3.5",
46+
"vitest": "^3.2.2",
47+
"vue-tsc": "^2.2.10"
4848
}
4949
}

src/components/ProfileConfig.vue

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import AutoSwitchInput from "./configs/AutoSwitchInput.vue";
1717
import AutoSwitchPacPreview from "./configs/AutoSwitchPacPreview.vue";
1818
import ScriptInput from "./configs/ScriptInput.vue";
1919
import {
20-
ProfileAuthSwitch,
20+
ProfileAutoSwitch,
2121
ProfileSimple,
2222
ProxyServer,
2323
SystemProfile,
@@ -38,7 +38,7 @@ const chooseRandomColor = () => {
3838
return colors[idx];
3939
};
4040
41-
type ConfigState = (ProfileSimple | ProfileAuthSwitch) & {
41+
type ConfigState = (ProfileSimple | ProfileAutoSwitch) & {
4242
[key: string]: any;
4343
};
4444
@@ -132,7 +132,10 @@ const proxyServerFieldRule = (
132132
return {
133133
type: "object",
134134
required: required,
135-
validator(value, callback) {
135+
validator(
136+
value: ProxyServer | undefined,
137+
callback: (message?: string) => void
138+
) {
136139
if (value == undefined || value.scheme == "direct") {
137140
return;
138141
}
@@ -151,7 +154,10 @@ const pacScriptFieldRule = (
151154
return {
152155
type: "object",
153156
required: required,
154-
validator(value, callback) {
157+
validator(
158+
value: PacScript | undefined,
159+
callback: (message?: string) => void
160+
) {
155161
if (value == undefined) {
156162
return;
157163
}
@@ -421,7 +427,7 @@ watchEffect(async () => {
421427

422428
<AutoSwitchPacPreview
423429
v-if="profileConfig.proxyType == 'auto'"
424-
:profile="(profileConfig as ProfileAuthSwitch)"
430+
:profile="(profileConfig as ProfileAutoSwitch)"
425431
/>
426432
</a-space>
427433
</template>

src/components/configs/AutoSwitchInput.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
22
import { IconCopy, IconPlus, IconDelete } from "@arco-design/web-vue/es/icon";
3-
import { FieldRule } from "@arco-design/web-vue/es/form";
3+
import type { FieldRule } from "@arco-design/web-vue";
44
55
import { Host } from "@/adapters";
66
import {
@@ -101,7 +101,7 @@ const getConditionInputRule = (type: AutoSwitchType): FieldRule<string> => {
101101
102102
case "url":
103103
return {
104-
validator: async (value, cb) => {
104+
validator: async (value: string, cb: (message?: string) => void) => {
105105
console.log("test");
106106
let u;
107107
try {
@@ -134,7 +134,7 @@ const getConditionInputRule = (type: AutoSwitchType): FieldRule<string> => {
134134
case "cidr":
135135
return {
136136
required: true,
137-
validator: (value, cb) => {
137+
validator: (value: string, cb: (message?: string) => void) => {
138138
if (!value || !isValidCIDR(value)) {
139139
cb(
140140
Host.getMessage("config_section_auto_switch_type_cidr_malformed")

src/components/configs/AutoSwitchPacPreview.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
22
import { IconCopy } from "@arco-design/web-vue/es/icon";
3-
import { ProfileAuthSwitch } from "@/services/profile";
3+
import { ProfileAutoSwitch } from "@/services/profile";
44
import { useClipboard, watchDebounced } from "@vueuse/core";
55
import { ref } from "vue";
66
import { previewAutoSwitchPac } from "@/services/proxy";
@@ -9,7 +9,7 @@ import hljsVuePlugin from "@highlightjs/vue-plugin";
99
const highlightjs = hljsVuePlugin.component;
1010
1111
const { profile } = defineProps<{
12-
profile: ProfileAuthSwitch;
12+
profile: ProfileAutoSwitch;
1313
}>();
1414
1515
const pacScript = ref<string>("");

src/services/profile.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,11 @@ export type ProfilePreset = ProxyConfigMeta & {
6868
proxyType: "system" | "direct";
6969
};
7070

71-
export type ProfileAuthSwitch = ProxyConfigMeta & {
71+
export type ProfileAutoSwitch = ProxyConfigMeta & {
7272
proxyType: "auto";
7373
} & ProxyConfigAutoSwitch;
7474

75-
export type ProxyProfile = ProfileSimple | ProfilePreset | ProfileAuthSwitch;
75+
export type ProxyProfile = ProfileSimple | ProfilePreset | ProfileAutoSwitch;
7676

7777
export const SystemProfile: Record<string, ProxyProfile> = {
7878
DIRECT: {

src/services/proxy/auth.ts

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import type { ProxyAuthInfo, ProxyProfile } from "../profile";
2+
import type { ProfileLoader } from "./profile2config";
3+
4+
export class ProfileAuthProvider {
5+
private searchedProfiles: Set<string> = new Set();
6+
7+
constructor(
8+
private profile: ProxyProfile,
9+
private profileLoader?: ProfileLoader
10+
) {}
11+
12+
async getAuthInfos(host: string, port: number): Promise<ProxyAuthInfo[]> {
13+
this.searchedProfiles.clear();
14+
return this.getAuthInfosForProfile(host, port, this.profile);
15+
}
16+
17+
private async getAuthInfosForProfile(
18+
host: string,
19+
port: number,
20+
profile: ProxyProfile
21+
): Promise<ProxyAuthInfo[]> {
22+
// avoid infinite loop
23+
if (this.searchedProfiles.has(profile.profileID)) {
24+
return [];
25+
}
26+
this.searchedProfiles.add(profile.profileID);
27+
28+
switch (profile.proxyType) {
29+
case "proxy":
30+
return this.getAuthInfosForProxyProfile(host, port, profile);
31+
case "auto":
32+
return this.getAuthInfosForAutoProfile(host, port, profile);
33+
34+
default:
35+
return [];
36+
}
37+
}
38+
39+
private async getAuthInfosForProxyProfile(
40+
host: string,
41+
port: number,
42+
profile: ProxyProfile & { proxyType: "proxy" }
43+
): Promise<ProxyAuthInfo[]> {
44+
const ret: ProxyAuthInfo[] = [];
45+
const auths = [
46+
profile.proxyRules.default,
47+
profile.proxyRules.ftp,
48+
profile.proxyRules.http,
49+
profile.proxyRules.https,
50+
];
51+
52+
// check if there's any matching host and port
53+
auths.map((item) => {
54+
if (!item) return;
55+
56+
if (
57+
item.host == host &&
58+
(item.port === undefined || item.port == port) &&
59+
item.auth
60+
) {
61+
ret.push(item.auth);
62+
}
63+
});
64+
65+
return ret;
66+
}
67+
68+
private async getAuthInfosForAutoProfile(
69+
host: string,
70+
port: number,
71+
profile: ProxyProfile & { proxyType: "auto" }
72+
): Promise<ProxyAuthInfo[]> {
73+
const ret: ProxyAuthInfo[] = [];
74+
75+
for (const rule of profile.rules) {
76+
if (rule.type == "disabled") {
77+
continue;
78+
}
79+
80+
const profile = await this.loadProfile(rule.profileID);
81+
if (!profile) {
82+
continue;
83+
}
84+
85+
const authInfos = await this.getAuthInfosForProfile(host, port, profile);
86+
authInfos && ret.push(...authInfos);
87+
}
88+
89+
// don't forget the default profile
90+
const defaultProfile = await this.loadProfile(profile.defaultProfileID);
91+
if (defaultProfile) {
92+
const authInfos = await this.getAuthInfosForProfile(
93+
host,
94+
port,
95+
defaultProfile
96+
);
97+
authInfos && ret.push(...authInfos);
98+
}
99+
100+
return ret;
101+
}
102+
103+
private async loadProfile(
104+
profileID: string
105+
): Promise<ProxyProfile | undefined> {
106+
if (!this.profileLoader) {
107+
return;
108+
}
109+
110+
return await this.profileLoader(profileID);
111+
}
112+
}

src/services/proxy/index.ts

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import {
44
ProxyAuthInfo,
55
SystemProfile,
66
getProfile,
7-
ProfileAuthSwitch,
7+
ProfileAutoSwitch,
88
} from "../profile";
99
import { ProxySettingResultDetails } from "@/adapters";
1010
import { ProfileConverter } from "./profile2config";
11+
import { ProfileAuthProvider } from "./auth";
1112

1213
export type ProxySetting = {
1314
activeProfile?: ProxyProfile;
@@ -80,7 +81,7 @@ export async function refreshProxy() {
8081
await Host.setProxy(await profile.toProxyConfig());
8182
}
8283

83-
export async function previewAutoSwitchPac(val: ProfileAuthSwitch) {
84+
export async function previewAutoSwitchPac(val: ProfileAutoSwitch) {
8485
const profile = new ProfileConverter(val, getProfile);
8586
return await profile.toPAC();
8687
}
@@ -90,30 +91,10 @@ export async function getAuthInfos(
9091
port: number
9192
): Promise<ProxyAuthInfo[]> {
9293
const profile = await Host.get<ProxyProfile>(keyActiveProfile);
93-
if (!profile || profile.proxyType !== "proxy") {
94+
if (!profile) {
9495
return [];
9596
}
9697

97-
const ret: ProxyAuthInfo[] = [];
98-
const auths = [
99-
profile.proxyRules.default,
100-
profile.proxyRules.ftp,
101-
profile.proxyRules.http,
102-
profile.proxyRules.https,
103-
];
104-
105-
// check if there's any matching host and port
106-
auths.map((item) => {
107-
if (!item) return;
108-
109-
if (
110-
item.host == host &&
111-
(item.port === undefined || item.port == port) &&
112-
item.auth
113-
) {
114-
ret.push(item.auth);
115-
}
116-
});
117-
118-
return ret;
98+
const authProvider = new ProfileAuthProvider(profile, getProfile);
99+
return await authProvider.getAuthInfos(host, port);
119100
}

src/services/proxy/profile2config.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { generate as generateJS } from "escodegen";
22
import type { Program, Statement } from "acorn";
33
import {
44
AutoSwitchRule,
5-
ProfileAuthSwitch,
5+
ProfileAutoSwitch,
66
ProxyProfile,
77
ProxyServer,
88
} from "../profile";
@@ -14,7 +14,9 @@ import {
1414
} from "./scriptHelper";
1515
import { ProxyConfig } from "@/adapters";
1616

17-
type ProfileLoader = (profileID: string) => Promise<ProxyProfile | undefined>;
17+
export type ProfileLoader = (
18+
profileID: string
19+
) => Promise<ProxyProfile | undefined>;
1820

1921
export class ProfileConverter {
2022
constructor(
@@ -44,6 +46,10 @@ export class ProfileConverter {
4446
}
4547
}
4648

49+
/**
50+
* Convert the `auto` profile to a PAC script
51+
* @returns the PAC script
52+
*/
4753
async toPAC() {
4854
const astProgram: Program = {
4955
type: "Program",
@@ -299,7 +305,7 @@ export class ProfileConverter {
299305
);
300306
}
301307

302-
private async prepareAutoProfilePrecedence(profile: ProfileAuthSwitch) {
308+
private async prepareAutoProfilePrecedence(profile: ProfileAutoSwitch) {
303309
const loadedProfiles = new Set<string>();
304310
const stmt: Statement[] = [
305311
// var profiles = profiles || {};

0 commit comments

Comments
 (0)