mirror of
https://git.mirrors.martin98.com/https://github.com/sub-store-org/Sub-Store.git
synced 2025-08-11 00:39:01 +08:00
Fixed Trojan issue
This commit is contained in:
parent
8504738ee1
commit
a0d8e79d3c
@ -59,7 +59,6 @@ $app.route("/api/sub/:name").get(getSub).patch(updateSub).delete(deleteSub);
|
|||||||
|
|
||||||
$app.route("/api/sub").get(getAllSubs).post(newSub).delete(deleteAllSubs);
|
$app.route("/api/sub").get(getAllSubs).post(newSub).delete(deleteAllSubs);
|
||||||
|
|
||||||
|
|
||||||
// refresh
|
// refresh
|
||||||
$app.post("/api/refresh", refreshResource);
|
$app.post("/api/refresh", refreshResource);
|
||||||
|
|
||||||
@ -85,7 +84,9 @@ $app.start();
|
|||||||
|
|
||||||
async function IP_API(req, res) {
|
async function IP_API(req, res) {
|
||||||
const server = decodeURIComponent(req.params.server);
|
const server = decodeURIComponent(req.params.server);
|
||||||
const result = await $.http.get(`http://ip-api.com/json/${server}?lang=zh-CN`).then(resp => JSON.parse(resp.body));
|
const result = await $.http
|
||||||
|
.get(`http://ip-api.com/json/${server}?lang=zh-CN`)
|
||||||
|
.then((resp) => JSON.parse(resp.body));
|
||||||
res.json(result);
|
res.json(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +113,7 @@ async function downloadResource(url) {
|
|||||||
// refresh resource
|
// refresh resource
|
||||||
async function refreshResource(req, res) {
|
async function refreshResource(req, res) {
|
||||||
const Base64 = new Base64Code();
|
const Base64 = new Base64Code();
|
||||||
const {url} = req.body;
|
const { url } = req.body;
|
||||||
const raw = await downloadResource(url);
|
const raw = await downloadResource(url);
|
||||||
$.write(raw, `#${Base64.safeEncode(url)}`);
|
$.write(raw, `#${Base64.safeEncode(url)}`);
|
||||||
res.json({
|
res.json({
|
||||||
@ -122,7 +123,7 @@ async function refreshResource(req, res) {
|
|||||||
|
|
||||||
// download subscription, for APP only
|
// download subscription, for APP only
|
||||||
async function downloadSub(req, res) {
|
async function downloadSub(req, res) {
|
||||||
const {name} = req.params;
|
const { name } = req.params;
|
||||||
const platform = req.query.target || getPlatformFromHeaders(req.headers);
|
const platform = req.query.target || getPlatformFromHeaders(req.headers);
|
||||||
const allSubs = $.read(SUBS_KEY);
|
const allSubs = $.read(SUBS_KEY);
|
||||||
if (allSubs[name]) {
|
if (allSubs[name]) {
|
||||||
@ -147,7 +148,7 @@ async function downloadSub(req, res) {
|
|||||||
async function parseSub(sub, platform) {
|
async function parseSub(sub, platform) {
|
||||||
let raw;
|
let raw;
|
||||||
const key = new Base64Code().safeEncode(sub.url);
|
const key = new Base64Code().safeEncode(sub.url);
|
||||||
if (platform === "Raw" || platform === 'URI') {
|
if (platform === "Raw" || platform === "URI") {
|
||||||
const cache = $.read(`#${key}`);
|
const cache = $.read(`#${key}`);
|
||||||
if (!cache) {
|
if (!cache) {
|
||||||
raw = await downloadResource(sub.url);
|
raw = await downloadResource(sub.url);
|
||||||
@ -210,7 +211,7 @@ async function parseSub(sub, platform) {
|
|||||||
let script;
|
let script;
|
||||||
// process script
|
// process script
|
||||||
if (item.type.indexOf("Script") !== -1) {
|
if (item.type.indexOf("Script") !== -1) {
|
||||||
const {mode, content} = item.args;
|
const { mode, content } = item.args;
|
||||||
if (mode === "link") {
|
if (mode === "link") {
|
||||||
// if this is remote script, download it
|
// if this is remote script, download it
|
||||||
script = await $.http
|
script = await $.http
|
||||||
@ -239,12 +240,9 @@ async function parseSub(sub, platform) {
|
|||||||
$filter.setFilter(filter(item.args));
|
$filter.setFilter(filter(item.args));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
|
||||||
proxies = $filter.process(proxies);
|
proxies = $filter.process(proxies);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
$.error(
|
$.error(`Failed to apply filter "${item.type}"!\n REASON: ${err}`);
|
||||||
`Failed to apply filter "${item.type}"!\n REASON: ${err}`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (item.type.indexOf("Operator") !== -1) {
|
} else if (item.type.indexOf("Operator") !== -1) {
|
||||||
@ -263,7 +261,7 @@ async function parseSub(sub, platform) {
|
|||||||
try {
|
try {
|
||||||
proxies = $operator.process(proxies);
|
proxies = $operator.process(proxies);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
`Failed to apply operator "${item.type}"!\n REASON: ${err}`
|
`Failed to apply operator "${item.type}"!\n REASON: ${err}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -275,7 +273,7 @@ async function parseSub(sub, platform) {
|
|||||||
Loon_Producer,
|
Loon_Producer,
|
||||||
Surge_Producer,
|
Surge_Producer,
|
||||||
Raw_Producer,
|
Raw_Producer,
|
||||||
URI_Producer
|
URI_Producer,
|
||||||
]);
|
]);
|
||||||
return $parser.produce(proxies);
|
return $parser.produce(proxies);
|
||||||
}
|
}
|
||||||
@ -321,7 +319,7 @@ function getFlowHeaders(headers, proxies) {
|
|||||||
|
|
||||||
// Subscriptions
|
// Subscriptions
|
||||||
async function getSub(req, res) {
|
async function getSub(req, res) {
|
||||||
const {name} = req.params;
|
const { name } = req.params;
|
||||||
const sub = $.read(SUBS_KEY)[name];
|
const sub = $.read(SUBS_KEY)[name];
|
||||||
if (sub) {
|
if (sub) {
|
||||||
res.json({
|
res.json({
|
||||||
@ -362,7 +360,7 @@ async function newSub(req, res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function updateSub(req, res) {
|
async function updateSub(req, res) {
|
||||||
const {name} = req.params;
|
const { name } = req.params;
|
||||||
$.info(`Updating subscription: ${name}`);
|
$.info(`Updating subscription: ${name}`);
|
||||||
let sub = req.body;
|
let sub = req.body;
|
||||||
const allSubs = $.read(SUBS_KEY);
|
const allSubs = $.read(SUBS_KEY);
|
||||||
@ -401,7 +399,7 @@ async function updateSub(req, res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function deleteSub(req, res) {
|
async function deleteSub(req, res) {
|
||||||
const {name} = req.params;
|
const { name } = req.params;
|
||||||
// delete from subscriptions
|
// delete from subscriptions
|
||||||
let allSubs = $.read(SUBS_KEY);
|
let allSubs = $.read(SUBS_KEY);
|
||||||
delete allSubs[name];
|
delete allSubs[name];
|
||||||
@ -436,7 +434,7 @@ async function deleteAllSubs(req, res) {
|
|||||||
|
|
||||||
// Collections
|
// Collections
|
||||||
async function downloadCollection(req, res) {
|
async function downloadCollection(req, res) {
|
||||||
const {name} = req.params;
|
const { name } = req.params;
|
||||||
const collection = $.read(COLLECTIONS_KEY)[name];
|
const collection = $.read(COLLECTIONS_KEY)[name];
|
||||||
const platform = getPlatformFromHeaders(req.headers);
|
const platform = getPlatformFromHeaders(req.headers);
|
||||||
if (collection) {
|
if (collection) {
|
||||||
@ -463,7 +461,7 @@ async function downloadCollection(req, res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getCollection(req, res) {
|
async function getCollection(req, res) {
|
||||||
const {name} = req.params;
|
const { name } = req.params;
|
||||||
const collection = $.read(COLLECTIONS_KEY)[name];
|
const collection = $.read(COLLECTIONS_KEY)[name];
|
||||||
if (collection) {
|
if (collection) {
|
||||||
res.json({
|
res.json({
|
||||||
@ -504,7 +502,7 @@ async function newCollection(req, res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function updateCollection(req, res) {
|
async function updateCollection(req, res) {
|
||||||
const {name} = req.params;
|
const { name } = req.params;
|
||||||
let collection = req.body;
|
let collection = req.body;
|
||||||
const allCol = $.read(COLLECTIONS_KEY);
|
const allCol = $.read(COLLECTIONS_KEY);
|
||||||
if (allCol[name]) {
|
if (allCol[name]) {
|
||||||
@ -529,7 +527,7 @@ async function updateCollection(req, res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function deleteCollection(req, res) {
|
async function deleteCollection(req, res) {
|
||||||
const {name} = req.params;
|
const { name } = req.params;
|
||||||
let allCol = $.read(COLLECTIONS_KEY);
|
let allCol = $.read(COLLECTIONS_KEY);
|
||||||
delete allCol[name];
|
delete allCol[name];
|
||||||
$.write(allCol, COLLECTIONS_KEY);
|
$.write(allCol, COLLECTIONS_KEY);
|
||||||
@ -579,7 +577,7 @@ function ProxyParser(targetPlatform) {
|
|||||||
if (line.startsWith("#")) continue; // skip comments
|
if (line.startsWith("#")) continue; // skip comments
|
||||||
let matched = false;
|
let matched = false;
|
||||||
for (const p of parsers) {
|
for (const p of parsers) {
|
||||||
const {patternTest, func} = p;
|
const { patternTest, func } = p;
|
||||||
|
|
||||||
// some lines with weird format may produce errors!
|
// some lines with weird format may produce errors!
|
||||||
let patternMatched;
|
let patternMatched;
|
||||||
@ -601,7 +599,8 @@ function ProxyParser(targetPlatform) {
|
|||||||
}
|
}
|
||||||
// skip unsupported proxies
|
// skip unsupported proxies
|
||||||
// if proxy.supported is undefined, assume that all platforms are supported.
|
// if proxy.supported is undefined, assume that all platforms are supported.
|
||||||
if (proxy.supported && proxy.supported[targetPlatform] === false) continue;
|
if (proxy.supported && proxy.supported[targetPlatform] === false)
|
||||||
|
continue;
|
||||||
result.push(proxy);
|
result.push(proxy);
|
||||||
break;
|
break;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -634,7 +633,7 @@ function ProxyParser(targetPlatform) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(v => v.length > 0) // discard empty lines
|
.filter((v) => v.length > 0) // discard empty lines
|
||||||
.join("\n");
|
.join("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -658,15 +657,20 @@ function ProxyParser(targetPlatform) {
|
|||||||
raw = raw
|
raw = raw
|
||||||
.replace(/ - /g, " - ")
|
.replace(/ - /g, " - ")
|
||||||
.replace(/:(?!\s)/g, ": ")
|
.replace(/:(?!\s)/g, ": ")
|
||||||
.replace(/\,\"/g, ", \"")
|
.replace(/\,\"/g, ', "')
|
||||||
.replace(/: {/g, ": {, ")
|
.replace(/: {/g, ": {, ")
|
||||||
.replace(/, (host|path|tls|mux|skip)/g, ", $1")
|
.replace(/, (host|path|tls|mux|skip)/g, ", $1")
|
||||||
.replace(/{name: /g, "{name: \"")
|
.replace(/{name: /g, '{name: "')
|
||||||
.replace(/, server:/g, "\", server:")
|
.replace(/, server:/g, '", server:')
|
||||||
.replace(/{|}/g, "")
|
.replace(/{|}/g, "")
|
||||||
.replace(/,/g, "\n ")
|
.replace(/,/g, "\n ");
|
||||||
}
|
}
|
||||||
raw = raw.replace(/ -\n.*name/g, " - name").replace(/\$|\`/g, "").split("proxy-providers:")[0].split("proxy-groups:")[0].replace(/\"(name|type|server|port|cipher|password|)\"/g, "$1")
|
raw = raw
|
||||||
|
.replace(/ -\n.*name/g, " - name")
|
||||||
|
.replace(/\$|\`/g, "")
|
||||||
|
.split("proxy-providers:")[0]
|
||||||
|
.split("proxy-groups:")[0]
|
||||||
|
.replace(/\"(name|type|server|port|cipher|password|)\"/g, "$1");
|
||||||
const proxies = YAML.eval(raw).proxies;
|
const proxies = YAML.eval(raw).proxies;
|
||||||
output = proxies.map((p) => JSON.stringify(p));
|
output = proxies.map((p) => JSON.stringify(p));
|
||||||
} else if (raw.indexOf("ssd://") === 0) {
|
} else if (raw.indexOf("ssd://") === 0) {
|
||||||
@ -693,8 +697,12 @@ function ProxyParser(targetPlatform) {
|
|||||||
let hostname = server.server;
|
let hostname = server.server;
|
||||||
port = server.port ? server.port : port;
|
port = server.port ? server.port : port;
|
||||||
let tag = server.remarks ? server.remarks : i;
|
let tag = server.remarks ? server.remarks : i;
|
||||||
let plugin = server.plugin_options ? "/?plugin=" + encodeURIComponent(server.plugin + ";" + server.plugin_options) : ""
|
let plugin = server.plugin_options
|
||||||
output[i] = "ss://" + userinfo + "@" + hostname + ":" + port + plugin + "#" + tag
|
? "/?plugin=" +
|
||||||
|
encodeURIComponent(server.plugin + ";" + server.plugin_options)
|
||||||
|
: "";
|
||||||
|
output[i] =
|
||||||
|
"ss://" + userinfo + "@" + hostname + ":" + port + plugin + "#" + tag;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// check if content is based64 encoded
|
// check if content is based64 encoded
|
||||||
@ -767,7 +775,7 @@ function ProxyOperator() {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {setOperator, process};
|
return { setOperator, process };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************** URI Format ***************************************/
|
/**************************** URI Format ***************************************/
|
||||||
@ -836,7 +844,7 @@ function URI_SS() {
|
|||||||
mode: "websocket",
|
mode: "websocket",
|
||||||
host: params["obfs-host"],
|
host: params["obfs-host"],
|
||||||
path: params.path || "",
|
path: params.path || "",
|
||||||
tls: params.tls
|
tls: params.tls,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -845,7 +853,7 @@ function URI_SS() {
|
|||||||
}
|
}
|
||||||
return proxy;
|
return proxy;
|
||||||
};
|
};
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse URI SSR format, such as ssr://xxx
|
// Parse URI SSR format, such as ssr://xxx
|
||||||
@ -907,7 +915,7 @@ function URI_SSR() {
|
|||||||
return proxy;
|
return proxy;
|
||||||
};
|
};
|
||||||
|
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
// V2rayN URI VMess format
|
// V2rayN URI VMess format
|
||||||
@ -991,7 +999,7 @@ function URI_VMess() {
|
|||||||
return proxy;
|
return proxy;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trojan URI format
|
// Trojan URI format
|
||||||
@ -1023,7 +1031,7 @@ function URI_Trojan() {
|
|||||||
supported,
|
supported,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************** Clash ***************************************/
|
/**************************** Clash ***************************************/
|
||||||
@ -1032,7 +1040,7 @@ function Clash_All() {
|
|||||||
return line.indexOf("{") !== -1;
|
return line.indexOf("{") !== -1;
|
||||||
};
|
};
|
||||||
const func = (line) => JSON.parse(line);
|
const func = (line) => JSON.parse(line);
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************** Quantumult X ***************************************/
|
/**************************** Quantumult X ***************************************/
|
||||||
@ -1090,7 +1098,7 @@ function QX_SS() {
|
|||||||
}
|
}
|
||||||
return proxy;
|
return proxy;
|
||||||
};
|
};
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
function QX_SSR() {
|
function QX_SSR() {
|
||||||
@ -1129,7 +1137,7 @@ function QX_SSR() {
|
|||||||
}
|
}
|
||||||
return proxy;
|
return proxy;
|
||||||
};
|
};
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
function QX_VMess() {
|
function QX_VMess() {
|
||||||
@ -1165,7 +1173,7 @@ function QX_VMess() {
|
|||||||
return proxy;
|
return proxy;
|
||||||
};
|
};
|
||||||
|
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
function QX_Trojan() {
|
function QX_Trojan() {
|
||||||
@ -1187,7 +1195,7 @@ function QX_Trojan() {
|
|||||||
proxy.scert = !JSON.parse(params["tls-verification"] || "true");
|
proxy.scert = !JSON.parse(params["tls-verification"] || "true");
|
||||||
return proxy;
|
return proxy;
|
||||||
};
|
};
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
function QX_Http() {
|
function QX_Http() {
|
||||||
@ -1214,7 +1222,7 @@ function QX_Http() {
|
|||||||
return proxy;
|
return proxy;
|
||||||
};
|
};
|
||||||
|
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
function getQXParams(line) {
|
function getQXParams(line) {
|
||||||
@ -1262,7 +1270,7 @@ function Loon_SS() {
|
|||||||
}
|
}
|
||||||
return proxy;
|
return proxy;
|
||||||
};
|
};
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
function Loon_SSR() {
|
function Loon_SSR() {
|
||||||
@ -1293,7 +1301,7 @@ function Loon_SSR() {
|
|||||||
"obfs-param": params[8].match(/{(.*)}/)[1],
|
"obfs-param": params[8].match(/{(.*)}/)[1],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
function Loon_VMess() {
|
function Loon_VMess() {
|
||||||
@ -1341,7 +1349,7 @@ function Loon_VMess() {
|
|||||||
}
|
}
|
||||||
return proxy;
|
return proxy;
|
||||||
};
|
};
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
function Loon_Trojan() {
|
function Loon_Trojan() {
|
||||||
@ -1372,7 +1380,7 @@ function Loon_Trojan() {
|
|||||||
return proxy;
|
return proxy;
|
||||||
};
|
};
|
||||||
|
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
function Loon_Http() {
|
function Loon_Http() {
|
||||||
@ -1403,7 +1411,7 @@ function Loon_Http() {
|
|||||||
|
|
||||||
return proxy;
|
return proxy;
|
||||||
};
|
};
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************** Surge ***************************************/
|
/**************************** Surge ***************************************/
|
||||||
@ -1433,7 +1441,7 @@ function Surge_SS() {
|
|||||||
}
|
}
|
||||||
return proxy;
|
return proxy;
|
||||||
};
|
};
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
function Surge_VMess() {
|
function Surge_VMess() {
|
||||||
@ -1469,7 +1477,7 @@ function Surge_VMess() {
|
|||||||
}
|
}
|
||||||
return proxy;
|
return proxy;
|
||||||
};
|
};
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
function Surge_Trojan() {
|
function Surge_Trojan() {
|
||||||
@ -1492,7 +1500,7 @@ function Surge_Trojan() {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
function Surge_Http() {
|
function Surge_Http() {
|
||||||
@ -1519,7 +1527,7 @@ function Surge_Http() {
|
|||||||
if (params.password !== "none") proxy.password = params.password;
|
if (params.password !== "none") proxy.password = params.password;
|
||||||
return proxy;
|
return proxy;
|
||||||
};
|
};
|
||||||
return {patternTest, func};
|
return { patternTest, func };
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSurgeParams(line) {
|
function getSurgeParams(line) {
|
||||||
@ -1551,7 +1559,7 @@ function QX_Producer() {
|
|||||||
obfs_opts = `,obfs=${proxy["plugin-opts"].mode},obfs-host=${proxy["plugin-opts"].host}`;
|
obfs_opts = `,obfs=${proxy["plugin-opts"].mode},obfs-host=${proxy["plugin-opts"].host}`;
|
||||||
}
|
}
|
||||||
if (proxy.plugin === "v2ray-plugin") {
|
if (proxy.plugin === "v2ray-plugin") {
|
||||||
const {tls, host, path} = proxy["plugin-opts"];
|
const { tls, host, path } = proxy["plugin-opts"];
|
||||||
obfs_opts = `,obfs=${tls ? "wss" : "ws"},obfs-host=${host}${
|
obfs_opts = `,obfs=${tls ? "wss" : "ws"},obfs-host=${host}${
|
||||||
path ? ",obfs-uri=" + path : ""
|
path ? ",obfs-uri=" + path : ""
|
||||||
}`;
|
}`;
|
||||||
@ -1608,7 +1616,7 @@ function QX_Producer() {
|
|||||||
case "trojan":
|
case "trojan":
|
||||||
return `trojan=${proxy.server}:${proxy.port},password=${
|
return `trojan=${proxy.server}:${proxy.port},password=${
|
||||||
proxy.password
|
proxy.password
|
||||||
},tls-host=${proxy.sni},tls-verification=${
|
}${proxy.sni ? ",tls-host=" + proxy.sni : ""},tls-verification=${
|
||||||
proxy.scert ? "false" : "true"
|
proxy.scert ? "false" : "true"
|
||||||
}${proxy.tfo ? ",fast-open=true" : ",fast-open=false"}${
|
}${proxy.tfo ? ",fast-open=true" : ",fast-open=false"}${
|
||||||
proxy.udp ? ",udp-relay=true" : ",udp-relay=false"
|
proxy.udp ? ",udp-relay=true" : ",udp-relay=false"
|
||||||
@ -1630,7 +1638,7 @@ function QX_Producer() {
|
|||||||
`Platform ${targetPlatform} does not support proxy type: ${proxy.type}`
|
`Platform ${targetPlatform} does not support proxy type: ${proxy.type}`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
return {targetPlatform, output};
|
return { targetPlatform, output };
|
||||||
}
|
}
|
||||||
|
|
||||||
function Loon_Producer() {
|
function Loon_Producer() {
|
||||||
@ -1642,7 +1650,7 @@ function Loon_Producer() {
|
|||||||
obfs_opts = ",,";
|
obfs_opts = ",,";
|
||||||
if (proxy.plugin) {
|
if (proxy.plugin) {
|
||||||
if (proxy.plugin === "obfs") {
|
if (proxy.plugin === "obfs") {
|
||||||
const {mode, host} = proxy["plugin-opts"];
|
const { mode, host } = proxy["plugin-opts"];
|
||||||
obfs_opts = `,${mode},${host}`;
|
obfs_opts = `,${mode},${host}`;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -1671,7 +1679,11 @@ function Loon_Producer() {
|
|||||||
proxy.cipher === "auto" ? "none" : proxy.cipher
|
proxy.cipher === "auto" ? "none" : proxy.cipher
|
||||||
},"${proxy.uuid}",over-tls:${proxy.tls}${obfs_opts}`;
|
},"${proxy.uuid}",over-tls:${proxy.tls}${obfs_opts}`;
|
||||||
case "trojan":
|
case "trojan":
|
||||||
return `${proxy.name}=trojan,${proxy.server},${proxy.port},"${proxy.password}",tls-name:${proxy.sni},skip-cert-verify:${proxy.scert}`;
|
return `${proxy.name}=trojan,${proxy.server},${proxy.port},"${
|
||||||
|
proxy.password
|
||||||
|
}"${proxy.sni ? ",tls-name:" + proxy.sni : ""},skip-cert-verify:${
|
||||||
|
proxy.scert || "false"
|
||||||
|
}`;
|
||||||
case "http":
|
case "http":
|
||||||
tls_opts = "";
|
tls_opts = "";
|
||||||
const base = `${proxy.name}=${proxy.tls ? "http" : "https"},${
|
const base = `${proxy.name}=${proxy.tls ? "http" : "https"},${
|
||||||
@ -1687,7 +1699,7 @@ function Loon_Producer() {
|
|||||||
`Platform ${targetPlatform} does not support proxy type: ${proxy.type}`
|
`Platform ${targetPlatform} does not support proxy type: ${proxy.type}`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
return {targetPlatform, output};
|
return { targetPlatform, output };
|
||||||
}
|
}
|
||||||
|
|
||||||
function Surge_Producer() {
|
function Surge_Producer() {
|
||||||
@ -1730,7 +1742,7 @@ function Surge_Producer() {
|
|||||||
case "trojan":
|
case "trojan":
|
||||||
return `${proxy.name}=trojan,${proxy.server},${proxy.port},password=${
|
return `${proxy.name}=trojan,${proxy.server},${proxy.port},password=${
|
||||||
proxy.password
|
proxy.password
|
||||||
},sni=${proxy.sni},tfo=${proxy.tfo || "false"}`;
|
}${proxy.sni ? ",sni=" + proxy.sni : ""},tfo=${proxy.tfo || "false"}`;
|
||||||
case "http":
|
case "http":
|
||||||
tls_opts = ",tls=false";
|
tls_opts = ",tls=false";
|
||||||
if (proxy.tls) {
|
if (proxy.tls) {
|
||||||
@ -1746,7 +1758,7 @@ function Surge_Producer() {
|
|||||||
`Platform ${targetPlatform} does not support proxy type: ${proxy.type}`
|
`Platform ${targetPlatform} does not support proxy type: ${proxy.type}`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
return {targetPlatform, output};
|
return { targetPlatform, output };
|
||||||
}
|
}
|
||||||
|
|
||||||
function Raw_Producer() {
|
function Raw_Producer() {
|
||||||
@ -1754,7 +1766,7 @@ function Raw_Producer() {
|
|||||||
const output = (proxy) => {
|
const output = (proxy) => {
|
||||||
return JSON.stringify(proxy);
|
return JSON.stringify(proxy);
|
||||||
};
|
};
|
||||||
return {targetPlatform, output};
|
return { targetPlatform, output };
|
||||||
}
|
}
|
||||||
|
|
||||||
function URI_Producer() {
|
function URI_Producer() {
|
||||||
@ -1765,29 +1777,49 @@ function URI_Producer() {
|
|||||||
switch (proxy.type) {
|
switch (proxy.type) {
|
||||||
case "ss":
|
case "ss":
|
||||||
const userinfo = `${proxy.cipher}:${proxy.password}`;
|
const userinfo = `${proxy.cipher}:${proxy.password}`;
|
||||||
result = `ss://${Base64.safeEncode(userinfo)}@${proxy.server}:${proxy.port}/`;
|
result = `ss://${Base64.safeEncode(userinfo)}@${proxy.server}:${
|
||||||
|
proxy.port
|
||||||
|
}/`;
|
||||||
if (proxy.plugin) {
|
if (proxy.plugin) {
|
||||||
result += "?plugin=";
|
result += "?plugin=";
|
||||||
const opts = proxy['plugin-opts'];
|
const opts = proxy["plugin-opts"];
|
||||||
switch (proxy.plugin) {
|
switch (proxy.plugin) {
|
||||||
case "obfs":
|
case "obfs":
|
||||||
result += encodeURIComponent(`simple-obfs;obfs=${opts.mode}${opts.host ? ";obfs-host=" + opts.host : ""}`);
|
result += encodeURIComponent(
|
||||||
break
|
`simple-obfs;obfs=${opts.mode}${
|
||||||
|
opts.host ? ";obfs-host=" + opts.host : ""
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
break;
|
||||||
case "v2ray-plugin":
|
case "v2ray-plugin":
|
||||||
result += encodeURIComponent(`v2ray-plugin;obfs=${opts.mode}${opts.host ? ";obfs-host" + opts.host : ""}${opts.tls ? ";tls" : ""}`);
|
result += encodeURIComponent(
|
||||||
break
|
`v2ray-plugin;obfs=${opts.mode}${
|
||||||
|
opts.host ? ";obfs-host" + opts.host : ""
|
||||||
|
}${opts.tls ? ";tls" : ""}`
|
||||||
|
);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
console.log(`FUCK`);
|
console.log(`FUCK`);
|
||||||
throw new Error(`Unsupported plugin option: ${proxy.plugin}`);
|
throw new Error(`Unsupported plugin option: ${proxy.plugin}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result += `#${encodeURIComponent(proxy.name)}`;
|
result += `#${encodeURIComponent(proxy.name)}`;
|
||||||
break
|
break;
|
||||||
case "ssr":
|
case "ssr":
|
||||||
result = `${proxy.server}:${proxy.port}:${proxy.protocol}:${proxy.cipher}:${proxy.obfs}:${Base64.safeEncode(proxy.password)}/`;
|
result = `${proxy.server}:${proxy.port}:${proxy.protocol}:${
|
||||||
result += `?remarks=${proxy.name}${proxy['obfs-param'] ? "&obfsparam=" + Base64.safeEncode(proxy['obfs-param']) : ""}${proxy['protocol-param'] ? "&protocolparam=" + Base64.safeEncode(proxy['protocol-param']) : ""}`;
|
proxy.cipher
|
||||||
|
}:${proxy.obfs}:${Base64.safeEncode(proxy.password)}/`;
|
||||||
|
result += `?remarks=${proxy.name}${
|
||||||
|
proxy["obfs-param"]
|
||||||
|
? "&obfsparam=" + Base64.safeEncode(proxy["obfs-param"])
|
||||||
|
: ""
|
||||||
|
}${
|
||||||
|
proxy["protocol-param"]
|
||||||
|
? "&protocolparam=" + Base64.safeEncode(proxy["protocol-param"])
|
||||||
|
: ""
|
||||||
|
}`;
|
||||||
result = "vmess://" + Base64.safeEncode(result);
|
result = "vmess://" + Base64.safeEncode(result);
|
||||||
break
|
break;
|
||||||
case "vmess":
|
case "vmess":
|
||||||
// V2RayN URI format
|
// V2RayN URI format
|
||||||
result = {
|
result = {
|
||||||
@ -1798,29 +1830,29 @@ function URI_Producer() {
|
|||||||
type: "",
|
type: "",
|
||||||
aid: 0,
|
aid: 0,
|
||||||
net: proxy.network || "tcp",
|
net: proxy.network || "tcp",
|
||||||
tls: proxy.tls ? "tls" : ""
|
tls: proxy.tls ? "tls" : "",
|
||||||
}
|
};
|
||||||
// obfs
|
// obfs
|
||||||
if (proxy.network === 'ws') {
|
if (proxy.network === "ws") {
|
||||||
result.path = proxy['ws-path'] || "/";
|
result.path = proxy["ws-path"] || "/";
|
||||||
result.host = proxy['ws-headers'].Host || proxy.server;
|
result.host = proxy["ws-headers"].Host || proxy.server;
|
||||||
}
|
}
|
||||||
result = Base64.safeEncode(JSON.stringify(result));
|
result = Base64.safeEncode(JSON.stringify(result));
|
||||||
break
|
break;
|
||||||
case "trojan":
|
case "trojan":
|
||||||
result = `trojan://${proxy.password}@${proxy.server}:${proxy.port}#${proxy.name}`;
|
result = `trojan://${proxy.password}@${proxy.server}:${proxy.port}#${proxy.name}`;
|
||||||
break
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Cannot handle proxy type: ${proxy.type}`);
|
throw new Error(`Cannot handle proxy type: ${proxy.type}`);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
return {targetPlatform, output};
|
return { targetPlatform, output };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************** Operators ***************************************/
|
/**************************** Operators ***************************************/
|
||||||
// force to set some properties (e.g., scert, udp, tfo, etc.)
|
// force to set some properties (e.g., scert, udp, tfo, etc.)
|
||||||
function SetPropertyOperator({key, value}) {
|
function SetPropertyOperator({ key, value }) {
|
||||||
return {
|
return {
|
||||||
name: "Set Property Operator",
|
name: "Set Property Operator",
|
||||||
func: (proxies) => {
|
func: (proxies) => {
|
||||||
@ -1912,7 +1944,7 @@ function KeywordRenameOperator(keywords) {
|
|||||||
name: "Keyword Rename Operator",
|
name: "Keyword Rename Operator",
|
||||||
func: (proxies) => {
|
func: (proxies) => {
|
||||||
return proxies.map((proxy) => {
|
return proxies.map((proxy) => {
|
||||||
for (const {old, now} of keywords) {
|
for (const { old, now } of keywords) {
|
||||||
proxy.name = proxy.name.replaceAll(old, now).trim();
|
proxy.name = proxy.name.replaceAll(old, now).trim();
|
||||||
}
|
}
|
||||||
return proxy;
|
return proxy;
|
||||||
@ -1928,7 +1960,7 @@ function RegexRenameOperator(regex) {
|
|||||||
name: "Regex Rename Operator",
|
name: "Regex Rename Operator",
|
||||||
func: (proxies) => {
|
func: (proxies) => {
|
||||||
return proxies.map((proxy) => {
|
return proxies.map((proxy) => {
|
||||||
for (const {expr, now} of regex) {
|
for (const { expr, now } of regex) {
|
||||||
proxy.name = proxy.name.replace(new RegExp(expr, "g"), now).trim();
|
proxy.name = proxy.name.replace(new RegExp(expr, "g"), now).trim();
|
||||||
}
|
}
|
||||||
return proxy;
|
return proxy;
|
||||||
@ -2003,7 +2035,7 @@ function ScriptOperator(script) {
|
|||||||
|
|
||||||
/**************************** Filters ***************************************/
|
/**************************** Filters ***************************************/
|
||||||
// filter by keywords
|
// filter by keywords
|
||||||
function KeywordFilter({keywords = [], keep = true}) {
|
function KeywordFilter({ keywords = [], keep = true }) {
|
||||||
return {
|
return {
|
||||||
name: "Keyword Filter",
|
name: "Keyword Filter",
|
||||||
func: (proxies) => {
|
func: (proxies) => {
|
||||||
@ -2058,7 +2090,7 @@ function RegionFilter(regions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// filter by regex
|
// filter by regex
|
||||||
function RegexFilter({regex = [], keep = true}) {
|
function RegexFilter({ regex = [], keep = true }) {
|
||||||
return {
|
return {
|
||||||
name: "Regex Filter",
|
name: "Regex Filter",
|
||||||
func: (proxies) => {
|
func: (proxies) => {
|
||||||
@ -2396,21 +2428,21 @@ function ENV() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function HTTP(defaultOptions = {}) {
|
function HTTP(defaultOptions = {}) {
|
||||||
const {isQX, isLoon, isSurge} = ENV();
|
const { isQX, isLoon, isSurge } = ENV();
|
||||||
const methods = ["GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS", "PATCH"];
|
const methods = ["GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS", "PATCH"];
|
||||||
|
|
||||||
function send(method, options) {
|
function send(method, options) {
|
||||||
options = options.hasOwnProperty("url") ? options : {url: options};
|
options = options.hasOwnProperty("url") ? options : { url: options };
|
||||||
options.url = defaultOptions.baseURL ? defaultOptions.baseURL + options.url : options.url;
|
options.url = defaultOptions.baseURL
|
||||||
options = {...defaultOptions, ...options};
|
? defaultOptions.baseURL + options.url
|
||||||
|
: options.url;
|
||||||
|
options = { ...defaultOptions, ...options };
|
||||||
const timeout = options.timeout;
|
const timeout = options.timeout;
|
||||||
const events = {
|
const events = {
|
||||||
...{
|
...{
|
||||||
onRequest: () => {
|
onRequest: () => {},
|
||||||
},
|
|
||||||
onResponse: (resp) => resp,
|
onResponse: (resp) => resp,
|
||||||
onTimeout: () => {
|
onTimeout: () => {},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
...options.events,
|
...options.events,
|
||||||
};
|
};
|
||||||
@ -2419,7 +2451,7 @@ function HTTP(defaultOptions = {}) {
|
|||||||
|
|
||||||
let worker;
|
let worker;
|
||||||
if (isQX) {
|
if (isQX) {
|
||||||
worker = $task.fetch({method, ...options});
|
worker = $task.fetch({ method, ...options });
|
||||||
} else {
|
} else {
|
||||||
worker = new Promise((resolve, reject) => {
|
worker = new Promise((resolve, reject) => {
|
||||||
const request = isSurge || isLoon ? $httpClient : require("request");
|
const request = isSurge || isLoon ? $httpClient : require("request");
|
||||||
@ -2465,7 +2497,7 @@ function HTTP(defaultOptions = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function API(name = "untitled", debug = false) {
|
function API(name = "untitled", debug = false) {
|
||||||
const {isQX, isLoon, isSurge, isNode, isJSBox, isScriptable} = ENV();
|
const { isQX, isLoon, isSurge, isNode, isJSBox, isScriptable } = ENV();
|
||||||
return new (class {
|
return new (class {
|
||||||
constructor(name, debug) {
|
constructor(name, debug) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@ -2513,7 +2545,7 @@ function API(name = "untitled", debug = false) {
|
|||||||
this.node.fs.writeFileSync(
|
this.node.fs.writeFileSync(
|
||||||
fpath,
|
fpath,
|
||||||
JSON.stringify({}),
|
JSON.stringify({}),
|
||||||
{flag: "wx"},
|
{ flag: "wx" },
|
||||||
(err) => console.log(err)
|
(err) => console.log(err)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -2525,7 +2557,7 @@ function API(name = "untitled", debug = false) {
|
|||||||
this.node.fs.writeFileSync(
|
this.node.fs.writeFileSync(
|
||||||
fpath,
|
fpath,
|
||||||
JSON.stringify({}),
|
JSON.stringify({}),
|
||||||
{flag: "wx"},
|
{ flag: "wx" },
|
||||||
(err) => console.log(err)
|
(err) => console.log(err)
|
||||||
);
|
);
|
||||||
this.cache = {};
|
this.cache = {};
|
||||||
@ -2546,13 +2578,13 @@ function API(name = "untitled", debug = false) {
|
|||||||
this.node.fs.writeFileSync(
|
this.node.fs.writeFileSync(
|
||||||
`${this.name}.json`,
|
`${this.name}.json`,
|
||||||
data,
|
data,
|
||||||
{flag: "w"},
|
{ flag: "w" },
|
||||||
(err) => console.log(err)
|
(err) => console.log(err)
|
||||||
);
|
);
|
||||||
this.node.fs.writeFileSync(
|
this.node.fs.writeFileSync(
|
||||||
"root.json",
|
"root.json",
|
||||||
JSON.stringify(this.root),
|
JSON.stringify(this.root),
|
||||||
{flag: "w"},
|
{ flag: "w" },
|
||||||
(err) => console.log(err)
|
(err) => console.log(err)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -2630,7 +2662,7 @@ function API(name = "untitled", debug = false) {
|
|||||||
let opts = {};
|
let opts = {};
|
||||||
if (openURL) opts["openUrl"] = openURL;
|
if (openURL) opts["openUrl"] = openURL;
|
||||||
if (mediaURL) opts["mediaUrl"] = mediaURL;
|
if (mediaURL) opts["mediaUrl"] = mediaURL;
|
||||||
if (JSON.stringify(opts) === '{}') {
|
if (JSON.stringify(opts) === "{}") {
|
||||||
$notification.post(title, subtitle, content);
|
$notification.post(title, subtitle, content);
|
||||||
} else {
|
} else {
|
||||||
$notification.post(title, subtitle, content, opts);
|
$notification.post(title, subtitle, content, opts);
|
||||||
@ -2682,7 +2714,7 @@ function API(name = "untitled", debug = false) {
|
|||||||
|
|
||||||
/*********************************** Mini Express *************************************/
|
/*********************************** Mini Express *************************************/
|
||||||
function express(port = 3000) {
|
function express(port = 3000) {
|
||||||
const {isNode} = ENV();
|
const { isNode } = ENV();
|
||||||
const DEFAULT_HEADERS = {
|
const DEFAULT_HEADERS = {
|
||||||
"Content-Type": "text/plain;charset=UTF-8",
|
"Content-Type": "text/plain;charset=UTF-8",
|
||||||
"Access-Control-Allow-Origin": "*",
|
"Access-Control-Allow-Origin": "*",
|
||||||
@ -2696,9 +2728,9 @@ function express(port = 3000) {
|
|||||||
const express_ = require("express");
|
const express_ = require("express");
|
||||||
const bodyParser = require("body-parser");
|
const bodyParser = require("body-parser");
|
||||||
const app = express_();
|
const app = express_();
|
||||||
app.use(bodyParser.json({verify: rawBodySaver}));
|
app.use(bodyParser.json({ verify: rawBodySaver }));
|
||||||
app.use(bodyParser.urlencoded({verify: rawBodySaver, extended: true}));
|
app.use(bodyParser.urlencoded({ verify: rawBodySaver, extended: true }));
|
||||||
app.use(bodyParser.raw({verify: rawBodySaver, type: "*/*"}));
|
app.use(bodyParser.raw({ verify: rawBodySaver, type: "*/*" }));
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
res.set(DEFAULT_HEADERS);
|
res.set(DEFAULT_HEADERS);
|
||||||
next();
|
next();
|
||||||
@ -2730,19 +2762,19 @@ function express(port = 3000) {
|
|||||||
|
|
||||||
// dispatch url to route
|
// dispatch url to route
|
||||||
const dispatch = (request, start = 0) => {
|
const dispatch = (request, start = 0) => {
|
||||||
let {method, url, headers, body} = request;
|
let { method, url, headers, body } = request;
|
||||||
if (/json/i.test(headers["Content-Type"])) {
|
if (/json/i.test(headers["Content-Type"])) {
|
||||||
body = JSON.parse(body);
|
body = JSON.parse(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
method = method.toUpperCase();
|
method = method.toUpperCase();
|
||||||
const {path, query} = extractURL(url);
|
const { path, query } = extractURL(url);
|
||||||
let handler = null;
|
let handler = null;
|
||||||
let i;
|
let i;
|
||||||
|
|
||||||
for (i = start; i < handlers.length; i++) {
|
for (i = start; i < handlers.length; i++) {
|
||||||
if (handlers[i].method === "ALL" || method === handlers[i].method) {
|
if (handlers[i].method === "ALL" || method === handlers[i].method) {
|
||||||
const {pattern} = handlers[i];
|
const { pattern } = handlers[i];
|
||||||
if (patternMatched(pattern, path)) {
|
if (patternMatched(pattern, path)) {
|
||||||
handler = handlers[i];
|
handler = handlers[i];
|
||||||
break;
|
break;
|
||||||
@ -2786,7 +2818,7 @@ function express(port = 3000) {
|
|||||||
METHODS_NAMES.forEach((method) => {
|
METHODS_NAMES.forEach((method) => {
|
||||||
app[method.toLowerCase()] = (pattern, callback) => {
|
app[method.toLowerCase()] = (pattern, callback) => {
|
||||||
// add handler
|
// add handler
|
||||||
handlers.push({method, pattern, callback});
|
handlers.push({ method, pattern, callback });
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2796,7 +2828,7 @@ function express(port = 3000) {
|
|||||||
METHODS_NAMES.forEach((method) => {
|
METHODS_NAMES.forEach((method) => {
|
||||||
chainApp[method.toLowerCase()] = (callback) => {
|
chainApp[method.toLowerCase()] = (callback) => {
|
||||||
// add handler
|
// add handler
|
||||||
handlers.push({method, pattern, callback});
|
handlers.push({ method, pattern, callback });
|
||||||
return chainApp;
|
return chainApp;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -2821,7 +2853,7 @@ function express(port = 3000) {
|
|||||||
|
|
||||||
function Response() {
|
function Response() {
|
||||||
let statusCode = 200;
|
let statusCode = 200;
|
||||||
const {isQX, isLoon, isSurge} = ENV();
|
const { isQX, isLoon, isSurge } = ENV();
|
||||||
const headers = DEFAULT_HEADERS;
|
const headers = DEFAULT_HEADERS;
|
||||||
const STATUS_CODE_MAP = {
|
const STATUS_CODE_MAP = {
|
||||||
200: "HTTP/1.1 200 OK",
|
200: "HTTP/1.1 200 OK",
|
||||||
|
2
backend/sub-store.min.js
vendored
2
backend/sub-store.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user