users.html 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>Users List</title>
  6. <meta name="viewport" content="width=device-width, initial-scale=1" >
  7. <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  8. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css" />
  9. <script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js"></script>
  10. <style>
  11. body{
  12. background-color: rgb(243, 243, 243);
  13. }
  14. </style>
  15. </head>
  16. <body>
  17. <br>
  18. <div class="ui container">
  19. <div class="ui segment">
  20. <h4 class="ui header">
  21. <img src="img/user.svg">
  22. <div class="content">
  23. <span id="currentUsername"><i class="ui loading spinner icon"></i> Loading</span>
  24. <div class="sub header">Current User Information</div>
  25. </div>
  26. </h4>
  27. </div>
  28. <div class="ui segment">
  29. <table class="ui unstackable basic celled table">
  30. <thead>
  31. <tr><th>Username</th>
  32. <th>Actions</th>
  33. </tr></thead>
  34. <tbody id="userTable">
  35. <tr>
  36. <td colspan="2"><i class="ui loading spinner icon"></i> Loading</td>
  37. </tr>
  38. </tbody>
  39. </table>
  40. <div class="ui divider"></div>
  41. <form id="newUserForm" class="ui form" onsubmit="handleNewUser(event);">
  42. <div class="field">
  43. <label>Username</label>
  44. <input id="username" type="text">
  45. </div>
  46. <div class="field">
  47. <label>Password</label>
  48. <input id="password" type="password">
  49. </div>
  50. <div class="field">
  51. <label>Confirm Password</label>
  52. <input id="confirmpw" type="password">
  53. </div>
  54. <button class="ui basic button"><i class="ui green add icon"></i> Create User</button>
  55. </form>
  56. </div>
  57. </div>
  58. <script>
  59. var currentUserInfo = {};
  60. //Load current login user info from server
  61. function initUserInfo(){
  62. $.get("/api/user/info", function(data){
  63. currentUserInfo = data;
  64. var html = data.username;
  65. if (data.admin){
  66. html += ` <i class="yellow shield alternate icon"></i>`;
  67. }else{
  68. //Hide the new user section
  69. $("#newUserForm").remove();
  70. }
  71. $("#currentUsername").html(html);
  72. initUserList();
  73. })
  74. }
  75. initUserInfo();
  76. //Load user list from WebStick
  77. function initUserList(){
  78. $("#userTable").html(`<tr>
  79. <td colspan="2"><i class="ui loading spinner icon"></i> Loading</td>
  80. </tr>`);
  81. $.get("/api/user/list", function(data){
  82. if (data.error != undefined){
  83. alert(data.error);
  84. }else{
  85. $("#userTable").html(``);
  86. data.forEach(function(user){
  87. let username = user.Username;
  88. if (!currentUserInfo.admin){
  89. //Not admin
  90. var actionField = '<small style="opacity: 0.3;">No available actions</small>';
  91. if (username == currentUserInfo.username){
  92. actionField = `<button class="ui basic button" onclick="changePassword('${username}');"><i class="ui blue edit icon"></i> Change Password</button>`;
  93. }
  94. $("#userTable").append(`<tr>
  95. <td>${username}</td>
  96. <td>
  97. ${actionField}
  98. </td>
  99. </tr>`);
  100. }else{
  101. //admin
  102. $("#userTable").append(`<tr>
  103. <td>${username}</td>
  104. <td userid="${username}">
  105. <button class="ui basic button" onclick="changePassword('${username}');"><i class="ui blue edit icon"></i> Change Password</button>
  106. <button class="ui basic button" onclick="delUser('${username}');"><i class="ui red trash icon"></i> Remove</button>
  107. </td>
  108. </tr>`);
  109. }
  110. });
  111. if (data.length == 0){
  112. $("#userTable").append(`<tr>
  113. <td colspan="2"><i class="green circle check icon"></i> No registered user</td>
  114. </tr>`);
  115. }
  116. }
  117. })
  118. }
  119. //Create new user
  120. function handleNewUser(e){
  121. e.preventDefault();
  122. let username = $("#username").val().trim();
  123. let password = $("#password").val().trim();
  124. let confirmpw = $("#confirmpw").val().trim();
  125. if (password != confirmpw){
  126. //Mismatch
  127. $("#confirmpw").parent().addClass("error");
  128. return;
  129. }else{
  130. $("#confirmpw").parent().removeClass("error");
  131. }
  132. //Create the user
  133. $.post("/api/user/new?username=" + username + "&password=" + password, function(data){
  134. if (data.error != undefined){
  135. alert(data.error);
  136. }else{
  137. //User added
  138. initUserList();
  139. $("#username").val("");
  140. $("#password").val("");
  141. $("#confirmpw").val("");
  142. }
  143. })
  144. }
  145. //Server side will check for if you are admin
  146. function delUser(username){
  147. $.post("/api/user/del?username=" + username, function(data){
  148. if (data.error != undefined){
  149. alert(data.error);
  150. }else{
  151. //ok!
  152. initUserList();
  153. }
  154. })
  155. }
  156. //Change password, admin can change all user's password,
  157. //user can only change their own password
  158. function changePassword(username){
  159. let newpassword = prompt("New password", "");
  160. let confirmNewPassword = prompt("Confirm new password", "");
  161. if (newpassword != confirmNewPassword){
  162. alert("Confirm password not match!");
  163. return;
  164. }
  165. //Request server side to change user password
  166. $.post("/api/user/chpw?username=" + username + "&newpw=" + newpassword, function(data){
  167. if (data.error != undefined){
  168. alert(data.error);
  169. }else{
  170. alert("Password updated!");
  171. }
  172. })
  173. }
  174. </script>
  175. </body>
  176. </html>