ssrurl.htm 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. <%+cbi/valueheader%>
  2. <script type="text/javascript">
  3. //<![CDATA[
  4. function padright(str, cnt, pad) {
  5. return str + Array(cnt + 1).join(pad);
  6. }
  7. function b64EncodeUnicode(str) {
  8. return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
  9. return String.fromCharCode('0x' + p1);
  10. }));
  11. }
  12. function b64encutf8safe(str) {
  13. return b64EncodeUnicode(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '');
  14. }
  15. function b64DecodeUnicode(str) {
  16. return decodeURIComponent(Array.prototype.map.call(atob(str), function (c) {
  17. return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
  18. }).join(''));
  19. }
  20. function b64decutf8safe(str) {
  21. var l;
  22. str = str.replace(/-/g, "+").replace(/_/g, "/");
  23. l = str.length;
  24. l = (4 - l % 4) % 4;
  25. if (l) str = padright(str, l, "=");
  26. return b64DecodeUnicode(str);
  27. }
  28. function b64encsafe(str) {
  29. return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, '')
  30. }
  31. function b64decsafe(str) {
  32. var l;
  33. str = str.replace(/-/g, "+").replace(/_/g, "/");
  34. l = str.length;
  35. l = (4 - l % 4) % 4;
  36. if (l) str = padright(str, l, "=");
  37. return atob(str);
  38. }
  39. function dictvalue(d, key) {
  40. var v = d[key];
  41. if (typeof (v) == 'undefined' || v == '') return '';
  42. return b64decsafe(v);
  43. }
  44. function export_ssr_url(btn, urlname, sid) {
  45. var s = document.getElementById(urlname + '-status');
  46. if (!s) return false;
  47. var v_server = document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0];
  48. var v_port = document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0];
  49. var v_protocol = document.getElementsByName('cbid.shadowsocksr.' + sid + '.protocol')[0];
  50. var v_method = document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method')[0];
  51. var v_obfs = document.getElementsByName('cbid.shadowsocksr.' + sid + '.obfs')[0];
  52. var v_password = document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0];
  53. var v_obfs_param = document.getElementsByName('cbid.shadowsocksr.' + sid + '.obfs_param')[0];
  54. var v_protocol_param = document.getElementsByName('cbid.shadowsocksr.' + sid + '.protocol_param')[0];
  55. var v_alias = document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0];
  56. 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);
  57. var textarea = document.createElement("textarea");
  58. textarea.textContent = "ssr://" + b64encsafe(ssr_str);
  59. textarea.style.position = "fixed";
  60. document.body.appendChild(textarea);
  61. textarea.select();
  62. try {
  63. document.execCommand("copy"); // Security exception may be thrown by some browsers.
  64. s.innerHTML = "<font color='green'><%:Copy SSR to clipboard successfully.%></font>";
  65. } catch (ex) {
  66. s.innerHTML = "<font color='red'><%:Unable to copy SSR to clipboard.%></font>";
  67. } finally {
  68. document.body.removeChild(textarea);
  69. }
  70. return false;
  71. }
  72. function import_ssr_url(btn, urlname, sid) {
  73. var s = document.getElementById(urlname + '-status');
  74. if (!s) return false;
  75. var ssrurl = prompt("<%:Paste sharing link here%>", "");
  76. if (ssrurl == null || ssrurl == "") {
  77. s.innerHTML = "<font color='red'><%:User cancelled.%></font>";
  78. return false;
  79. }
  80. s.innerHTML = "";
  81. //var ssu = ssrurl.match(/ssr:\/\/([A-Za-z0-9_-]+)/i);
  82. var ssu = ssrurl.split('://');
  83. //console.log(ssu.length);
  84. var event = document.createEvent("HTMLEvents");
  85. event.initEvent("change", true, true);
  86. switch (ssu[0]) {
  87. case "ss":
  88. var url0, param = "";
  89. var sipIndex = ssu[1].indexOf("@");
  90. var ploc = ssu[1].indexOf("#");
  91. if (ploc > 0) {
  92. url0 = ssu[1].substr(0, ploc);
  93. param = ssu[1].substr(ploc + 1);
  94. } else {
  95. url0 = ssu[1];
  96. }
  97. if (sipIndex != -1) {
  98. // SIP002
  99. var userInfo = b64decsafe(url0.substr(0, sipIndex));
  100. var temp = url0.substr(sipIndex + 1).split("/?");
  101. var serverInfo = temp[0].split(":");
  102. var server = serverInfo[0];
  103. var port = serverInfo[1];
  104. var method, password, plugin, pluginOpts;
  105. if (temp[1]) {
  106. var pluginInfo = decodeURIComponent(temp[1]);
  107. var pluginIndex = pluginInfo.indexOf(";");
  108. var pluginNameInfo = pluginInfo.substr(0, pluginIndex);
  109. plugin = pluginNameInfo.substr(pluginNameInfo.indexOf("=") + 1);
  110. pluginOpts = pluginInfo.substr(pluginIndex + 1);
  111. }
  112. var userInfoSplitIndex = userInfo.indexOf(":");
  113. if (userInfoSplitIndex != -1) {
  114. method = userInfo.substr(0, userInfoSplitIndex);
  115. password = userInfo.substr(userInfoSplitIndex + 1);
  116. }
  117. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "ss";
  118. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
  119. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = server;
  120. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = port;
  121. document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = password || "";
  122. document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method_ss')[0].value = method || "";
  123. document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin')[0].value = plugin || "none";
  124. document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin')[0].dispatchEvent(event);
  125. document.getElementsByName('cbid.shadowsocksr.' + sid + '.plugin_opts')[0].value = pluginOpts || "";
  126. if (param != undefined) {
  127. document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param);
  128. }
  129. s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
  130. } else {
  131. var sstr = b64decsafe(url0);
  132. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "ss";
  133. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
  134. var team = sstr.split('@');
  135. console.log(param);
  136. var part1 = team[0].split(':');
  137. var part2 = team[1].split(':');
  138. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = part2[0];
  139. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = part2[1];
  140. document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = part1[1];
  141. document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method_ss')[0].value = part1[0];
  142. if (param != undefined) {
  143. document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param);
  144. }
  145. s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
  146. }
  147. return false;
  148. case "ssr":
  149. var sstr = b64decsafe(ssu[1]);
  150. var ploc = sstr.indexOf("/?");
  151. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "ssr";
  152. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
  153. var url0, param = "";
  154. if (ploc > 0) {
  155. url0 = sstr.substr(0, ploc);
  156. param = sstr.substr(ploc + 2);
  157. }
  158. var ssm = url0.match(/^(.+):([^:]+):([^:]*):([^:]+):([^:]*):([^:]+)/);
  159. if (!ssm || ssm.length < 7) return false;
  160. var pdict = {};
  161. if (param.length > 2) {
  162. var a = param.split('&');
  163. for (var i = 0; i < a.length; i++) {
  164. var b = a[i].split('=');
  165. pdict[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || '');
  166. }
  167. }
  168. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = ssm[1];
  169. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = ssm[2];
  170. document.getElementsByName('cbid.shadowsocksr.' + sid + '.protocol')[0].value = ssm[3];
  171. document.getElementsByName('cbid.shadowsocksr.' + sid + '.encrypt_method')[0].value = ssm[4];
  172. document.getElementsByName('cbid.shadowsocksr.' + sid + '.obfs')[0].value = ssm[5];
  173. document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = b64decsafe(ssm[6]);
  174. document.getElementsByName('cbid.shadowsocksr.' + sid + '.obfs_param')[0].value = dictvalue(pdict, 'obfsparam');
  175. document.getElementsByName('cbid.shadowsocksr.' + sid + '.protocol_param')[0].value = dictvalue(pdict, 'protoparam');
  176. var rem = pdict['remarks'];
  177. if (typeof (rem) != 'undefined' && rem != '' && rem.length > 0) document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = b64decutf8safe(rem);
  178. s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
  179. return false;
  180. case "trojan":
  181. var url0, param = "";
  182. var ploc = ssu[1].indexOf("#");
  183. if (ploc > 0) {
  184. url0 = ssu[1].substr(0, ploc);
  185. param = ssu[1].substr(ploc + 1);
  186. } else {
  187. url0 = ssu[1]
  188. }
  189. var sstr = url0;
  190. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "trojan";
  191. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
  192. var team = sstr.split('@');
  193. var password = team[0]
  194. var serverPart = team[1].split(':');
  195. var others = serverPart[1].split('?');
  196. var port = others[0]
  197. var queryParam = {}
  198. if (others.length > 1) {
  199. var queryParams = others[1]
  200. var queryArray = queryParams.split('&');
  201. for (i = 0; i < queryArray.length; i++) {
  202. var params = queryArray[i].split('=');
  203. queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
  204. }
  205. }
  206. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = serverPart[0];
  207. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = port;
  208. document.getElementsByName('cbid.shadowsocksr.' + sid + '.password')[0].value = password;
  209. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].checked = true;
  210. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event);
  211. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = queryParam.peer || '';
  212. document.getElementsByName('cbid.shadowsocksr.' + sid + '.insecure')[0].checked = queryParam.allowInsecure == '1';
  213. if (param != undefined) {
  214. document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param);
  215. }
  216. s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
  217. return false;
  218. case "vmess":
  219. var sstr = b64DecodeUnicode(ssu[1]);
  220. var ploc = sstr.indexOf("/?");
  221. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "vmess";
  222. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
  223. var url0, param = "";
  224. if (ploc > 0) {
  225. url0 = sstr.substr(0, ploc);
  226. param = sstr.substr(ploc + 2);
  227. }
  228. var ssm = JSON.parse(sstr);
  229. document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = ssm.ps;
  230. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = ssm.add;
  231. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = ssm.port;
  232. document.getElementsByName('cbid.shadowsocksr.' + sid + '.alter_id')[0].value = ssm.aid;
  233. document.getElementsByName('cbid.shadowsocksr.' + sid + '.uuid')[0].value = ssm.id;
  234. document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].value = ssm.net;
  235. document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].dispatchEvent(event);
  236. if (ssm.net == "tcp") {
  237. if (ssm.type && ssm.type != "http") {
  238. ssm.type = "none"
  239. }
  240. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tcp_guise')[0].value = ssm.type;
  241. document.getElementsByName('cbid.shadowsocksr.' + sid + '.http_host')[0].value = ssm.host;
  242. document.getElementsByName('cbid.shadowsocksr.' + sid + '.http_path')[0].value = ssm.path;
  243. }
  244. if (ssm.net == "ws") {
  245. document.getElementsByName('cbid.shadowsocksr.' + sid + '.ws_host')[0].value = ssm.host;
  246. document.getElementsByName('cbid.shadowsocksr.' + sid + '.ws_path')[0].value = ssm.path;
  247. }
  248. if (ssm.net == "h2") {
  249. document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_host')[0].value = ssm.host;
  250. document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_path')[0].value = ssm.path;
  251. }
  252. if (ssm.net == "quic") {
  253. document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_security')[0].value = ssm.securty;
  254. document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_key')[0].value = ssm.key;
  255. }
  256. if (ssm.net == "kcp") {
  257. document.getElementsByName('cbid.shadowsocksr.' + sid + '.kcp_guise')[0].value = ssm.type;
  258. }
  259. if (ssm.tls == "tls") {
  260. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].checked = true;
  261. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event);
  262. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = ssm.host;
  263. }
  264. document.getElementsByName('cbid.shadowsocksr.' + sid + '.mux')[0].checked = true;
  265. document.getElementsByName('cbid.shadowsocksr.' + sid + '.mux')[0].dispatchEvent(event);
  266. s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
  267. return false;
  268. case "vless":
  269. var url0, param = "";
  270. var ploc = ssu[1].indexOf("#");
  271. if (ploc > 0) {
  272. url0 = ssu[1].substr(0, ploc);
  273. param = decodeURIComponent(ssu[1].substr(ploc + 1));
  274. } else {
  275. url0 = ssu[1]
  276. }
  277. var sstr = url0;
  278. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].value = "vless";
  279. document.getElementsByName('cbid.shadowsocksr.' + sid + '.type')[0].dispatchEvent(event);
  280. var team = sstr.split('@');
  281. var uuid = team[0]
  282. var serverPart = team[1].split(':');
  283. var others = serverPart[1].split('?');
  284. var port = others[0]
  285. var queryParam = {}
  286. if (others.length > 1) {
  287. var queryParams = others[1]
  288. var queryArray = queryParams.split('&');
  289. for (i = 0; i < queryArray.length; i++) {
  290. var params = queryArray[i].split('=');
  291. queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
  292. }
  293. }
  294. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server')[0].value = serverPart[0];
  295. document.getElementsByName('cbid.shadowsocksr.' + sid + '.server_port')[0].value = port;
  296. document.getElementsByName('cbid.shadowsocksr.' + sid + '.vmess_id')[0].value = uuid;
  297. document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].value = queryParam.type || "tcp";
  298. document.getElementsByName('cbid.shadowsocksr.' + sid + '.transport')[0].dispatchEvent(event);
  299. document.getElementsByName('cbid.shadowsocksr.' + sid + '.vless_encryption')[0].value = queryParam.encryption || "none";
  300. if (queryParam.security == "tls") {
  301. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].checked = true;
  302. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = queryParam.sni || serverPart[0];
  303. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls')[0].dispatchEvent(event);
  304. }
  305. switch (queryParam.type) {
  306. case "ws":
  307. document.getElementsByName('cbid.shadowsocksr.' + sid + '.ws_host')[0].value = queryParam.host;
  308. document.getElementsByName('cbid.shadowsocksr.' + sid + '.ws_path')[0].value = queryParam.path;
  309. break;
  310. case "kcp":
  311. document.getElementsByName('cbid.shadowsocksr.' + sid + '.kcp_guise')[0].value = queryParam.headerType || "none";
  312. document.getElementsByName('cbid.shadowsocksr.' + sid + '.kcp_guise')[0].dispatchEvent(event);
  313. document.getElementsByName('cbid.shadowsocksr.' + sid + '.seed')[0].value = queryParam.seed;
  314. break;
  315. case "http":
  316. document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_host')[0].value = queryParam.host;
  317. document.getElementsByName('cbid.shadowsocksr.' + sid + '.h2_path')[0].value = queryParam.path;
  318. break;
  319. case "quic":
  320. document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_guise')[0].value = queryParam.headerType || "none";
  321. document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_guise')[0].dispatchEvent(event);
  322. document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_security')[0].value = queryParam.quicSecurity;
  323. document.getElementsByName('cbid.shadowsocksr.' + sid + '.quic_key')[0].value = queryParam.key;
  324. break;
  325. default:
  326. if (queryParam.security == "xtls") {
  327. document.getElementsByName('cbid.shadowsocksr.' + sid + '.xtls')[0].checked = true;
  328. document.getElementsByName('cbid.shadowsocksr.' + sid + '.xtls')[0].dispatchEvent(event);
  329. document.getElementsByName('cbid.shadowsocksr.' + sid + '.vless_flow')[0].value = queryParam.flow || "xtls-rprx-splice";
  330. document.getElementsByName('cbid.shadowsocksr.' + sid + '.tls_host')[0].value = queryParam.sni || serverPart[0];
  331. }
  332. break;
  333. }
  334. if (param != undefined) {
  335. document.getElementsByName('cbid.shadowsocksr.' + sid + '.alias')[0].value = decodeURI(param);
  336. }
  337. s.innerHTML = "<font color='green'><%:Import configuration information successfully.%></font>";
  338. return false;
  339. default:
  340. s.innerHTML = "<font color='red'><%:Invalid format.%></font>";
  341. return false;
  342. }
  343. }
  344. //]]>
  345. </script>
  346. <input type="button" class="cbi-button cbi-button-apply" value="<%:Import%>" onclick="return import_ssr_url(this, '<%=self.option%>', '<%=self.value%>')" />
  347. <span id="<%=self.option%>-status"></span>
  348. <%+cbi/valuefooter%>