mirror of
https://github.com/sub-store-org/Sub-Store.git
synced 2025-08-10 00:52:40 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10ec8a25a2 | ||
|
|
aa0943a909 | ||
|
|
a0c1bbbf70 | ||
|
|
fea9de4fae | ||
|
|
cddd1818fe | ||
|
|
f94830b2df | ||
|
|
e02a26040e |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sub-store",
|
"name": "sub-store",
|
||||||
"version": "2.14.347",
|
"version": "2.14.352",
|
||||||
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
|
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.",
|
||||||
"main": "src/main.js",
|
"main": "src/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
"dns-packet": "^5.6.1",
|
"dns-packet": "^5.6.1",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"http-proxy-middleware": "^2.0.6",
|
"http-proxy-middleware": "^2.0.6",
|
||||||
|
"ip-address": "^9.0.5",
|
||||||
"js-base64": "^3.7.2",
|
"js-base64": "^3.7.2",
|
||||||
"jsrsasign": "^11.1.0",
|
"jsrsasign": "^11.1.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
|||||||
25
backend/pnpm-lock.yaml
generated
25
backend/pnpm-lock.yaml
generated
@@ -32,6 +32,9 @@ dependencies:
|
|||||||
http-proxy-middleware:
|
http-proxy-middleware:
|
||||||
specifier: ^2.0.6
|
specifier: ^2.0.6
|
||||||
version: registry.npmmirror.com/http-proxy-middleware@2.0.6
|
version: registry.npmmirror.com/http-proxy-middleware@2.0.6
|
||||||
|
ip-address:
|
||||||
|
specifier: ^9.0.5
|
||||||
|
version: registry.npmmirror.com/ip-address@9.0.5
|
||||||
js-base64:
|
js-base64:
|
||||||
specifier: ^3.7.2
|
specifier: ^3.7.2
|
||||||
version: registry.npmmirror.com/js-base64@3.7.2
|
version: registry.npmmirror.com/js-base64@3.7.2
|
||||||
@@ -6031,6 +6034,16 @@ packages:
|
|||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
registry.npmmirror.com/ip-address@9.0.5:
|
||||||
|
resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ip-address/-/ip-address-9.0.5.tgz}
|
||||||
|
name: ip-address
|
||||||
|
version: 9.0.5
|
||||||
|
engines: {node: '>= 12'}
|
||||||
|
dependencies:
|
||||||
|
jsbn: registry.npmmirror.com/jsbn@1.1.0
|
||||||
|
sprintf-js: registry.npmmirror.com/sprintf-js@1.1.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
registry.npmmirror.com/ip6addr@0.2.5:
|
registry.npmmirror.com/ip6addr@0.2.5:
|
||||||
resolution: {integrity: sha512-9RGGSB6Zc9Ox5DpDGFnJdIeF0AsqXzdH+FspCfPPaU/L/4tI6P+5lIoFUFm9JXs9IrJv1boqAaNCQmoDADTSKQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ip6addr/-/ip6addr-0.2.5.tgz}
|
resolution: {integrity: sha512-9RGGSB6Zc9Ox5DpDGFnJdIeF0AsqXzdH+FspCfPPaU/L/4tI6P+5lIoFUFm9JXs9IrJv1boqAaNCQmoDADTSKQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/ip6addr/-/ip6addr-0.2.5.tgz}
|
||||||
name: ip6addr
|
name: ip6addr
|
||||||
@@ -6576,6 +6589,12 @@ packages:
|
|||||||
version: 0.1.1
|
version: 0.1.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
registry.npmmirror.com/jsbn@1.1.0:
|
||||||
|
resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jsbn/-/jsbn-1.1.0.tgz}
|
||||||
|
name: jsbn
|
||||||
|
version: 1.1.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
registry.npmmirror.com/jsesc@0.5.0:
|
registry.npmmirror.com/jsesc@0.5.0:
|
||||||
resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jsesc/-/jsesc-0.5.0.tgz}
|
resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/jsesc/-/jsesc-0.5.0.tgz}
|
||||||
name: jsesc
|
name: jsesc
|
||||||
@@ -9095,6 +9114,12 @@ packages:
|
|||||||
version: 1.0.3
|
version: 1.0.3
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
registry.npmmirror.com/sprintf-js@1.1.3:
|
||||||
|
resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.1.3.tgz}
|
||||||
|
name: sprintf-js
|
||||||
|
version: 1.1.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
registry.npmmirror.com/sshpk@1.16.1:
|
registry.npmmirror.com/sshpk@1.16.1:
|
||||||
resolution: {integrity: sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/sshpk/-/sshpk-1.16.1.tgz}
|
resolution: {integrity: sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/sshpk/-/sshpk-1.16.1.tgz}
|
||||||
name: sshpk
|
name: sshpk
|
||||||
|
|||||||
@@ -2,7 +2,13 @@ import { Buffer } from 'buffer';
|
|||||||
import rs from '@/utils/rs';
|
import rs from '@/utils/rs';
|
||||||
import YAML from '@/utils/yaml';
|
import YAML from '@/utils/yaml';
|
||||||
import download from '@/utils/download';
|
import download from '@/utils/download';
|
||||||
import { isIPv4, isIPv6, isValidPortNumber, isNotBlank } from '@/utils';
|
import {
|
||||||
|
isIPv4,
|
||||||
|
isIPv6,
|
||||||
|
isValidPortNumber,
|
||||||
|
isNotBlank,
|
||||||
|
ipAddress,
|
||||||
|
} from '@/utils';
|
||||||
import PROXY_PROCESSORS, { ApplyProcessor } from './processors';
|
import PROXY_PROCESSORS, { ApplyProcessor } from './processors';
|
||||||
import PROXY_PREPROCESSORS from './preprocessors';
|
import PROXY_PREPROCESSORS from './preprocessors';
|
||||||
import PROXY_PRODUCERS from './producers';
|
import PROXY_PRODUCERS from './producers';
|
||||||
@@ -267,6 +273,7 @@ export const ProxyUtils = {
|
|||||||
parse,
|
parse,
|
||||||
process: processFn,
|
process: processFn,
|
||||||
produce,
|
produce,
|
||||||
|
ipAddress,
|
||||||
isIPv4,
|
isIPv4,
|
||||||
isIPv6,
|
isIPv6,
|
||||||
isIP,
|
isIP,
|
||||||
@@ -407,6 +414,15 @@ function lastParse(proxy) {
|
|||||||
if (['hysteria', 'hysteria2'].includes(proxy.type) && !proxy.ports) {
|
if (['hysteria', 'hysteria2'].includes(proxy.type) && !proxy.ports) {
|
||||||
delete proxy.ports;
|
delete proxy.ports;
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
['hysteria2'].includes(proxy.type) &&
|
||||||
|
proxy.obfs &&
|
||||||
|
!['salamander'].includes(proxy.obfs) &&
|
||||||
|
!proxy['obfs-password']
|
||||||
|
) {
|
||||||
|
proxy['obfs-password'] = proxy.obfs;
|
||||||
|
proxy.obfs = 'salamander';
|
||||||
|
}
|
||||||
if (['vless'].includes(proxy.type)) {
|
if (['vless'].includes(proxy.type)) {
|
||||||
// 删除 reality-opts: {}
|
// 删除 reality-opts: {}
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import resourceCache from '@/utils/resource-cache';
|
import resourceCache from '@/utils/resource-cache';
|
||||||
import scriptResourceCache from '@/utils/script-resource-cache';
|
import scriptResourceCache from '@/utils/script-resource-cache';
|
||||||
import { isIPv4, isIPv6 } from '@/utils';
|
import { isIPv4, isIPv6, ipAddress } from '@/utils';
|
||||||
import { FULL } from '@/utils/logical';
|
import { FULL } from '@/utils/logical';
|
||||||
import { getFlag, removeFlag } from '@/utils/geo';
|
import { getFlag, removeFlag } from '@/utils/geo';
|
||||||
import { doh } from '@/utils/dns';
|
import { doh } from '@/utils/dns';
|
||||||
@@ -364,9 +364,6 @@ function parseIP4P(IP4P) {
|
|||||||
let server;
|
let server;
|
||||||
let port;
|
let port;
|
||||||
try {
|
try {
|
||||||
if (!/^2001::[^:]+:[^:]+:[^:]+$/.test(IP4P)) {
|
|
||||||
throw new Error(`Invalid IP4P: ${IP4P}`);
|
|
||||||
}
|
|
||||||
let array = IP4P.split(':');
|
let array = IP4P.split(':');
|
||||||
|
|
||||||
port = parseInt(array[2], 16);
|
port = parseInt(array[2], 16);
|
||||||
@@ -622,14 +619,23 @@ function ResolveDomainOperator({
|
|||||||
if (!p['_no-resolve']) {
|
if (!p['_no-resolve']) {
|
||||||
if (results[p.server]) {
|
if (results[p.server]) {
|
||||||
p._resolved_ips = results[p.server];
|
p._resolved_ips = results[p.server];
|
||||||
const ip = Array.isArray(results[p.server])
|
let ip = Array.isArray(results[p.server])
|
||||||
? results[p.server][
|
? results[p.server][
|
||||||
Math.floor(
|
Math.floor(
|
||||||
Math.random() * results[p.server].length,
|
Math.random() * results[p.server].length,
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
: results[p.server];
|
: results[p.server];
|
||||||
if (_type === 'IP4P') {
|
if (type === 'IPv6' && isIPv6(ip)) {
|
||||||
|
try {
|
||||||
|
ip = new ipAddress.Address6(ip).correctForm();
|
||||||
|
} catch (e) {
|
||||||
|
$.error(
|
||||||
|
`Failed to parse IPv6 address: ${ip}: ${e}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (/^2001::[^:]+:[^:]+:[^:]+$/.test(ip)) {
|
||||||
|
p._IP4P = ip;
|
||||||
const { server, port } = parseIP4P(ip);
|
const { server, port } = parseIP4P(ip);
|
||||||
if (server && port) {
|
if (server && port) {
|
||||||
p._domain = p.server;
|
p._domain = p.server;
|
||||||
@@ -640,7 +646,7 @@ function ResolveDomainOperator({
|
|||||||
if (!isIP(p._IP)) {
|
if (!isIP(p._IP)) {
|
||||||
p._IP = p.server;
|
p._IP = p.server;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!p.resolved) {
|
||||||
p.resolved = false;
|
p.resolved = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -653,6 +659,15 @@ function ResolveDomainOperator({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
p._domain = p.server;
|
||||||
|
p.server = ip;
|
||||||
|
p.resolved = true;
|
||||||
|
p[`_${type}`] = p.server;
|
||||||
|
if (!isIP(p._IP)) {
|
||||||
|
p._IP = p.server;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!p.resolved) {
|
||||||
p.resolved = false;
|
p.resolved = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -329,6 +329,7 @@ export function getFlag(name) {
|
|||||||
'台',
|
'台',
|
||||||
'臺',
|
'臺',
|
||||||
'Taipei',
|
'Taipei',
|
||||||
|
'Tai Wan',
|
||||||
],
|
],
|
||||||
'🇺🇦': ['Ukraine', '乌克兰', '烏克蘭'],
|
'🇺🇦': ['Ukraine', '乌克兰', '烏克蘭'],
|
||||||
'🇺🇸': [
|
'🇺🇸': [
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import * as ipAddress from 'ip-address';
|
||||||
// source: https://stackoverflow.com/a/36760050
|
// source: https://stackoverflow.com/a/36760050
|
||||||
const IPV4_REGEX = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$/;
|
const IPV4_REGEX = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$/;
|
||||||
|
|
||||||
@@ -94,6 +95,7 @@ function getPolicyDescriptor(str) {
|
|||||||
// })();
|
// })();
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
ipAddress,
|
||||||
isIPv4,
|
isIPv4,
|
||||||
isIPv6,
|
isIPv6,
|
||||||
isValidPortNumber,
|
isValidPortNumber,
|
||||||
|
|||||||
@@ -3,13 +3,12 @@ function operator(proxies = [], targetPlatform, context) {
|
|||||||
// 可参考 https://t.me/zhetengsha/970
|
// 可参考 https://t.me/zhetengsha/970
|
||||||
// https://t.me/zhetengsha/1009
|
// https://t.me/zhetengsha/1009
|
||||||
|
|
||||||
|
|
||||||
// proxies 为传入的内部节点数组
|
// proxies 为传入的内部节点数组
|
||||||
// 可在预览界面点击节点查看 JSON 结构 或查看 `target=JSON` 的通用订阅
|
// 可在预览界面点击节点查看 JSON 结构 或查看 `target=JSON` 的通用订阅
|
||||||
// 0. 结构大致参考了 Clash.Meta(mihomo), 可参考 mihomo 的文档, 例如 `xudp`, `smux` 都可以自己设置. 但是有私货, 下面是我能想起来的一些私货
|
// 0. 结构大致参考了 Clash.Meta(mihomo), 可参考 mihomo 的文档, 例如 `xudp`, `smux` 都可以自己设置. 但是有私货, 下面是我能想起来的一些私货
|
||||||
// 1. `_no-resolve` 为不解析域名
|
// 1. `_no-resolve` 为不解析域名
|
||||||
// 2. 域名解析后 会多一个 `_resolved` 字段, 表示是否解析成功
|
// 2. 域名解析后 会多一个 `_resolved` 字段, 表示是否解析成功
|
||||||
// 3. 域名解析后会有`_IPv4`, `_IPv6`, `_IP`(若有多个步骤, 只取第一次成功的 v4 或 v6 数据), `_domain` 字段, `_resolved_ips` 为解析出的所有 IP
|
// 3. 域名解析后会有`_IPv4`, `_IPv6`, `_IP`(若有多个步骤, 只取第一次成功的 v4 或 v6 数据), `_IP4P`(若解析类型为 IPv6 且符合 IP4P 类型, 将自动转换), `_domain` 字段, `_resolved_ips` 为解析出的所有 IP
|
||||||
// 4. 节点字段 `exec` 为 `ssr-local` 路径, 默认 `/usr/local/bin/ssr-local`; 端口从 10000 开始递增(暂不支持配置)
|
// 4. 节点字段 `exec` 为 `ssr-local` 路径, 默认 `/usr/local/bin/ssr-local`; 端口从 10000 开始递增(暂不支持配置)
|
||||||
// 5. `_subName` 为单条订阅名
|
// 5. `_subName` 为单条订阅名
|
||||||
// 6. `_collectionName` 为组合订阅名
|
// 6. `_collectionName` 为组合订阅名
|
||||||
@@ -43,6 +42,7 @@ function operator(proxies = [], targetPlatform, context) {
|
|||||||
// parse, // 订阅解析
|
// parse, // 订阅解析
|
||||||
// process, // 节点操作/文件操作
|
// process, // 节点操作/文件操作
|
||||||
// produce, // 输出订阅
|
// produce, // 输出订阅
|
||||||
|
// ipAddress, // https://github.com/beaugunderson/ip-address
|
||||||
// isIPv4,
|
// isIPv4,
|
||||||
// isIPv6,
|
// isIPv6,
|
||||||
// isIP,
|
// isIP,
|
||||||
@@ -130,7 +130,6 @@ function operator(proxies = [], targetPlatform, context) {
|
|||||||
// yaml.proxies.unshift(...clashMetaProxies)
|
// yaml.proxies.unshift(...clashMetaProxies)
|
||||||
// $content = ProxyUtils.yaml.dump(yaml)
|
// $content = ProxyUtils.yaml.dump(yaml)
|
||||||
|
|
||||||
|
|
||||||
// { $content, $files } will be passed to the next operator
|
// { $content, $files } will be passed to the next operator
|
||||||
// $content is the final content of the file
|
// $content is the final content of the file
|
||||||
|
|
||||||
@@ -224,7 +223,7 @@ function operator(proxies = [], targetPlatform, context) {
|
|||||||
// 参数说明
|
// 参数说明
|
||||||
// 可参考 https://github.com/sub-store-org/Sub-Store/wiki/%E9%93%BE%E6%8E%A5%E5%8F%82%E6%95%B0%E8%AF%B4%E6%98%8E
|
// 可参考 https://github.com/sub-store-org/Sub-Store/wiki/%E9%93%BE%E6%8E%A5%E5%8F%82%E6%95%B0%E8%AF%B4%E6%98%8E
|
||||||
|
|
||||||
console.log(JSON.stringify(context, null, 2))
|
console.log(JSON.stringify(context, null, 2));
|
||||||
|
|
||||||
return proxies
|
return proxies;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user