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