ssrurl.htm 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  1. <%+cbi/valueheader%>
  2. <%
  3. local map = self.map
  4. local ss_type = map:get("@server_subscribe[0]", "ss_type")
  5. -%>
  6. <script type="text/javascript">
  7. //<![CDATA[
  8. let ss_type = "<%=ss_type%>"
  9. function padright(str, cnt, pad) {
  10. return str + Array(cnt + 1).join(pad);
  11. }
  12. function b64EncodeUnicode(str) {
  13. return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
  14. return String.fromCharCode('0x' + p1);
  15. }));
  16. }
  17. function b64encutf8safe(str) {
  18. return b64EncodeUnicode(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '');
  19. }
  20. function b64DecodeUnicode(str) {
  21. return decodeURIComponent(Array.prototype.map.call(atob(str), function (c) {
  22. return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
  23. }).join(''));
  24. }
  25. function b64decutf8safe(str) {
  26. var l;
  27. str = str.replace(/-/g, "+").replace(/_/g, "/");
  28. l = str.length;
  29. l = (4 - l % 4) % 4;
  30. if (l) str = padright(str, l, "=");
  31. return b64DecodeUnicode(str);
  32. }
  33. function b64encsafe(str) {
  34. return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '')
  35. }
  36. function b64decsafe(str) {
  37. var l;
  38. str = str.replace(/-/g, "+").replace(/_/g, "/");
  39. l = str.length;
  40. l = (4 - l % 4) % 4;
  41. if (l) str = padright(str, l, "=");
  42. return atob(str);
  43. }
  44. function dictvalue(d, key) {
  45. var v = d[key];
  46. if (typeof (v) == 'undefined' || v == '') return '';
  47. return b64decsafe(v);
  48. }
  49. function export_ssr_url(btn, urlname, sid) {
  50. var s = document.getElementById(urlname + '-status');
  51. if (!s) return false;
  52. var v_server = document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0];
  53. var v_port = document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0];
  54. var v_protocol = document.getElementsByName('cbid.shadowsocksr.' + sid + '.protocol')[0];
  55. var v_method = document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method')[0];
  56. var v_obfs = document.getElementsByName('cbid.shadowsocksr.' + sid + '.obfs')[0];
  57. var v_password = document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0];
  58. var v_obfs_param = document.getElementsByName('cbid.shadowsocksr.' + sid + '.obfs_param')[0];
  59. var v_protocol_param = document.getElementsByName('cbid.shadowsocksr.' + sid + '.protocol_param')[0];
  60. var v_alias = document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0];
  61. var ssr_str = v_server.value + ":" + v_port.value + ":" + v_protocol.value + ":" + v_method.value + ":" + v_obfs.value + ":" + b64encsafe(v_password.value) + "/?obfsparam=" + b64encsafe(v_obfs_param.value) + "&protoparam=" + b64encsafe(v_protocol_param.value) + "&remarks=" + b64encutf8safe(v_alias.value);
  62. var textarea = document.createElement("textarea");
  63. textarea.textContent = "ssr://" + b64encsafe(ssr_str);
  64. textarea.style.position = "fixed";
  65. document.body.appendChild(textarea);
  66. textarea.select();
  67. try {
  68. document.execCommand("copy"); // Security exception may be thrown by some browsers.
  69. s.innerHTML = "<font style=\'color:green\'><%:Copy SSR to clipboard successfully.%></font>";
  70. } catch (ex) {
  71. s.innerHTML = "<font style=\'color:red\'><%:Unable to copy SSR to clipboard.%></font>";
  72. } finally {
  73. document.body.removeChild(textarea);
  74. }
  75. return false;
  76. }
  77. function import_ssr_url(btn, urlname, sid) {
  78. var s = document.getElementById(urlname + '-status');
  79. if (!s) return false;
  80. var ssrurl = prompt("<%:Paste sharing link here%>", "");
  81. if (ssrurl == null || ssrurl == "") {
  82. s.innerHTML = "<font style=\'color:red\'><%:User cancelled.%></font>";
  83. return false;
  84. }
  85. s.innerHTML = "";
  86. //var ssu = ssrurl.match(/ssr:\/\/([A-Za-z0-9_-]+)/i);
  87. ssrurl = ssrurl.replace(/&([a-zA-Z]+);/g, '&').replace(/\s*#\s*/, '#').trim(); //一些奇葩的链接用"&amp;"当做"&","#"前后带空格
  88. var ssu = ssrurl.split('://');
  89. //console.log(ssu.length);
  90. var event = document.createEvent("HTMLEvents");
  91. event.initEvent("change", true, true);
  92. switch (ssu[0]) {
  93. case "hysteria2":
  94. case "hy2":
  95. try {
  96. var url = new URL("http://" + ssu[1]);
  97. var params = url.searchParams;
  98. } catch(e) {
  99. alert(e);
  100. return false;
  101. }
  102. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = (ssu[0] === "hy2") ? "hysteria2" : ssu[0];
  103. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
  104. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = url.hostname;
  105. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = url.port || "443";
  106. if (params.get("lazy") === "1") {
  107. document.getElementsByName('cbid.shadowsocksr.' + sid + '.lazy_mode')[0].checked = true;
  108. document.getElementsByName('cbid.shadowsocksr.' + sid + '.lazy_mode')[0].dispatchEvent(event);
  109. }
  110. if (params.get("mport")) {
  111. document.getElementsByName('cbid.shadowsocksr.' + sid + '.flag_port_hopping')[0].checked = true; // 设置 flag_port_hopping 为 true
  112. document.getElementsByName('cbid.shadowsocksr.' + sid + '.flag_port_hopping')[0].dispatchEvent(event); // 触发事件
  113. document.getElementsByName('cbid.shadowsocksr.' + sid + '.port_range')[0].value = params.get("mport") || "";
  114. }
  115. if (params.get("protocol")) {
  116. document.getElementsByName('cbid.shadowsocksr.' + sid + '.flag_transport')[0].checked = true; // 设置 flag_transport 为 true
  117. document.getElementsByName('cbid.shadowsocksr.' + sid + '.flag_transport')[0].dispatchEvent(event); // 触发事件
  118. document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport_protocol')[0].value = params.get("protocol") || "udp";
  119. }
  120. document.getElementsByName('cbid.shadowsocksr.' + sid + '.hy2_auth')[0].value = decodeURIComponent(url.username);
  121. document.getElementsByName('cbid.shadowsocksr.' + sid + '.hy2_auth')[0].dispatchEvent(event);
  122. document.getElementsByName('cbid.shadowsocksr.' + sid + '.uplink_capacity')[0].value =
  123. (params.get("upmbps") && params.get("upmbps").match(/\d+/)) ? params.get("upmbps").match(/\d+/)[0] : "";
  124. document.getElementsByName('cbid.shadowsocksr.' + sid + '.downlink_capacity')[0].value =
  125. (params.get("downmbps") && params.get("downmbps").match(/\d+/)) ? params.get("downmbps").match(/\d+/)[0] : "";
  126. if (params.get("obfs") && params.get("obfs") !== "none") {
  127. document.getElementsByName('cbid.shadowsocksr.' + sid + '.flag_obfs')[0].checked = true; // 设置 flag_obfs 为 true
  128. document.getElementsByName('cbid.shadowsocksr.' + sid + '.flag_obfs')[0].dispatchEvent(event); // 触发事件
  129. document.getElementsByName('cbid.shadowsocksr.' + sid + '.obfs_type')[0].value = params.get("obfs");
  130. document.getElementsByName('cbid.shadowsocksr.' + sid + '.salamander')[0].value = params.get("obfs-password") || params.get("obfs_password");
  131. }
  132. if (params.get("sni") || params.get("alpn")) {
  133. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].checked = true; // 设置 flag_obfs 为 true
  134. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event); // 触发事件
  135. if (params.get("sni")) {
  136. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = params.get("sni") || "";
  137. }
  138. if (params.get("alpn")) {
  139. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_alpn')[0].value = params.get("alpn") || "";
  140. }
  141. }
  142. if (params.get("insecure") === "1") {
  143. document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = true;
  144. document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].dispatchEvent(event);
  145. }
  146. if (params.get("pinSHA256")) {
  147. document.getElementsByName('cbid.shadowsocksr.' + sid + '.pinsha256')[0].value = params.get("pinSHA256") || "";
  148. }
  149. document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = url.hash ? decodeURIComponent(url.hash.slice(1)) : "";
  150. s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
  151. return false;
  152. case "ss":
  153. var url0 = (ssu[1] || "");
  154. var param = "";
  155. // 先分离 #(alias)
  156. var hashIndex = url0.indexOf("#");
  157. if (hashIndex >= 0) {
  158. param = url0.substring(hashIndex + 1);
  159. url0 = url0.substring(0, hashIndex);
  160. }
  161. // 再分离 ? 或 /?(参数)
  162. var queryIndex = (url0 = url0.replace('/?', '?')).indexOf("?");
  163. var query = "";
  164. if (queryIndex >= 0) {
  165. query = url0.substring(queryIndex + 1);
  166. url0 = url0.substring(0, queryIndex);
  167. }
  168. var params = Object.fromEntries(new URLSearchParams(query));
  169. if ( ! params.type) {
  170. // 普通 SS 导入逻辑
  171. // 判断是否 SIP002 格式(即含 @)
  172. if (url0.indexOf("@") !== -1) {
  173. // === SIP002 格式 ===
  174. var sipIndex = url0.indexOf("@");
  175. // 先 URL 解码 base64 再解码
  176. var userInfoB64 = decodeURIComponent(url0.substring(0, sipIndex));
  177. var userInfo = b64decsafe(userInfoB64);
  178. var userInfoSplitIndex = userInfo.indexOf(":");
  179. if(userInfoSplitIndex < 0) {
  180. // 格式错误
  181. s.innerHTML = "<font style='color:red'><%:Userinfo format error.%></font>";
  182. break;
  183. }
  184. var method = userInfo.substring(0, userInfoSplitIndex);
  185. var password = userInfo.substring(userInfoSplitIndex + 1);
  186. var serverPart = url0.substring(sipIndex + 1);
  187. var serverInfo = serverPart.split(":");
  188. var server = serverInfo[0];
  189. var port = serverInfo[1];
  190. var plugin = "", pluginOpts = "";
  191. if (params.plugin) {
  192. var pluginParams = decodeURIComponent(params.plugin).split(";");
  193. plugin = pluginParams.shift();
  194. pluginOpts = pluginParams.join(";");
  195. }
  196. } else {
  197. // === Base64 SS2022 / 普通格式 的整体编码格式 ===
  198. // 先 URL 解码整个字符串
  199. var decodedUrl0 = decodeURIComponent(url0);
  200. var sstr = b64decsafe(decodedUrl0);
  201. if (!sstr) {
  202. s.innerHTML = "<font style='color:red'><%:Base64 sstr failed.%></font>";
  203. break;
  204. }
  205. // 支持 SS2022 / 普通格式
  206. var regex2022 = /^([^:]+):([^:]+):([^@]+)@([^:]+):(\d+)$/;
  207. var regexNormal = /^([^:]+):([^@]+)@([^:]+):(\d+)$/;
  208. var m2022 = sstr.match(regex2022);
  209. var mNormal = sstr.match(regexNormal);
  210. if (m2022) {
  211. var method = m2022[1];
  212. var password = m2022[2] + ":" + m2022[3];
  213. var server = m2022[4];
  214. var port = m2022[5];
  215. } else if (mNormal) {
  216. var method = mNormal[1];
  217. var password = mNormal[2];
  218. var server = mNormal[3];
  219. var port = mNormal[4];
  220. } else {
  221. s.innerHTML = "<font style='color:red'><%:SS URL base64 sstr format not recognized.%></font>";
  222. break;
  223. }
  224. var plugin = "", pluginOpts = "";
  225. if (params["shadow-tls"]) {
  226. try {
  227. var decoded_tls = JSON.parse(atob(decodeURIComponent(params["shadow-tls"])));
  228. plugin = "shadow-tls";
  229. var versionFlag = "";
  230. if (decoded_tls.version && !isNaN(decoded_tls.version)) {
  231. versionFlag = "v" + decoded_tls.version + "=1;";
  232. }
  233. pluginOpts = versionFlag + "host=" + (decoded_tls.host || "") + ";passwd=" + (decoded_tls.password || "");
  234. } catch (e) {
  235. console.log("shadow-tls decode failed:", e);
  236. }
  237. }
  238. }
  239. // 判断密码是否经过url编码
  240. const isURLEncodedPassword = function(pwd) {
  241. if (!/%[0-9A-Fa-f]{2}/.test(pwd)) return false;
  242. try {
  243. const decoded = decodeURIComponent(pwd.replace(/\+/g, "%20"));
  244. const reencoded = encodeURIComponent(decoded);
  245. return reencoded === pwd;
  246. } catch (e) {
  247. return false;
  248. }
  249. }
  250. if (isURLEncodedPassword(password)) {
  251. password = decodeURIComponent(password); // 解码URL编码
  252. } else {
  253. password = password; // 保持原始值
  254. }
  255. // === 填充配置项 ===
  256. var has_ss_type = (ss_type === "ss-rust") ? "ss-rust" : "ss-libev";
  257. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = ssu[0];
  258. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
  259. document.getElementsByName('cbid.shadowsocksr.' + sid + '.has_ss_type')[0].value = has_ss_type;
  260. document.getElementsByName('cbid.shadowsocksr.' + sid + '.has_ss_type')[0].dispatchEvent(event);
  261. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = server;
  262. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = port;
  263. document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = password || "";
  264. document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method_ss')[0].value = method;
  265. document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method_ss')[0].dispatchEvent(event);
  266. if (plugin && plugin !== "none") {
  267. document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_plugin')[0].checked = true; // 设置 enable_plugin 为 true
  268. document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_plugin')[0].dispatchEvent(event); // 触发事件
  269. document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin')[0].value = plugin;
  270. document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin')[0].dispatchEvent(event);
  271. if (plugin !== undefined) {
  272. document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin_opts')[0].value = pluginOpts || "";
  273. }
  274. } else {
  275. document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_plugin')[0].checked = false;
  276. }
  277. if (param != undefined) {
  278. document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURIComponent(param);
  279. }
  280. s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
  281. return false;
  282. } else {
  283. try {
  284. // Xray SS 导入逻辑
  285. // 拆分 @,判断是否是 base64 userinfo 的格式
  286. var parts = url0.split("@");
  287. if (parts.length > 1) {
  288. // @ 前是 base64(method:password),后面是 server:port?params
  289. var userinfo = b64decsafe(parts[0]);
  290. var sepIndex = userinfo.indexOf(":");
  291. if (sepIndex > -1) {
  292. method = userinfo.slice(0, sepIndex);
  293. password = userinfo.slice(sepIndex + 1); //一些链接用明文uuid做密码
  294. }
  295. }
  296. var url = new URL("http://" + url0 + (param ? "#" + encodeURIComponent(param) : ""));
  297. } catch(e) {
  298. alert(e);
  299. return false;
  300. }
  301. // Check if the elements exist before trying to modify them
  302. function setElementValue(name, value) {
  303. const element = document.getElementsByName(name)[0];
  304. if (element) {
  305. if (typeof value === 'boolean') {
  306. element.checked = value;
  307. } else {
  308. element.value = value;
  309. }
  310. }
  311. }
  312. function dispatchEventIfExists(name, event) {
  313. const element = document.getElementsByName(name)[0];
  314. if (element) {
  315. element.dispatchEvent(event);
  316. }
  317. }
  318. setElementValue('cbid.shadowsocksr.' + sid + '.alias', url.hash ? decodeURIComponent(url.hash.slice(1)) : "");
  319. setElementValue('cbid.shadowsocksr.' + sid + '.type', "v2ray");
  320. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.type', event);
  321. setElementValue('cbid.shadowsocksr.' + sid + '.v2ray_protocol', "shadowsocks");
  322. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.v2ray_protocol', event);
  323. setElementValue('cbid.shadowsocksr.' + sid + '.server', url.hostname);
  324. setElementValue('cbid.shadowsocksr.' + sid + '.server_port', url.port || "80");
  325. setElementValue('cbid.shadowsocksr.' + sid + '.password', password || url.username);
  326. setElementValue('cbid.shadowsocksr.' + sid + '.transport',
  327. params.type === "http" ? "h2" :
  328. (["xhttp", "splithttp"].includes(params.type) ? "xhttp" :
  329. (["tcp", "raw"].includes(params.type) ? "raw" :
  330. (params.type || "raw")))
  331. );
  332. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.transport', event);
  333. setElementValue('cbid.shadowsocksr.' + sid + '.encrypt_method_ss', method || params.encryption || "none");
  334. if ([ "tls", "xtls", "reality" ].includes(params.security)) {
  335. setElementValue('cbid.shadowsocksr.' + sid + '.' + params.security, true);
  336. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.' + params.security, event);
  337. if (params.security === "tls") {
  338. if (params.ech && params.ech.trim() !== "") {
  339. setElementValue('cbid.shadowsocksr.' + sid + '.enable_ech', true); // 设置 enable_ech 为 true
  340. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.enable_ech', event); // 触发事件
  341. setElementValue('cbid.shadowsocksr.' + sid + '.ech_config', params.ech || "");
  342. }
  343. if (params.allowInsecure === "1") {
  344. setElementValue('cbid.shadowsocksr.' + sid + '.insecure', true); // 设置 insecure 为 true
  345. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.insecure', event); // 触发事件
  346. }
  347. }
  348. if (params.security === "reality") {
  349. setElementValue('cbid.shadowsocksr.' + sid + '.reality_publickey', params.pbk ? decodeURIComponent(params.pbk) : "");
  350. setElementValue('cbid.shadowsocksr.' + sid + '.reality_shortid', params.sid || "");
  351. setElementValue('cbid.shadowsocksr.' + sid + '.reality_spiderx', params.spx ? decodeURIComponent(params.spx) : "");
  352. if (params.pqv && params.pqv.trim() !== "") {
  353. setElementValue('cbid.shadowsocksr.' + sid + '.enable_mldsa65verify', true); // 设置 enable_mldsa65verify 为 true
  354. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.enable_mldsa65verify', event); // 触发事件
  355. setElementValue('cbid.shadowsocksr.' + sid + '.reality_mldsa65verify', params.pqv || "");
  356. }
  357. }
  358. setElementValue('cbid.shadowsocksr.' + sid + '.tls_flow', params.flow || "none");
  359. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.tls_flow', event);
  360. setElementValue('cbid.shadowsocksr.' + sid + '.tls_alpn', params.alpn || "");
  361. setElementValue('cbid.shadowsocksr.' + sid + '.fingerprint', params.fp || "");
  362. setElementValue('cbid.shadowsocksr.' + sid + '.tls_host', params.sni || "");
  363. }
  364. switch (params.type) {
  365. case "ws":
  366. if (params.security !== "tls") {
  367. setElementValue('cbid.shadowsocksr.' + sid + '.ws_host', params.host ? decodeURIComponent(params.host) : "");
  368. }
  369. setElementValue('cbid.shadowsocksr.' + sid + '.ws_path', params.path ? decodeURIComponent(params.path) : "/");
  370. break;
  371. case "httpupgrade":
  372. if (params.security !== "tls") {
  373. setElementValue('cbid.shadowsocksr.' + sid + '.httpupgrade_host', params.host ? decodeURIComponent(params.host) : "");
  374. }
  375. setElementValue('cbid.shadowsocksr.' + sid + '.httpupgrade_path', params.path ? decodeURIComponent(params.path) : "/");
  376. break;
  377. case "xhttp":
  378. case "splithttp":
  379. if (params.security !== "tls") {
  380. setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_host', params.host ? decodeURIComponent(params.host) : "");
  381. }
  382. setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_mode', params.mode || "auto");
  383. setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_path', params.path ? decodeURIComponent(params.path) : "/");
  384. if (params.extra && params.extra.trim() !== "") {
  385. setElementValue('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra', true); // 设置 enable_xhttp_extra 为 true
  386. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra', event); // 触发事件
  387. setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_extra', params.extra || "");
  388. }
  389. break;
  390. case "kcp":
  391. setElementValue('cbid.shadowsocksr.' + sid + '.kcp_guise', params.headerType || "none");
  392. setElementValue('cbid.shadowsocksr.' + sid + '.seed', params.seed || "");
  393. break;
  394. case "http":
  395. /* this is non-standard, bullshit */
  396. case "h2":
  397. setElementValue('cbid.shadowsocksr.' + sid + '.h2_host', params.host ? decodeURIComponent(params.host) : "");
  398. setElementValue('cbid.shadowsocksr.' + sid + '.h2_path', params.path ? decodeURIComponent(params.path) : "");
  399. break;
  400. case "quic":
  401. setElementValue('cbid.shadowsocksr.' + sid + '.quic_guise', params.headerType || "none");
  402. setElementValue('cbid.shadowsocksr.' + sid + '.quic_security', params.quicSecurity || "none");
  403. setElementValue('cbid.shadowsocksr.' + sid + '.quic_key', params.key || "");
  404. break;
  405. case "grpc":
  406. setElementValue('cbid.shadowsocksr.' + sid + '.serviceName', params.serviceName || "");
  407. setElementValue('cbid.shadowsocksr.' + sid + '.grpc_mode', params.mode || "gun");
  408. break;
  409. case "tcp":
  410. case "raw":
  411. setElementValue('cbid.shadowsocksr.' + sid + '.tcp_guise', params.headerType || "none");
  412. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.tcp_guise', event);
  413. if (params.headerType === "http") {
  414. setElementValue('cbid.shadowsocksr.' + sid + '.http_host', params.host ? decodeURIComponent(params.host) : "");
  415. setElementValue('cbid.shadowsocksr.' + sid + '.http_path', params.path ? decodeURIComponent(params.path) : "");
  416. }
  417. break;
  418. }
  419. s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
  420. return false;
  421. }
  422. case "ssr":
  423. var sstr = b64decsafe((ssu[1] || "").replace(/#.*/, "").trim());
  424. var ploc = sstr.indexOf("/?");
  425. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = ssu[0];
  426. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
  427. var url0, param = "";
  428. if (ploc > 0) {
  429. url0 = sstr.substr(0, ploc);
  430. param = sstr.substr(ploc + 2);
  431. }
  432. var ssm = url0.match(/^(.+):([^:]+):([^:]*):([^:]+):([^:]*):([^:]+)/);
  433. if (!ssm || ssm.length < 7) return false;
  434. var pdict = {};
  435. if (param.length > 2) {
  436. var a = param.split('&');
  437. for (var i = 0; i < a.length; i++) {
  438. var b = a[i].split('=');
  439. pdict[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || '');
  440. }
  441. }
  442. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = ssm[1];
  443. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = ssm[2];
  444. document.getElementsByName('cbid.shadowsocksr.' + sid + '.protocol')[0].value = ssm[3];
  445. document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method')[0].value = ssm[4];
  446. document.getElementsByName('cbid.shadowsocksr.' + sid + '.obfs')[0].value = ssm[5];
  447. document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = b64decsafe(ssm[6]);
  448. document.getElementsByName('cbid.shadowsocksr.' + sid + '.obfs_param')[0].value = dictvalue(pdict, 'obfsparam');
  449. document.getElementsByName('cbid.shadowsocksr.' + sid + '.protocol_param')[0].value = dictvalue(pdict, 'protoparam');
  450. var rem = pdict['remarks'];
  451. if (typeof (rem) != 'undefined' && rem != '' && rem.length > 0) document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = b64decutf8safe(rem);
  452. s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
  453. return false;
  454. case "trojan":
  455. try {
  456. var url = new URL("http://" + ssu[1]);
  457. var params = url.searchParams;
  458. } catch(e) {
  459. alert(e);
  460. return false;
  461. }
  462. if (!params.get("type")) {
  463. // 普通 Trojan 导入逻辑
  464. document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = url.hash ? decodeURIComponent(url.hash.slice(1)) : "";
  465. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "trojan";
  466. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
  467. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = url.hostname;
  468. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = url.port || "80";
  469. document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = decodeURIComponent(url.username);
  470. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].checked = true;
  471. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event);
  472. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = params.get("peer") || params.get("sni");
  473. if (params.get("allowInsecure") === "1") {
  474. document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = true; // 设置 insecure 为 true
  475. document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].dispatchEvent(event); // 触发事件
  476. }
  477. if (params.get("tfo") === "1") {
  478. document.getElementsByName('cbid.shadowsocksr.' + sid + '.fast_open')[0].checked = true; // 设置 fast_open 为 true
  479. document.getElementsByName('cbid.shadowsocksr.' + sid + '.fast_open')[0].dispatchEvent(event); // 触发事件
  480. }
  481. s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
  482. return false;
  483. } else {
  484. // Xray Trojan 导入逻辑
  485. document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = url.hash ? decodeURIComponent(url.hash.slice(1)) : "";
  486. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "v2ray";
  487. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
  488. document.getElementsByName('cbid.shadowsocksr.' + sid + '.v2ray_protocol')[0].value = "trojan";
  489. document.getElementsByName('cbid.shadowsocksr.' + sid + '.v2ray_protocol')[0].dispatchEvent(event);
  490. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = url.hostname;
  491. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = url.port || "80";
  492. document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = decodeURIComponent(url.username);
  493. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].checked = true;
  494. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event);
  495. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = params.get("sni");
  496. if (params.get("allowInsecure") === "1") {
  497. document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = true; // 设置 insecure 为 true
  498. document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].dispatchEvent(event); // 触发事件
  499. }
  500. if (params.get("ech") && params.get("ech").trim() !== "") {
  501. document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_ech')[0].checked = true; // 设置 enable_ech 为 true
  502. document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_ech')[0].dispatchEvent(event); // 触发事件
  503. document.getElementsByName('cbid.shadowsocksr.' + sid + '.ech_config')[0].value = params.get("ech");
  504. }
  505. document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].value =
  506. params.get("type") == "http" ? "h2" :
  507. (["xhttp", "splithttp"].includes(params.get("type")) ? "xhttp" :
  508. (["tcp", "raw"].includes(params.get("type")) ? "raw" :
  509. (params.get("type") || "raw")));
  510. document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].dispatchEvent(event);
  511. if (params.get("security") === "tls") {
  512. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_alpn')[0].value = params.get("alpn") || "";
  513. document.getElementsByName('cbid.shadowsocksr.' + sid + '.fingerprint')[0].value = params.get("fp") || "";
  514. }
  515. switch (params.get("type")) {
  516. case "ws":
  517. if (params.get("security") !== "tls") {
  518. document.getElementsByName('cbid.shadowsocksr.' + sid + '.ws_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
  519. }
  520. document.getElementsByName('cbid.shadowsocksr.' + sid + '.ws_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
  521. break;
  522. case "httpupgrade":
  523. if (params.get("security") !== "tls") {
  524. document.getElementsByName('cbid.shadowsocksr.' + sid + '.httpupgrade_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
  525. }
  526. document.getElementsByName('cbid.shadowsocksr.' + sid + '.httpupgrade_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
  527. break;
  528. case "xhttp":
  529. case "splithttp":
  530. document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
  531. document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_mode')[0].value = params.get("mode") || "auto";
  532. document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "/";
  533. if (params.get("extra") && params.get("extra").trim() !== "") {
  534. document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra')[0].checked = true; // 设置 enable_xhttp_extra 为 true
  535. document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra')[0].dispatchEvent(event); // 触发事件
  536. document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_extra')[0].value = params.get("extra") || "";
  537. }
  538. break;
  539. case "kcp":
  540. document.getElementsByName('cbid.shadowsocksr.' + sid + '.kcp_guise')[0].value = params.get("headerType") || "none";
  541. document.getElementsByName('cbid.shadowsocksr.' + sid + '.seed')[0].value = params.get("seed") || "";
  542. break;
  543. case "http":
  544. /* this is non-standard, bullshit */
  545. case "h2":
  546. document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
  547. document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
  548. break;
  549. case "quic":
  550. document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_guise')[0].value = params.get("headerType") || "none";
  551. document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_security')[0].value = params.get("quicSecurity") || "none";
  552. document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_key')[0].value = params.get("key") || "";
  553. break;
  554. case "grpc":
  555. document.getElementsByName('cbid.shadowsocksr.' + sid + '.serviceName')[0].value = params.get("serviceName") || "";
  556. document.getElementsByName('cbid.shadowsocksr.' + sid + '.grpc_mode')[0].value = params.get("mode") || "gun";
  557. break;
  558. case "raw":
  559. case "tcp":
  560. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tcp_guise')[0].value = params.get("headerType") || "none";
  561. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tcp_guise')[0].dispatchEvent(event);
  562. if (params.get("headerType") === "http") {
  563. document.getElementsByName('cbid.shadowsocksr.' + sid + '.http_host')[0].value = params.get("host") ? decodeURIComponent(params.get("host")) : "";
  564. document.getElementsByName('cbid.shadowsocksr.' + sid + '.http_path')[0].value = params.get("path") ? decodeURIComponent(params.get("path")) : "";
  565. }
  566. break;
  567. }
  568. s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
  569. return false;
  570. }
  571. case "vmess":
  572. var sstr = b64DecodeUnicode((ssu[1] || "").replace(/#.*/, "").trim());
  573. var ploc = sstr.indexOf("/?");
  574. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "v2ray";
  575. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
  576. document.getElementsByName('cbid.shadowsocksr.' + sid + '.v2ray_protocol')[0].value = "vmess";
  577. document.getElementsByName('cbid.shadowsocksr.' + sid + '.v2ray_protocol')[0].dispatchEvent(event);
  578. var url0, param = "";
  579. if (ploc > 0) {
  580. url0 = sstr.substr(0, ploc);
  581. param = sstr.substr(ploc + 2);
  582. }
  583. var ssm = JSON.parse(sstr);
  584. document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = ssm.ps;
  585. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = ssm.add;
  586. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = ssm.port;
  587. document.getElementsByName('cbid.shadowsocksr.' + sid + '.alter_id')[0].value = ssm.aid;
  588. document.getElementsByName('cbid.shadowsocksr.' + sid + '.vmess_id')[0].value = ssm.id;
  589. document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].value =
  590. (["xhttp", "splithttp"].includes(ssm.net) ? "xhttp" :
  591. (["tcp", "raw"].includes(ssm.net) ? "raw" :
  592. (ssm.net || "raw")));
  593. document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].dispatchEvent(event);
  594. if (ssm.net === "raw" || ssm.net === "tcp") {
  595. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tcp_guise')[0].value = ssm.type;
  596. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tcp_guise')[0].dispatchEvent(event);
  597. if (ssm.type === "http") {
  598. document.getElementsByName('cbid.shadowsocksr.' + sid + '.http_host')[0].value = ssm.host;
  599. document.getElementsByName('cbid.shadowsocksr.' + sid + '.http_path')[0].value = ssm.path;
  600. }
  601. }
  602. if (ssm.net == "ws") {
  603. document.getElementsByName('cbid.shadowsocksr.' + sid + '.ws_host')[0].value = ssm.host;
  604. document.getElementsByName('cbid.shadowsocksr.' + sid + '.ws_path')[0].value = ssm.path;
  605. }
  606. if (ssm.net == "httpupgrade") {
  607. document.getElementsByName('cbid.shadowsocksr.' + sid + '.httpupgrade_host')[0].value = ssm.host;
  608. document.getElementsByName('cbid.shadowsocksr.' + sid + '.httpupgrade_path')[0].value = ssm.path;
  609. }
  610. if (ssm.net == "xhttp" || ssm.net == "splithttp") {
  611. document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_mode')[0].value = ssm.mode || "auto";
  612. document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_host')[0].value = ssm.host;
  613. document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_path')[0].value = ssm.path;
  614. if (ssm.extra !== "" && ssm.extra !== undefined) {
  615. document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra')[0].checked = true; // 设置 enable_xhttp_extra 为 true
  616. document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra')[0].dispatchEvent(event); // 触发事件
  617. document.getElementsByName('cbid.shadowsocksr.' + sid + '.xhttp_extra')[0].value = ssm.extra;
  618. }
  619. }
  620. if (ssm.net == "h2") {
  621. document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_host')[0].value = ssm.host;
  622. document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_path')[0].value = ssm.path;
  623. }
  624. if (ssm.net == "quic") {
  625. document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_security')[0].value = ssm.securty;
  626. document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_key')[0].value = ssm.key;
  627. }
  628. if (ssm.net == "kcp") {
  629. document.getElementsByName('cbid.shadowsocksr.' + sid + '.kcp_guise')[0].value = ssm.type;
  630. }
  631. if (ssm.tls == "tls") {
  632. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].checked = true;
  633. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event);
  634. if (ssm.fp !== "" && ssm.fp !== undefined) {
  635. document.getElementsByName('cbid.shadowsocksr.' + sid + '.fingerprint')[0].value = ssm.fp;
  636. }
  637. if (ssm.alpn !== "" && ssm.alpn !== undefined) {
  638. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_alpn')[0].value = ssm.alpn;
  639. }
  640. if (ssm.host !== "" && ssm.host !== undefined) {
  641. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = ssm.sni || ssm.host;
  642. }
  643. if (ssm.ech !== "" && ssm.ech !== undefined) {
  644. document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_ech')[0].checked = true; // 设置 enable_ech 为 true
  645. document.getElementsByName('cbid.shadowsocksr.' + sid + '.enable_ech')[0].dispatchEvent(event); // 触发事件
  646. document.getElementsByName('cbid.shadowsocksr.' + sid + '.ech_config')[0].value = ssm.ech;
  647. }
  648. document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked =
  649. !!(ssm.allowInsecure ?? ssm.allowlnsecure ?? ssm['skip-cert-verify']); // 设置 insecure 为 true
  650. document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].dispatchEvent(event); // 触发事件
  651. }
  652. if (ssm.mux !== undefined) {
  653. document.getElementsByName('cbid.shadowsocksr.' + sid + '.mux')[0].checked = true;
  654. document.getElementsByName('cbid.shadowsocksr.' + sid + '.mux')[0].dispatchEvent(event);
  655. }
  656. s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
  657. return false;
  658. case "vless":
  659. try {
  660. var url = new URL("http://" + ssu[1]);
  661. var params = url.searchParams;
  662. } catch(e) {
  663. alert(e);
  664. return false;
  665. }
  666. // Check if the elements exist before trying to modify them
  667. function setElementValue(name, value) {
  668. const element = document.getElementsByName(name)[0];
  669. if (element) {
  670. if (element.type === "checkbox" || element.type === "radio") {
  671. element.checked = value === true;
  672. } else {
  673. element.value = value;
  674. }
  675. }
  676. }
  677. function dispatchEventIfExists(name, event) {
  678. const element = document.getElementsByName(name)[0];
  679. if (element) {
  680. element.dispatchEvent(event);
  681. }
  682. }
  683. setElementValue('cbid.shadowsocksr.' + sid + '.alias', url.hash ? decodeURIComponent(url.hash.slice(1)) : "");
  684. setElementValue('cbid.shadowsocksr.' + sid + '.type', "v2ray");
  685. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.type', event);
  686. setElementValue('cbid.shadowsocksr.' + sid + '.v2ray_protocol', "vless");
  687. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.v2ray_protocol', event);
  688. setElementValue('cbid.shadowsocksr.' + sid + '.server', url.hostname);
  689. setElementValue('cbid.shadowsocksr.' + sid + '.server_port', url.port || "80");
  690. setElementValue('cbid.shadowsocksr.' + sid + '.vmess_id', url.username);
  691. setElementValue('cbid.shadowsocksr.' + sid + '.transport',
  692. params.get("type") === "http" ? "h2" :
  693. (["xhttp", "splithttp"].includes(params.get("type")) ? "xhttp" :
  694. (["tcp", "raw"].includes(params.get("type")) ? "raw" :
  695. (params.get("type") || "raw")))
  696. );
  697. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.transport', event);
  698. setElementValue('cbid.shadowsocksr.' + sid + '.vless_encryption', params.get("encryption") || "none");
  699. if ([ "tls", "xtls", "reality" ].includes(params.get("security"))) {
  700. setElementValue('cbid.shadowsocksr.' + sid + '.' + params.get("security"), true);
  701. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.' + params.get("security"), event);
  702. if (params.get("security") === "tls") {
  703. if (params.get("ech") && params.get("ech").trim() !== "") {
  704. setElementValue('cbid.shadowsocksr.' + sid + '.enable_ech', true); // 设置 enable_ech 为 true
  705. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.enable_ech', event); // 触发事件
  706. setElementValue('cbid.shadowsocksr.' + sid + '.ech_config', params.get("ech") || "");
  707. }
  708. if (params.get("allowInsecure") === "1") {
  709. setElementValue('cbid.shadowsocksr.' + sid + '.insecure', true); // 设置 insecure 为 true
  710. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.insecure', event); // 触发事件
  711. }
  712. }
  713. if (params.get("security") === "reality") {
  714. setElementValue('cbid.shadowsocksr.' + sid + '.reality_publickey', params.get("pbk") ? decodeURIComponent(params.get("pbk")) : "");
  715. setElementValue('cbid.shadowsocksr.' + sid + '.reality_shortid', params.get("sid") || "");
  716. setElementValue('cbid.shadowsocksr.' + sid + '.reality_spiderx', params.get("spx") ? decodeURIComponent(params.get("spx")) : "");
  717. if (params.get("pqv") && params.get("pqv").trim() !== "") {
  718. setElementValue('cbid.shadowsocksr.' + sid + '.enable_mldsa65verify', true); // 设置 enable_mldsa65verify 为 true
  719. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.enable_mldsa65verify', event); // 触发事件
  720. setElementValue('cbid.shadowsocksr.' + sid + '.reality_mldsa65verify', params.get("pqv") || "");
  721. }
  722. }
  723. setElementValue('cbid.shadowsocksr.' + sid + '.tls_flow', params.get("flow") || "none");
  724. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.tls_flow', event);
  725. setElementValue('cbid.shadowsocksr.' + sid + '.tls_alpn', params.get("alpn") || "");
  726. setElementValue('cbid.shadowsocksr.' + sid + '.fingerprint', params.get("fp") || "");
  727. setElementValue('cbid.shadowsocksr.' + sid + '.tls_host', params.get("sni") || "");
  728. }
  729. switch (params.get("type")) {
  730. case "ws":
  731. if (params.get("security") !== "tls") {
  732. setElementValue('cbid.shadowsocksr.' + sid + '.ws_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
  733. }
  734. setElementValue('cbid.shadowsocksr.' + sid + '.ws_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
  735. break;
  736. case "httpupgrade":
  737. if (params.get("security") !== "tls") {
  738. setElementValue('cbid.shadowsocksr.' + sid + '.httpupgrade_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
  739. }
  740. setElementValue('cbid.shadowsocksr.' + sid + '.httpupgrade_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
  741. break;
  742. case "xhttp":
  743. case "splithttp":
  744. if (params.get("security") !== "tls") {
  745. setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
  746. }
  747. setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_mode', params.get("mode") || "auto");
  748. setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_path', params.get("path") ? decodeURIComponent(params.get("path")) : "/");
  749. if (params.get("extra") && params.get("extra").trim() !== "") {
  750. setElementValue('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra', true); // 设置 enable_xhttp_extra 为 true
  751. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.enable_xhttp_extra', event); // 触发事件
  752. setElementValue('cbid.shadowsocksr.' + sid + '.xhttp_extra', params.get("extra") || "");
  753. }
  754. break;
  755. case "kcp":
  756. setElementValue('cbid.shadowsocksr.' + sid + '.kcp_guise', params.get("headerType") || "none");
  757. setElementValue('cbid.shadowsocksr.' + sid + '.seed', params.get("seed") || "");
  758. break;
  759. case "http":
  760. /* this is non-standard, bullshit */
  761. case "h2":
  762. setElementValue('cbid.shadowsocksr.' + sid + '.h2_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
  763. setElementValue('cbid.shadowsocksr.' + sid + '.h2_path', params.get("path") ? decodeURIComponent(params.get("path")) : "");
  764. break;
  765. case "quic":
  766. setElementValue('cbid.shadowsocksr.' + sid + '.quic_guise', params.get("headerType") || "none");
  767. setElementValue('cbid.shadowsocksr.' + sid + '.quic_security', params.get("quicSecurity") || "none");
  768. setElementValue('cbid.shadowsocksr.' + sid + '.quic_key', params.get("key") || "");
  769. break;
  770. case "grpc":
  771. setElementValue('cbid.shadowsocksr.' + sid + '.serviceName', params.get("serviceName") || "");
  772. setElementValue('cbid.shadowsocksr.' + sid + '.grpc_mode', params.get("mode") || "gun");
  773. break;
  774. case "tcp":
  775. case "raw":
  776. setElementValue('cbid.shadowsocksr.' + sid + '.tcp_guise', params.get("headerType") || "none");
  777. dispatchEventIfExists('cbid.shadowsocksr.' + sid + '.tcp_guise', event);
  778. if (params.get("headerType") === "http") {
  779. setElementValue('cbid.shadowsocksr.' + sid + '.http_host', params.get("host") ? decodeURIComponent(params.get("host")) : "");
  780. setElementValue('cbid.shadowsocksr.' + sid + '.http_path', params.get("path") ? decodeURIComponent(params.get("path")) : "");
  781. }
  782. break;
  783. }
  784. s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
  785. return false;
  786. case "tuic":
  787. var url0 = (ssu[1] || "");
  788. var param = "";
  789. // 先分离 #(alias)
  790. var hashIndex = url0.indexOf("#");
  791. if (hashIndex >= 0) {
  792. param = url0.substring(hashIndex + 1);
  793. url0 = url0.substring(0, hashIndex);
  794. }
  795. // 再分离 ? 或 /?(参数)
  796. var queryIndex = (url0 = url0.replace('/?', '?')).indexOf("?");
  797. var query = "";
  798. if (queryIndex >= 0) {
  799. query = url0.substring(queryIndex + 1);
  800. url0 = url0.substring(0, queryIndex);
  801. }
  802. var params = Object.fromEntries(new URLSearchParams(query));
  803. var sipIndex = url0.indexOf("@");
  804. var userInfo = url0.substring(0, sipIndex); // 格式:uuid:password
  805. var hostPart = url0.substring(sipIndex + 1); // 格式:hostname:port
  806. var userInfoSplitIndex = userInfo.indexOf(":");
  807. if(userInfoSplitIndex < 0) {
  808. // 格式错误
  809. s.innerHTML = "<font style='color:red'><%:Userinfo format error.%></font>";
  810. break;
  811. }
  812. var method = userInfo.substring(0, userInfoSplitIndex);
  813. var password = userInfo.substring(userInfoSplitIndex + 1);
  814. var url = new URL("http://" + hostPart); // 用 URL 提取 host 与 port
  815. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = ssu[0];
  816. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
  817. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = url.hostname;
  818. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = url.port;
  819. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_uuid')[0].value = method;
  820. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_ip')[0].value = params.sni || "";
  821. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_passwd')[0].value = password;
  822. document.getElementsByName('cbid.shadowsocksr.' + sid + '.udp_relay_mode')[0].value = params.udp_relay_mode || "native";
  823. document.getElementsByName('cbid.shadowsocksr.' + sid + '.congestion_control')[0].value = params.congestion_control || "cubic";
  824. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tuic_alpn')[0].value = params.alpn || "";
  825. if (param != undefined) {
  826. document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURIComponent(param);
  827. }
  828. s.innerHTML = "<font style=\'color:green\'><%:Import configuration information successfully.%></font>";
  829. return false;
  830. default:
  831. s.innerHTML = "<font style=\'color:red\'><%:Invalid format.%></font>";
  832. return false;
  833. }
  834. }
  835. //]]>
  836. </script>
  837. <input type="button" class="btn cbi-button cbi-button-apply" value="<%:Import%>" onclick="return import_ssr_url(this, '<%=self.option%>', '<%=self.value%>')" />
  838. <span id="<%=self.option%>-status"></span>
  839. <%+cbi/valuefooter%>