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

     1  var templates = []
     2  var icons = {
     3      "application/vnd.ms-excel": "fa-file-excel-o",
     4      "text/plain": "fa-file-text-o",
     5      "image/gif": "fa-file-image-o",
     6      "image/png": "fa-file-image-o",
     7      "application/pdf": "fa-file-pdf-o",
     8      "application/x-zip-compressed": "fa-file-archive-o",
     9      "application/x-gzip": "fa-file-archive-o",
    10      "application/vnd.openxmlformats-officedocument.presentationml.presentation": "fa-file-powerpoint-o",
    11      "application/vnd.openxmlformats-officedocument.wordprocessingml.document": "fa-file-word-o",
    12      "application/octet-stream": "fa-file-o",
    13      "application/x-msdownload": "fa-file-o"
    14  }
    15  
    16  // Save attempts to POST to /templates/
    17  function save(idx) {
    18      var template = {
    19          attachments: []
    20      }
    21      template.name = $("#name").val()
    22      template.subject = $("#subject").val()
    23      template.html = CKEDITOR.instances["html_editor"].getData();
    24      // Fix the URL Scheme added by CKEditor (until we can remove it from the plugin)
    25      template.html = template.html.replace(/https?:\/\/{{\.URL}}/gi, "{{.URL}}")
    26      // If the "Add Tracker Image" checkbox is checked, add the tracker
    27      if ($("#use_tracker_checkbox").prop("checked")) {
    28          if (template.html.indexOf("{{.Tracker}}") == -1 &&
    29              template.html.indexOf("{{.TrackingUrl}}") == -1) {
    30              template.html = template.html.replace("</body>", "{{.Tracker}}</body>")
    31          }
    32      } else {
    33          // Otherwise, remove the tracker
    34          template.html = template.html.replace("{{.Tracker}}</body>", "</body>")
    35      }
    36      template.text = $("#text_editor").val()
    37      // Add the attachments
    38      $.each($("#attachmentsTable").DataTable().rows().data(), function (i, target) {
    39          template.attachments.push({
    40              name: unescapeHtml(target[1]),
    41              content: target[3],
    42              type: target[4],
    43          })
    44      })
    45  
    46      if (idx != -1) {
    47          template.id = templates[idx].id
    48          api.templateId.put(template)
    49              .success(function (data) {
    50                  successFlash("Template edited successfully!")
    51                  load()
    52                  dismiss()
    53              })
    54              .error(function (data) {
    55                  modalError(data.responseJSON.message)
    56              })
    57      } else {
    58          // Submit the template
    59          api.templates.post(template)
    60              .success(function (data) {
    61                  successFlash("Template added successfully!")
    62                  load()
    63                  dismiss()
    64              })
    65              .error(function (data) {
    66                  modalError(data.responseJSON.message)
    67              })
    68      }
    69  }
    70  
    71  function dismiss() {
    72      $("#modal\\.flashes").empty()
    73      $("#attachmentsTable").dataTable().DataTable().clear().draw()
    74      $("#name").val("")
    75      $("#subject").val("")
    76      $("#text_editor").val("")
    77      $("#html_editor").val("")
    78      $("#modal").modal('hide')
    79  }
    80  
    81  function deleteTemplate(idx) {
    82      if (confirm("Delete " + templates[idx].name + "?")) {
    83          api.templateId.delete(templates[idx].id)
    84              .success(function (data) {
    85                  successFlash(data.message)
    86                  load()
    87              })
    88      }
    89  }
    90  
    91  function attach(files) {
    92      attachmentsTable = $("#attachmentsTable").DataTable({
    93          destroy: true,
    94          "order": [
    95              [1, "asc"]
    96          ],
    97          columnDefs: [{
    98              orderable: false,
    99              targets: "no-sort"
   100          }, {
   101              sClass: "datatable_hidden",
   102              targets: [3, 4]
   103          }]
   104      });
   105      $.each(files, function (i, file) {
   106          var reader = new FileReader();
   107          /* Make this a datatable */
   108          reader.onload = function (e) {
   109              var icon = icons[file.type] || "fa-file-o"
   110              // Add the record to the modal
   111              attachmentsTable.row.add([
   112                  '<i class="fa ' + icon + '"></i>',
   113                  escapeHtml(file.name),
   114                  '<span class="remove-row"><i class="fa fa-trash-o"></i></span>',
   115                  reader.result.split(",")[1],
   116                  file.type || "application/octet-stream"
   117              ]).draw()
   118          }
   119          reader.onerror = function (e) {
   120              console.log(e)
   121          }
   122          reader.readAsDataURL(file)
   123      })
   124  }
   125  
   126  function edit(idx) {
   127      $("#modalSubmit").unbind('click').click(function () {
   128          save(idx)
   129      })
   130      $("#attachmentUpload").unbind('click').click(function () {
   131          this.value = null
   132      })
   133      $("#html_editor").ckeditor()
   134      $("#attachmentsTable").show()
   135      attachmentsTable = $('#attachmentsTable').DataTable({
   136          destroy: true,
   137          "order": [
   138              [1, "asc"]
   139          ],
   140          columnDefs: [{
   141              orderable: false,
   142              targets: "no-sort"
   143          }, {
   144              sClass: "datatable_hidden",
   145              targets: [3, 4]
   146          }]
   147      });
   148      var template = {
   149          attachments: []
   150      }
   151      if (idx != -1) {
   152          template = templates[idx]
   153          $("#name").val(template.name)
   154          $("#subject").val(template.subject)
   155          $("#html_editor").val(template.html)
   156          $("#text_editor").val(template.text)
   157          $.each(template.attachments, function (i, file) {
   158              var icon = icons[file.type] || "fa-file-o"
   159              // Add the record to the modal
   160              attachmentsTable.row.add([
   161                  '<i class="fa ' + icon + '"></i>',
   162                  escapeHtml(file.name),
   163                  '<span class="remove-row"><i class="fa fa-trash-o"></i></span>',
   164                  file.content,
   165                  file.type || "application/octet-stream"
   166              ]).draw()
   167          })
   168          if (template.html.indexOf("{{.Tracker}}") != -1) {
   169              $("#use_tracker_checkbox").prop("checked", true)
   170          } else {
   171              $("#use_tracker_checkbox").prop("checked", false)
   172          }
   173  
   174      }
   175      // Handle Deletion
   176      $("#attachmentsTable").unbind('click').on("click", "span>i.fa-trash-o", function () {
   177          attachmentsTable.row($(this).parents('tr'))
   178              .remove()
   179              .draw();
   180      })
   181  }
   182  
   183  function copy(idx) {
   184      $("#modalSubmit").unbind('click').click(function () {
   185          save(-1)
   186      })
   187      $("#attachmentUpload").unbind('click').click(function () {
   188          this.value = null
   189      })
   190      $("#html_editor").ckeditor()
   191      $("#attachmentsTable").show()
   192      attachmentsTable = $('#attachmentsTable').DataTable({
   193          destroy: true,
   194          "order": [
   195              [1, "asc"]
   196          ],
   197          columnDefs: [{
   198              orderable: false,
   199              targets: "no-sort"
   200          }, {
   201              sClass: "datatable_hidden",
   202              targets: [3, 4]
   203          }]
   204      });
   205      var template = {
   206          attachments: []
   207      }
   208      template = templates[idx]
   209      $("#name").val("Copy of " + template.name)
   210      $("#subject").val(template.subject)
   211      $("#html_editor").val(template.html)
   212      $("#text_editor").val(template.text)
   213      $.each(template.attachments, function (i, file) {
   214          var icon = icons[file.type] || "fa-file-o"
   215          // Add the record to the modal
   216          attachmentsTable.row.add([
   217              '<i class="fa ' + icon + '"></i>',
   218              escapeHtml(file.name),
   219              '<span class="remove-row"><i class="fa fa-trash-o"></i></span>',
   220              file.content,
   221              file.type || "application/octet-stream"
   222          ]).draw()
   223      })
   224      // Handle Deletion
   225      $("#attachmentsTable").unbind('click').on("click", "span>i.fa-trash-o", function () {
   226          attachmentsTable.row($(this).parents('tr'))
   227              .remove()
   228              .draw();
   229      })
   230      if (template.html.indexOf("{{.Tracker}}") != -1) {
   231          $("#use_tracker_checkbox").prop("checked", true)
   232      } else {
   233          $("#use_tracker_checkbox").prop("checked", false)
   234      }
   235  }
   236  
   237  function importEmail() {
   238      raw = $("#email_content").val()
   239      convert_links = $("#convert_links_checkbox").prop("checked")
   240      if (!raw) {
   241          modalError("No Content Specified!")
   242      } else {
   243          $.ajax({
   244              method: "POST",
   245              url: "/api/import/email",
   246              data: JSON.stringify({
   247                  content: raw,
   248                  convert_links: convert_links
   249              }),
   250              dataType: "json",
   251              contentType: "application/json"
   252          })
   253              .success(function (data) {
   254                  $("#text_editor").val(data.text)
   255                  $("#html_editor").val(data.html)
   256                  $("#subject").val(data.subject)
   257                  $("#importEmailModal").modal("hide")
   258              })
   259              .error(function (data) {
   260                  modalError(data.responseJSON.message)
   261              })
   262      }
   263  }
   264  
   265  function load() {
   266      $("#templateTable").hide()
   267      $("#emptyMessage").hide()
   268      $("#loading").show()
   269      api.templates.get()
   270          .success(function (ts) {
   271              templates = ts
   272              $("#loading").hide()
   273              if (templates.length > 0) {
   274                  $("#templateTable").show()
   275                  templateTable = $("#templateTable").DataTable({
   276                      destroy: true,
   277                      columnDefs: [{
   278                          orderable: false,
   279                          targets: "no-sort"
   280                      }]
   281                  });
   282                  templateTable.clear()
   283                  $.each(templates, function (i, template) {
   284                      templateTable.row.add([
   285                          escapeHtml(template.name),
   286                          moment(template.modified_date).format('MMMM Do YYYY, h:mm:ss a'),
   287                          "<div class='pull-right'><span data-toggle='modal' data-target='#modal'><button class='btn btn-primary' data-toggle='tooltip' data-placement='left' title='Edit Template' onclick='edit(" + i + ")'>\
   288                      <i class='fa fa-pencil'></i>\
   289                      </button></span>\
   290  		    <span data-toggle='modal' data-target='#modal'><button class='btn btn-primary' data-toggle='tooltip' data-placement='left' title='Copy Template' onclick='copy(" + i + ")'>\
   291                      <i class='fa fa-copy'></i>\
   292                      </button></span>\
   293                      <button class='btn btn-danger' data-toggle='tooltip' data-placement='left' title='Delete Template' onclick='deleteTemplate(" + i + ")'>\
   294                      <i class='fa fa-trash-o'></i>\
   295                      </button></div>"
   296                      ]).draw()
   297                  })
   298                  $('[data-toggle="tooltip"]').tooltip()
   299              } else {
   300                  $("#emptyMessage").show()
   301              }
   302          })
   303          .error(function () {
   304              $("#loading").hide()
   305              errorFlash("Error fetching templates")
   306          })
   307  }
   308  
   309  $(document).ready(function () {
   310      // Setup multiple modals
   311      // Code based on http://miles-by-motorcycle.com/static/bootstrap-modal/index.html
   312      $('.modal').on('hidden.bs.modal', function (event) {
   313          $(this).removeClass('fv-modal-stack');
   314          $('body').data('fv_open_modals', $('body').data('fv_open_modals') - 1);
   315      });
   316      $('.modal').on('shown.bs.modal', function (event) {
   317          // Keep track of the number of open modals
   318          if (typeof ($('body').data('fv_open_modals')) == 'undefined') {
   319              $('body').data('fv_open_modals', 0);
   320          }
   321          // if the z-index of this modal has been set, ignore.
   322          if ($(this).hasClass('fv-modal-stack')) {
   323              return;
   324          }
   325          $(this).addClass('fv-modal-stack');
   326          // Increment the number of open modals
   327          $('body').data('fv_open_modals', $('body').data('fv_open_modals') + 1);
   328          // Setup the appropriate z-index
   329          $(this).css('z-index', 1040 + (10 * $('body').data('fv_open_modals')));
   330          $('.modal-backdrop').not('.fv-modal-stack').css('z-index', 1039 + (10 * $('body').data('fv_open_modals')));
   331          $('.modal-backdrop').not('fv-modal-stack').addClass('fv-modal-stack');
   332      });
   333      $.fn.modal.Constructor.prototype.enforceFocus = function () {
   334          $(document)
   335              .off('focusin.bs.modal') // guard against infinite focus loop
   336              .on('focusin.bs.modal', $.proxy(function (e) {
   337                  if (
   338                      this.$element[0] !== e.target && !this.$element.has(e.target).length
   339                      // CKEditor compatibility fix start.
   340                      && !$(e.target).closest('.cke_dialog, .cke').length
   341                      // CKEditor compatibility fix end.
   342                  ) {
   343                      this.$element.trigger('focus');
   344                  }
   345              }, this));
   346      };
   347      $('#modal').on('hidden.bs.modal', function (event) {
   348          dismiss()
   349      });
   350      $("#importEmailModal").on('hidden.bs.modal', function (event) {
   351          $("#email_content").val("")
   352      })
   353      load()
   354  
   355  })