github.com/lunarobliq/gophish@v0.8.1-0.20230523153303-93511002234d/static/js/src/app/landing_pages.js (about)

     1  /*
     2  	landing_pages.js
     3  	Handles the creation, editing, and deletion of landing pages
     4  	Author: Jordan Wright <github.com/jordan-wright>
     5  */
     6  var pages = []
     7  
     8  
     9  // Save attempts to POST to /templates/
    10  function save(idx) {
    11      var page = {}
    12      page.name = $("#name").val()
    13      editor = CKEDITOR.instances["html_editor"]
    14      page.html = editor.getData()
    15      page.capture_credentials = $("#capture_credentials_checkbox").prop("checked")
    16      page.capture_passwords = $("#capture_passwords_checkbox").prop("checked")
    17      page.redirect_url = $("#redirect_url_input").val()
    18      if (idx != -1) {
    19          page.id = pages[idx].id
    20          api.pageId.put(page)
    21              .success(function (data) {
    22                  successFlash("Page edited successfully!")
    23                  load()
    24                  dismiss()
    25              })
    26      } else {
    27          // Submit the page
    28          api.pages.post(page)
    29              .success(function (data) {
    30                  successFlash("Page added successfully!")
    31                  load()
    32                  dismiss()
    33              })
    34              .error(function (data) {
    35                  modalError(data.responseJSON.message)
    36              })
    37      }
    38  }
    39  
    40  function dismiss() {
    41      $("#modal\\.flashes").empty()
    42      $("#name").val("")
    43      $("#html_editor").val("")
    44      $("#url").val("")
    45      $("#redirect_url_input").val("")
    46      $("#modal").find("input[type='checkbox']").prop("checked", false)
    47      $("#capture_passwords").hide()
    48      $("#redirect_url").hide()
    49      $("#modal").modal('hide')
    50  }
    51  
    52  var deletePage = function (idx) {
    53      Swal.fire({
    54          title: "Are you sure?",
    55          text: "This will delete the landing page. This can't be undone!",
    56          type: "warning",
    57          animation: false,
    58          showCancelButton: true,
    59          confirmButtonText: "Delete " + escapeHtml(pages[idx].name),
    60          confirmButtonColor: "#428bca",
    61          reverseButtons: true,
    62          allowOutsideClick: false,
    63          preConfirm: function () {
    64              return new Promise(function (resolve, reject) {
    65                  api.pageId.delete(pages[idx].id)
    66                      .success(function (msg) {
    67                          resolve()
    68                      })
    69                      .error(function (data) {
    70                          reject(data.responseJSON.message)
    71                      })
    72              })
    73          }
    74      }).then(function (result) {
    75          if (result.value){
    76              Swal.fire(
    77                  'Landing Page Deleted!',
    78                  'This landing page has been deleted!',
    79                  'success'
    80              );
    81          }
    82          $('button:contains("OK")').on('click', function () {
    83              location.reload()
    84          })
    85      })
    86  }
    87  
    88  function importSite() {
    89      url = $("#url").val()
    90      if (!url) {
    91          modalError("No URL Specified!")
    92      } else {
    93          api.clone_site({
    94                  url: url,
    95                  include_resources: false
    96              })
    97              .success(function (data) {
    98                  $("#html_editor").val(data.html)
    99                  CKEDITOR.instances["html_editor"].setMode('wysiwyg')
   100                  $("#importSiteModal").modal("hide")
   101              })
   102              .error(function (data) {
   103                  modalError(data.responseJSON.message)
   104              })
   105      }
   106  }
   107  
   108  function edit(idx) {
   109      $("#modalSubmit").unbind('click').click(function () {
   110          save(idx)
   111      })
   112      $("#html_editor").ckeditor()
   113      setupAutocomplete(CKEDITOR.instances["html_editor"])
   114      var page = {}
   115      if (idx != -1) {
   116          $("#modalLabel").text("Edit Landing Page")
   117          page = pages[idx]
   118          $("#name").val(page.name)
   119          $("#html_editor").val(page.html)
   120          $("#capture_credentials_checkbox").prop("checked", page.capture_credentials)
   121          $("#capture_passwords_checkbox").prop("checked", page.capture_passwords)
   122          $("#redirect_url_input").val(page.redirect_url)
   123          if (page.capture_credentials) {
   124              $("#capture_passwords").show()
   125              $("#redirect_url").show()
   126          }
   127      } else {
   128          $("#modalLabel").text("New Landing Page")
   129      }
   130  }
   131  
   132  function copy(idx) {
   133      $("#modalSubmit").unbind('click').click(function () {
   134          save(-1)
   135      })
   136      $("#html_editor").ckeditor()
   137      var page = pages[idx]
   138      $("#name").val("Copy of " + page.name)
   139      $("#html_editor").val(page.html)
   140  }
   141  
   142  function load() {
   143      /*
   144          load() - Loads the current pages using the API
   145      */
   146      $("#pagesTable").hide()
   147      $("#emptyMessage").hide()
   148      $("#loading").show()
   149      api.pages.get()
   150          .success(function (ps) {
   151              pages = ps
   152              $("#loading").hide()
   153              if (pages.length > 0) {
   154                  $("#pagesTable").show()
   155                  pagesTable = $("#pagesTable").DataTable({
   156                      destroy: true,
   157                      columnDefs: [{
   158                          orderable: false,
   159                          targets: "no-sort"
   160                      }]
   161                  });
   162                  pagesTable.clear()
   163                  pageRows = []
   164                  $.each(pages, function (i, page) {
   165                      pageRows.push([
   166                          escapeHtml(page.name),
   167                          moment(page.modified_date).format('MMMM Do YYYY, h:mm:ss a'),
   168                          "<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 Page' onclick='edit(" + i + ")'>\
   169                      <i class='fa fa-pencil'></i>\
   170                      </button></span>\
   171  		    <span data-toggle='modal' data-target='#modal'><button class='btn btn-primary' data-toggle='tooltip' data-placement='left' title='Copy Page' onclick='copy(" + i + ")'>\
   172                      <i class='fa fa-copy'></i>\
   173                      </button></span>\
   174                      <button class='btn btn-danger' data-toggle='tooltip' data-placement='left' title='Delete Page' onclick='deletePage(" + i + ")'>\
   175                      <i class='fa fa-trash-o'></i>\
   176                      </button></div>"
   177                      ])
   178                  })
   179                  pagesTable.rows.add(pageRows).draw()
   180                  $('[data-toggle="tooltip"]').tooltip()
   181              } else {
   182                  $("#emptyMessage").show()
   183              }
   184          })
   185          .error(function () {
   186              $("#loading").hide()
   187              errorFlash("Error fetching pages")
   188          })
   189  }
   190  
   191  $(document).ready(function () {
   192      // Setup multiple modals
   193      // Code based on http://miles-by-motorcycle.com/static/bootstrap-modal/index.html
   194      $('.modal').on('hidden.bs.modal', function (event) {
   195          $(this).removeClass('fv-modal-stack');
   196          $('body').data('fv_open_modals', $('body').data('fv_open_modals') - 1);
   197      });
   198      $('.modal').on('shown.bs.modal', function (event) {
   199          // Keep track of the number of open modals
   200          if (typeof ($('body').data('fv_open_modals')) == 'undefined') {
   201              $('body').data('fv_open_modals', 0);
   202          }
   203          // if the z-index of this modal has been set, ignore.
   204          if ($(this).hasClass('fv-modal-stack')) {
   205              return;
   206          }
   207          $(this).addClass('fv-modal-stack');
   208          // Increment the number of open modals
   209          $('body').data('fv_open_modals', $('body').data('fv_open_modals') + 1);
   210          // Setup the appropriate z-index
   211          $(this).css('z-index', 1040 + (10 * $('body').data('fv_open_modals')));
   212          $('.modal-backdrop').not('.fv-modal-stack').css('z-index', 1039 + (10 * $('body').data('fv_open_modals')));
   213          $('.modal-backdrop').not('fv-modal-stack').addClass('fv-modal-stack');
   214      });
   215      $.fn.modal.Constructor.prototype.enforceFocus = function () {
   216          $(document)
   217              .off('focusin.bs.modal') // guard against infinite focus loop
   218              .on('focusin.bs.modal', $.proxy(function (e) {
   219                  if (
   220                      this.$element[0] !== e.target && !this.$element.has(e.target).length
   221                      // CKEditor compatibility fix start.
   222                      &&
   223                      !$(e.target).closest('.cke_dialog, .cke').length
   224                      // CKEditor compatibility fix end.
   225                  ) {
   226                      this.$element.trigger('focus');
   227                  }
   228              }, this));
   229      };
   230      // Scrollbar fix - https://stackoverflow.com/questions/19305821/multiple-modals-overlay
   231      $(document).on('hidden.bs.modal', '.modal', function () {
   232          $('.modal:visible').length && $(document.body).addClass('modal-open');
   233      });
   234      $('#modal').on('hidden.bs.modal', function (event) {
   235          dismiss()
   236      });
   237      $("#capture_credentials_checkbox").change(function () {
   238          $("#capture_passwords").toggle()
   239          $("#redirect_url").toggle()
   240      })
   241      CKEDITOR.on('dialogDefinition', function (ev) {
   242          // Take the dialog name and its definition from the event data.
   243          var dialogName = ev.data.name;
   244          var dialogDefinition = ev.data.definition;
   245  
   246          // Check if the definition is from the dialog window you are interested in (the "Link" dialog window).
   247          if (dialogName == 'link') {
   248              dialogDefinition.minWidth = 500
   249              dialogDefinition.minHeight = 100
   250  
   251              // Remove the linkType field
   252              var infoTab = dialogDefinition.getContents('info');
   253              infoTab.get('linkType').hidden = true;
   254          }
   255      });
   256  
   257      load()
   258  })