users.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. <html>
  2. <?php include("header.php") ?>
  3. <style type="text/css">
  4. </style>
  5. <div class="sidebar">
  6. <button class="add-user-modal button"><i class="fa fa-user-plus"></i> Add New User</button>
  7. </div>
  8. <div class="content">
  9. <div id="message-center"></div>
  10. <table>
  11. <tr>
  12. <th>Id</th>
  13. <th style="width: 160px;">Display Name</th>
  14. <th style="width: 160px;">Username</th>
  15. <th style="width: 160px;">Email</th>
  16. <th style="width: 200px;">Domains</th>
  17. <?php if($superadmin): ?>
  18. <th style="width: 160px;">Password</th>
  19. <?php endif; ?>
  20. <th style="width: 120px;">Actions</th>
  21. </tr>
  22. <?php foreach($users as $user) : ?>
  23. <?php if (empty($user)) continue; ?>
  24. <tr class="display-row">
  25. <td><?=$user['user_id']?></td>
  26. <td><?=$user['display_name']?></td>
  27. <td><?=$user['username']?></td>
  28. <td><?=$user['email']?></td>
  29. <td><?php if(empty($user['domains'])) { echo "no assigned domains"; } else { ?>
  30. <?php foreach($user['domains'] as $domain) : ?>
  31. <div class="domain"><?=$domain['subdomain']?></div>
  32. <?php endforeach; ?>
  33. <?php }?></td>
  34. <?php if($superadmin): ?>
  35. <td>[hidden]</td>
  36. <?php endif; ?>
  37. <td>
  38. <button class="edit button">Edit</button>
  39. </td>
  40. </tr>
  41. <tr class="edit-row">
  42. <td><?=$user['user_id']?></td>
  43. <td><input type="text" name="display_name" value="<?=$user['display_name']?>" /></td>
  44. <td><input type="text" name="username" value="<?=$user['username']?>" /></td>
  45. <td><input type="text" name="email" value="<?=$user['email']?>" /></td>
  46. <td><?php if(empty($user['domains'])) { echo ""; } else { ?>
  47. <?php foreach($user['domains'] as $domain) : ?>
  48. <div class="domain"><?=$domain['subdomain']?><button class="remove-domain" data-user="<?=$user['user_id']?>" data-client="<?=$domain['client_id']?>">X</button></div>
  49. <?php endforeach; ?>
  50. <?php }?><input type="text" name="subdomain" /><button class="add-domain" data-user="<?=$user['user_id']?>">+</button></td>
  51. <?php if($superadmin): ?>
  52. <td><input type="text" name="password" value="" /></td>
  53. <?php endif; ?>
  54. <td>
  55. <button class="save button" data-user="<?=$user['user_id']?>">Save</button>
  56. <button class="cancel button">Cancel</button>
  57. <!--<button class="change-password">Change Password</button>-->
  58. </td>
  59. </tr>
  60. <?php endforeach; ?>
  61. </table>
  62. </div>
  63. <div class="modal-overlay"></div>
  64. <div class="modal-popup"><button class="modal-close">X</button>
  65. <h1>Add User</h1>
  66. <hr />
  67. <div class="modal-message"></div>
  68. <form id="add-user-form" autocomplete="off" style="display:none;">
  69. <div class="input-row centered"><input name="display_name" type="text" placeholder="display name" autocomplete="off" /></div>
  70. <div class="input-row centered"><input name="new_username" type="text" placeholder="username" autocomplete="off" /></div>
  71. <div class="input-row centered"><input name="new_email" type="text" placeholder="email" autocomplete="off" /></div>
  72. <div class="input-row centered"><input name="new_password" type="password" placeholder="password" autocomplete="off" /></div>
  73. <!--<div class="input-row centered"><input name="password_confirm" type="password" placeholder="password (confirm)" /></div>-->
  74. <div class="input-row centered"><button class="add-user">Add User</button></div>
  75. </form>
  76. </div>
  77. </body>
  78. <script type="text/javascript">
  79. document.addEventListener("DOMContentLoaded", function(event) {
  80. bindButtons();
  81. <?php if($superadmin): ?>
  82. superadminNotice();
  83. <?php endif; ?>
  84. });
  85. function bindButtons() {
  86. var addUserModalButton = document.getElementsByClassName("add-user-modal")[0];
  87. addUserModalButton.addEventListener("click", addUserModalButton_click);
  88. var addUserButton = document.getElementsByClassName("add-user")[0];
  89. addUserButton.addEventListener("click", addUserButton_click);
  90. var editButtons = document.getElementsByClassName("edit");
  91. for(var i = 0; i < editButtons.length; i++) {
  92. editButtons[i].addEventListener("click", editButton_click);
  93. }
  94. var cancelButtons = document.getElementsByClassName("cancel");
  95. for(var i = 0; i < cancelButtons.length; i++) {
  96. cancelButtons[i].addEventListener("click", cancelButton_click);
  97. }
  98. var saveButtons = document.getElementsByClassName("save");
  99. for(var i = 0; i < saveButtons.length; i++) {
  100. saveButtons[i].addEventListener("click", saveButton_click);
  101. }
  102. var addDomainButtons = document.getElementsByClassName("add-domain");
  103. for(var i = 0; i < addDomainButtons.length; i++) {
  104. addDomainButtons[i].addEventListener("click", addDomainButton_click);
  105. }
  106. var removeDomainButtons = document.getElementsByClassName("remove-domain");
  107. for(var i = 0; i < removeDomainButtons.length; i++) {
  108. removeDomainButtons[i].addEventListener("click", removeDomainButton_click);
  109. }
  110. var overlay = document.getElementsByClassName("modal-overlay")[0];
  111. overlay.addEventListener("click", closeModal_click);
  112. var closeModal = document.getElementsByClassName("modal-close")[0];
  113. closeModal.addEventListener("click", closeModal_click);
  114. }
  115. function addUserModalButton_click(event) {
  116. var overlay = document.getElementsByClassName("modal-overlay")[0];
  117. var popup = document.getElementsByClassName("modal-popup")[0];
  118. //TODO: clear the modal form
  119. //var modalContent = document.getElementsByClassName("modal-content")[0];
  120. var addUserForm = document.getElementById("add-user-form");
  121. addUserForm.style.display = "block";
  122. //modalContent.innerHTML = addUserForm.innerHTML;
  123. overlay.classList.add("make-visible");
  124. popup.classList.add("make-visible");
  125. }
  126. function addUserButton_click(event) {
  127. event.preventDefault();
  128. var form = this.parentNode.parentNode;
  129. var inputFields = form.getElementsByTagName("input");
  130. var username = inputFields.new_username.value;
  131. var email = inputFields.new_email.value;
  132. var displayName = inputFields.display_name.value;
  133. var password = inputFields.new_password.value;
  134. if(!validateAddUserFields(username, displayName, password, email)) {
  135. return;
  136. }
  137. var postData = {"username": username, "display_name": displayName, "password": password, "email": email};
  138. var promise = ajaxPost("/api/adduser", postData);
  139. promise.success = function(response) {
  140. var message = document.getElementsByClassName("modal-message")[0];
  141. if(response.hasOwnProperty("error")) {
  142. message.innerHTML = response.error;
  143. if(response.hasOwnProperty("exception")) {
  144. console.warn(response.exception);
  145. }
  146. } else {
  147. location.reload();
  148. }
  149. };
  150. promise.failure = function(response) {
  151. console.warn("Communication failure", response);
  152. };
  153. }
  154. function validateAddUserFields(username, displayName, password, email) {
  155. var message = document.getElementsByClassName("modal-message")[0];
  156. if(username.length < 3) {
  157. message.innerHTML = "username too short";
  158. return false;
  159. }
  160. if(username.trim() != username || encodeURIComponent(username) != username) {
  161. message.innerHTML = "username contains invalid characters";
  162. return false;
  163. }
  164. if(username == "admin") {
  165. message.innerHTML = "reserved username";
  166. return false;
  167. }
  168. if(displayName.length < 3) {
  169. message.innerHTML = "display name is too short";
  170. return false;
  171. }
  172. if(displayName.trim() != displayName) {
  173. message.innerHTML = "display name contains invalid characters";
  174. return false;
  175. }
  176. if(password.length < 8) {
  177. message.innerHTML = "password must be at least 8 characters long";
  178. return false;
  179. }
  180. return true;
  181. }
  182. function editButton_click(event) {
  183. this.parentNode.parentNode.style="display: none";
  184. this.parentNode.parentNode.nextElementSibling.style="display: table-row";
  185. }
  186. function cancelButton_click(event) {
  187. this.parentNode.parentNode.style="display: none";
  188. this.parentNode.parentNode.previousElementSibling.style="display: table-row";
  189. }
  190. function saveButton_click(event) {
  191. this.parentNode.parentNode.style="display: none";
  192. this.parentNode.parentNode.previousElementSibling.style="display: table-row";
  193. var userId = this.getAttribute("data-user");
  194. var inputFields = this.parentNode.parentNode.getElementsByTagName("input");
  195. var username = inputFields.username.value;
  196. var displayName = inputFields.display_name.value;
  197. var email = inputFields.email.value;
  198. <?php if($superadmin): ?>
  199. var password = inputFields.password.value;
  200. <?php endif; ?>
  201. var postData = {};
  202. postData.user_id = userId;
  203. postData.username = username;
  204. postData.display_name = displayName;
  205. postData.email = email;
  206. <?php if($superadmin): ?>
  207. postData.password = password;
  208. <?php endif; ?>
  209. var promise = ajaxPost("/api/edituser", postData);
  210. promise.success = function(response) {
  211. //TODO: instead of reload, update display section
  212. if(response.error) {
  213. errorMessage(response.error);
  214. } else {
  215. location.reload();
  216. }
  217. };
  218. promise.failure = function(response) {
  219. console.warn("Communication failure", response);
  220. };
  221. }
  222. function addDomainButton_click(event) {
  223. var userId = this.getAttribute("data-user");
  224. var inputFields = this.parentNode.getElementsByTagName("input");
  225. var subdomain = inputFields.subdomain.value;
  226. var postData = {"user_id": userId, "subdomain": subdomain};
  227. var promise = ajaxPost("/api/addusertoaccount", postData);
  228. promise.success = function(response) {
  229. location.reload();
  230. };
  231. promise.failure = function(response) {
  232. console.warn("Communication failure", response);
  233. };
  234. }
  235. function removeDomainButton_click(event) {
  236. var userId = this.getAttribute("data-user");
  237. var clientId = this.getAttribute("data-client");
  238. var postData = {"user_id": userId, "client_id": clientId};
  239. var promise = ajaxPost("/api/removeuserfromaccount", postData);
  240. promise.success = function(response) {
  241. location.reload();
  242. };
  243. promise.failure = function(response) {
  244. console.warn("Communication failure", response);
  245. };
  246. }
  247. function closeModal_click(event) {
  248. var overlay = document.getElementsByClassName("modal-overlay")[0];
  249. var popup = document.getElementsByClassName("modal-popup")[0];
  250. overlay.classList.remove("make-visible");
  251. popup.classList.remove("make-visible");
  252. }
  253. </script>
  254. </html>