402 lines
18 KiB
HTML
402 lines
18 KiB
HTML
<%+cbi/valueheader%>
|
|
|
|
<script type="text/javascript">//<![CDATA[
|
|
console.log("init")
|
|
const GET_FLAG_URL = '<%=luci.dispatcher.build_url("admin", "services", "vssr","flag")%>';
|
|
var sid;
|
|
|
|
function getFlag(remark, hosts, sid) {
|
|
XHR.get(GET_FLAG_URL,
|
|
{ host: hosts, remark: remark },
|
|
function (x, rv) {
|
|
el('.flag').value = rv.flag.replace(/[\r\n]/g, "");
|
|
}
|
|
);
|
|
|
|
}
|
|
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, "=");
|
|
try {
|
|
return atob(str);
|
|
} catch (err) {
|
|
return str;
|
|
}
|
|
}
|
|
function parseQueryString (url){
|
|
var json = {};
|
|
var arr = url.substr(url.indexOf('?') + 1).split('&');
|
|
arr.forEach(item=>{
|
|
var tmp = item.split('=');
|
|
json[tmp[0]] = tmp[1];
|
|
});
|
|
return json;
|
|
}
|
|
|
|
function dictvalue(d, key) {
|
|
var v = d[key];
|
|
if (typeof (v) == 'undefined' || v == '')
|
|
return '';
|
|
return b64decsafe(v);
|
|
}
|
|
|
|
function el(id) {
|
|
return document.getElementById('cbid.vssr.' + sid + id);
|
|
}
|
|
|
|
function getParam(obj,key,defalut=""){
|
|
var val = (obj[key] != undefined) ? obj[key] :defalut;
|
|
return val
|
|
}
|
|
|
|
function import_ssr_url(btn, urlname, sids) {
|
|
sid = sids;
|
|
var s = document.getElementById(urlname + '-status');
|
|
if (!s)
|
|
return false;
|
|
var ssrurl = prompt("<%:Paste Node Link Here%> ssr:// | ss:// | vmess:// | vless:// | trojan://", "");
|
|
if (ssrurl == null || ssrurl == "") {
|
|
s.innerHTML = "<font color='red'><%:User Cancel%></font>";
|
|
return false;
|
|
}
|
|
s.innerHTML = "";
|
|
//var ssu = ssrurl.match(/ssr:\/\/([A-Za-z0-9_-]+)/i);
|
|
var ssu = ssrurl.split('://');
|
|
var event = document.createEvent("HTMLEvents");
|
|
event.initEvent("change", true, true);
|
|
var rema = "";
|
|
switch (ssu[0]) {
|
|
case "ssr":
|
|
var sstr = b64decsafe(ssu[1]);
|
|
var ploc = sstr.indexOf("/?");
|
|
el('.type').value = "ssr";
|
|
el('.type').dispatchEvent(event);
|
|
var url0, param = "";
|
|
if (ploc > 0) {
|
|
url0 = sstr.substr(0, ploc);
|
|
param = sstr.substr(ploc + 2);
|
|
}
|
|
var ssm = url0.match(/^(.+):([^:]+):([^:]*):([^:]+):([^:]*):([^:]+)/);
|
|
if (!ssm || ssm.length < 7)
|
|
return false;
|
|
var pdict = {};
|
|
if (param.length > 2) {
|
|
var a = param.split('&');
|
|
for (var i = 0; i < a.length; i++) {
|
|
var b = a[i].split('=');
|
|
pdict[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || '');
|
|
}
|
|
}
|
|
el('.server').value = ssm[1];
|
|
el('.server_port').value = ssm[2];
|
|
el('.protocol').value = ssm[3];
|
|
el('.encrypt_method').value = ssm[4];
|
|
el('.obfs').value = ssm[5];
|
|
el('.password').value = b64decsafe(ssm[6]);
|
|
el('.obfs_param').value = dictvalue(pdict, 'obfsparam');
|
|
el('.protocol_param').value = dictvalue(pdict, 'protoparam');
|
|
|
|
var rem = pdict['remarks'];
|
|
if (typeof (rem) != 'undefined' && rem != '' && rem.length > 0)
|
|
rema = b64decutf8safe(rem);
|
|
el('.alias').value = b64decutf8safe(rem);
|
|
getFlag(rema, ssm[1], sid); //get flag iso code
|
|
s.innerHTML = "<font color='green'><%:Import%>ShadowsocksR<%:Configuration Succeeded%></font>";
|
|
break;
|
|
case "ss":
|
|
var url0, param = "";
|
|
var sipIndex = ssu[1].indexOf("@");
|
|
var ploc = ssu[1].indexOf("#");
|
|
if (ploc > 0) {
|
|
url0 = ssu[1].substr(0, ploc);
|
|
param = ssu[1].substr(ploc + 1);
|
|
} else {
|
|
url0 = ssu[1];
|
|
}
|
|
|
|
if (sipIndex != -1) {
|
|
// SIP002
|
|
var userInfo = b64decsafe(url0.substr(0, sipIndex));
|
|
var temp = url0.substr(sipIndex + 1).split("/?");
|
|
if(temp.length == 1){
|
|
temp = url0.substr(sipIndex + 1).split("?");
|
|
}
|
|
var serverInfo = temp[0].split(":");
|
|
var server = serverInfo[0];
|
|
var port = serverInfo[1];
|
|
var method, password, plugin, pluginOpts;
|
|
if (temp[1]) {
|
|
var pluginInfo = decodeURIComponent(temp[1]);
|
|
var pluginIndex = pluginInfo.indexOf(";");
|
|
var pluginNameInfo = pluginInfo.substr(0, pluginIndex);
|
|
plugin = pluginNameInfo.substr(pluginNameInfo.indexOf("=") + 1)
|
|
pluginOpts = pluginInfo.substr(pluginIndex + 1);
|
|
}
|
|
|
|
var userInfoSplitIndex = userInfo.indexOf(":");
|
|
if (userInfoSplitIndex != -1) {
|
|
method = userInfo.substr(0, userInfoSplitIndex);
|
|
password = userInfo.substr(userInfoSplitIndex + 1);
|
|
}
|
|
el('.type').value = "ss";
|
|
el('.type').dispatchEvent(event);
|
|
el('.server').value = server;
|
|
el('.server_port').value = port;
|
|
el('.password').value = password || "";
|
|
el('.encrypt_method_ss').value = method || "";
|
|
el('.plugin').value = plugin || "";
|
|
el('.plugin_opts').value = pluginOpts || "";
|
|
} else {
|
|
var sstr = b64decsafe(url0);
|
|
el('.type').value = "ss";
|
|
el('.type').dispatchEvent(event);
|
|
var team = sstr.split('@');
|
|
var part1 = team[0].split(':');
|
|
var part2 = team[1].split(':');
|
|
el('.server').value = part2[0];
|
|
el('.server_port').value = part2[1];
|
|
el('.password').value = part1[1];
|
|
el('.encrypt_method_ss').value = part1[0];
|
|
el('.plugin').value = "";
|
|
el('.plugin_opts').value = "";
|
|
}
|
|
|
|
if (param != undefined) {
|
|
rema = decodeURI(param)
|
|
el('.alias').value = decodeURI(param);
|
|
}
|
|
getFlag(rema, server, sid); //get flag iso code
|
|
s.innerHTML = "<font color='green'><%:Import%>Shadowsocks<%:Configuration Succeeded%></font>";
|
|
break;
|
|
case "trojan":
|
|
var ploc = ssu[1].indexOf("#");
|
|
if (ploc > 0) {
|
|
url0 = ssu[1].substr(0, ploc);
|
|
param = ssu[1].substr(ploc + 1);
|
|
} else {
|
|
url0 = ssu[1]
|
|
}
|
|
el('.type').value = "trojan";
|
|
el('.type').dispatchEvent(event);
|
|
var team = url0.split('@');
|
|
var part1 = team[0].split(':');
|
|
var part2 = team[1].split(':');
|
|
var others = part2[1].split('?');
|
|
var queryParam = {}
|
|
if (others.length > 1) {
|
|
var queryParams = others[1]
|
|
var queryArray = queryParams.split('&')
|
|
for (i = 0; i < queryArray.length; i++) {
|
|
var params = queryArray[i].split('=');
|
|
queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
|
|
}
|
|
}
|
|
el('.server').value = part2[0];
|
|
el('.server_port').value = others[0];
|
|
el('.password').value = decodeURI(part1[0]);
|
|
if (queryParam.peer || queryParam.sni) {
|
|
el('.peer').value = queryParam.peer || queryParam.sni;
|
|
}
|
|
if (url0.indexOf('allowInsecure=1') != -1) {
|
|
el('.insecure').value = 1;
|
|
}
|
|
|
|
if (param != undefined) {
|
|
rema = decodeURI(param)
|
|
el('.alias').value = decodeURI(param);
|
|
}
|
|
getFlag(rema, part2[0], sid); //get flag iso code
|
|
|
|
s.innerHTML = "<font color='green'>导入Trojan<%:Configuration Succeeded%></font>";
|
|
break;
|
|
case "vmess":
|
|
var sstr = b64DecodeUnicode(ssu[1]);
|
|
var ploc = sstr.indexOf("/?");
|
|
el('.type').value = "v2ray";
|
|
el('.type').dispatchEvent(event);
|
|
var url0, param = "";
|
|
if (ploc > 0) {
|
|
url0 = sstr.substr(0, ploc);
|
|
param = sstr.substr(ploc + 2);
|
|
}
|
|
var ssm = JSON.parse(sstr);
|
|
el('.alias').value = ssm.ps;
|
|
el('.server').value = ssm.add;
|
|
el('.server_port').value = ssm.port;
|
|
el('.alter_id').value = ssm.aid;
|
|
el('.vmess_id').value = ssm.id;
|
|
el('.transport').value = ssm.net;
|
|
el('.transport').dispatchEvent(event);
|
|
if (ssm.net == "tcp") {
|
|
try {
|
|
el('.http_host').value = ssm.host;
|
|
el('.http_path').value = ssm.path;
|
|
} catch (err) { }
|
|
|
|
}
|
|
if (ssm.net == "ws") {
|
|
try {
|
|
el('.ws_host').value = ssm.host;
|
|
el('.ws_path').value = ssm.path;
|
|
} catch (err) { }
|
|
}
|
|
if (ssm.net == "h2") {
|
|
try {
|
|
el('.h2_host').value = ssm.host;
|
|
el('.h2_path').value = ssm.path;
|
|
} catch (err) { }
|
|
}
|
|
if (ssm.net == "quic") {
|
|
try {
|
|
el('.quic_security').value = ssm.securty;
|
|
el('.quic_key').value = ssm.key;
|
|
} catch (err) { }
|
|
}
|
|
if (ssm.net == "kcp") {
|
|
try {
|
|
el('.kcp_guise').value = ssm.type;
|
|
} catch (err) { }
|
|
try {
|
|
el('.seed').value = ssm.seed;
|
|
} catch (err) { }
|
|
}
|
|
if (ssm.tls == "tls") {
|
|
try {
|
|
el('.tls').checked = true;
|
|
el('.tls').dispatchEvent(event);
|
|
el('.tls_host').value = ssm.host;
|
|
} catch (err) { }
|
|
}
|
|
el('.mux').checked = true;
|
|
el('.mux').dispatchEvent(event);
|
|
|
|
getFlag(ssm.ps, ssm.add, sid); //get flag iso code
|
|
|
|
s.innerHTML = "<font color='green'><%:Import%>V2ray<%:Configuration Succeeded%></font>";
|
|
break;
|
|
case "vless":
|
|
el('.type').value = "vless";
|
|
el('.type').dispatchEvent(event);
|
|
var alias,pstring = "";
|
|
if(ssu[1].indexOf("#") > 0 ){
|
|
alias = ssu[1].split("#")[1]
|
|
el('.alias').value = alias;
|
|
pstring = ssu[1].split("#")[0]
|
|
}
|
|
var parameter = parseQueryString(pstring);
|
|
var url0;
|
|
var ploc = pstring.indexOf("?");
|
|
var server = "";
|
|
if (ploc > 0) {
|
|
url0 = pstring.substr(0, ploc);
|
|
var arr1 = url0.split("@");
|
|
el('.vmess_id').value = arr1[0];
|
|
var arr2 = arr1[1].split(":");
|
|
server = arr2[0];
|
|
el('.server').value = server;
|
|
el('.server_port').value = arr2[1];
|
|
}
|
|
el('.vless_encryption').value = getParam(parameter,"encryption","none");
|
|
if(parameter.type != undefined){
|
|
el('.transport').value = getParam(parameter,"type");
|
|
el('.transport').dispatchEvent(event);
|
|
switch(parameter.type){
|
|
case "tcp":
|
|
try {
|
|
el('.http_host').value = getParam(parameter,"host");
|
|
el('.http_path').value = getParam(parameter,"path");
|
|
} catch (err) { }
|
|
break;
|
|
case "ws":
|
|
try {
|
|
el('.ws_host').value = getParam(parameter,"host");
|
|
el('.ws_path').value = getParam(parameter,"path");
|
|
} catch (err) { }
|
|
break;
|
|
case "h2":
|
|
try {
|
|
el('.h2_host').value = getParam(parameter,"host");
|
|
el('.h2_path').value = getParam(parameter,"path");
|
|
} catch (err) { }
|
|
break;
|
|
case "quic":
|
|
try {
|
|
el('.quic_security').value = getParam(parameter,"quic_security");
|
|
el('.quic_key').value = getParam(parameter,"quic_key");
|
|
} catch (err) { }
|
|
break;
|
|
case "kcp":
|
|
try {
|
|
el('.kcp_guise').value = getParam(parameter,"headerType");
|
|
el('.seed').value = getParam(parameter,"seed");
|
|
} catch (err) { }
|
|
break;
|
|
}
|
|
}
|
|
if (parameter.security == "tls") {
|
|
try {
|
|
el('.tls').checked = true;
|
|
el('.tls').dispatchEvent(event);
|
|
el('.tls_host').value = getParam(parameter,"host");
|
|
} catch (err) { }
|
|
}
|
|
if (parameter.security == "xtls") {
|
|
try {
|
|
el('.tls').checked = true;
|
|
el('.tls').dispatchEvent(event);
|
|
el('.tls_host').value = getParam(parameter,"host");
|
|
el('.xtls').checked = true;
|
|
el('.xtls').dispatchEvent(event);
|
|
el('.vless_flow').value = getParam(parameter,"flow");
|
|
} catch (err) { }
|
|
}
|
|
getFlag(alias, server, sid); //get flag iso code
|
|
s.innerHTML = "<font color='green'><%:Import%>Vless<%:Configuration Succeeded%></font>";
|
|
break;
|
|
default:
|
|
s.innerHTML = "<font color='red'><%:Invalid Format%></font>";
|
|
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//]]></script>
|
|
|
|
<input type="button" class="cbi-button cbi-button-apply" value="<%:Import Configuration%>"
|
|
onclick="return import_ssr_url(this, '<%=self.option%>', '<%=self.value%>')" />
|
|
<span id="<%=self.option%>-status"></span>
|
|
|
|
<%+cbi/valuefooter%>
|