github.com/jonathaningram/gophish@v0.3.1-0.20170829042651-ac3fe6aeae6c/static/js/src/app/campaigns.js (about)

     1  // labels is a map of campaign statuses to
     2  // CSS classes
     3  var labels = {
     4      "In progress": "label-primary",
     5      "Queued": "label-info",
     6      "Completed": "label-success",
     7      "Emails Sent": "label-success",
     8      "Error": "label-danger"
     9  }
    10  
    11  var campaigns = []
    12  var campaign = {}
    13  
    14  // Launch attempts to POST to /campaigns/
    15  function launch() {
    16      swal({
    17          title: "Are you sure?",
    18          text: "This will schedule the campaign to be launched.",
    19          type: "question",
    20          animation: false,
    21          showCancelButton: true,
    22          confirmButtonText: "Launch",
    23          confirmButtonColor: "#428bca",
    24          reverseButtons: true,
    25          allowOutsideClick: false,
    26          showLoaderOnConfirm: true,
    27          preConfirm: function () {
    28              return new Promise(function (resolve, reject) {
    29                  groups = []
    30                  $("#users").select2("data").forEach(function (group) {
    31                      groups.push({ name: group.text });
    32                  })
    33                  // Validate our fields
    34                  campaign = {
    35                      name: $("#name").val(),
    36                      template: {
    37                          name: $("#template").select2("data")[0].text
    38                      },
    39                      url: $("#url").val(),
    40                      page: {
    41                          name: $("#page").select2("data")[0].text
    42                      },
    43                      smtp: {
    44                          name: $("#profile").select2("data")[0].text
    45                      },
    46                      launch_date: moment($("#launch_date").val(), "MM/DD/YYYY hh:mm a").utc().format(),
    47                      groups: groups
    48                  }
    49                  console.log("Launching campaign at time: " + campaign.launch_date)
    50                  // Submit the campaign
    51                  api.campaigns.post(campaign)
    52                      .success(function (data) {
    53                          resolve()
    54                          campaign = data
    55                      })
    56                      .error(function (data) {
    57                          $("#modal\\.flashes").empty().append("<div style=\"text-align:center\" class=\"alert alert-danger\">\
    58              <i class=\"fa fa-exclamation-circle\"></i> " + data.responseJSON.message + "</div>")
    59                          swal.close()
    60                      })
    61              })
    62          }
    63      }).then(function () {
    64          swal(
    65              'Campaign Scheduled!',
    66              'This campaign has been scheduled for launch!',
    67              'success'
    68          );
    69          $('button:contains("OK")').on('click', function () {
    70              window.location = "/campaigns/" + campaign.id.toString()
    71          })
    72      })
    73  }
    74  
    75  // Attempts to send a test email by POSTing to /campaigns/
    76  function sendTestEmail() {
    77      var test_email_request = {
    78          template: {
    79              name: $("#template").select2("data")[0].text
    80          },
    81          first_name: $("input[name=to_first_name]").val(),
    82          last_name: $("input[name=to_last_name]").val(),
    83          email: $("input[name=to_email]").val(),
    84          position: $("input[name=to_position]").val(),
    85          url: $("#url").val(),
    86          page: {
    87              name: $("#page").select2("data")[0].text
    88          },
    89          smtp: {
    90              name: $("#profile").select2("data")[0].text
    91          }
    92      }
    93      btnHtml = $("#sendTestModalSubmit").html()
    94      $("#sendTestModalSubmit").html('<i class="fa fa-spinner fa-spin"></i> Sending')
    95      // Send the test email
    96      api.send_test_email(test_email_request)
    97          .success(function (data) {
    98              $("#sendTestEmailModal\\.flashes").empty().append("<div style=\"text-align:center\" class=\"alert alert-success\">\
    99              <i class=\"fa fa-check-circle\"></i> Email Sent!</div>")
   100              $("#sendTestModalSubmit").html(btnHtml)
   101          })
   102          .error(function (data) {
   103              $("#sendTestEmailModal\\.flashes").empty().append("<div style=\"text-align:center\" class=\"alert alert-danger\">\
   104              <i class=\"fa fa-exclamation-circle\"></i> " + data.responseJSON.message + "</div>")
   105              $("#sendTestModalSubmit").html(btnHtml)
   106          })
   107  }
   108  
   109  function dismiss() {
   110      $("#modal\\.flashes").empty();
   111      $("#name").val("");
   112      $("#template").val("").change();
   113      $("#page").val("").change();
   114      $("#url").val("");
   115      $("#profile").val("").change();
   116      $("#users").val("").change();
   117      $("#modal").modal('hide');
   118  }
   119  
   120  function deleteCampaign(idx) {
   121      swal({
   122          title: "Are you sure?",
   123          text: "This will delete the campaign. This can't be undone!",
   124          type: "warning",
   125          animation: false,
   126          showCancelButton: true,
   127          confirmButtonText: "Delete " + campaigns[idx].name,
   128          confirmButtonColor: "#428bca",
   129          reverseButtons: true,
   130          allowOutsideClick: false,
   131          preConfirm: function () {
   132              return new Promise(function (resolve, reject) {
   133                  api.campaignId.delete(campaigns[idx].id)
   134                      .success(function (msg) {
   135                          resolve()
   136                      })
   137                      .error(function (data) {
   138                          reject(data.responseJSON.message)
   139                      })
   140              })
   141          }
   142      }).then(function () {
   143          swal(
   144              'Campaign Deleted!',
   145              'This campaign has been deleted!',
   146              'success'
   147          );
   148          $('button:contains("OK")').on('click', function () {
   149              location.reload()
   150          })
   151      })
   152  }
   153  
   154  function setupOptions() {
   155      api.groups.get()
   156          .success(function (groups) {
   157              if (groups.length == 0) {
   158                  modalError("No groups found!")
   159                  return false;
   160              } else {
   161                  var group_s2 = $.map(groups, function (obj) {
   162                      obj.text = obj.name
   163                      return obj
   164                  });
   165                  $("#users.form-control").select2({
   166                      placeholder: "Select Groups",
   167                      data: group_s2,
   168                  });
   169              }
   170          });
   171      api.templates.get()
   172          .success(function (templates) {
   173              if (templates.length == 0) {
   174                  modalError("No templates found!")
   175                  return false
   176              } else {
   177                  var template_s2 = $.map(templates, function (obj) {
   178                      obj.text = obj.name
   179                      return obj
   180                  });
   181                  $("#template.form-control").select2({
   182                      placeholder: "Select a Template",
   183                      data: template_s2,
   184                  });
   185              }
   186          });
   187      api.pages.get()
   188          .success(function (pages) {
   189              if (pages.length == 0) {
   190                  modalError("No pages found!")
   191                  return false
   192              } else {
   193                  var page_s2 = $.map(pages, function (obj) {
   194                      obj.text = obj.name
   195                      return obj
   196                  });
   197                  $("#page.form-control").select2({
   198                      placeholder: "Select a Landing Page",
   199                      data: page_s2,
   200                  });
   201              }
   202          });
   203      api.SMTP.get()
   204          .success(function (profiles) {
   205              if (profiles.length == 0) {
   206                  modalError("No profiles found!")
   207                  return false
   208              } else {
   209                  var profile_s2 = $.map(profiles, function (obj) {
   210                      obj.text = obj.name
   211                      return obj
   212                  });
   213                  $("#profile.form-control").select2({
   214                      placeholder: "Select a Sending Profile",
   215                      data: profile_s2,
   216                  });
   217              }
   218          });
   219  }
   220  
   221  function edit(campaign) {
   222      setupOptions();
   223  }
   224  
   225  function copy(idx) {
   226      setupOptions();
   227      // Set our initial values
   228      api.campaignId.get(campaigns[idx].id)
   229          .success(function (campaign) {
   230              $("#name").val("Copy of " + campaign.name)
   231              if (!campaign.template.id) {
   232                  $("#template").select2({
   233                      placeholder: campaign.template.name
   234                  });
   235              } else {
   236                  $("#template").select2("val", campaign.template.id.toString());
   237              }
   238              if (!campaign.page.id) {
   239                  $("#page").select2({
   240                      placeholder: campaign.page.name
   241                  });
   242              } else {
   243                  $("#page").select2("val", campaign.page.id.toString());
   244              }
   245              if (!campaign.smtp.id) {
   246                  $("#profile").select2({
   247                      placeholder: campaign.smtp.name
   248                  });
   249              } else {
   250                  $("#profile").select2("val", campaign.smtp.id.toString());
   251              }
   252              $("#url").val(campaign.url)
   253          })
   254          .error(function (data) {
   255              $("#modal\\.flashes").empty().append("<div style=\"text-align:center\" class=\"alert alert-danger\">\
   256              <i class=\"fa fa-exclamation-circle\"></i> " + data.responseJSON.message + "</div>")
   257          })
   258  }
   259  
   260  $(document).ready(function () {
   261      $("#launch_date").datetimepicker({
   262          "widgetPositioning": {
   263              "vertical": "bottom"
   264          },
   265          "showTodayButton": true,
   266          "defaultDate": moment()
   267      })
   268      // Setup multiple modals
   269      // Code based on http://miles-by-motorcycle.com/static/bootstrap-modal/index.html
   270      $('.modal').on('hidden.bs.modal', function (event) {
   271          $(this).removeClass('fv-modal-stack');
   272          $('body').data('fv_open_modals', $('body').data('fv_open_modals') - 1);
   273      });
   274      $('.modal').on('shown.bs.modal', function (event) {
   275          // Keep track of the number of open modals
   276          if (typeof ($('body').data('fv_open_modals')) == 'undefined') {
   277              $('body').data('fv_open_modals', 0);
   278          }
   279          // if the z-index of this modal has been set, ignore.
   280          if ($(this).hasClass('fv-modal-stack')) {
   281              return;
   282          }
   283          $(this).addClass('fv-modal-stack');
   284          // Increment the number of open modals
   285          $('body').data('fv_open_modals', $('body').data('fv_open_modals') + 1);
   286          // Setup the appropriate z-index
   287          $(this).css('z-index', 1040 + (10 * $('body').data('fv_open_modals')));
   288          $('.modal-backdrop').not('.fv-modal-stack').css('z-index', 1039 + (10 * $('body').data('fv_open_modals')));
   289          $('.modal-backdrop').not('fv-modal-stack').addClass('fv-modal-stack');
   290      });
   291      // Scrollbar fix - https://stackoverflow.com/questions/19305821/multiple-modals-overlay
   292      $(document).on('hidden.bs.modal', '.modal', function () {
   293          $('.modal:visible').length && $(document.body).addClass('modal-open');
   294      });
   295      $('#modal').on('hidden.bs.modal', function (event) {
   296          dismiss()
   297      });
   298      api.campaigns.summary()
   299          .success(function (data) {
   300              campaigns = data.campaigns
   301              $("#loading").hide()
   302              if (campaigns.length > 0) {
   303                  $("#campaignTable").show()
   304                  campaignTable = $("#campaignTable").DataTable({
   305                      columnDefs: [{
   306                          orderable: false,
   307                          targets: "no-sort"
   308                      }],
   309                      order: [
   310                          [1, "desc"]
   311                      ]
   312                  });
   313                  $.each(campaigns, function (i, campaign) {
   314                      console.log(campaign)
   315                      console.log(campaign.created_date)
   316                      label = labels[campaign.status] || "label-default";
   317  
   318                      //section for tooltips on the status of a campaign to show some quick stats
   319                      var launchDate;
   320                      if (moment(campaign.launch_date).isAfter(moment())) {
   321                          launchDate = "Scheduled to start: " + moment(campaign.launch_date).format('MMMM Do YYYY, h:mm:ss a')
   322                          var quickStats = launchDate + "<br><br>" + "Number of recipients: " + campaign.stats.total
   323                      } else {
   324                          launchDate = "Launch Date: " + moment(campaign.launch_date).format('MMMM Do YYYY, h:mm:ss a')
   325                          var quickStats = launchDate + "<br><br>" + "Number of recipients: " + campaign.stats.total + "<br><br>" + "Emails opened: " + campaign.stats.opened + "<br><br>" + "Emails clicked: " + campaign.stats.clicked + "<br><br>" + "Submitted Credentials: " + campaign.stats.submitted_data + "<br><br>" + "Errors : " + campaign.stats.error
   326                      }
   327  
   328                      campaignTable.row.add([
   329                          escapeHtml(campaign.name),
   330                          moment(campaign.created_date).format('MMMM Do YYYY, h:mm:ss a'),
   331                          "<span class=\"label " + label + "\" data-toggle=\"tooltip\" data-placement=\"right\" data-html=\"true\" title=\"" + quickStats + "\">" + campaign.status + "</span>",
   332                          "<div class='pull-right'><a class='btn btn-primary' href='/campaigns/" + campaign.id + "' data-toggle='tooltip' data-placement='left' title='View Results'>\
   333                      <i class='fa fa-bar-chart'></i>\
   334                      </a>\
   335              <span data-toggle='modal' data-target='#modal'><button class='btn btn-primary' data-toggle='tooltip' data-placement='left' title='Copy Campaign' onclick='copy(" + i + ")'>\
   336                      <i class='fa fa-copy'></i>\
   337                      </button></span>\
   338                      <button class='btn btn-danger' onclick='deleteCampaign(" + i + ")' data-toggle='tooltip' data-placement='left' title='Delete Campaign'>\
   339                      <i class='fa fa-trash-o'></i>\
   340                      </button></div>"
   341                      ]).draw()
   342                      $('[data-toggle="tooltip"]').tooltip()
   343                  })
   344              } else {
   345                  $("#emptyMessage").show()
   346              }
   347          })
   348          .error(function () {
   349              $("#loading").hide()
   350              errorFlash("Error fetching campaigns")
   351          })
   352      // Select2 Defaults
   353      $.fn.select2.defaults.set("width", "100%");
   354      $.fn.select2.defaults.set("dropdownParent", $("#modal_body"));
   355      $.fn.select2.defaults.set("theme", "bootstrap");
   356  })