Skip to content

Commit e24de8d

Browse files
committed
feat: 支持 WireGuard URI 输入和输出
1 parent 93a5ce6 commit e24de8d

File tree

4 files changed

+132
-2
lines changed

4 files changed

+132
-2
lines changed

backend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sub-store",
3-
"version": "2.14.282",
3+
"version": "2.14.283",
44
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
55
"main": "src/main.js",
66
"scripts": {

backend/src/core/proxy-utils/parsers/index.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,89 @@ function URI_TUIC() {
674674
};
675675
return { name, test, parse };
676676
}
677+
function URI_WireGuard() {
678+
const name = 'URI WireGuard Parser';
679+
const test = (line) => {
680+
return /^(wireguard|wg):\/\//.test(line);
681+
};
682+
const parse = (line) => {
683+
line = line.split(/(wireguard|wg):\/\//)[2];
684+
/* eslint-disable no-unused-vars */
685+
let [
686+
__,
687+
___,
688+
privateKey,
689+
server,
690+
____,
691+
port,
692+
_____,
693+
addons = '',
694+
name,
695+
] = /^((.*?)@)?(.*?)(:(\d+))?\/?(\?(.*?))?(?:#(.*?))?$/.exec(line);
696+
/* eslint-enable no-unused-vars */
697+
698+
port = parseInt(`${port}`, 10);
699+
if (isNaN(port)) {
700+
port = 51820;
701+
}
702+
privateKey = decodeURIComponent(privateKey);
703+
if (name != null) {
704+
name = decodeURIComponent(name);
705+
}
706+
name = name ?? `WireGuard ${server}:${port}`;
707+
const proxy = {
708+
type: 'wireguard',
709+
name,
710+
server,
711+
port,
712+
'private-key': privateKey,
713+
udp: true,
714+
};
715+
for (const addon of addons.split('&')) {
716+
let [key, value] = addon.split('=');
717+
key = key.replace(/_/, '-');
718+
value = decodeURIComponent(value);
719+
if (['reserved'].includes(key)) {
720+
const parsed = value
721+
.split(',')
722+
.map((i) => parseInt(i.trim(), 10))
723+
.filter((i) => Number.isInteger(i));
724+
if (parsed.length === 3) {
725+
proxy[key] = parsed;
726+
}
727+
} else if (['address', 'ip'].includes(key)) {
728+
value.split(',').map((i) => {
729+
const ip = i
730+
.trim()
731+
.replace(/\/\d+$/, '')
732+
.replace(/^\[/, '')
733+
.replace(/\]$/, '');
734+
if (isIPv4(ip)) {
735+
proxy.ip = ip;
736+
} else if (isIPv6(ip)) {
737+
proxy.ipv6 = ip;
738+
}
739+
});
740+
} else if (['mtu'].includes(key)) {
741+
const parsed = parseInt(value.trim(), 10);
742+
if (Number.isInteger(parsed)) {
743+
proxy[key] = parsed;
744+
}
745+
} else if (/publickey/i.test(key)) {
746+
proxy['public-key'] = value;
747+
} else if (/privatekey/i.test(key)) {
748+
proxy['private-key'] = value;
749+
} else if (['udp'].includes(key)) {
750+
proxy[key] = /(TRUE)|1/i.test(value);
751+
} else if (!['flag'].includes(key)) {
752+
proxy[key] = value;
753+
}
754+
}
755+
756+
return proxy;
757+
};
758+
return { name, test, parse };
759+
}
677760

678761
// Trojan URI format
679762
function URI_Trojan() {
@@ -1196,6 +1279,7 @@ export default [
11961279
URI_VMess(),
11971280
URI_VLESS(),
11981281
URI_TUIC(),
1282+
URI_WireGuard(),
11991283
URI_Hysteria(),
12001284
URI_Hysteria2(),
12011285
URI_Trojan(),

backend/src/core/proxy-utils/preprocessors/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ function Base64Encoded() {
2222
'aHR0c', // htt
2323
'dmxlc3M=', // vless
2424
'aHlzdGVyaWEy', // hysteria2
25+
'd2lyZWd1YXJkOi8v', // wireguard://
26+
'd2c6Ly8=', // wg://
27+
'dHVpYzovLw==', // tuic://
2528
];
2629

2730
const test = function (raw) {

backend/src/core/proxy-utils/producers/uri.js

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,51 @@ export default function URI_Producer() {
411411
}?${tuicParams.join('&')}#${encodeURIComponent(
412412
proxy.name,
413413
)}`;
414-
break;
415414
}
415+
break;
416+
case 'wireguard':
417+
let wireguardParams = [];
418+
419+
Object.keys(proxy).forEach((key) => {
420+
if (
421+
![
422+
'name',
423+
'type',
424+
'server',
425+
'port',
426+
'ip',
427+
'ipv6',
428+
'private-key',
429+
].includes(key)
430+
) {
431+
if (['public-key'].includes(key)) {
432+
wireguardParams.push(`publickey=${proxy[key]}`);
433+
} else if (['udp'].includes(key)) {
434+
if (proxy[key]) {
435+
wireguardParams.push(`${key}=1`);
436+
}
437+
} else if (proxy[key]) {
438+
wireguardParams.push(
439+
`${key}=${encodeURIComponent(proxy[key])}`,
440+
);
441+
}
442+
}
443+
});
444+
if (proxy.ip && proxy.ipv6) {
445+
wireguardParams.push(
446+
`address=${proxy.ip}/32,${proxy.ipv6}/128`,
447+
);
448+
} else if (proxy.ip) {
449+
wireguardParams.push(`address=${proxy.ip}/32`);
450+
} else if (proxy.ipv6) {
451+
wireguardParams.push(`address=${proxy.ipv6}/128`);
452+
}
453+
result = `wireguard://${encodeURIComponent(
454+
proxy['private-key'],
455+
)}@${proxy.server}:${proxy.port}/?${wireguardParams.join(
456+
'&',
457+
)}#${encodeURIComponent(proxy.name)}`;
458+
break;
416459
}
417460
return result;
418461
};

0 commit comments

Comments
 (0)