Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
3b94c23
update github action
SYM01 Oct 20, 2024
e8467f8
minor change to System profile
SYM01 Oct 20, 2024
6426011
Build(deps): Bump nanoid from 3.3.7 to 3.3.8 (#21)
dependabot[bot] Jan 13, 2025
8292e79
Avoid blocking 401 authentication request (#22) (#23)
SYM01 Jan 14, 2025
ca949f6
Support Firefox (#18)
SYM01 Jan 17, 2025
33c0d0e
[i18n] Updates for file public/_locales/en/messages.json (#25)
transifex-integration[bot] Jan 17, 2025
1beabb4
Merge branch 'main' into develop
SYM01 Jan 17, 2025
ca27aed
sentry integration (#29)
SYM01 Jan 25, 2025
accb03b
[WIP] support exporting
SYM01 Jan 25, 2025
654f865
[WIP] support import/export settings (#7)
SYM01 Jan 28, 2025
8f048df
Support import/export profiles and close #7 (#30)
SYM01 Feb 6, 2025
29f8506
Merge remote-tracking branch 'origin/main' into develop
SYM01 Feb 6, 2025
76f9233
optimized description
SYM01 Feb 6, 2025
9abae03
[i18n] Updates for file public/_locales/en/messages.json (#32)
transifex-integration[bot] Feb 6, 2025
204d459
fix an import issue (#33) (#35)
SYM01 Feb 18, 2025
438b9e4
Merge branch 'main' into develop
SYM01 Feb 18, 2025
fd571be
optimized sentry release
SYM01 Feb 19, 2025
9b10c01
Optimize Development Flow (#37)
SYM01 Mar 1, 2025
5c61a9b
UX improvement and close #28 (#38)
SYM01 Mar 16, 2025
d688606
[i18n] Updates for file public/_locales/en/messages.json (#40)
transifex-integration[bot] Mar 16, 2025
4213518
Support Authentication in Auto Switch Profiles, fixing #34 (#45)
SYM01 Jun 8, 2025
ea212a1
Merge remote-tracking branch 'origin/main' into develop
SYM01 Jun 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,091 changes: 593 additions & 498 deletions package-lock.json

Large diffs are not rendered by default.

26 changes: 13 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,33 @@
},
"dependencies": {
"@highlightjs/vue-plugin": "^2.1.0",
"@sentry/vue": "^8.51.0",
"@vueuse/core": "^12.4.0",
"acorn": "^8.14.0",
"@sentry/vue": "^8.55.0",
"@vueuse/core": "^12.8.2",
"acorn": "^8.14.1",
"escodegen": "^2.1.0",
"espree": "^10.3.0",
"io-ts": "^2.2.22",
"ipaddr.js": "^2.2.0",
"vue": "^3.5.13",
"vue-router": "^4.5.0"
"vue": "^3.5.16",
"vue-router": "^4.5.1"
},
"devDependencies": {
"@arco-design/web-vue": "^2.56.3",
"@sentry/vite-plugin": "^3.0.0",
"@arco-design/web-vue": "^2.57.0",
"@sentry/vite-plugin": "^3.5.0",
"@types/chrome": "^0.0.266",
"@types/escodegen": "^0.0.10",
"@types/espree": "^10.1.0",
"@types/firefox-webext-browser": "^120.0.4",
"@types/node": "^22.10.6",
"@vitejs/plugin-vue": "^5.2.1",
"@vitest/coverage-v8": "^3.0.6",
"@vitejs/plugin-vue": "^5.2.4",
"@vitest/coverage-v8": "^3.2.2",
"rollup-plugin-visualizer": "^5.14.0",
"sass-embedded": "^1.83.3",
"typescript": "^5.7.3",
"typescript": "^5.8.3",
"unplugin-auto-import": "^19.0.0",
"unplugin-vue-components": "^28.0.0",
"vite": "^6.1.0",
"vitest": "^3.0.6",
"vue-tsc": "^2.2.2"
"vite": "^6.3.5",
"vitest": "^3.2.2",
"vue-tsc": "^2.2.10"
}
}
16 changes: 11 additions & 5 deletions src/components/ProfileConfig.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import AutoSwitchInput from "./configs/AutoSwitchInput.vue";
import AutoSwitchPacPreview from "./configs/AutoSwitchPacPreview.vue";
import ScriptInput from "./configs/ScriptInput.vue";
import {
ProfileAuthSwitch,
ProfileAutoSwitch,
ProfileSimple,
ProxyServer,
SystemProfile,
Expand All @@ -38,7 +38,7 @@ const chooseRandomColor = () => {
return colors[idx];
};

type ConfigState = (ProfileSimple | ProfileAuthSwitch) & {
type ConfigState = (ProfileSimple | ProfileAutoSwitch) & {
[key: string]: any;
};

Expand Down Expand Up @@ -132,7 +132,10 @@ const proxyServerFieldRule = (
return {
type: "object",
required: required,
validator(value, callback) {
validator(
value: ProxyServer | undefined,
callback: (message?: string) => void
) {
if (value == undefined || value.scheme == "direct") {
return;
}
Expand All @@ -151,7 +154,10 @@ const pacScriptFieldRule = (
return {
type: "object",
required: required,
validator(value, callback) {
validator(
value: PacScript | undefined,
callback: (message?: string) => void
) {
if (value == undefined) {
return;
}
Expand Down Expand Up @@ -421,7 +427,7 @@ watchEffect(async () => {

<AutoSwitchPacPreview
v-if="profileConfig.proxyType == 'auto'"
:profile="(profileConfig as ProfileAuthSwitch)"
:profile="(profileConfig as ProfileAutoSwitch)"
/>
</a-space>
</template>
Expand Down
6 changes: 3 additions & 3 deletions src/components/configs/AutoSwitchInput.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { IconCopy, IconPlus, IconDelete } from "@arco-design/web-vue/es/icon";
import { FieldRule } from "@arco-design/web-vue/es/form";
import type { FieldRule } from "@arco-design/web-vue";

import { Host } from "@/adapters";
import {
Expand Down Expand Up @@ -101,7 +101,7 @@ const getConditionInputRule = (type: AutoSwitchType): FieldRule<string> => {

case "url":
return {
validator: async (value, cb) => {
validator: async (value: string, cb: (message?: string) => void) => {
console.log("test");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It looks like there's a console.log("test") statement here. Was this intended for debugging and should it be removed before merging?

let u;
try {
Expand Down Expand Up @@ -134,7 +134,7 @@ const getConditionInputRule = (type: AutoSwitchType): FieldRule<string> => {
case "cidr":
return {
required: true,
validator: (value, cb) => {
validator: (value: string, cb: (message?: string) => void) => {
if (!value || !isValidCIDR(value)) {
cb(
Host.getMessage("config_section_auto_switch_type_cidr_malformed")
Expand Down
4 changes: 2 additions & 2 deletions src/components/configs/AutoSwitchPacPreview.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { IconCopy } from "@arco-design/web-vue/es/icon";
import { ProfileAuthSwitch } from "@/services/profile";
import { ProfileAutoSwitch } from "@/services/profile";
import { useClipboard, watchDebounced } from "@vueuse/core";
import { ref } from "vue";
import { previewAutoSwitchPac } from "@/services/proxy";
Expand All @@ -9,7 +9,7 @@ import hljsVuePlugin from "@highlightjs/vue-plugin";
const highlightjs = hljsVuePlugin.component;

const { profile } = defineProps<{
profile: ProfileAuthSwitch;
profile: ProfileAutoSwitch;
}>();

const pacScript = ref<string>("");
Expand Down
4 changes: 2 additions & 2 deletions src/services/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ export type ProfilePreset = ProxyConfigMeta & {
proxyType: "system" | "direct";
};

export type ProfileAuthSwitch = ProxyConfigMeta & {
export type ProfileAutoSwitch = ProxyConfigMeta & {
proxyType: "auto";
} & ProxyConfigAutoSwitch;

export type ProxyProfile = ProfileSimple | ProfilePreset | ProfileAuthSwitch;
export type ProxyProfile = ProfileSimple | ProfilePreset | ProfileAutoSwitch;

export const SystemProfile: Record<string, ProxyProfile> = {
DIRECT: {
Expand Down
112 changes: 112 additions & 0 deletions src/services/proxy/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import type { ProxyAuthInfo, ProxyProfile } from "../profile";
import type { ProfileLoader } from "./profile2config";

export class ProfileAuthProvider {
private searchedProfiles: Set<string> = new Set();

constructor(
private profile: ProxyProfile,
private profileLoader?: ProfileLoader
) {}

async getAuthInfos(host: string, port: number): Promise<ProxyAuthInfo[]> {
this.searchedProfiles.clear();
return this.getAuthInfosForProfile(host, port, this.profile);
}

private async getAuthInfosForProfile(
host: string,
port: number,
profile: ProxyProfile
): Promise<ProxyAuthInfo[]> {
// avoid infinite loop
if (this.searchedProfiles.has(profile.profileID)) {
return [];
}
this.searchedProfiles.add(profile.profileID);

switch (profile.proxyType) {
case "proxy":
return this.getAuthInfosForProxyProfile(host, port, profile);
case "auto":
return this.getAuthInfosForAutoProfile(host, port, profile);

default:
return [];
}
}

private async getAuthInfosForProxyProfile(
host: string,
port: number,
profile: ProxyProfile & { proxyType: "proxy" }
): Promise<ProxyAuthInfo[]> {
const ret: ProxyAuthInfo[] = [];
const auths = [
profile.proxyRules.default,
profile.proxyRules.ftp,
profile.proxyRules.http,
profile.proxyRules.https,
];

// check if there's any matching host and port
auths.map((item) => {
if (!item) return;

if (
item.host == host &&
(item.port === undefined || item.port == port) &&
item.auth
) {
ret.push(item.auth);
}
});

return ret;
}

private async getAuthInfosForAutoProfile(
host: string,
port: number,
profile: ProxyProfile & { proxyType: "auto" }
): Promise<ProxyAuthInfo[]> {
const ret: ProxyAuthInfo[] = [];

for (const rule of profile.rules) {
if (rule.type == "disabled") {
continue;
}

const profile = await this.loadProfile(rule.profileID);
if (!profile) {
continue;
}

const authInfos = await this.getAuthInfosForProfile(host, port, profile);
authInfos && ret.push(...authInfos);
}

// don't forget the default profile
const defaultProfile = await this.loadProfile(profile.defaultProfileID);
if (defaultProfile) {
const authInfos = await this.getAuthInfosForProfile(
host,
port,
defaultProfile
);
authInfos && ret.push(...authInfos);
}

return ret;
}

private async loadProfile(
profileID: string
): Promise<ProxyProfile | undefined> {
if (!this.profileLoader) {
return;
}

return await this.profileLoader(profileID);
}
}
31 changes: 6 additions & 25 deletions src/services/proxy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import {
ProxyAuthInfo,
SystemProfile,
getProfile,
ProfileAuthSwitch,
ProfileAutoSwitch,
} from "../profile";
import { ProxySettingResultDetails } from "@/adapters";
import { ProfileConverter } from "./profile2config";
import { ProfileAuthProvider } from "./auth";

export type ProxySetting = {
activeProfile?: ProxyProfile;
Expand Down Expand Up @@ -80,7 +81,7 @@ export async function refreshProxy() {
await Host.setProxy(await profile.toProxyConfig());
}

export async function previewAutoSwitchPac(val: ProfileAuthSwitch) {
export async function previewAutoSwitchPac(val: ProfileAutoSwitch) {
const profile = new ProfileConverter(val, getProfile);
return await profile.toPAC();
}
Expand All @@ -90,30 +91,10 @@ export async function getAuthInfos(
port: number
): Promise<ProxyAuthInfo[]> {
const profile = await Host.get<ProxyProfile>(keyActiveProfile);
if (!profile || profile.proxyType !== "proxy") {
if (!profile) {
return [];
}

const ret: ProxyAuthInfo[] = [];
const auths = [
profile.proxyRules.default,
profile.proxyRules.ftp,
profile.proxyRules.http,
profile.proxyRules.https,
];

// check if there's any matching host and port
auths.map((item) => {
if (!item) return;

if (
item.host == host &&
(item.port === undefined || item.port == port) &&
item.auth
) {
ret.push(item.auth);
}
});

return ret;
const authProvider = new ProfileAuthProvider(profile, getProfile);
return await authProvider.getAuthInfos(host, port);
}
12 changes: 9 additions & 3 deletions src/services/proxy/profile2config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { generate as generateJS } from "escodegen";
import type { Program, Statement } from "acorn";
import {
AutoSwitchRule,
ProfileAuthSwitch,
ProfileAutoSwitch,
ProxyProfile,
ProxyServer,
} from "../profile";
Expand All @@ -14,7 +14,9 @@ import {
} from "./scriptHelper";
import { ProxyConfig } from "@/adapters";

type ProfileLoader = (profileID: string) => Promise<ProxyProfile | undefined>;
export type ProfileLoader = (
profileID: string
) => Promise<ProxyProfile | undefined>;

export class ProfileConverter {
constructor(
Expand Down Expand Up @@ -44,6 +46,10 @@ export class ProfileConverter {
}
}

/**
* Convert the `auto` profile to a PAC script
* @returns the PAC script
*/
async toPAC() {
const astProgram: Program = {
type: "Program",
Expand Down Expand Up @@ -299,7 +305,7 @@ export class ProfileConverter {
);
}

private async prepareAutoProfilePrecedence(profile: ProfileAuthSwitch) {
private async prepareAutoProfilePrecedence(profile: ProfileAutoSwitch) {
const loadedProfiles = new Set<string>();
const stmt: Statement[] = [
// var profiles = profiles || {};
Expand Down
Loading