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

     1  var groups = []
     2  
     3  // Save attempts to POST or PUT to /groups/
     4  function save(id) {
     5      var targets = []
     6      $.each($("#targetsTable").DataTable().rows().data(), function (i, target) {
     7          targets.push({
     8              first_name: unescapeHtml(target[0]),
     9              last_name: unescapeHtml(target[1]),
    10              email: unescapeHtml(target[2]),
    11              position: unescapeHtml(target[3])
    12          })
    13      })
    14      var group = {
    15          name: $("#name").val(),
    16          targets: targets
    17      }
    18      // Submit the group
    19      if (id != -1) {
    20          // If we're just editing an existing group,
    21          // we need to PUT /groups/:id
    22          group.id = id
    23          api.groupId.put(group)
    24              .success(function (data) {
    25                  successFlash("Group updated successfully!")
    26                  load()
    27                  dismiss()
    28                  $("#modal").modal('hide')
    29              })
    30              .error(function (data) {
    31                  modalError(data.responseJSON.message)
    32              })
    33      } else {
    34          // Else, if this is a new group, POST it
    35          // to /groups
    36          api.groups.post(group)
    37              .success(function (data) {
    38                  successFlash("Group added successfully!")
    39                  load()
    40                  dismiss()
    41                  $("#modal").modal('hide')
    42              })
    43              .error(function (data) {
    44                  modalError(data.responseJSON.message)
    45              })
    46      }
    47  }
    48  
    49  function dismiss() {
    50      $("#targetsTable").dataTable().DataTable().clear().draw()
    51      $("#name").val("")
    52      $("#modal\\.flashes").empty()
    53  }
    54  
    55  function edit(id) {
    56      targets = $("#targetsTable").dataTable({
    57          destroy: true, // Destroy any other instantiated table - http://datatables.net/manual/tech-notes/3#destroy
    58          columnDefs: [{
    59              orderable: false,
    60              targets: "no-sort"
    61          }]
    62      })
    63      $("#modalSubmit").unbind('click').click(function () {
    64          save(id)
    65      })
    66      if (id == -1) {
    67          $("#groupModalLabel").text("New Group");
    68          var group = {}
    69      } else {
    70          $("#groupModalLabel").text("Edit Group");
    71          api.groupId.get(id)
    72              .success(function (group) {
    73                  $("#name").val(group.name)
    74                  targetRows = []
    75                  $.each(group.targets, function (i, record) {
    76                    targetRows.push([
    77                        escapeHtml(record.first_name),
    78                        escapeHtml(record.last_name),
    79                        escapeHtml(record.email),
    80                        escapeHtml(record.position),
    81                        '<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>'
    82                    ])
    83                  });
    84                  targets.DataTable().rows.add(targetRows).draw()
    85              })
    86              .error(function () {
    87                  errorFlash("Error fetching group")
    88              })
    89      }
    90      // Handle file uploads
    91      $("#csvupload").fileupload({
    92          url: "/api/import/group",
    93          dataType: "json",
    94          beforeSend: function (xhr) {
    95              xhr.setRequestHeader('Authorization', 'Bearer ' + user.api_key);
    96          },
    97          add: function (e, data) {
    98              $("#modal\\.flashes").empty()
    99              var acceptFileTypes = /(csv|txt)$/i;
   100              var filename = data.originalFiles[0]['name']
   101              if (filename && !acceptFileTypes.test(filename.split(".").pop())) {
   102                  modalError("Unsupported file extension (use .csv or .txt)")
   103                  return false;
   104              }
   105              data.submit();
   106          },
   107          done: function (e, data) {
   108              $.each(data.result, function (i, record) {
   109                  addTarget(
   110                      record.first_name,
   111                      record.last_name,
   112                      record.email,
   113                      record.position);
   114              });
   115              targets.DataTable().draw();
   116          }
   117      })
   118  }
   119  
   120  var downloadCSVTemplate = function () {
   121      var csvScope = [{
   122          'First Name': 'Example',
   123          'Last Name': 'User',
   124          'Email': 'foobar@example.com',
   125          'Position': 'Systems Administrator'
   126      }]
   127      var filename = 'group_template.csv'
   128      var csvString = Papa.unparse(csvScope, {})
   129      var csvData = new Blob([csvString], {
   130          type: 'text/csv;charset=utf-8;'
   131      });
   132      if (navigator.msSaveBlob) {
   133          navigator.msSaveBlob(csvData, filename);
   134      } else {
   135          var csvURL = window.URL.createObjectURL(csvData);
   136          var dlLink = document.createElement('a');
   137          dlLink.href = csvURL;
   138          dlLink.setAttribute('download', filename)
   139          document.body.appendChild(dlLink)
   140          dlLink.click();
   141          document.body.removeChild(dlLink)
   142      }
   143  }
   144  
   145  
   146  var deleteGroup = function (id) {
   147      var group = groups.find(function (x) {
   148          return x.id === id
   149      })
   150      if (!group) {
   151          return
   152      }
   153      Swal.fire({
   154          title: "Are you sure?",
   155          text: "This will delete the group. This can't be undone!",
   156          type: "warning",
   157          animation: false,
   158          showCancelButton: true,
   159          confirmButtonText: "Delete " + escapeHtml(group.name),
   160          confirmButtonColor: "#428bca",
   161          reverseButtons: true,
   162          allowOutsideClick: false,
   163          preConfirm: function () {
   164              return new Promise(function (resolve, reject) {
   165                  api.groupId.delete(id)
   166                      .success(function (msg) {
   167                          resolve()
   168                      })
   169                      .error(function (data) {
   170                          reject(data.responseJSON.message)
   171                      })
   172              })
   173          }
   174      }).then(function (result) {
   175          if (result.value){
   176              Swal.fire(
   177                  'Group Deleted!',
   178                  'This group has been deleted!',
   179                  'success'
   180              );
   181          }
   182          $('button:contains("OK")').on('click', function () {
   183              location.reload()
   184          })
   185      })
   186  }
   187  
   188  function addTarget(firstNameInput, lastNameInput, emailInput, positionInput) {
   189      // Create new data row.
   190      var email = escapeHtml(emailInput).toLowerCase();
   191      var newRow = [
   192          escapeHtml(firstNameInput),
   193          escapeHtml(lastNameInput),
   194          email,
   195          escapeHtml(positionInput),
   196          '<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>'
   197      ];
   198  
   199      // Check table to see if email already exists.
   200      var targetsTable = targets.DataTable();
   201      var existingRowIndex = targetsTable
   202          .column(2, {
   203              order: "index"
   204          }) // Email column has index of 2
   205          .data()
   206          .indexOf(email);
   207      // Update or add new row as necessary.
   208      if (existingRowIndex >= 0) {
   209          targetsTable
   210              .row(existingRowIndex, {
   211                  order: "index"
   212              })
   213              .data(newRow);
   214      } else {
   215          targetsTable.row.add(newRow);
   216      }
   217  }
   218  
   219  function load() {
   220      $("#groupTable").hide()
   221      $("#emptyMessage").hide()
   222      $("#loading").show()
   223      api.groups.summary()
   224          .success(function (response) {
   225              $("#loading").hide()
   226              if (response.total > 0) {
   227                  groups = response.groups
   228                  $("#emptyMessage").hide()
   229                  $("#groupTable").show()
   230                  var groupTable = $("#groupTable").DataTable({
   231                      destroy: true,
   232                      columnDefs: [{
   233                          orderable: false,
   234                          targets: "no-sort"
   235                      }]
   236                  });
   237                  groupTable.clear();
   238                  groupRows = []
   239                  $.each(groups, function (i, group) {
   240                      groupRows.push([
   241                          escapeHtml(group.name),
   242                          escapeHtml(group.num_targets),
   243                          moment(group.modified_date).format('MMMM Do YYYY, h:mm:ss a'),
   244                          "<div class='pull-right'><button class='btn btn-primary' data-toggle='modal' data-backdrop='static' data-target='#modal' onclick='edit(" + group.id + ")'>\
   245                      <i class='fa fa-pencil'></i>\
   246                      </button>\
   247                      <button class='btn btn-danger' onclick='deleteGroup(" + group.id + ")'>\
   248                      <i class='fa fa-trash-o'></i>\
   249                      </button></div>"
   250                      ])
   251                  })
   252                  groupTable.rows.add(groupRows).draw()
   253              } else {
   254                  $("#emptyMessage").show()
   255              }
   256          })
   257          .error(function () {
   258              errorFlash("Error fetching groups")
   259          })
   260  }
   261  
   262  $(document).ready(function () {
   263      load()
   264      // Setup the event listeners
   265      // Handle manual additions
   266      $("#targetForm").submit(function () {
   267          // Validate the form data
   268          var targetForm = document.getElementById("targetForm")
   269          if (!targetForm.checkValidity()) {
   270              targetForm.reportValidity()
   271              return
   272          }
   273          addTarget(
   274              $("#firstName").val(),
   275              $("#lastName").val(),
   276              $("#email").val(),
   277              $("#position").val());
   278          targets.DataTable().draw();
   279  
   280          // Reset user input.
   281          $("#targetForm>div>input").val('');
   282          $("#firstName").focus();
   283          return false;
   284      });
   285      // Handle Deletion
   286      $("#targetsTable").on("click", "span>i.fa-trash-o", function () {
   287          targets.DataTable()
   288              .row($(this).parents('tr'))
   289              .remove()
   290              .draw();
   291      });
   292      $("#modal").on("hide.bs.modal", function () {
   293          dismiss();
   294      });
   295      $("#csv-template").click(downloadCSVTemplate)
   296  });