github.com/lunarobliq/gophish@v0.8.1-0.20230523153303-93511002234d/static/js/src/app/users.js (about)

     1  let users = []
     2  
     3  // Save attempts to POST or PUT to /users/
     4  const save = (id) => {
     5      // Validate that the passwords match
     6      if ($("#password").val() !== $("#confirm_password").val()) {
     7          modalError("Passwords must match.")
     8          return
     9      }
    10      let user = {
    11          username: $("#username").val(),
    12          password: $("#password").val(),
    13          role: $("#role").val(),
    14          password_change_required: $("#force_password_change_checkbox").prop('checked'),
    15          account_locked: $("#account_locked_checkbox").prop('checked')
    16      }
    17      // Submit the user
    18      if (id != -1) {
    19          // If we're just editing an existing user,
    20          // we need to PUT /user/:id
    21          user.id = id
    22          api.userId.put(user)
    23              .success((data) => {
    24                  successFlash("User " + escapeHtml(user.username) + " updated successfully!")
    25                  load()
    26                  dismiss()
    27                  $("#modal").modal('hide')
    28              })
    29              .error((data) => {
    30                  modalError(data.responseJSON.message)
    31              })
    32      } else {
    33          // Else, if this is a new user, POST it
    34          // to /user
    35          api.users.post(user)
    36              .success((data) => {
    37                  successFlash("User " + escapeHtml(user.username) + " registered successfully!")
    38                  load()
    39                  dismiss()
    40                  $("#modal").modal('hide')
    41              })
    42              .error((data) => {
    43                  modalError(data.responseJSON.message)
    44              })
    45      }
    46  }
    47  
    48  const dismiss = () => {
    49      $("#username").val("")
    50      $("#password").val("")
    51      $("#confirm_password").val("")
    52      $("#role").val("")
    53      $("#force_password_change_checkbox").prop('checked', true)
    54      $("#account_locked_checkbox").prop('checked', false)
    55      $("#modal\\.flashes").empty()
    56  }
    57  
    58  const edit = (id) => {
    59      $("#username").attr("disabled", false);
    60      $("#modalSubmit").unbind('click').click(() => {
    61          save(id)
    62      })
    63      $("#role").select2()
    64      if (id == -1) {
    65          $("#userModalLabel").text("New User")
    66          $("#role").val("user")
    67          $("#role").trigger("change")
    68      } else {
    69          $("#userModalLabel").text("Edit User")
    70          api.userId.get(id)
    71              .success((user) => {
    72                  $("#username").val(user.username)
    73                  $("#role").val(user.role.slug)
    74                  $("#role").trigger("change")
    75                  $("#force_password_change_checkbox").prop('checked', user.password_change_required)
    76                  $("#account_locked_checkbox").prop('checked', user.account_locked)
    77                  if (user.username == "admin") {
    78                      $("#username").attr("disabled", true);
    79                  }
    80              })
    81              .error(function () {
    82                  errorFlash("Error fetching user")
    83              })
    84      }
    85  }
    86  
    87  const deleteUser = (id) => {
    88      var user = users.find(x => x.id == id)
    89      if (!user) {
    90          return
    91      }
    92      if (user.username == "admin") {
    93          Swal.fire({
    94              title: "Unable to Delete User",
    95              text: "The user account " + escapeHtml(user.username) + " cannot be deleted.",
    96              type: "info"
    97          });
    98          return
    99      }
   100      Swal.fire({
   101          title: "Are you sure?",
   102          text: "This will delete the account for " + escapeHtml(user.username) + " as well as all of the objects they have created.\n\nThis can't be undone!",
   103          type: "warning",
   104          animation: false,
   105          showCancelButton: true,
   106          confirmButtonText: "Delete",
   107          confirmButtonColor: "#428bca",
   108          reverseButtons: true,
   109          allowOutsideClick: false,
   110          preConfirm: function () {
   111              return new Promise((resolve, reject) => {
   112                  api.userId.delete(id)
   113                      .success((msg) => {
   114                          resolve()
   115                      })
   116                      .error((data) => {
   117                          reject(data.responseJSON.message)
   118                      })
   119              })
   120              .catch(error => {
   121                  Swal.showValidationMessage(error)
   122                })
   123          }
   124      }).then(function (result) {
   125          if (result.value){
   126              Swal.fire(
   127                  'User Deleted!',
   128                  "The user account for " + escapeHtml(user.username) + " and all associated objects have been deleted!",
   129                  'success'
   130              );
   131          }
   132          $('button:contains("OK")').on('click', function () {
   133              location.reload()
   134          })
   135      })
   136  }
   137  
   138  const impersonate = (id) => {
   139      var user = users.find(x => x.id == id)
   140      if (!user) {
   141          return
   142      }
   143      Swal.fire({
   144          title: "Are you sure?",
   145          html: "You will be logged out of your account and logged in as <strong>" + escapeHtml(user.username) + "</strong>",
   146          type: "warning",
   147          animation: false,
   148          showCancelButton: true,
   149          confirmButtonText: "Swap User",
   150          confirmButtonColor: "#428bca",
   151          reverseButtons: true,
   152          allowOutsideClick: false,
   153      }).then((result) => {
   154          if (result.value) {
   155  
   156           fetch('/impersonate', {
   157                  method: 'post',
   158                  body: "username=" + user.username + "&csrf_token=" + encodeURIComponent(csrf_token),
   159                  headers: {
   160                      'Content-Type': 'application/x-www-form-urlencoded',
   161                    },
   162            }).then((response) => {
   163                  if (response.status == 200) {
   164                      Swal.fire({
   165                          title: "Success!",
   166                          html: "Successfully changed to user <strong>" + escapeHtml(user.username) + "</strong>.",
   167                          type: "success",
   168                          showCancelButton: false,
   169                          confirmButtonText: "Home",
   170                          allowOutsideClick: false,
   171                      }).then((result) => {
   172                          if (result.value) {
   173                              window.location.href = "/"
   174                          }});
   175                  } else {
   176                      Swal.fire({
   177                          title: "Error!",
   178                          type: "error",
   179                          html: "Failed to change to user <strong>" + escapeHtml(user.username) + "</strong>.",
   180                          showCancelButton: false,
   181                      })
   182                  }
   183              })
   184          }
   185        })
   186  }
   187  
   188  const load = () => {
   189      $("#userTable").hide()
   190      $("#loading").show()
   191      api.users.get()
   192          .success((us) => {
   193              users = us
   194              $("#loading").hide()
   195              $("#userTable").show()
   196              let userTable = $("#userTable").DataTable({
   197                  destroy: true,
   198                  columnDefs: [{
   199                      orderable: false,
   200                      targets: "no-sort"
   201                  }]
   202              });
   203              userTable.clear();
   204              userRows = []
   205              $.each(users, (i, user) => {
   206                  lastlogin = ""
   207                  if (user.last_login != "0001-01-01T00:00:00Z") {
   208                      lastlogin = moment(user.last_login).format('MMMM Do YYYY, h:mm:ss a')
   209                  }
   210                  userRows.push([
   211                      escapeHtml(user.username),
   212                      escapeHtml(user.role.name),
   213                      lastlogin,
   214                      "<div class='pull-right'>\
   215                      <button class='btn btn-warning impersonate_button' data-user-id='" + user.id + "'>\
   216                      <i class='fa fa-retweet'></i>\
   217                      </button>\
   218                      <button class='btn btn-primary edit_button' data-toggle='modal' data-backdrop='static' data-target='#modal' data-user-id='" + user.id + "'>\
   219                      <i class='fa fa-pencil'></i>\
   220                      </button>\
   221                      <button class='btn btn-danger delete_button' data-user-id='" + user.id + "'>\
   222                      <i class='fa fa-trash-o'></i>\
   223                      </button></div>"
   224                  ])
   225              })
   226              userTable.rows.add(userRows).draw();
   227          })
   228          .error(() => {
   229              errorFlash("Error fetching users")
   230          })
   231  }
   232  
   233  $(document).ready(function () {
   234      load()
   235      // Setup the event listeners
   236      $("#modal").on("hide.bs.modal", function () {
   237          dismiss();
   238      });
   239      // Select2 Defaults
   240      $.fn.select2.defaults.set("width", "100%");
   241      $.fn.select2.defaults.set("dropdownParent", $("#role-select"));
   242      $.fn.select2.defaults.set("theme", "bootstrap");
   243      $.fn.select2.defaults.set("sorter", function (data) {
   244          return data.sort(function (a, b) {
   245              if (a.text.toLowerCase() > b.text.toLowerCase()) {
   246                  return 1;
   247              }
   248              if (a.text.toLowerCase() < b.text.toLowerCase()) {
   249                  return -1;
   250              }
   251              return 0;
   252          });
   253      })
   254      $("#new_button").on("click", function () {
   255          edit(-1)
   256      })
   257      $("#userTable").on('click', '.edit_button', function (e) {
   258          edit($(this).attr('data-user-id'))
   259      })
   260      $("#userTable").on('click', '.delete_button', function (e) {
   261          deleteUser($(this).attr('data-user-id'))
   262      })
   263      $("#userTable").on('click', '.impersonate_button', function (e) {
   264          impersonate($(this).attr('data-user-id'))
   265      })
   266  });