github.com/merlinepedra/gophish1@v0.9.0/static/js/src/app/sending_profiles.js (about)

     1  var profiles = []
     2  
     3  // Attempts to send a test email by POSTing to /campaigns/
     4  function sendTestEmail() {
     5      var headers = [];
     6      $.each($("#headersTable").DataTable().rows().data(), function (i, header) {
     7          headers.push({
     8              key: unescapeHtml(header[0]),
     9              value: unescapeHtml(header[1]),
    10          })
    11      })
    12      var test_email_request = {
    13          template: {},
    14          first_name: $("input[name=to_first_name]").val(),
    15          last_name: $("input[name=to_last_name]").val(),
    16          email: $("input[name=to_email]").val(),
    17          position: $("input[name=to_position]").val(),
    18          url: '',
    19          smtp: {
    20              from_address: $("#from").val(),
    21              host: $("#host").val(),
    22              username: $("#username").val(),
    23              password: $("#password").val(),
    24              ignore_cert_errors: $("#ignore_cert_errors").prop("checked"),
    25              headers: headers,
    26          }
    27      }
    28      btnHtml = $("#sendTestModalSubmit").html()
    29      $("#sendTestModalSubmit").html('<i class="fa fa-spinner fa-spin"></i> Sending')
    30      // Send the test email
    31      api.send_test_email(test_email_request)
    32          .success(function (data) {
    33              $("#sendTestEmailModal\\.flashes").empty().append("<div style=\"text-align:center\" class=\"alert alert-success\">\
    34  	    <i class=\"fa fa-check-circle\"></i> Email Sent!</div>")
    35              $("#sendTestModalSubmit").html(btnHtml)
    36          })
    37          .error(function (data) {
    38              $("#sendTestEmailModal\\.flashes").empty().append("<div style=\"text-align:center\" class=\"alert alert-danger\">\
    39  	    <i class=\"fa fa-exclamation-circle\"></i> " + data.responseJSON.message + "</div>")
    40              $("#sendTestModalSubmit").html(btnHtml)
    41          })
    42  }
    43  
    44  // Save attempts to POST to /smtp/
    45  function save(idx) {
    46      var profile = {
    47          headers: []
    48      }
    49      $.each($("#headersTable").DataTable().rows().data(), function (i, header) {
    50          profile.headers.push({
    51              key: unescapeHtml(header[0]),
    52              value: unescapeHtml(header[1]),
    53          })
    54      })
    55      profile.name = $("#name").val()
    56      profile.interface_type = $("#interface_type").val()
    57      profile.from_address = $("#from").val()
    58      profile.host = $("#host").val()
    59      profile.username = $("#username").val()
    60      profile.password = $("#password").val()
    61      profile.ignore_cert_errors = $("#ignore_cert_errors").prop("checked")
    62      if (idx != -1) {
    63          profile.id = profiles[idx].id
    64          api.SMTPId.put(profile)
    65              .success(function (data) {
    66                  successFlash("Profile edited successfully!")
    67                  load()
    68                  dismiss()
    69              })
    70              .error(function (data) {
    71                  modalError(data.responseJSON.message)
    72              })
    73      } else {
    74          // Submit the profile
    75          api.SMTP.post(profile)
    76              .success(function (data) {
    77                  successFlash("Profile added successfully!")
    78                  load()
    79                  dismiss()
    80              })
    81              .error(function (data) {
    82                  modalError(data.responseJSON.message)
    83              })
    84      }
    85  }
    86  
    87  function dismiss() {
    88      $("#modal\\.flashes").empty()
    89      $("#name").val("")
    90      $("#interface_type").val("SMTP")
    91      $("#from").val("")
    92      $("#host").val("")
    93      $("#username").val("")
    94      $("#password").val("")
    95      $("#ignore_cert_errors").prop("checked", true)
    96      $("#headersTable").dataTable().DataTable().clear().draw()
    97      $("#modal").modal('hide')
    98  }
    99  
   100  var dismissSendTestEmailModal = function () {
   101      $("#sendTestEmailModal\\.flashes").empty()
   102      $("#sendTestModalSubmit").html("<i class='fa fa-envelope'></i> Send")
   103  }
   104  
   105  
   106  var deleteProfile = function (idx) {
   107      Swal.fire({
   108          title: "Are you sure?",
   109          text: "This will delete the sending profile. This can't be undone!",
   110          type: "warning",
   111          animation: false,
   112          showCancelButton: true,
   113          confirmButtonText: "Delete " + escapeHtml(profiles[idx].name),
   114          confirmButtonColor: "#428bca",
   115          reverseButtons: true,
   116          allowOutsideClick: false,
   117          preConfirm: function () {
   118              return new Promise(function (resolve, reject) {
   119                  api.SMTPId.delete(profiles[idx].id)
   120                      .success(function (msg) {
   121                          resolve()
   122                      })
   123                      .error(function (data) {
   124                          reject(data.responseJSON.message)
   125                      })
   126              })
   127          }
   128      }).then(function (result) {
   129          if (result.value){
   130              Swal.fire(
   131                  'Sending Profile Deleted!',
   132                  'This sending profile has been deleted!',
   133                  'success'
   134              );
   135          }
   136          $('button:contains("OK")').on('click', function () {
   137              location.reload()
   138          })
   139      })
   140  }
   141  
   142  function edit(idx) {
   143      headers = $("#headersTable").dataTable({
   144          destroy: true, // Destroy any other instantiated table - http://datatables.net/manual/tech-notes/3#destroy
   145          columnDefs: [{
   146              orderable: false,
   147              targets: "no-sort"
   148          }]
   149      })
   150  
   151      $("#modalSubmit").unbind('click').click(function () {
   152          save(idx)
   153      })
   154      var profile = {}
   155      if (idx != -1) {
   156          profile = profiles[idx]
   157          $("#name").val(profile.name)
   158          $("#interface_type").val(profile.interface_type)
   159          $("#from").val(profile.from_address)
   160          $("#host").val(profile.host)
   161          $("#username").val(profile.username)
   162          $("#password").val(profile.password)
   163          $("#ignore_cert_errors").prop("checked", profile.ignore_cert_errors)
   164          $.each(profile.headers, function (i, record) {
   165              addCustomHeader(record.key, record.value)
   166          });
   167      }
   168  }
   169  
   170  function copy(idx) {
   171      $("#modalSubmit").unbind('click').click(function () {
   172          save(-1)
   173      })
   174      var profile = {}
   175      profile = profiles[idx]
   176      $("#name").val("Copy of " + profile.name)
   177      $("#interface_type").val(profile.interface_type)
   178      $("#from").val(profile.from_address)
   179      $("#host").val(profile.host)
   180      $("#username").val(profile.username)
   181      $("#password").val(profile.password)
   182      $("#ignore_cert_errors").prop("checked", profile.ignore_cert_errors)
   183  }
   184  
   185  function load() {
   186      $("#profileTable").hide()
   187      $("#emptyMessage").hide()
   188      $("#loading").show()
   189      api.SMTP.get()
   190          .success(function (ss) {
   191              profiles = ss
   192              $("#loading").hide()
   193              if (profiles.length > 0) {
   194                  $("#profileTable").show()
   195                  profileTable = $("#profileTable").DataTable({
   196                      destroy: true,
   197                      columnDefs: [{
   198                          orderable: false,
   199                          targets: "no-sort"
   200                      }]
   201                  });
   202                  profileTable.clear()
   203                  $.each(profiles, function (i, profile) {
   204                      profileTable.row.add([
   205                          escapeHtml(profile.name),
   206                          profile.interface_type,
   207                          moment(profile.modified_date).format('MMMM Do YYYY, h:mm:ss a'),
   208                          "<div class='pull-right'><span data-toggle='modal' data-backdrop='static' data-target='#modal'><button class='btn btn-primary' data-toggle='tooltip' data-placement='left' title='Edit Profile' onclick='edit(" + i + ")'>\
   209                      <i class='fa fa-pencil'></i>\
   210                      </button></span>\
   211  		    <span data-toggle='modal' data-target='#modal'><button class='btn btn-primary' data-toggle='tooltip' data-placement='left' title='Copy Profile' onclick='copy(" + i + ")'>\
   212                      <i class='fa fa-copy'></i>\
   213                      </button></span>\
   214                      <button class='btn btn-danger' data-toggle='tooltip' data-placement='left' title='Delete Profile' onclick='deleteProfile(" + i + ")'>\
   215                      <i class='fa fa-trash-o'></i>\
   216                      </button></div>"
   217                      ]).draw()
   218                  })
   219                  $('[data-toggle="tooltip"]').tooltip()
   220              } else {
   221                  $("#emptyMessage").show()
   222              }
   223          })
   224          .error(function () {
   225              $("#loading").hide()
   226              errorFlash("Error fetching profiles")
   227          })
   228  }
   229  
   230  function addCustomHeader(header, value) {
   231      // Create new data row.
   232      var newRow = [
   233          escapeHtml(header),
   234          escapeHtml(value),
   235          '<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>'
   236      ];
   237  
   238      // Check table to see if header already exists.
   239      var headersTable = headers.DataTable();
   240      var existingRowIndex = headersTable
   241          .column(0) // Email column has index of 2
   242          .data()
   243          .indexOf(escapeHtml(header));
   244  
   245      // Update or add new row as necessary.
   246      if (existingRowIndex >= 0) {
   247          headersTable
   248              .row(existingRowIndex, {
   249                  order: "index"
   250              })
   251              .data(newRow);
   252      } else {
   253          headersTable.row.add(newRow);
   254      }
   255      headersTable.draw();
   256  }
   257  
   258  $(document).ready(function () {
   259      // Setup multiple modals
   260      // Code based on http://miles-by-motorcycle.com/static/bootstrap-modal/index.html
   261      $('.modal').on('hidden.bs.modal', function (event) {
   262          $(this).removeClass('fv-modal-stack');
   263          $('body').data('fv_open_modals', $('body').data('fv_open_modals') - 1);
   264      });
   265      $('.modal').on('shown.bs.modal', function (event) {
   266          // Keep track of the number of open modals
   267          if (typeof ($('body').data('fv_open_modals')) == 'undefined') {
   268              $('body').data('fv_open_modals', 0);
   269          }
   270          // if the z-index of this modal has been set, ignore.
   271          if ($(this).hasClass('fv-modal-stack')) {
   272              return;
   273          }
   274          $(this).addClass('fv-modal-stack');
   275          // Increment the number of open modals
   276          $('body').data('fv_open_modals', $('body').data('fv_open_modals') + 1);
   277          // Setup the appropriate z-index
   278          $(this).css('z-index', 1040 + (10 * $('body').data('fv_open_modals')));
   279          $('.modal-backdrop').not('.fv-modal-stack').css('z-index', 1039 + (10 * $('body').data('fv_open_modals')));
   280          $('.modal-backdrop').not('fv-modal-stack').addClass('fv-modal-stack');
   281      });
   282      $.fn.modal.Constructor.prototype.enforceFocus = function () {
   283          $(document)
   284              .off('focusin.bs.modal') // guard against infinite focus loop
   285              .on('focusin.bs.modal', $.proxy(function (e) {
   286                  if (
   287                      this.$element[0] !== e.target && !this.$element.has(e.target).length
   288                      // CKEditor compatibility fix start.
   289                      &&
   290                      !$(e.target).closest('.cke_dialog, .cke').length
   291                      // CKEditor compatibility fix end.
   292                  ) {
   293                      this.$element.trigger('focus');
   294                  }
   295              }, this));
   296      };
   297      // Scrollbar fix - https://stackoverflow.com/questions/19305821/multiple-modals-overlay
   298      $(document).on('hidden.bs.modal', '.modal', function () {
   299          $('.modal:visible').length && $(document.body).addClass('modal-open');
   300      });
   301      $('#modal').on('hidden.bs.modal', function (event) {
   302          dismiss()
   303      });
   304      $("#sendTestEmailModal").on("hidden.bs.modal", function (event) {
   305          dismissSendTestEmailModal()
   306      })
   307      // Code to deal with custom email headers
   308      $("#headersForm").on('submit', function () {
   309          headerKey = $("#headerKey").val();
   310          headerValue = $("#headerValue").val();
   311  
   312          if (headerKey == "" || headerValue == "") {
   313              return false;
   314          }
   315          addCustomHeader(headerKey, headerValue);
   316          // Reset user input.
   317          $("#headersForm>div>input").val('');
   318          $("#headerKey").focus();
   319          return false;
   320      });
   321      // Handle Deletion
   322      $("#headersTable").on("click", "span>i.fa-trash-o", function () {
   323          headers.DataTable()
   324              .row($(this).parents('tr'))
   325              .remove()
   326              .draw();
   327      });
   328      load()
   329  })