github.com/jonathaningram/gophish@v0.3.1-0.20170829042651-ac3fe6aeae6c/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  function deleteProfile(idx) {
   101      if (confirm("Delete " + profiles[idx].name + "?")) {
   102          api.SMTPId.delete(profiles[idx].id)
   103              .success(function(data) {
   104                  successFlash(data.message)
   105                  load()
   106              })
   107      }
   108  }
   109  
   110  function edit(idx) {
   111      headers = $("#headersTable").dataTable({
   112          destroy: true, // Destroy any other instantiated table - http://datatables.net/manual/tech-notes/3#destroy
   113          columnDefs: [{
   114              orderable: false,
   115              targets: "no-sort"
   116          }]
   117      })
   118  
   119      $("#modalSubmit").unbind('click').click(function() {
   120          save(idx)
   121      })
   122      var profile = {}
   123      if (idx != -1) {
   124          profile = profiles[idx]
   125          $("#name").val(profile.name)
   126          $("#interface_type").val(profile.interface_type)
   127          $("#from").val(profile.from_address)
   128          $("#host").val(profile.host)
   129          $("#username").val(profile.username)
   130          $("#password").val(profile.password)
   131          $("#ignore_cert_errors").prop("checked", profile.ignore_cert_errors)
   132          $.each(profile.headers, function(i, record) {
   133              addCustomHeader(record.key, record.value)
   134          });
   135      }
   136  }
   137  
   138  function copy(idx) {
   139      $("#modalSubmit").unbind('click').click(function() {
   140          save(-1)
   141      })
   142      var profile = {}
   143      profile = profiles[idx]
   144      $("#name").val("Copy of " + profile.name)
   145      $("#interface_type").val(profile.interface_type)
   146      $("#from").val(profile.from_address)
   147      $("#host").val(profile.host)
   148      $("#username").val(profile.username)
   149      $("#password").val(profile.password)
   150      $("#ignore_cert_errors").prop("checked", profile.ignore_cert_errors)
   151  }
   152  
   153  function load() {
   154      $("#profileTable").hide()
   155      $("#emptyMessage").hide()
   156      $("#loading").show()
   157      api.SMTP.get()
   158          .success(function(ss) {
   159              profiles = ss
   160              $("#loading").hide()
   161              if (profiles.length > 0) {
   162                  $("#profileTable").show()
   163                  profileTable = $("#profileTable").DataTable({
   164                      destroy: true,
   165                      columnDefs: [{
   166                          orderable: false,
   167                          targets: "no-sort"
   168                      }]
   169                  });
   170                  profileTable.clear()
   171                  $.each(profiles, function(i, profile) {
   172                      profileTable.row.add([
   173                          escapeHtml(profile.name),
   174                          profile.interface_type,
   175                          moment(profile.modified_date).format('MMMM Do YYYY, h:mm:ss a'),
   176                          "<div class='pull-right'><span data-toggle='modal' data-target='#modal'><button class='btn btn-primary' data-toggle='tooltip' data-placement='left' title='Edit Profile' onclick='edit(" + i + ")'>\
   177                      <i class='fa fa-pencil'></i>\
   178                      </button></span>\
   179  		    <span data-toggle='modal' data-target='#modal'><button class='btn btn-primary' data-toggle='tooltip' data-placement='left' title='Copy Profile' onclick='copy(" + i + ")'>\
   180                      <i class='fa fa-copy'></i>\
   181                      </button></span>\
   182                      <button class='btn btn-danger' data-toggle='tooltip' data-placement='left' title='Delete Profile' onclick='deleteProfile(" + i + ")'>\
   183                      <i class='fa fa-trash-o'></i>\
   184                      </button></div>"
   185                      ]).draw()
   186                  })
   187                  $('[data-toggle="tooltip"]').tooltip()
   188              } else {
   189                  $("#emptyMessage").show()
   190              }
   191          })
   192          .error(function() {
   193              $("#loading").hide()
   194              errorFlash("Error fetching profiles")
   195          })
   196  }
   197  
   198  function addCustomHeader(header, value) {
   199      // Create new data row.
   200      var newRow = [
   201          escapeHtml(header),
   202          escapeHtml(value),
   203          '<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>'
   204      ];
   205  
   206      // Check table to see if header already exists.
   207      var headersTable = headers.DataTable();
   208      var existingRowIndex = headersTable
   209          .column(0) // Email column has index of 2
   210          .data()
   211          .indexOf(escapeHtml(header));
   212  
   213      // Update or add new row as necessary.
   214      if (existingRowIndex >= 0) {
   215          headersTable
   216              .row(existingRowIndex, {
   217                  order: "index"
   218              })
   219              .data(newRow);
   220      } else {
   221          headersTable.row.add(newRow);
   222      }
   223      headersTable.draw();
   224  }
   225  
   226  $(document).ready(function() {
   227      // Setup multiple modals
   228      // Code based on http://miles-by-motorcycle.com/static/bootstrap-modal/index.html
   229      $('.modal').on('hidden.bs.modal', function(event) {
   230          $(this).removeClass('fv-modal-stack');
   231          $('body').data('fv_open_modals', $('body').data('fv_open_modals') - 1);
   232      });
   233      $('.modal').on('shown.bs.modal', function(event) {
   234          // Keep track of the number of open modals
   235          if (typeof($('body').data('fv_open_modals')) == 'undefined') {
   236              $('body').data('fv_open_modals', 0);
   237          }
   238          // if the z-index of this modal has been set, ignore.
   239          if ($(this).hasClass('fv-modal-stack')) {
   240              return;
   241          }
   242          $(this).addClass('fv-modal-stack');
   243          // Increment the number of open modals
   244          $('body').data('fv_open_modals', $('body').data('fv_open_modals') + 1);
   245          // Setup the appropriate z-index
   246          $(this).css('z-index', 1040 + (10 * $('body').data('fv_open_modals')));
   247          $('.modal-backdrop').not('.fv-modal-stack').css('z-index', 1039 + (10 * $('body').data('fv_open_modals')));
   248          $('.modal-backdrop').not('fv-modal-stack').addClass('fv-modal-stack');
   249      });
   250      $.fn.modal.Constructor.prototype.enforceFocus = function() {
   251          $(document)
   252              .off('focusin.bs.modal') // guard against infinite focus loop
   253              .on('focusin.bs.modal', $.proxy(function(e) {
   254                  if (
   255                      this.$element[0] !== e.target && !this.$element.has(e.target).length
   256                      // CKEditor compatibility fix start.
   257                      && !$(e.target).closest('.cke_dialog, .cke').length
   258                      // CKEditor compatibility fix end.
   259                  ) {
   260                      this.$element.trigger('focus');
   261                  }
   262              }, this));
   263      };
   264      $('#modal').on('hidden.bs.modal', function(event) {
   265          dismiss()
   266      });
   267      // Code to deal with custom email headers
   268      $("#headersForm").on('submit', function() {
   269          headerKey = $("#headerKey").val();
   270          headerValue = $("#headerValue").val();
   271  
   272          if (headerKey == "" || headerValue == "") {
   273              return false;
   274          }
   275          addCustomHeader(headerKey, headerValue);
   276          // Reset user input.
   277          $("#headersForm>div>input").val('');
   278          $("#headerKey").focus();
   279          return false;
   280      });
   281      // Handle Deletion
   282      $("#headersTable").on("click", "span>i.fa-trash-o", function() {
   283          headers.DataTable()
   284              .row($(this).parents('tr'))
   285              .remove()
   286              .draw();
   287      });
   288      load()
   289  })