From 4966132397d3b421e97caacc7ea11f81a9c92afa Mon Sep 17 00:00:00 2001 From: xream Date: Wed, 17 Jan 2024 20:31:43 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20produceArtifact=20=E6=94=AF=E6=8C=81=20?= =?UTF-8?q?Stash=20internal=20(Fixes=20#271)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/package.json | 2 +- .../src/core/proxy-utils/producers/stash.js | 438 +++++++++--------- 2 files changed, 221 insertions(+), 219 deletions(-) diff --git a/backend/package.json b/backend/package.json index 5cfa86f2d..baf4cc49e 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "sub-store", - "version": "2.14.173", + "version": "2.14.174", "description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.", "main": "src/main.js", "scripts": { diff --git a/backend/src/core/proxy-utils/producers/stash.js b/backend/src/core/proxy-utils/producers/stash.js index 25cab3da6..3d017da40 100644 --- a/backend/src/core/proxy-utils/producers/stash.js +++ b/backend/src/core/proxy-utils/producers/stash.js @@ -2,241 +2,243 @@ import { isPresent } from '@/core/proxy-utils/producers/utils'; export default function Stash_Producer() { const type = 'ALL'; - const produce = (proxies) => { + const produce = (proxies, type, opts = {}) => { // https://stash.wiki/proxy-protocols/proxy-types#shadowsocks - return ( - 'proxies:\n' + - proxies - .filter((proxy) => { + const list = proxies + .filter((proxy) => { + if (opts['include-unsupported-proxy']) return true; + if ( + ![ + 'ss', + 'ssr', + 'vmess', + 'socks5', + 'http', + 'snell', + 'trojan', + 'tuic', + 'vless', + 'wireguard', + 'hysteria', + 'hysteria2', + ].includes(proxy.type) || + (proxy.type === 'ss' && + ![ + 'aes-128-gcm', + 'aes-192-gcm', + 'aes-256-gcm', + 'aes-128-cfb', + 'aes-192-cfb', + 'aes-256-cfb', + 'aes-128-ctr', + 'aes-192-ctr', + 'aes-256-ctr', + 'rc4-md5', + 'chacha20-ietf', + 'xchacha20', + 'chacha20-ietf-poly1305', + 'xchacha20-ietf-poly1305', + ].includes(proxy.cipher)) || + (proxy.type === 'snell' && String(proxy.version) === '4') || + (proxy.type === 'vless' && proxy['reality-opts']) + ) { + return false; + } + return true; + }) + .map((proxy) => { + if (proxy.type === 'vmess') { + // handle vmess aead + if (isPresent(proxy, 'aead')) { + if (proxy.aead) { + proxy.alterId = 0; + } + delete proxy.aead; + } + if (isPresent(proxy, 'sni')) { + proxy.servername = proxy.sni; + delete proxy.sni; + } + // https://github.com/MetaCubeX/Clash.Meta/blob/Alpha/docs/config.yaml#L400 + // https://stash.wiki/proxy-protocols/proxy-types#vmess if ( + isPresent(proxy, 'cipher') && ![ - 'ss', - 'ssr', - 'vmess', - 'socks5', - 'http', - 'snell', - 'trojan', - 'tuic', - 'vless', - 'wireguard', - 'hysteria', - 'hysteria2', - ].includes(proxy.type) || - (proxy.type === 'ss' && - ![ - 'aes-128-gcm', - 'aes-192-gcm', - 'aes-256-gcm', - 'aes-128-cfb', - 'aes-192-cfb', - 'aes-256-cfb', - 'aes-128-ctr', - 'aes-192-ctr', - 'aes-256-ctr', - 'rc4-md5', - 'chacha20-ietf', - 'xchacha20', - 'chacha20-ietf-poly1305', - 'xchacha20-ietf-poly1305', - ].includes(proxy.cipher)) || - (proxy.type === 'snell' && - String(proxy.version) === '4') || - (proxy.type === 'vless' && proxy['reality-opts']) + 'auto', + 'aes-128-gcm', + 'chacha20-poly1305', + 'none', + ].includes(proxy.cipher) ) { - return false; - } - return true; - }) - .map((proxy) => { - if (proxy.type === 'vmess') { - // handle vmess aead - if (isPresent(proxy, 'aead')) { - if (proxy.aead) { - proxy.alterId = 0; - } - delete proxy.aead; - } - if (isPresent(proxy, 'sni')) { - proxy.servername = proxy.sni; - delete proxy.sni; - } - // https://github.com/MetaCubeX/Clash.Meta/blob/Alpha/docs/config.yaml#L400 - // https://stash.wiki/proxy-protocols/proxy-types#vmess - if ( - isPresent(proxy, 'cipher') && - ![ - 'auto', - 'aes-128-gcm', - 'chacha20-poly1305', - 'none', - ].includes(proxy.cipher) - ) { - proxy.cipher = 'auto'; - } - } else if (proxy.type === 'tuic') { - if (isPresent(proxy, 'alpn')) { - proxy.alpn = Array.isArray(proxy.alpn) - ? proxy.alpn - : [proxy.alpn]; - } else { - proxy.alpn = ['h3']; - } - if ( - isPresent(proxy, 'tfo') && - !isPresent(proxy, 'fast-open') - ) { - proxy['fast-open'] = proxy.tfo; - delete proxy.tfo; - } - // https://github.com/MetaCubeX/Clash.Meta/blob/Alpha/adapter/outbound/tuic.go#L197 - if ( - (!proxy.token || proxy.token.length === 0) && - !isPresent(proxy, 'version') - ) { - proxy.version = 5; - } - } else if (proxy.type === 'hysteria') { - // auth_str 将会在未来某个时候删除 但是有的机场不规范 - if ( - isPresent(proxy, 'auth_str') && - !isPresent(proxy, 'auth-str') - ) { - proxy['auth-str'] = proxy['auth_str']; - } - if (isPresent(proxy, 'alpn')) { - proxy.alpn = Array.isArray(proxy.alpn) - ? proxy.alpn - : [proxy.alpn]; - } - if ( - isPresent(proxy, 'tfo') && - !isPresent(proxy, 'fast-open') - ) { - proxy['fast-open'] = proxy.tfo; - delete proxy.tfo; - } - if ( - isPresent(proxy, 'down') && - !isPresent(proxy, 'down-speed') - ) { - proxy['down-speed'] = proxy.down; - delete proxy.down; - } - if ( - isPresent(proxy, 'up') && - !isPresent(proxy, 'up-speed') - ) { - proxy['up-speed'] = proxy.up; - delete proxy.up; - } - if (isPresent(proxy, 'down-speed')) { - proxy['down-speed'] = - `${proxy['down-speed']}`.match(/\d+/)?.[0] || 0; - } - if (isPresent(proxy, 'up-speed')) { - proxy['up-speed'] = - `${proxy['up-speed']}`.match(/\d+/)?.[0] || 0; - } - } else if (proxy.type === 'hysteria2') { - if ( - isPresent(proxy, 'password') && - !isPresent(proxy, 'auth') - ) { - proxy.auth = proxy.password; - delete proxy.password; - } - if ( - isPresent(proxy, 'tfo') && - !isPresent(proxy, 'fast-open') - ) { - proxy['fast-open'] = proxy.tfo; - delete proxy.tfo; - } - if ( - isPresent(proxy, 'down') && - !isPresent(proxy, 'down-speed') - ) { - proxy['down-speed'] = proxy.down; - delete proxy.down; - } - if ( - isPresent(proxy, 'up') && - !isPresent(proxy, 'up-speed') - ) { - proxy['up-speed'] = proxy.up; - delete proxy.up; - } - if (isPresent(proxy, 'down-speed')) { - proxy['down-speed'] = - `${proxy['down-speed']}`.match(/\d+/)?.[0] || 0; - } - if (isPresent(proxy, 'up-speed')) { - proxy['up-speed'] = - `${proxy['up-speed']}`.match(/\d+/)?.[0] || 0; - } - } else if (proxy.type === 'wireguard') { - proxy.keepalive = - proxy.keepalive ?? proxy['persistent-keepalive']; - proxy['persistent-keepalive'] = proxy.keepalive; - proxy['preshared-key'] = - proxy['preshared-key'] ?? proxy['pre-shared-key']; - proxy['pre-shared-key'] = proxy['preshared-key']; - } else if (proxy.type === 'vless') { - if (isPresent(proxy, 'sni')) { - proxy.servername = proxy.sni; - delete proxy.sni; - } + proxy.cipher = 'auto'; + } + } else if (proxy.type === 'tuic') { + if (isPresent(proxy, 'alpn')) { + proxy.alpn = Array.isArray(proxy.alpn) + ? proxy.alpn + : [proxy.alpn]; + } else { + proxy.alpn = ['h3']; } - if ( - ['vmess', 'vless'].includes(proxy.type) && - proxy.network === 'http' + isPresent(proxy, 'tfo') && + !isPresent(proxy, 'fast-open') ) { - let httpPath = proxy['http-opts']?.path; - if ( - isPresent(proxy, 'http-opts.path') && - !Array.isArray(httpPath) - ) { - proxy['http-opts'].path = [httpPath]; - } - let httpHost = proxy['http-opts']?.headers?.Host; - if ( - isPresent(proxy, 'http-opts.headers.Host') && - !Array.isArray(httpHost) - ) { - proxy['http-opts'].headers.Host = [httpHost]; - } + proxy['fast-open'] = proxy.tfo; + delete proxy.tfo; } + // https://github.com/MetaCubeX/Clash.Meta/blob/Alpha/adapter/outbound/tuic.go#L197 if ( - ['trojan', 'tuic', 'hysteria', 'hysteria2'].includes( - proxy.type, - ) + (!proxy.token || proxy.token.length === 0) && + !isPresent(proxy, 'version') ) { - delete proxy.tls; + proxy.version = 5; } - if (proxy['tls-fingerprint']) { - proxy.fingerprint = proxy['tls-fingerprint']; + } else if (proxy.type === 'hysteria') { + // auth_str 将会在未来某个时候删除 但是有的机场不规范 + if ( + isPresent(proxy, 'auth_str') && + !isPresent(proxy, 'auth-str') + ) { + proxy['auth-str'] = proxy['auth_str']; } - delete proxy['tls-fingerprint']; - - if (proxy['test-url']) { - proxy['benchmark-url'] = proxy['test-url']; - delete proxy['test-url']; + if (isPresent(proxy, 'alpn')) { + proxy.alpn = Array.isArray(proxy.alpn) + ? proxy.alpn + : [proxy.alpn]; } + if ( + isPresent(proxy, 'tfo') && + !isPresent(proxy, 'fast-open') + ) { + proxy['fast-open'] = proxy.tfo; + delete proxy.tfo; + } + if ( + isPresent(proxy, 'down') && + !isPresent(proxy, 'down-speed') + ) { + proxy['down-speed'] = proxy.down; + delete proxy.down; + } + if ( + isPresent(proxy, 'up') && + !isPresent(proxy, 'up-speed') + ) { + proxy['up-speed'] = proxy.up; + delete proxy.up; + } + if (isPresent(proxy, 'down-speed')) { + proxy['down-speed'] = + `${proxy['down-speed']}`.match(/\d+/)?.[0] || 0; + } + if (isPresent(proxy, 'up-speed')) { + proxy['up-speed'] = + `${proxy['up-speed']}`.match(/\d+/)?.[0] || 0; + } + } else if (proxy.type === 'hysteria2') { + if ( + isPresent(proxy, 'password') && + !isPresent(proxy, 'auth') + ) { + proxy.auth = proxy.password; + delete proxy.password; + } + if ( + isPresent(proxy, 'tfo') && + !isPresent(proxy, 'fast-open') + ) { + proxy['fast-open'] = proxy.tfo; + delete proxy.tfo; + } + if ( + isPresent(proxy, 'down') && + !isPresent(proxy, 'down-speed') + ) { + proxy['down-speed'] = proxy.down; + delete proxy.down; + } + if ( + isPresent(proxy, 'up') && + !isPresent(proxy, 'up-speed') + ) { + proxy['up-speed'] = proxy.up; + delete proxy.up; + } + if (isPresent(proxy, 'down-speed')) { + proxy['down-speed'] = + `${proxy['down-speed']}`.match(/\d+/)?.[0] || 0; + } + if (isPresent(proxy, 'up-speed')) { + proxy['up-speed'] = + `${proxy['up-speed']}`.match(/\d+/)?.[0] || 0; + } + } else if (proxy.type === 'wireguard') { + proxy.keepalive = + proxy.keepalive ?? proxy['persistent-keepalive']; + proxy['persistent-keepalive'] = proxy.keepalive; + proxy['preshared-key'] = + proxy['preshared-key'] ?? proxy['pre-shared-key']; + proxy['pre-shared-key'] = proxy['preshared-key']; + } else if (proxy.type === 'vless') { + if (isPresent(proxy, 'sni')) { + proxy.servername = proxy.sni; + delete proxy.sni; + } + } - delete proxy.subName; - delete proxy.collectionName; + if ( + ['vmess', 'vless'].includes(proxy.type) && + proxy.network === 'http' + ) { + let httpPath = proxy['http-opts']?.path; if ( - ['grpc'].includes(proxy.network) && - proxy[`${proxy.network}-opts`] + isPresent(proxy, 'http-opts.path') && + !Array.isArray(httpPath) ) { - delete proxy[`${proxy.network}-opts`]['_grpc-type']; + proxy['http-opts'].path = [httpPath]; } - return ' - ' + JSON.stringify(proxy) + '\n'; - }) - .join('') - ); + let httpHost = proxy['http-opts']?.headers?.Host; + if ( + isPresent(proxy, 'http-opts.headers.Host') && + !Array.isArray(httpHost) + ) { + proxy['http-opts'].headers.Host = [httpHost]; + } + } + if ( + ['trojan', 'tuic', 'hysteria', 'hysteria2'].includes( + proxy.type, + ) + ) { + delete proxy.tls; + } + if (proxy['tls-fingerprint']) { + proxy.fingerprint = proxy['tls-fingerprint']; + } + delete proxy['tls-fingerprint']; + + if (proxy['test-url']) { + proxy['benchmark-url'] = proxy['test-url']; + delete proxy['test-url']; + } + + delete proxy.subName; + delete proxy.collectionName; + if ( + ['grpc'].includes(proxy.network) && + proxy[`${proxy.network}-opts`] + ) { + delete proxy[`${proxy.network}-opts`]['_grpc-type']; + } + return proxy; + }); + return type === 'internal' + ? list + : 'proxies:\n' + + list + .map((proxy) => ' - ' + JSON.stringify(proxy) + '\n') + .join(''); }; return { type, produce }; }