123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- <!DOCTYPE html>
- <html>
- <head>
- <!-- Notes: This should be open in its original path-->
- <meta charset="utf-8">
- <meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
- <link rel="stylesheet" href="../script/semantic/semantic.min.css">
- <script src="../script/jquery-3.6.0.min.js"></script>
- <script src="../script/semantic/semantic.min.js"></script>
- <script src="../script/utils.js"></script>
- </head>
- <body>
- <link rel="stylesheet" href="../darktheme.css">
- <script src="../script/darktheme.js"></script>
- <br>
- <div class="ui container">
- <div class="ui header">
- <div class="content">
- Basic Auth Settings
- <div class="sub header" id="epname"></div>
- </div>
- </div>
- <div class="ui divider"></div>
- <h3 class="ui header">Basic Auth Credential</h3>
- <div class="scrolling content ui form">
- <div id="inlineEditBasicAuthCredentials" class="field">
- <p>Enter the username and password for allowing them to access this proxy endpoint</p>
- <table class="ui very basic compacted unstackable celled table">
- <thead>
- <tr>
- <th>Username</th>
- <th>Password</th>
- <th>Remove</th>
- </tr></thead>
- <tbody id="inlineEditBasicAuthCredentialTable">
- <tr>
- <td colspan="3"><i class="ui green circle check icon"></i> No Entered Credential</td>
- </tr>
- </tbody>
- </table>
- <div class="three small fields credentialEntry">
- <div class="field">
- <input id="inlineEditBasicAuthCredUsername" type="text" placeholder="Username" autocomplete="off">
- </div>
- <div class="field">
- <input id="inlineEditBasicAuthCredPassword" type="password" placeholder="Password" autocomplete="off">
- </div>
- <div class="field" >
- <button class="ui basic button" onclick="addCredentialsToEditingList();"><i class="green add icon"></i> Add Credential</button>
- </div>
- <div class="ui divider"></div>
- </div>
- </div>
- </div>
- <div class="ui divider"></div>
- <h3 class="ui header">Authentication Exclusion Paths</h3>
- <div class="scrolling content ui form">
- <p>Exclude specific directories / paths which contains the following subpath prefix from authentication. Useful if you are hosting services require remote API access.</p>
- <table class="ui very basic compacted unstackable celled table">
- <thead>
- <tr>
- <th>Path Prefix</th>
- <th>Remove</th>
- </tr></thead>
- <tbody id="exclusionPaths">
- <tr>
- <td colspan="2"><i class="ui green circle check icon"></i> No Path Excluded</td>
- </tr>
- </tbody>
- </table>
- <div class="field">
- <input id="newExclusionPath" type="text" placeholder="/public/api/" autocomplete="off">
- <small>Make sure you add the tailing slash for only selecting the files / folder inside that path.</small>
- </div>
- <div class="field" >
- <button class="ui basic button" onclick="addExceptionPath();"><i class="yellow add icon"></i> Add Exception</button>
- </div>
- <div class="field">
- <div class="ui basic message">
- <h4>How to use set excluded paths?</h4>
- <p>All request URI that contains the given prefix will be allowed to bypass authentication and <b>the prefix must start with a slash.</b> For example, given the following prefix.<br>
- <code>/public/res/</code><br>
- <br>
- Zoraxy will allow authentication bypass of any subdirectories or resources under the /public/res/ directory. For example, the following paths access will be able to bypass basic auth mechanism under this setting.<br>
- <code>/public/res/photo.png</code><br>
- <code>/public/res/far/boo/</code></p>
- </div>
- </div>
- <div class="ui divider"></div>
- <div class="field" >
- <button class="ui basic button" style="float: right;" onclick="closeThisWrapper();">Close</button>
- </div>
- </div>
-
- <br><br><br><br>
- </div>
- <script>
- let editingCredentials = [];
- let editingEndpoint = {};
- if (window.location.hash.length > 1){
- let payloadHash = window.location.hash.substr(1);
- try{
- payloadHash = JSON.parse(decodeURIComponent(payloadHash));
- loadBasicAuthCredentials(payloadHash.ep);
- $("#epname").text(payloadHash.ep);
- editingEndpoint = payloadHash;
- }catch(ex){
- console.log("Unable to load endpoint data from hash")
- }
- }
- function loadBasicAuthCredentials(uuid){
- $.ajax({
- url: "/api/proxy/updateCredentials",
- method: "GET",
- data: {
- ep: uuid,
- },
- success: function(data){
- //Push the existing account to list
- for(var i = 0; i < data.length; i++){
- // Create a new credential object
- var credential = {
- username: data[i],
- password: ""
- };
- // Add the credential to the global credentials array
- editingCredentials.push(credential);
- }
- console.log(data);
- updateEditingCredentialList();
- }
- })
- }
- function addCredentialsToEditingList() {
- // Retrieve the username and password input values
- var username = $('#inlineEditBasicAuthCredUsername').val();
- var password = $('#inlineEditBasicAuthCredPassword').val();
-
- if(username == "" || password == ""){
- parent.msgbox("Username or password cannot be empty", false, 5000);
- return;
- }
- if (alreadyExists(username)){
- parent.msgbox("Credential with same username already exists", false, 5000);
- return;
- }
-
- // Create a new credential object
- var credential = {
- username: username,
- password: password
- };
- // Add the credential to the global credentials array
- editingCredentials.push(credential);
- // Clear the input fields
- $('#inlineEditBasicAuthCredUsername').val('');
- $('#inlineEditBasicAuthCredPassword').val('');
- // Update the table body with the credentials
- updateEditingCredentialList();
- //Save the table
- saveCredentials();
- }
- function addExceptionPath(){
- // Retrieve the username and password input values
- var newExclusionPathMatchingPrefix = $('#newExclusionPath').val().trim();
- if (newExclusionPathMatchingPrefix == ""){
- parent.msgbox("Matching prefix cannot be empty!", false, 5000);
- return;
- }
- $.cjax({
- url: "/api/proxy/auth/exceptions/add",
- data:{
- ep: editingEndpoint.ep,
- prefix: newExclusionPathMatchingPrefix
- },
- method: "POST",
- success: function(data){
- if (data.error != undefined){
- parent.msgbox(data.error, false, 5000);
- }else{
- initExceptionPaths();
- parent.msgbox("New exception path added", true);
- $('#newExclusionPath').val("");
- }
- }
- });
- }
- function removeExceptionPath(object){
- let matchingPrefix = $(object).attr("prefix");
- $.cjax({
- url: "/api/proxy/auth/exceptions/delete",
- data:{
- ep: editingEndpoint.ep,
- prefix: matchingPrefix
- },
- method: "POST",
- success: function(data){
- if (data.error != undefined){
- parent.msgbox(data.error, false, 5000);
- }else{
- initExceptionPaths();
- parent.msgbox("Exception path removed", true);
- }
- }
- });
- }
- //Load exception paths from server
- function initExceptionPaths(){
- $.get(`/api/proxy/auth/exceptions/list?ptype=${editingEndpoint.ept}&ep=${editingEndpoint.ep}`, function(data){
- if (data.error != undefined){
- parent.msgbox(data.error, false, 5000);
- }else{
- if (data.length == 0){
- $("#exclusionPaths").html(` <tr>
- <td colspan="2"><i class="ui green circle check icon"></i> No Path Excluded</td>
- </tr>`);
- }else{
- $("#exclusionPaths").html("");
- data.forEach(function(rule){
- $("#exclusionPaths").append(` <tr>
- <td>${rule.PathPrefix}</td>
- <td><button class="ui red basic mini icon button" onclick="removeExceptionPath(this);" prefix="${rule.PathPrefix}"><i class="ui red times icon"></i></button></td>
- </tr>`);
- })
- }
- }
- });
- }
- initExceptionPaths();
- function updateEditingCredentialList() {
- var tableBody = $('#inlineEditBasicAuthCredentialTable');
- tableBody.empty();
- if (editingCredentials.length === 0) {
- tableBody.append('<tr><td colspan="3"><i class="ui green circle check icon"></i> No Entered Credential</td></tr>');
- } else {
- for (var i = 0; i < editingCredentials.length; i++) {
- var credential = editingCredentials[i];
- var username = credential.username;
- var password = credential.password.replace(/./g, '*'); // Replace each character with '*'
-
- if (credential.password == ""){
- password = `<span style="color: #c9c9c9;"><i class="eye slash outline icon"></i> Hidden<span>`;
- }
- var row = '<tr>' +
- '<td>' + username + '</td>' +
- '<td>' + password + '</td>' +
- '<td><button class="ui basic button" onclick="removeCredentialFromEditingList(' + i + ');"><i class="red remove icon"></i> Remove</button></td>' +
- '</tr>';
- tableBody.append(row);
- }
- }
- }
- function removeCredentialFromEditingList(index) {
- // Remove the credential from the credentials array
- editingCredentials.splice(index, 1);
- // Update the table body
- updateEditingCredentialList();
-
- saveCredentials();
- }
- function alreadyExists(username){
- let isExists = false;
- editingCredentials.forEach(function(cred){
- if (cred.username == username){
- isExists = true;
- }
- });
- return isExists;
- }
- function closeThisWrapper(){
- parent.hideSideWrapper(true);
- }
- function saveCredentials(){
- $.cjax({
- url: "/api/proxy/updateCredentials",
- method: "POST",
- data: {
- ep: editingEndpoint.ep,
- creds: JSON.stringify(editingCredentials)
- },
- success: function(data){
- if (data.error != undefined){
- parent.msgbox(data.error, false, 6000);
- }else{
- parent.msgbox("Credentials Updated");
- //parent.hideSideWrapper(true);
- }
- }
- })
- }
- </script>
- </body>
- </html>
|