vdir.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. <div class="standardContainer">
  2. <div class="ui basic segment">
  3. <h2>Virtual Directory</h2>
  4. <p>A virtual directory is a consolidated view of multiple directories that provides a unified entry point for users to access disparate sources.</p>
  5. </div>
  6. <div id="currentVirtualDirectoryAttachingHost" class="ui basic segment">
  7. Select a host / routing rule to start editing Virtual Directory
  8. </div>
  9. <div class="ui stackable grid">
  10. <div class="six wide column">
  11. <h4>Select a Target Host / Site</h4>
  12. <p>Attach Virtual Directory routing rule to root proxy router</p>
  13. <div class="ui checkbox">
  14. <input type="checkbox" id="useRootProxyRouterForVdir" onchange="handleVdirAttachTargetChange(this);">
  15. <label>Use Root Proxy Router<br>
  16. <small>Only applicable when Default Site is set to "Reverse Proxy" mode</small></label>
  17. </div>
  18. <div class="ui horizontal divider">OR</div>
  19. <p>Create Virtual Directory routing in existing host / routing rule entries</p>
  20. <div class="ui fluid search selection dropdown">
  21. <input type="hidden" id="vdirBaseRoutingRule" name="vdirBaseRoutingRule" onchange="handleVdirAttachTargetChange();">
  22. <i class="dropdown icon"></i>
  23. <div class="default text">Select a host to edit</div>
  24. <div class="menu" id="hostDomainList">
  25. </div>
  26. </div>
  27. </div>
  28. <div class="ten wide column">
  29. <h4>Edit Virtual Directory Routing Rules</h4>
  30. <p>The following are the list of Virtual Directories currently handled by the host router above</p>
  31. <div style="width: 100%; overflow-x: auto; margin-bottom: 1em;">
  32. <table class="ui celled sortable basic unstackable compact table">
  33. <thead>
  34. <tr>
  35. <th>Virtual Directory</th>
  36. <th>Destination</th>
  37. <th class="no-sort" style="min-width: 7.2em;">Actions</th>
  38. </tr>
  39. </thead>
  40. <tbody id="vdirList">
  41. <tr>
  42. <td data-label="" colspan="3">No Selected Host</td>
  43. </tr>
  44. </tbody>
  45. </table>
  46. </div>
  47. <button class="ui icon right floated basic button" onclick="listVdirs();"><i class="green refresh icon"></i> Refresh</button>
  48. <br><br>
  49. <div class="ui divider"></div>
  50. <div id="newVDSection" class="disabled section">
  51. <h4>New Virtual Directory Rule</h4>
  52. <form class="ui form">
  53. <div class="field">
  54. <label>Matching Path Prefix</label>
  55. <input type="text" id="virtualDirectoryPath" placeholder="/mysite/">
  56. <small>Path that follows your select host / domain, e.g. <code>/mysite/</code> as path prefix will forward all request that matches <code>mydomain.com/mysite/*</code></small>
  57. </div>
  58. <div class="field">
  59. <label>Target IP Address or Domain Name with port</label>
  60. <input type="text" id="virtualDirectoryDomain" onchange="updateVDTargetTLSState();">
  61. <small>E.g. 192.168.0.101:8000 or example.com</small>
  62. </div>
  63. <div class="field">
  64. <div class="ui checkbox">
  65. <input type="checkbox" id="vdReqTls">
  66. <label>Proxy Target require TLS Connection <br><small>(i.e. Your proxy target starts with https://)</small></label>
  67. </div>
  68. </div>
  69. <!-- Advance configs -->
  70. <div class="ui basic segment" style="background-color: #f7f7f7; border-radius: 1em;">
  71. <div id="advanceProxyRules" class="ui fluid accordion">
  72. <div class="title">
  73. <i class="dropdown icon"></i>
  74. Advance Settings
  75. </div>
  76. <div class="content">
  77. <p></p>
  78. <div class="field">
  79. <div class="ui checkbox">
  80. <input type="checkbox" id="vdSkipTLSValidation">
  81. <label>Ignore TLS/SSL Verification Error<br><small>For targets that is using self-signed, expired certificate (Not Recommended)</small></label>
  82. </div>
  83. </div>
  84. </div>
  85. </div>
  86. </div>
  87. <button class="ui basic button" onclick="addVdirToHost(); event.preventDefault();"><i class="green add icon"></i> Create Virtual Directory</button>
  88. </form>
  89. </div>
  90. </div>
  91. </div>
  92. <br><br>
  93. </div>
  94. <script>
  95. //Virtual directories functions
  96. //Initialize the list of hosts that can be used to attach vdirs config
  97. function initVdirList(){
  98. //Load the hosts into the dropdown
  99. $("#hostDomainList").html("");
  100. $.get("/api/proxy/list?type=host", function(data){
  101. if (data.error != undefined){
  102. msgbox(data.error, false);
  103. }else{
  104. if (data.length == 0){
  105. //No hosts found
  106. }else{
  107. data.forEach(proxyEndpoint => {
  108. let domain = proxyEndpoint.RootOrMatchingDomain;
  109. $("#hostDomainList").append(`<div class="item" data-value="${domain}">${domain}</div>`);
  110. });
  111. //Update the dropdown events
  112. $("#vdirBaseRoutingRule").parent().dropdown();
  113. }
  114. }
  115. });
  116. }
  117. function handleVdirAttachTargetChange(targetCheckbox=undefined){
  118. if (targetCheckbox != undefined && targetCheckbox.checked){
  119. $("#vdirBaseRoutingRule").parent().addClass("disabled");
  120. //Load the vdir list for root
  121. loadVdirList("root");
  122. $("#newVDSection").removeClass("disabled");
  123. }else{
  124. $("#vdirBaseRoutingRule").parent().removeClass("disabled");
  125. let selectedEndpointRule = $("#vdirBaseRoutingRule").val();
  126. if (selectedEndpointRule != ""){
  127. loadVdirList(selectedEndpointRule);
  128. $("#newVDSection").removeClass("disabled");
  129. }else{
  130. $("#newVDSection").addClass("disabled");
  131. }
  132. }
  133. }
  134. function loadVdirList(endpoint){
  135. $("#currentVirtualDirectoryAttachingHost").html(`Editing Host: ${endpoint}`);
  136. let reqURL = "/api/proxy/vdir/list?type=host&ep=" + endpoint;
  137. if (endpoint == "root"){
  138. //Load root endpoint vdir list
  139. reqURL = "/api/proxy/vdir/list?type=root";
  140. }
  141. $.get(reqURL, function(data){
  142. if (data.error != undefined){
  143. msgbox(data.error, false);
  144. }else{
  145. $("#vdirList").html("");
  146. if (data.length == 0){
  147. //No virtual directory for this host
  148. $("#vdirList").append(`<tr>
  149. <td data-label="" colspan="3"><i class="green check circle icon"></i> No Virtual Directory Routing Rule</td>
  150. </tr>`);
  151. }else{
  152. //List the vdirs
  153. console.log(data);
  154. data.forEach(vdir => {
  155. $("#vdirList").append(`<tr>
  156. <td data-label="" editable="false">${vdir.MatchingPath}</td>
  157. <td data-label="" editable="true" datatype="domain">${vdir.Domain}</td>
  158. <td class="center aligned" editable="true" datatype="action" data-label="">
  159. <button class="ui circular mini basic icon button editBtn" onclick='editEndpoint("vdir","${vdir.RootOrMatchingDomain}")'><i class="edit icon"></i></button>
  160. <button class="ui circular mini red basic icon button" onclick='deleteEndpoint("vdir","${vdir.RootOrMatchingDomain}")'><i class="trash icon"></i></button>
  161. </td>
  162. </tr>`);
  163. })
  164. }
  165. }
  166. });
  167. }
  168. function updateVDTargetTLSState(){
  169. var targetDomain = $("#virtualDirectoryDomain").val().trim();
  170. if (targetDomain != ""){
  171. $.ajax({
  172. url: "/api/proxy/tlscheck",
  173. data: {url: targetDomain},
  174. success: function(data){
  175. if (data.error != undefined){
  176. }else if (data == "https"){
  177. $("#vdReqTls").parent().checkbox("set checked");
  178. }else if (data == "http"){
  179. $("#vdReqTls").parent().checkbox("set unchecked");
  180. }
  181. }
  182. });
  183. }
  184. }
  185. function reloadVdirList(){
  186. if ($("#useRootProxyRouterForVdir")[0].checked){
  187. loadVdirList("root");
  188. return;
  189. }
  190. let endpoint = $("#vdirBaseRoutingRule").val().trim();
  191. if (endpoint != ""){
  192. loadVdirList(endpoint);
  193. }
  194. }
  195. //Create a virtual directory routing rule and attach to this endpoint
  196. function addVdirToHost(){
  197. var matchingPath = $("#virtualDirectoryPath").val().trim();
  198. var targetDomain = $("#virtualDirectoryDomain").val().trim();
  199. var reqTLS = $("#vdReqTls")[0].checked;
  200. var skipTLSValidation = $("#vdSkipTLSValidation")[0].checked;
  201. //Validate the input data
  202. if (matchingPath == ""){
  203. $("#virtualDirectoryPath").parent().addClass('error');
  204. return;
  205. }else{
  206. $("#virtualDirectoryPath").parent().removeClass('error');
  207. }
  208. if (targetDomain == ""){
  209. $("#virtualDirectoryDomain").parent().addClass('error');
  210. return;
  211. }else{
  212. $("#virtualDirectoryDomain").parent().removeClass('error');
  213. }
  214. //Check if we are editing host
  215. let epType = "host";
  216. let endpoint = "root";
  217. if ($("#useRootProxyRouterForVdir")[0].checked){
  218. //Editing root virtual directory
  219. epType = "root";
  220. }else{
  221. //Editing hosts virtual directory
  222. endpoint = $("#vdirBaseRoutingRule").val().trim();
  223. }
  224. //Create a virtual directory endpoint
  225. $.ajax({
  226. url: "/api/proxy/vdir/add",
  227. method: "POST",
  228. data: {
  229. "type": epType,
  230. "endpoint": endpoint,
  231. "path": matchingPath,
  232. "domain":targetDomain,
  233. "reqTLS":reqTLS,
  234. "skipValid":skipTLSValidation,
  235. },
  236. success: function(data){
  237. if (data.error != undefined){
  238. msgbox(data.error, false);
  239. }else{
  240. msgbox("New Virtual Directory rule added");
  241. reloadVdirList();
  242. resetVdirForm();
  243. }
  244. },
  245. error: function(){
  246. msgbox("Add Virtual Directory failed due to unknown reasons", false);
  247. }
  248. })
  249. }
  250. //Reset the vdir form
  251. function resetVdirForm(){
  252. $("#virtualDirectoryPath").val("");
  253. $("#virtualDirectoryDomain").val("");
  254. $("#vdReqTls").parent().checkbox("set unchecked");
  255. $("#vdSkipTLSValidation").parent().checkbox("set unchecked");
  256. }
  257. /*
  258. function listVdirs(){
  259. $.get("/api/proxy/list?type=vdir", function(data){
  260. $("#vdirList").html(``);
  261. if (data.error !== undefined){
  262. $("#vdirList").append(`<tr>
  263. <td data-label="" colspan="3"><i class="remove icon"></i> ${data.error}</td>
  264. </tr>`);
  265. }else if (data.length == 0){
  266. $("#vdirList").append(`<tr>
  267. <td data-label="" colspan="3"><i class="checkmark icon"></i> No Virtual Directory Record</td>
  268. </tr>`);
  269. }else{
  270. data.forEach(vdir => {
  271. let tlsIcon = "";
  272. let vdirData = encodeURIComponent(JSON.stringify(vdir));
  273. if (vdir.RequireTLS){
  274. tlsIcon = `<i class="green lock icon" title="TLS Mode"></i>`;
  275. if (vdir.SkipCertValidations){
  276. tlsIcon = `<i class="yellow lock icon" title="TLS/SSL mode without verification"></i>`
  277. }
  278. }
  279. let tlsVerificationField = "";
  280. if (vdir.RequireTLS){
  281. tlsVerificationField = !vdir.SkipCertValidations?`<i class="ui green check icon"></i>`:`<i class="ui yellow exclamation circle icon" title="TLS/SSL Verification will be skipped on this host"></i>`
  282. }else{
  283. tlsVerificationField = "N/A"
  284. }
  285. $("#vdirList").append(`<tr eptuuid="${vdir.RootOrMatchingDomain}" payload="${vdirData}" class="vdirEntry">
  286. <td data-label="" editable="false">${vdir.RootOrMatchingDomain}</td>
  287. <td data-label="" editable="true" datatype="domain">${vdir.Domain} ${tlsIcon}</td>
  288. <td data-label="" editable="true" datatype="basicauth">${vdir.RequireBasicAuth?`<i class="ui green check icon"></i>`:`<i class="ui grey remove icon"></i>`}</td>
  289. <td class="center aligned" editable="true" datatype="action" data-label="">
  290. <button class="ui circular mini basic icon button editBtn" onclick='editEndpoint("vdir","${vdir.RootOrMatchingDomain}")'><i class="edit icon"></i></button>
  291. <button class="ui circular mini red basic icon button" onclick='deleteEndpoint("vdir","${vdir.RootOrMatchingDomain}")'><i class="trash icon"></i></button>
  292. </td>
  293. </tr>`);
  294. });
  295. }
  296. });
  297. }
  298. */
  299. //Bind on tab switch events
  300. tabSwitchEventBind["vdir"] = function(){
  301. initVdirList();
  302. }
  303. </script>