1461 lines
44 KiB
HTML
1461 lines
44 KiB
HTML
<%+cbi/valueheader%>
|
|
<script type="text/javascript">
|
|
//<![CDATA[
|
|
function padright(str, cnt, pad) {
|
|
return str + Array(cnt + 1).join(pad);
|
|
}
|
|
|
|
function b64EncodeUnicode(str) {
|
|
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
|
|
return String.fromCharCode('0x' + p1);
|
|
}));
|
|
}
|
|
|
|
function b64encutf8safe(str) {
|
|
return b64EncodeUnicode(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '');
|
|
}
|
|
|
|
function b64DecodeUnicode(str) {
|
|
return decodeURIComponent(Array.prototype.map.call(atob(str), function (c) {
|
|
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
|
}).join(''));
|
|
}
|
|
|
|
function b64decutf8safe(str) {
|
|
var l;
|
|
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
l = str.length;
|
|
l = (4 - l % 4) % 4;
|
|
if (l) str = padright(str, l, "=");
|
|
return b64DecodeUnicode(str);
|
|
}
|
|
|
|
function b64encsafe(str) {
|
|
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '')
|
|
}
|
|
|
|
function b64decsafe(str) {
|
|
var l;
|
|
str = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
l = str.length;
|
|
l = (4 - l % 4) % 4;
|
|
if (l) str = padright(str, l, "=");
|
|
return atob(str);
|
|
}
|
|
|
|
function dictvalue(d, key) {
|
|
var v = d[key];
|
|
if (typeof (v) == 'undefined' || v == '') return '';
|
|
return b64decsafe(v);
|
|
}
|
|
|
|
function parseUrl(url) {
|
|
var m = url.match(/^(([^:\/?#]+:)?(?:\/\/((?:([^\/?#:]*)([^\/?#:]*)@)?([^\/?#:]*)(?::([^\/?#:]*))?)))?([^?#]*)(\?[^#]*)?(#.*)?$/);
|
|
if (!m) return null;
|
|
return {
|
|
hash: m[10] || "",
|
|
host: m[3] || "",
|
|
hostname: m[6] || "",
|
|
href: m[0] || "",
|
|
origin: m[1] || "",
|
|
pathname: m[8] || (m[1] ? "/" : ""),
|
|
port: m[7] || "",
|
|
protocol: m[2] || "",
|
|
search: m[9] || "",
|
|
username: m[4] || "",
|
|
password: m[5] || ""
|
|
};
|
|
}
|
|
|
|
function decodeFragment(fragment) {
|
|
if (!fragment) return '';
|
|
try {
|
|
var decoded = decodeURIComponent(fragment);
|
|
while (decoded !== fragment) {
|
|
fragment = decoded;
|
|
decoded = decodeURIComponent(fragment);
|
|
}
|
|
return fragment;
|
|
} catch (e) {
|
|
return fragment;
|
|
}
|
|
}
|
|
|
|
function parseQuery(search) {
|
|
var query = {};
|
|
if (search && search.length > 1) {
|
|
var params = search.substring(1).split('&');
|
|
for (var i = 0; i < params.length; i++) {
|
|
var eqIndex = params[i].indexOf('=');
|
|
if (eqIndex !== -1) {
|
|
var key = params[i].substring(0, eqIndex);
|
|
var value = params[i].substring(eqIndex + 1);
|
|
try {
|
|
key = decodeURIComponent(key);
|
|
query[key] = value;
|
|
} catch (e) {
|
|
query[key] = value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return query;
|
|
}
|
|
|
|
function setFormValue(sid, field, value) {
|
|
var element = document.getElementsByName('cbid.openclash.' + sid + '.' + field)[0];
|
|
if (element) {
|
|
element.value = value;
|
|
var event = document.createEvent("HTMLEvents");
|
|
event.initEvent("change", true, true);
|
|
element.dispatchEvent(event);
|
|
}
|
|
}
|
|
|
|
function export_url(btn, urlname, sid) {
|
|
var s = document.getElementById(urlname + '-status');
|
|
if (!s) return false;
|
|
|
|
var v_type = document.getElementsByName('cbid.openclash.' + sid + '.type')[0];
|
|
if (!v_type) return false;
|
|
|
|
var type = v_type.value.toLowerCase();
|
|
var url = null;
|
|
|
|
try {
|
|
switch (type) {
|
|
case "ss":
|
|
url = exportSS(sid);
|
|
break;
|
|
case "ssr":
|
|
url = exportSSR(sid);
|
|
break;
|
|
case "vmess":
|
|
url = exportVmess(sid);
|
|
break;
|
|
case "vless":
|
|
url = exportVless(sid);
|
|
break;
|
|
case "trojan":
|
|
url = exportTrojan(sid);
|
|
break;
|
|
case "hysteria":
|
|
url = exportHysteria(sid);
|
|
break;
|
|
case "hysteria2":
|
|
url = exportHysteria2(sid);
|
|
break;
|
|
case "tuic":
|
|
url = exportTuic(sid);
|
|
break;
|
|
case "socks5":
|
|
url = exportSocks(sid);
|
|
break;
|
|
case "http":
|
|
url = exportHttp(sid);
|
|
break;
|
|
case "anytls":
|
|
url = exportAnyTLS(sid);
|
|
break;
|
|
default:
|
|
s.innerHTML = "<font style=\"color:red\"><%:Unsupported protocol type%></font>";
|
|
return false;
|
|
}
|
|
|
|
if (url) {
|
|
var textarea = document.createElement("textarea");
|
|
textarea.textContent = url;
|
|
textarea.style.position = "fixed";
|
|
document.body.appendChild(textarea);
|
|
textarea.select();
|
|
try {
|
|
document.execCommand("copy");
|
|
s.innerHTML = "<font style=\"color:green\"><%:Copy%> " + type.toUpperCase() + " <%:to clipboard successfully%></font>";
|
|
} catch (ex) {
|
|
s.innerHTML = "<font style=\"color:red\"><%:Unable to copy%> " + type.toUpperCase() + " <%:to clipboard%></font>";
|
|
} finally {
|
|
document.body.removeChild(textarea);
|
|
}
|
|
} else {
|
|
s.innerHTML = "<font style=\"color:red\"><%:Export failed%></font>";
|
|
}
|
|
} catch (e) {
|
|
s.innerHTML = "<font style=\"color:red\"><%:Export error%></font>";
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function getFormValue(sid, field) {
|
|
var element = document.getElementsByName('cbid.openclash.' + sid + '.' + field)[0];
|
|
return element ? element.value : '';
|
|
}
|
|
|
|
function exportSS(sid) {
|
|
var server = getFormValue(sid, 'server');
|
|
var port = getFormValue(sid, 'port');
|
|
var password = getFormValue(sid, 'password');
|
|
var cipher = getFormValue(sid, 'cipher');
|
|
var name = getFormValue(sid, 'name');
|
|
var obfs = getFormValue(sid, 'obfs');
|
|
var host = getFormValue(sid, 'host');
|
|
var path = getFormValue(sid, 'path');
|
|
var tls = getFormValue(sid, 'tls');
|
|
|
|
if (!server || !port || !password || !cipher) {
|
|
return null;
|
|
}
|
|
|
|
// SIP002 format
|
|
var userInfo = b64encsafe(cipher + ':' + password);
|
|
var url = userInfo + '@' + server + ':' + port + '/?';
|
|
|
|
var params = [];
|
|
|
|
if (obfs && obfs !== 'none') {
|
|
var plugin = '';
|
|
if (obfs === 'http' || obfs === 'tls') {
|
|
plugin = 'obfs-local;obfs=' + obfs;
|
|
if (host) {
|
|
plugin += ';obfs-host=' + host;
|
|
}
|
|
} else if (obfs === 'websocket') {
|
|
plugin = 'v2ray-plugin;mode=websocket';
|
|
if (host) {
|
|
plugin += ';host=' + host;
|
|
}
|
|
if (path) {
|
|
plugin += ';path=' + path;
|
|
}
|
|
if (tls === 'true') {
|
|
plugin += ';tls=true';
|
|
}
|
|
}
|
|
if (plugin) {
|
|
params.push('plugin=' + encodeURIComponent(plugin));
|
|
}
|
|
}
|
|
|
|
url += params.join('&');
|
|
|
|
if (name) {
|
|
url += '#' + encodeURIComponent(name);
|
|
}
|
|
|
|
return 'ss://' + url;
|
|
}
|
|
|
|
function exportSSR(sid) {
|
|
var server = getFormValue(sid, 'server');
|
|
var port = getFormValue(sid, 'port');
|
|
var protocol = getFormValue(sid, 'protocol');
|
|
var method = getFormValue(sid, 'cipher_ssr');
|
|
var obfs = getFormValue(sid, 'obfs_ssr');
|
|
var password = getFormValue(sid, 'password');
|
|
var obfs_param = getFormValue(sid, 'obfs_param');
|
|
var protocol_param = getFormValue(sid, 'protocol_param');
|
|
var name = getFormValue(sid, 'name');
|
|
|
|
if (!server || !port || !password || !method) {
|
|
return null;
|
|
}
|
|
|
|
var ssr_str = server + ":" + port + ":" + protocol + ":" + method + ":" + obfs + ":" +
|
|
b64encsafe(password) + "/?obfsparam=" + b64encsafe(obfs_param) +
|
|
"&protoparam=" + b64encsafe(protocol_param) + "&remarks=" + b64encutf8safe(name);
|
|
|
|
return "ssr://" + b64encsafe(ssr_str);
|
|
}
|
|
|
|
function exportVmess(sid) {
|
|
var server = getFormValue(sid, 'server');
|
|
var port = getFormValue(sid, 'port');
|
|
var uuid = getFormValue(sid, 'uuid');
|
|
var alterId = getFormValue(sid, 'alterId');
|
|
var security = getFormValue(sid, 'securitys');
|
|
var name = getFormValue(sid, 'name');
|
|
var obfs = getFormValue(sid, 'obfs_vmess');
|
|
var tls = getFormValue(sid, 'tls');
|
|
var servername = getFormValue(sid, 'servername');
|
|
|
|
if (!server || !port || !uuid) {
|
|
return null;
|
|
}
|
|
|
|
var info = {
|
|
"v": "2",
|
|
"ps": name || "",
|
|
"add": server,
|
|
"port": port,
|
|
"id": uuid,
|
|
"aid": alterId || "0",
|
|
"scy": security || "auto",
|
|
"net": "tcp",
|
|
"type": "none",
|
|
"host": "",
|
|
"path": "",
|
|
"tls": tls === 'true' ? "tls" : ""
|
|
};
|
|
|
|
if (tls === 'true' && servername) {
|
|
info.sni = servername;
|
|
}
|
|
|
|
// Handle network type
|
|
if (obfs === 'websocket') {
|
|
info.net = "ws";
|
|
info.path = getFormValue(sid, 'ws_opts_path') || '/';
|
|
var headers = getFormValue(sid, 'ws_opts_headers');
|
|
if (headers && headers.includes('Host:')) {
|
|
info.host = headers.split('Host:')[1].trim();
|
|
}
|
|
} else if (obfs === 'h2') {
|
|
info.net = "h2";
|
|
info.path = getFormValue(sid, 'h2_path') || '/';
|
|
info.host = getFormValue(sid, 'h2_host') || '';
|
|
} else if (obfs === 'grpc') {
|
|
info.net = "grpc";
|
|
info.path = getFormValue(sid, 'grpc_service_name') || '';
|
|
}
|
|
|
|
return "vmess://" + b64EncodeUnicode(JSON.stringify(info));
|
|
}
|
|
|
|
function exportVless(sid) {
|
|
var server = getFormValue(sid, 'server');
|
|
var port = getFormValue(sid, 'port');
|
|
var uuid = getFormValue(sid, 'uuid');
|
|
var name = getFormValue(sid, 'name');
|
|
var tls = getFormValue(sid, 'tls');
|
|
var servername = getFormValue(sid, 'servername');
|
|
var obfs = getFormValue(sid, 'obfs_vless');
|
|
var flow = getFormValue(sid, 'vless_flow');
|
|
|
|
if (!server || !port || !uuid) {
|
|
return null;
|
|
}
|
|
|
|
var url = uuid + '@' + server + ':' + port + '?';
|
|
var params = [];
|
|
|
|
params.push('encryption=none');
|
|
|
|
if (tls === 'true') {
|
|
if (flow && flow.includes('xtls')) {
|
|
params.push('security=xtls');
|
|
params.push('flow=' + flow);
|
|
} else {
|
|
params.push('security=tls');
|
|
}
|
|
if (servername) {
|
|
params.push('sni=' + encodeURIComponent(servername));
|
|
}
|
|
}
|
|
|
|
if (obfs === 'ws') {
|
|
params.push('type=ws');
|
|
var path = getFormValue(sid, 'ws_opts_path');
|
|
if (path) {
|
|
params.push('path=' + encodeURIComponent(path));
|
|
}
|
|
var headers = getFormValue(sid, 'ws_opts_headers');
|
|
if (headers && headers.includes('Host:')) {
|
|
var host = headers.split('Host:')[1].trim();
|
|
params.push('host=' + encodeURIComponent(host));
|
|
}
|
|
} else if (obfs === 'grpc') {
|
|
params.push('type=grpc');
|
|
var serviceName = getFormValue(sid, 'grpc_service_name');
|
|
if (serviceName) {
|
|
params.push('serviceName=' + encodeURIComponent(serviceName));
|
|
}
|
|
} else {
|
|
params.push('type=tcp');
|
|
}
|
|
|
|
url += params.join('&');
|
|
|
|
if (name) {
|
|
url += '#' + encodeURIComponent(name);
|
|
}
|
|
|
|
return 'vless://' + url;
|
|
}
|
|
|
|
function exportTrojan(sid) {
|
|
var server = getFormValue(sid, 'server');
|
|
var port = getFormValue(sid, 'port');
|
|
var password = getFormValue(sid, 'password');
|
|
var name = getFormValue(sid, 'name');
|
|
var sni = getFormValue(sid, 'sni');
|
|
var alpn = getFormValue(sid, 'alpn');
|
|
var skip_cert = getFormValue(sid, 'skip_cert_verify');
|
|
|
|
if (!server || !port || !password) {
|
|
return null;
|
|
}
|
|
|
|
var url = encodeURIComponent(password) + '@' + server + ':' + port + '/?';
|
|
var params = [];
|
|
|
|
if (sni) {
|
|
params.push('sni=' + encodeURIComponent(sni));
|
|
}
|
|
|
|
if (alpn) {
|
|
params.push('alpn=' + encodeURIComponent(alpn));
|
|
}
|
|
|
|
if (skip_cert === 'true') {
|
|
params.push('allowInsecure=1');
|
|
}
|
|
|
|
url += params.join('&');
|
|
|
|
if (name) {
|
|
url += '#' + encodeURIComponent(name);
|
|
}
|
|
|
|
return 'trojan://' + url;
|
|
}
|
|
|
|
function exportHysteria(sid) {
|
|
var server = getFormValue(sid, 'server');
|
|
var port = getFormValue(sid, 'port');
|
|
var auth = getFormValue(sid, 'hysteria_auth_str');
|
|
var name = getFormValue(sid, 'name');
|
|
var protocol = getFormValue(sid, 'hysteria_protocol');
|
|
var up = getFormValue(sid, 'hysteria_up');
|
|
var down = getFormValue(sid, 'hysteria_down');
|
|
var obfs = getFormValue(sid, 'hysteria_obfs');
|
|
var sni = getFormValue(sid, 'sni');
|
|
var alpn = getFormValue(sid, 'hysteria_alpn');
|
|
var skip_cert = getFormValue(sid, 'skip_cert_verify');
|
|
|
|
if (!server || !port) {
|
|
return null;
|
|
}
|
|
|
|
var url = server + ':' + port + '?';
|
|
var params = [];
|
|
|
|
if (auth) {
|
|
params.push('auth=' + encodeURIComponent(auth));
|
|
}
|
|
|
|
if (protocol) {
|
|
params.push('protocol=' + protocol);
|
|
}
|
|
|
|
if (up) {
|
|
params.push('up=' + up);
|
|
}
|
|
|
|
if (down) {
|
|
params.push('down=' + down);
|
|
}
|
|
|
|
if (obfs) {
|
|
params.push('obfsParam=' + encodeURIComponent(obfs));
|
|
}
|
|
|
|
if (sni) {
|
|
params.push('peer=' + encodeURIComponent(sni));
|
|
}
|
|
|
|
if (alpn) {
|
|
params.push('alpn=' + encodeURIComponent(alpn));
|
|
}
|
|
|
|
if (skip_cert === 'true') {
|
|
params.push('insecure=1');
|
|
}
|
|
|
|
url += params.join('&');
|
|
|
|
if (name) {
|
|
url += '#' + encodeURIComponent(name);
|
|
}
|
|
|
|
return 'hysteria://' + url;
|
|
}
|
|
|
|
function exportHysteria2(sid) {
|
|
var server = getFormValue(sid, 'server');
|
|
var port = getFormValue(sid, 'port');
|
|
var password = getFormValue(sid, 'password');
|
|
var name = getFormValue(sid, 'name');
|
|
var obfs = getFormValue(sid, 'hysteria_obfs');
|
|
var obfs_password = getFormValue(sid, 'hysteria_obfs_password');
|
|
var up = getFormValue(sid, 'hysteria_up');
|
|
var down = getFormValue(sid, 'hysteria_down');
|
|
var sni = getFormValue(sid, 'sni');
|
|
var alpn = getFormValue(sid, 'hysteria_alpn');
|
|
var skip_cert = getFormValue(sid, 'skip_cert_verify');
|
|
|
|
if (!server || !port) {
|
|
return null;
|
|
}
|
|
|
|
var url = '';
|
|
if (password) {
|
|
url += encodeURIComponent(password) + '@';
|
|
}
|
|
url += server + ':' + port + '?';
|
|
|
|
var params = [];
|
|
|
|
if (obfs) {
|
|
params.push('obfs=' + encodeURIComponent(obfs));
|
|
}
|
|
|
|
if (obfs_password) {
|
|
params.push('obfs-password=' + encodeURIComponent(obfs_password));
|
|
}
|
|
|
|
if (up) {
|
|
params.push('up=' + up);
|
|
}
|
|
|
|
if (down) {
|
|
params.push('down=' + down);
|
|
}
|
|
|
|
if (sni) {
|
|
params.push('sni=' + encodeURIComponent(sni));
|
|
}
|
|
|
|
if (alpn) {
|
|
params.push('alpn=' + encodeURIComponent(alpn));
|
|
}
|
|
|
|
if (skip_cert === 'true') {
|
|
params.push('insecure=1');
|
|
}
|
|
|
|
url += params.join('&');
|
|
|
|
if (name) {
|
|
url += '#' + encodeURIComponent(name);
|
|
}
|
|
|
|
return 'hysteria2://' + url;
|
|
}
|
|
|
|
function exportTuic(sid) {
|
|
var server = getFormValue(sid, 'server');
|
|
var port = getFormValue(sid, 'port');
|
|
var uuid = getFormValue(sid, 'uuid');
|
|
var password = getFormValue(sid, 'password');
|
|
var token = getFormValue(sid, 'tc_token');
|
|
var name = getFormValue(sid, 'name');
|
|
var cc = getFormValue(sid, 'congestion_controller');
|
|
var alpn = getFormValue(sid, 'tc_alpn');
|
|
var sni = getFormValue(sid, 'sni');
|
|
var disable_sni = getFormValue(sid, 'disable_sni');
|
|
var udp_relay = getFormValue(sid, 'udp_relay_mode');
|
|
|
|
if (!server || !port) {
|
|
return null;
|
|
}
|
|
|
|
var url = '';
|
|
if (password) {
|
|
// TUIC v5
|
|
url += encodeURIComponent(uuid) + ':' + encodeURIComponent(password) + '@';
|
|
} else if (token) {
|
|
// TUIC v4
|
|
url += encodeURIComponent(token) + '@';
|
|
}
|
|
|
|
url += server + ':' + port + '?';
|
|
|
|
var params = [];
|
|
|
|
if (cc) {
|
|
params.push('congestion_control=' + encodeURIComponent(cc));
|
|
}
|
|
|
|
if (alpn) {
|
|
params.push('alpn=' + encodeURIComponent(alpn));
|
|
}
|
|
|
|
if (sni) {
|
|
params.push('sni=' + encodeURIComponent(sni));
|
|
}
|
|
|
|
if (disable_sni === 'true') {
|
|
params.push('disable_sni=1');
|
|
}
|
|
|
|
if (udp_relay) {
|
|
params.push('udp_relay_mode=' + encodeURIComponent(udp_relay));
|
|
}
|
|
|
|
url += params.join('&');
|
|
|
|
if (name) {
|
|
url += '#' + encodeURIComponent(name);
|
|
}
|
|
|
|
return 'tuic://' + url;
|
|
}
|
|
|
|
function exportSocks(sid) {
|
|
var server = getFormValue(sid, 'server');
|
|
var port = getFormValue(sid, 'port');
|
|
var username = getFormValue(sid, 'auth_name');
|
|
var password = getFormValue(sid, 'auth_pass');
|
|
var name = getFormValue(sid, 'name');
|
|
|
|
if (!server || !port) {
|
|
return null;
|
|
}
|
|
|
|
var url = '';
|
|
if (username && password) {
|
|
url += encodeURIComponent(username) + ':' + encodeURIComponent(password) + '@';
|
|
}
|
|
url += server + ':' + port;
|
|
|
|
if (name) {
|
|
url += '#' + encodeURIComponent(name);
|
|
}
|
|
|
|
return 'socks5://' + url;
|
|
}
|
|
|
|
function exportHttp(sid) {
|
|
var server = getFormValue(sid, 'server');
|
|
var port = getFormValue(sid, 'port');
|
|
var username = getFormValue(sid, 'auth_name');
|
|
var password = getFormValue(sid, 'auth_pass');
|
|
var name = getFormValue(sid, 'name');
|
|
var tls = getFormValue(sid, 'tls');
|
|
|
|
if (!server || !port) {
|
|
return null;
|
|
}
|
|
|
|
var scheme = tls === 'true' ? 'https' : 'http';
|
|
var url = '';
|
|
|
|
if (username && password) {
|
|
url += encodeURIComponent(username) + ':' + encodeURIComponent(password) + '@';
|
|
}
|
|
url += server + ':' + port;
|
|
|
|
if (name) {
|
|
url += '#' + encodeURIComponent(name);
|
|
}
|
|
|
|
return scheme + '://' + url;
|
|
}
|
|
|
|
function exportAnyTLS(sid) {
|
|
var server = getFormValue(sid, 'server');
|
|
var port = getFormValue(sid, 'port');
|
|
var username = getFormValue(sid, 'auth_name');
|
|
var password = getFormValue(sid, 'password');
|
|
var name = getFormValue(sid, 'name');
|
|
var sni = getFormValue(sid, 'sni');
|
|
var fingerprint = getFormValue(sid, 'fingerprint');
|
|
var skip_cert = getFormValue(sid, 'skip_cert_verify');
|
|
|
|
if (!server || !port) {
|
|
return null;
|
|
}
|
|
|
|
var url = '';
|
|
if (username) {
|
|
url += encodeURIComponent(username);
|
|
if (password) {
|
|
url += ':' + encodeURIComponent(password);
|
|
}
|
|
url += '@';
|
|
}
|
|
url += server + ':' + port + '?';
|
|
|
|
var params = [];
|
|
|
|
if (sni) {
|
|
params.push('sni=' + encodeURIComponent(sni));
|
|
}
|
|
|
|
if (fingerprint) {
|
|
params.push('hpkp=' + encodeURIComponent(fingerprint));
|
|
}
|
|
|
|
if (skip_cert === 'true') {
|
|
params.push('insecure=1');
|
|
}
|
|
|
|
url += params.join('&');
|
|
|
|
if (name) {
|
|
url += '#' + encodeURIComponent(name);
|
|
}
|
|
|
|
return 'anytls://' + url;
|
|
}
|
|
|
|
function import_url(btn, urlname, sid) {
|
|
var s = document.getElementById(urlname + '-status');
|
|
if (!s) return false;
|
|
|
|
var ssrurl = prompt("<%:Paste sharing link here%>", "");
|
|
if (ssrurl == null || ssrurl == "") {
|
|
s.innerHTML = "<font style=\"color:red\"><%:User cancelled%></font>";
|
|
return false;
|
|
}
|
|
s.innerHTML = "";
|
|
|
|
var ssu = ssrurl.split('://');
|
|
if (ssu.length < 2) {
|
|
s.innerHTML = "<font style=\"color:red\"><%:Invalid format%></font>";
|
|
return false;
|
|
}
|
|
|
|
var scheme = ssu[0].toLowerCase();
|
|
var event = document.createEvent("HTMLEvents");
|
|
event.initEvent("change", true, true);
|
|
|
|
try {
|
|
switch (scheme) {
|
|
case "ss":
|
|
if (parseSS(ssu[1], sid)) {
|
|
s.innerHTML = "<font style=\"color:green\"><%:Import configuration information successfully%></font>";
|
|
} else {
|
|
s.innerHTML = "<font style=\"color:red\"><%:Invalid format%></font>";
|
|
}
|
|
break;
|
|
|
|
case "ssr":
|
|
if (parseSSR(ssu[1], sid)) {
|
|
s.innerHTML = "<font style=\"color:green\"><%:Import configuration information successfully%></font>";
|
|
} else {
|
|
s.innerHTML = "<font style=\"color:red\"><%:Invalid format%></font>";
|
|
}
|
|
break;
|
|
|
|
case "vmess":
|
|
if (parseVmess(ssu[1], sid)) {
|
|
s.innerHTML = "<font style=\"color:green\"><%:Import configuration information successfully%></font>";
|
|
} else {
|
|
s.innerHTML = "<font style=\"color:red\"><%:Invalid format%></font>";
|
|
}
|
|
break;
|
|
|
|
case "vless":
|
|
if (parseVless(ssrurl, sid)) {
|
|
s.innerHTML = "<font style=\"color:green\"><%:Import configuration information successfully%></font>";
|
|
} else {
|
|
s.innerHTML = "<font style=\"color:red\"><%:Invalid format%></font>";
|
|
}
|
|
break;
|
|
|
|
case "trojan":
|
|
if (parseTrojan(ssrurl, sid)) {
|
|
s.innerHTML = "<font style=\"color:green\"><%:Import configuration information successfully%></font>";
|
|
} else {
|
|
s.innerHTML = "<font style=\"color:red\"><%:Invalid format%></font>";
|
|
}
|
|
break;
|
|
|
|
case "hysteria":
|
|
if (parseHysteria(ssrurl, sid)) {
|
|
s.innerHTML = "<font style=\"color:green\"><%:Import configuration information successfully%></font>";
|
|
} else {
|
|
s.innerHTML = "<font style=\"color:red\"><%:Invalid format%></font>";
|
|
}
|
|
break;
|
|
|
|
case "hysteria2":
|
|
case "hy2":
|
|
if (parseHysteria2(ssrurl, sid)) {
|
|
s.innerHTML = "<font style=\"color:green\"><%:Import configuration information successfully%></font>";
|
|
} else {
|
|
s.innerHTML = "<font style=\"color:red\"><%:Invalid format%></font>";
|
|
}
|
|
break;
|
|
|
|
case "tuic":
|
|
if (parseTuic(ssrurl, sid)) {
|
|
s.innerHTML = "<font style=\"color:green\"><%:Import configuration information successfully%></font>";
|
|
} else {
|
|
s.innerHTML = "<font style=\"color:red\"><%:Invalid format%></font>";
|
|
}
|
|
break;
|
|
|
|
case "socks":
|
|
case "socks5":
|
|
case "socks5h":
|
|
if (parseSocks(ssrurl, sid)) {
|
|
s.innerHTML = "<font style=\"color:green\"><%:Import configuration information successfully%></font>";
|
|
} else {
|
|
s.innerHTML = "<font style=\"color:red\"><%:Invalid format%></font>";
|
|
}
|
|
break;
|
|
|
|
case "http":
|
|
case "https":
|
|
if (parseHttp(ssrurl, sid)) {
|
|
s.innerHTML = "<font style=\"color:green\"><%:Import configuration information successfully%></font>";
|
|
} else {
|
|
s.innerHTML = "<font style=\"color:red\"><%:Invalid format%></font>";
|
|
}
|
|
break;
|
|
|
|
case "anytls":
|
|
if (parseAnyTLS(ssrurl, sid)) {
|
|
s.innerHTML = "<font style=\"color:green\"><%:Import configuration information successfully%></font>";
|
|
} else {
|
|
s.innerHTML = "<font style=\"color:red\"><%:Invalid format%></font>";
|
|
}
|
|
break;
|
|
|
|
default:
|
|
s.innerHTML = "<font style=\"color:red\"><%:Invalid format%></font>";
|
|
return false;
|
|
}
|
|
} catch (e) {
|
|
s.innerHTML = "<font style=\"color:red\"><%:Parse error%></font>";
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function parseSS(body, sid) {
|
|
var url0, param = "";
|
|
var sipIndex = body.indexOf("@");
|
|
var ploc = body.indexOf("#");
|
|
|
|
if (ploc > 0) {
|
|
url0 = body.substr(0, ploc);
|
|
param = body.substr(ploc + 1);
|
|
} else {
|
|
url0 = body;
|
|
}
|
|
|
|
setFormValue(sid, 'type', 'ss');
|
|
|
|
if (sipIndex !== -1) {
|
|
// SIP002 format
|
|
var userInfo = b64decsafe(url0.substr(0, sipIndex));
|
|
var temp = url0.substr(sipIndex + 1).split("/?");
|
|
var serverInfo = temp[0].split(":");
|
|
var server = serverInfo[0];
|
|
var port = serverInfo[1];
|
|
var method, password;
|
|
|
|
if (temp[1]) {
|
|
var query = parseQuery("?" + temp[1]);
|
|
|
|
if (query.plugin) {
|
|
var decodedPlugin = decodeURIComponent(query.plugin);
|
|
|
|
var pluginParts = decodedPlugin.split(';');
|
|
var pluginName = pluginParts[0];
|
|
|
|
// obfs-local
|
|
if (pluginName === 'obfs-local' || pluginName.includes('obfs')) {
|
|
var obfsMode = 'http';
|
|
var obfsHost = '';
|
|
|
|
for (var i = 1; i < pluginParts.length; i++) {
|
|
var opt = pluginParts[i];
|
|
var eqIndex = opt.indexOf('=');
|
|
if (eqIndex !== -1) {
|
|
var key = opt.substring(0, eqIndex).trim();
|
|
var value = opt.substring(eqIndex + 1).trim();
|
|
|
|
if (key === 'obfs') {
|
|
obfsMode = value;
|
|
} else if (key === 'obfs-host') {
|
|
obfsHost = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
setFormValue(sid, 'obfs', obfsMode);
|
|
if (obfsHost) {
|
|
setFormValue(sid, 'host', obfsHost);
|
|
}
|
|
}
|
|
|
|
// v2ray-plugin
|
|
if (pluginName === 'v2ray-plugin') {
|
|
var v2rayMode = 'websocket';
|
|
var v2rayHost = '';
|
|
var v2rayPath = '/';
|
|
var v2rayTls = false;
|
|
|
|
for (var i = 1; i < pluginParts.length; i++) {
|
|
var opt = pluginParts[i];
|
|
var eqIndex = opt.indexOf('=');
|
|
if (eqIndex !== -1) {
|
|
var key = opt.substring(0, eqIndex).trim();
|
|
var value = opt.substring(eqIndex + 1).trim();
|
|
|
|
if (key === 'mode') {
|
|
v2rayMode = value;
|
|
} else if (key === 'host') {
|
|
v2rayHost = value;
|
|
} else if (key === 'path') {
|
|
v2rayPath = value;
|
|
} else if (key === 'tls') {
|
|
v2rayTls = value === 'true' || value === '1';
|
|
}
|
|
}
|
|
}
|
|
|
|
setFormValue(sid, 'obfs', 'websocket');
|
|
if (v2rayHost) {
|
|
setFormValue(sid, 'host', v2rayHost);
|
|
}
|
|
if (v2rayPath) {
|
|
setFormValue(sid, 'path', v2rayPath);
|
|
}
|
|
if (v2rayTls) {
|
|
setFormValue(sid, 'tls', 'true');
|
|
}
|
|
}
|
|
}
|
|
|
|
if (query['udp-over-tcp'] === 'true' || query['uot'] === '1') {
|
|
setFormValue(sid, 'udp_over_tcp', 'true');
|
|
}
|
|
}
|
|
|
|
var userInfoSplitIndex = userInfo.indexOf(":");
|
|
if (userInfoSplitIndex !== -1) {
|
|
method = userInfo.substr(0, userInfoSplitIndex);
|
|
password = userInfo.substr(userInfoSplitIndex + 1);
|
|
}
|
|
|
|
setFormValue(sid, 'server', server);
|
|
setFormValue(sid, 'port', port);
|
|
setFormValue(sid, 'password', password || "");
|
|
setFormValue(sid, 'cipher', method || "");
|
|
} else {
|
|
// Legacy format
|
|
var sstr = b64decsafe(url0);
|
|
var team = sstr.split('@');
|
|
var part1 = team[0].split(':');
|
|
var part2 = team[1].split(':');
|
|
|
|
setFormValue(sid, 'server', part2[0]);
|
|
setFormValue(sid, 'port', part2[1]);
|
|
setFormValue(sid, 'password', part1[1]);
|
|
setFormValue(sid, 'cipher', part1[0]);
|
|
}
|
|
|
|
if (param) {
|
|
setFormValue(sid, 'name', decodeURIComponent(param));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function parseSSR(body, sid) {
|
|
var dcBuf;
|
|
try {
|
|
dcBuf = b64decsafe(body);
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
|
|
setFormValue(sid, 'type', 'ssr');
|
|
|
|
// ssr://host:port:protocol:method:obfs:urlsafebase64pass/?obfsparam=...
|
|
var before, after;
|
|
var queryIndex = dcBuf.indexOf('/?');
|
|
if (queryIndex > 0) {
|
|
before = dcBuf.substr(0, queryIndex);
|
|
after = dcBuf.substr(queryIndex + 2);
|
|
} else {
|
|
before = dcBuf;
|
|
after = "";
|
|
}
|
|
|
|
var parts = before.split(':');
|
|
if (parts.length !== 6) {
|
|
return false;
|
|
}
|
|
|
|
var host = parts[0];
|
|
var port = parts[1];
|
|
var protocol = parts[2];
|
|
var method = parts[3];
|
|
var obfs = parts[4];
|
|
var password = b64decsafe(parts[5]);
|
|
|
|
setFormValue(sid, 'server', host);
|
|
setFormValue(sid, 'port', port);
|
|
setFormValue(sid, 'protocol', protocol);
|
|
setFormValue(sid, 'cipher_ssr', method);
|
|
setFormValue(sid, 'obfs_ssr', obfs);
|
|
setFormValue(sid, 'password', password);
|
|
|
|
if (after) {
|
|
var params = {};
|
|
var paramPairs = after.split('&');
|
|
for (var i = 0; i < paramPairs.length; i++) {
|
|
var pair = paramPairs[i].split('=');
|
|
if (pair.length === 2) {
|
|
var key = decodeURIComponent(pair[0]);
|
|
var value = pair[1];
|
|
params[key] = value;
|
|
}
|
|
}
|
|
|
|
if (params.obfsparam) {
|
|
setFormValue(sid, 'obfs_param', b64decsafe(params.obfsparam));
|
|
}
|
|
|
|
if (params.protoparam) {
|
|
setFormValue(sid, 'protocol_param', b64decsafe(params.protoparam));
|
|
}
|
|
|
|
if (params.remarks) {
|
|
setFormValue(sid, 'name', b64decutf8safe(params.remarks));
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function parseVmess(body, sid) {
|
|
try {
|
|
// Try V2rayN format first
|
|
var sstr = b64DecodeUnicode(body);
|
|
var ssm = JSON.parse(sstr);
|
|
|
|
setFormValue(sid, 'type', 'vmess');
|
|
setFormValue(sid, 'name', ssm.ps || '');
|
|
setFormValue(sid, 'server', ssm.add);
|
|
setFormValue(sid, 'port', ssm.port);
|
|
setFormValue(sid, 'alterId', ssm.aid || 0);
|
|
setFormValue(sid, 'uuid', ssm.id);
|
|
|
|
if (ssm.scy) {
|
|
setFormValue(sid, 'securitys', ssm.scy);
|
|
}
|
|
|
|
if (ssm.tls === "tls") {
|
|
setFormValue(sid, 'tls', 'true');
|
|
if (ssm.sni) {
|
|
setFormValue(sid, 'servername', ssm.sni);
|
|
}
|
|
}
|
|
|
|
var network = (ssm.net || 'tcp').toLowerCase();
|
|
if (network === 'ws') {
|
|
setFormValue(sid, 'obfs_vmess', 'websocket');
|
|
setFormValue(sid, 'ws_opts_path', ssm.path || '/');
|
|
if (ssm.host) {
|
|
setFormValue(sid, 'ws_opts_headers', 'Host: ' + ssm.host);
|
|
}
|
|
} else if (network === 'h2') {
|
|
setFormValue(sid, 'obfs_vmess', 'h2');
|
|
setFormValue(sid, 'h2_path', ssm.path || '/');
|
|
if (ssm.host) {
|
|
setFormValue(sid, 'h2_host', ssm.host);
|
|
}
|
|
} else if (network === 'tcp') {
|
|
if (ssm.type === 'http') {
|
|
setFormValue(sid, 'obfs_vmess', 'http');
|
|
if (ssm.path) {
|
|
setFormValue(sid, 'http_path', ssm.path);
|
|
}
|
|
if (ssm.host) {
|
|
setFormValue(sid, 'http_host', ssm.host);
|
|
}
|
|
} else {
|
|
setFormValue(sid, 'obfs_vmess', 'none');
|
|
}
|
|
} else if (network === 'grpc') {
|
|
setFormValue(sid, 'obfs_vmess', 'grpc');
|
|
setFormValue(sid, 'grpc_service_name', ssm.path || '');
|
|
}
|
|
|
|
return true;
|
|
} catch (e) {
|
|
// Try Xray VMessAEAD format
|
|
try {
|
|
var parsed = parseUrl('vmess://' + body);
|
|
if (!parsed) return false;
|
|
|
|
var query = parseQuery(parsed.search);
|
|
|
|
setFormValue(sid, 'type', 'vmess');
|
|
setFormValue(sid, 'server', parsed.hostname);
|
|
setFormValue(sid, 'port', parsed.port || '443');
|
|
setFormValue(sid, 'uuid', parsed.username);
|
|
setFormValue(sid, 'alterId', 0);
|
|
setFormValue(sid, 'securitys', query.encryption || 'auto');
|
|
|
|
if (parsed.hash) {
|
|
setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1)));
|
|
}
|
|
|
|
return true;
|
|
} catch (e2) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
function parseVless(url, sid) {
|
|
var parsed = parseUrl(url);
|
|
if (!parsed) return false;
|
|
|
|
var query = parseQuery(parsed.search);
|
|
|
|
setFormValue(sid, 'type', 'vless');
|
|
setFormValue(sid, 'server', parsed.hostname);
|
|
setFormValue(sid, 'port', parsed.port || '443');
|
|
setFormValue(sid, 'uuid', parsed.username);
|
|
|
|
if (query.security) {
|
|
if (query.security === 'tls' || query.security === 'xtls') {
|
|
setFormValue(sid, 'tls', 'true');
|
|
if (query.sni) {
|
|
setFormValue(sid, 'servername', decodeURIComponent(query.sni));
|
|
}
|
|
if (query.security === 'xtls') {
|
|
setFormValue(sid, 'vless_flow', query.flow || 'xtls-rprx-direct');
|
|
}
|
|
} else if (query.security === 'reality') {
|
|
setFormValue(sid, 'tls', 'true');
|
|
if (query.sni) {
|
|
setFormValue(sid, 'servername', decodeURIComponent(query.sni));
|
|
}
|
|
if (query.pbk || query['public-key']) {
|
|
setFormValue(sid, 'reality_public_key', query.pbk || query['public-key']);
|
|
}
|
|
if (query.sid || query['short-id']) {
|
|
setFormValue(sid, 'reality_short_id', query.sid || query['short-id']);
|
|
}
|
|
}
|
|
}
|
|
|
|
var network = (query.type || 'tcp').toLowerCase();
|
|
if (network === 'ws') {
|
|
setFormValue(sid, 'obfs_vless', 'ws');
|
|
setFormValue(sid, 'ws_opts_path', decodeURIComponent(query.path || '/'));
|
|
if (query.host) {
|
|
setFormValue(sid, 'ws_opts_headers', 'Host: ' + decodeURIComponent(query.host));
|
|
}
|
|
} else if (network === 'grpc') {
|
|
setFormValue(sid, 'obfs_vless', 'grpc');
|
|
setFormValue(sid, 'grpc_service_name', decodeURIComponent(query.serviceName || query.path || ''));
|
|
} else {
|
|
setFormValue(sid, 'obfs_vless', 'tcp');
|
|
}
|
|
|
|
if (parsed.hash) {
|
|
setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1)));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function parseTrojan(url, sid) {
|
|
var parsed = parseUrl(url);
|
|
if (!parsed) return false;
|
|
|
|
var query = parseQuery(parsed.search);
|
|
|
|
setFormValue(sid, 'type', 'trojan');
|
|
setFormValue(sid, 'server', parsed.hostname);
|
|
setFormValue(sid, 'port', parsed.port || '443');
|
|
setFormValue(sid, 'password', parsed.username);
|
|
|
|
if (query.sni) {
|
|
setFormValue(sid, 'sni', decodeURIComponent(query.sni));
|
|
}
|
|
|
|
if (query.alpn) {
|
|
// Handle ALPN - multiple values support, decode properly
|
|
setFormValue(sid, 'alpn', decodeURIComponent(query.alpn));
|
|
}
|
|
|
|
var network = (query.type || '').toLowerCase();
|
|
if (network === 'ws') {
|
|
setFormValue(sid, 'obfs_trojan', 'ws');
|
|
setFormValue(sid, 'trojan_ws_path', decodeURIComponent(query.path || '/'));
|
|
if (query.host) {
|
|
setFormValue(sid, 'trojan_ws_headers', 'Host: ' + decodeURIComponent(query.host));
|
|
}
|
|
} else if (network === 'grpc') {
|
|
setFormValue(sid, 'obfs_trojan', 'grpc');
|
|
setFormValue(sid, 'grpc_service_name', decodeURIComponent(query.serviceName || ''));
|
|
}
|
|
|
|
if (query.allowInsecure === '1') {
|
|
setFormValue(sid, 'skip_cert_verify', 'true');
|
|
}
|
|
|
|
if (parsed.hash) {
|
|
setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1)));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function parseHysteria(url, sid) {
|
|
var parsed = parseUrl(url);
|
|
if (!parsed) return false;
|
|
|
|
var query = parseQuery(parsed.search);
|
|
|
|
setFormValue(sid, 'type', 'hysteria');
|
|
setFormValue(sid, 'server', parsed.hostname);
|
|
setFormValue(sid, 'port', parsed.port || '443');
|
|
|
|
if (query.auth) {
|
|
setFormValue(sid, 'hysteria_auth_str', decodeURIComponent(query.auth));
|
|
}
|
|
|
|
if (query.protocol) {
|
|
setFormValue(sid, 'flag_transport', '1');
|
|
setFormValue(sid, 'hysteria_protocol', query.protocol);
|
|
}
|
|
|
|
if (query.up || query.upmbps) {
|
|
var upSpeed = decodeURIComponent(query.up || query.upmbps);
|
|
upSpeed = upSpeed.replace(/[^0-9]/g, '');
|
|
setFormValue(sid, 'hysteria_up', upSpeed);
|
|
}
|
|
|
|
if (query.down || query.downmbps) {
|
|
var downSpeed = decodeURIComponent(query.down || query.downmbps);
|
|
downSpeed = downSpeed.replace(/[^0-9]/g, '');
|
|
setFormValue(sid, 'hysteria_down', downSpeed);
|
|
}
|
|
|
|
if (query.obfs || query.obfsParam) {
|
|
setFormValue(sid, 'hysteria_obfs', decodeURIComponent(query.obfs || query.obfsParam));
|
|
}
|
|
|
|
if (query.peer) {
|
|
setFormValue(sid, 'sni', decodeURIComponent(query.peer));
|
|
}
|
|
|
|
if (query.alpn) {
|
|
setFormValue(sid, 'hysteria_alpn', decodeURIComponent(query.alpn));
|
|
}
|
|
|
|
if (query.insecure === '1') {
|
|
setFormValue(sid, 'skip_cert_verify', 'true');
|
|
}
|
|
|
|
if (parsed.hash) {
|
|
setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1)));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function parseHysteria2(url, sid) {
|
|
var parsed = parseUrl(url);
|
|
if (!parsed) return false;
|
|
|
|
var query = parseQuery(parsed.search);
|
|
|
|
setFormValue(sid, 'type', 'hysteria2');
|
|
setFormValue(sid, 'server', parsed.hostname);
|
|
setFormValue(sid, 'port', parsed.port || '443');
|
|
|
|
if (parsed.username) {
|
|
setFormValue(sid, 'password', parsed.username);
|
|
}
|
|
|
|
if (query.obfs) {
|
|
setFormValue(sid, 'hysteria_obfs', decodeURIComponent(query.obfs));
|
|
}
|
|
|
|
if (query['obfs-password']) {
|
|
setFormValue(sid, 'hysteria_obfs_password', decodeURIComponent(query['obfs-password']));
|
|
}
|
|
|
|
if (query.up) {
|
|
setFormValue(sid, 'hysteria_up', decodeURIComponent(query.up));
|
|
}
|
|
|
|
if (query.down) {
|
|
setFormValue(sid, 'hysteria_down', decodeURIComponent(query.down));
|
|
}
|
|
|
|
if (query.sni) {
|
|
setFormValue(sid, 'sni', decodeURIComponent(query.sni));
|
|
}
|
|
|
|
if (query.alpn) {
|
|
setFormValue(sid, 'hysteria_alpn', decodeURIComponent(query.alpn));
|
|
}
|
|
|
|
if (query.insecure === '1') {
|
|
setFormValue(sid, 'skip_cert_verify', 'true');
|
|
}
|
|
|
|
if (parsed.hash) {
|
|
setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1)));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function parseTuic(url, sid) {
|
|
var parsed = parseUrl(url);
|
|
if (!parsed) return false;
|
|
|
|
var query = parseQuery(parsed.search);
|
|
|
|
setFormValue(sid, 'type', 'tuic');
|
|
setFormValue(sid, 'server', parsed.hostname);
|
|
setFormValue(sid, 'port', parsed.port || '443');
|
|
|
|
// Check if it's v5 (has password) or v4 (token only)
|
|
if (parsed.password) {
|
|
setFormValue(sid, 'uuid', parsed.username);
|
|
setFormValue(sid, 'password', parsed.password);
|
|
} else {
|
|
setFormValue(sid, 'tc_token', parsed.username);
|
|
}
|
|
|
|
if (query.congestion_control) {
|
|
setFormValue(sid, 'congestion_controller', decodeURIComponent(query.congestion_control));
|
|
}
|
|
|
|
if (query.alpn) {
|
|
setFormValue(sid, 'tc_alpn', decodeURIComponent(query.alpn));
|
|
}
|
|
|
|
if (query.sni) {
|
|
setFormValue(sid, 'sni', decodeURIComponent(query.sni));
|
|
}
|
|
|
|
if (query.disable_sni === '1') {
|
|
setFormValue(sid, 'disable_sni', 'true');
|
|
}
|
|
|
|
if (query.udp_relay_mode) {
|
|
setFormValue(sid, 'udp_relay_mode', decodeURIComponent(query.udp_relay_mode));
|
|
}
|
|
|
|
if (parsed.hash) {
|
|
setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1)));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function parseSocks(url, sid) {
|
|
var parsed = parseUrl(url);
|
|
if (!parsed) return false;
|
|
|
|
setFormValue(sid, 'type', 'socks5');
|
|
setFormValue(sid, 'server', parsed.hostname);
|
|
setFormValue(sid, 'port', parsed.port || '1080');
|
|
|
|
if (parsed.username) {
|
|
try {
|
|
var decoded = atob(parsed.username);
|
|
var parts = decoded.split(':');
|
|
setFormValue(sid, 'auth_name', parts[0] || '');
|
|
setFormValue(sid, 'auth_pass', parts[1] || '');
|
|
} catch (e) {
|
|
setFormValue(sid, 'auth_name', parsed.username);
|
|
if (parsed.password) {
|
|
setFormValue(sid, 'auth_pass', parsed.password);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (parsed.hash) {
|
|
setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1)));
|
|
} else {
|
|
setFormValue(sid, 'name', parsed.hostname + ':' + parsed.port);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function parseHttp(url, sid) {
|
|
var parsed = parseUrl(url);
|
|
if (!parsed) return false;
|
|
|
|
setFormValue(sid, 'type', 'http');
|
|
setFormValue(sid, 'server', parsed.hostname);
|
|
setFormValue(sid, 'port', parsed.port || (parsed.protocol === 'https:' ? '443' : '80'));
|
|
|
|
if (parsed.protocol === 'https:') {
|
|
setFormValue(sid, 'tls', 'true');
|
|
}
|
|
|
|
if (parsed.username) {
|
|
try {
|
|
var decoded = atob(parsed.username);
|
|
var parts = decoded.split(':');
|
|
setFormValue(sid, 'auth_name', parts[0] || '');
|
|
setFormValue(sid, 'auth_pass', parts[1] || '');
|
|
} catch (e) {
|
|
setFormValue(sid, 'auth_name', parsed.username);
|
|
if (parsed.password) {
|
|
setFormValue(sid, 'auth_pass', parsed.password);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (parsed.hash) {
|
|
setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1)));
|
|
} else {
|
|
setFormValue(sid, 'name', parsed.hostname + ':' + parsed.port);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function parseAnyTLS(url, sid) {
|
|
var parsed = parseUrl(url);
|
|
if (!parsed) return false;
|
|
|
|
var query = parseQuery(parsed.search);
|
|
|
|
setFormValue(sid, 'type', 'anytls');
|
|
setFormValue(sid, 'server', parsed.hostname);
|
|
setFormValue(sid, 'port', parsed.port || '443');
|
|
setFormValue(sid, 'auth_name', parsed.username);
|
|
setFormValue(sid, 'password', parsed.password || parsed.username);
|
|
|
|
if (query.sni) {
|
|
setFormValue(sid, 'sni', query.sni);
|
|
}
|
|
|
|
if (query.hpkp) {
|
|
setFormValue(sid, 'fingerprint', query.hpkp);
|
|
}
|
|
|
|
if (query.insecure === '1') {
|
|
setFormValue(sid, 'skip_cert_verify', 'true');
|
|
}
|
|
|
|
if (parsed.hash) {
|
|
setFormValue(sid, 'name', decodeFragment(parsed.hash.substr(1)));
|
|
} else {
|
|
setFormValue(sid, 'name', parsed.hostname + ':' + parsed.port);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//]]>
|
|
</script>
|
|
<input type="button" class="btn cbi-button cbi-button-apply" value="<%:Import%>" onclick="return import_url(this, '<%=self.option%>', '<%=self.value%>')" />
|
|
<input type="button" class="btn cbi-button cbi-button-apply" value="<%:Export%>" onclick="return export_url(this, '<%=self.option%>', '<%=self.value%>')" />
|
|
<span id="<%=self.option%>-status"></span>
|
|
<%+cbi/valuefooter%> |