github.com/merlinepedra/gophish1@v0.9.0/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 page = pages[idx] 117 $("#name").val(page.name) 118 $("#html_editor").val(page.html) 119 $("#capture_credentials_checkbox").prop("checked", page.capture_credentials) 120 $("#capture_passwords_checkbox").prop("checked", page.capture_passwords) 121 $("#redirect_url_input").val(page.redirect_url) 122 if (page.capture_credentials) { 123 $("#capture_passwords").show() 124 $("#redirect_url").show() 125 } 126 } 127 } 128 129 function copy(idx) { 130 $("#modalSubmit").unbind('click').click(function () { 131 save(-1) 132 }) 133 $("#html_editor").ckeditor() 134 var page = pages[idx] 135 $("#name").val("Copy of " + page.name) 136 $("#html_editor").val(page.html) 137 } 138 139 function load() { 140 /* 141 load() - Loads the current pages using the API 142 */ 143 $("#pagesTable").hide() 144 $("#emptyMessage").hide() 145 $("#loading").show() 146 api.pages.get() 147 .success(function (ps) { 148 pages = ps 149 $("#loading").hide() 150 if (pages.length > 0) { 151 $("#pagesTable").show() 152 pagesTable = $("#pagesTable").DataTable({ 153 destroy: true, 154 columnDefs: [{ 155 orderable: false, 156 targets: "no-sort" 157 }] 158 }); 159 pagesTable.clear() 160 $.each(pages, function (i, page) { 161 pagesTable.row.add([ 162 escapeHtml(page.name), 163 moment(page.modified_date).format('MMMM Do YYYY, h:mm:ss a'), 164 "<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 + ")'>\ 165 <i class='fa fa-pencil'></i>\ 166 </button></span>\ 167 <span data-toggle='modal' data-target='#modal'><button class='btn btn-primary' data-toggle='tooltip' data-placement='left' title='Copy Page' onclick='copy(" + i + ")'>\ 168 <i class='fa fa-copy'></i>\ 169 </button></span>\ 170 <button class='btn btn-danger' data-toggle='tooltip' data-placement='left' title='Delete Page' onclick='deletePage(" + i + ")'>\ 171 <i class='fa fa-trash-o'></i>\ 172 </button></div>" 173 ]).draw() 174 }) 175 $('[data-toggle="tooltip"]').tooltip() 176 } else { 177 $("#emptyMessage").show() 178 } 179 }) 180 .error(function () { 181 $("#loading").hide() 182 errorFlash("Error fetching pages") 183 }) 184 } 185 186 $(document).ready(function () { 187 // Setup multiple modals 188 // Code based on http://miles-by-motorcycle.com/static/bootstrap-modal/index.html 189 $('.modal').on('hidden.bs.modal', function (event) { 190 $(this).removeClass('fv-modal-stack'); 191 $('body').data('fv_open_modals', $('body').data('fv_open_modals') - 1); 192 }); 193 $('.modal').on('shown.bs.modal', function (event) { 194 // Keep track of the number of open modals 195 if (typeof ($('body').data('fv_open_modals')) == 'undefined') { 196 $('body').data('fv_open_modals', 0); 197 } 198 // if the z-index of this modal has been set, ignore. 199 if ($(this).hasClass('fv-modal-stack')) { 200 return; 201 } 202 $(this).addClass('fv-modal-stack'); 203 // Increment the number of open modals 204 $('body').data('fv_open_modals', $('body').data('fv_open_modals') + 1); 205 // Setup the appropriate z-index 206 $(this).css('z-index', 1040 + (10 * $('body').data('fv_open_modals'))); 207 $('.modal-backdrop').not('.fv-modal-stack').css('z-index', 1039 + (10 * $('body').data('fv_open_modals'))); 208 $('.modal-backdrop').not('fv-modal-stack').addClass('fv-modal-stack'); 209 }); 210 $.fn.modal.Constructor.prototype.enforceFocus = function () { 211 $(document) 212 .off('focusin.bs.modal') // guard against infinite focus loop 213 .on('focusin.bs.modal', $.proxy(function (e) { 214 if ( 215 this.$element[0] !== e.target && !this.$element.has(e.target).length 216 // CKEditor compatibility fix start. 217 && 218 !$(e.target).closest('.cke_dialog, .cke').length 219 // CKEditor compatibility fix end. 220 ) { 221 this.$element.trigger('focus'); 222 } 223 }, this)); 224 }; 225 // Scrollbar fix - https://stackoverflow.com/questions/19305821/multiple-modals-overlay 226 $(document).on('hidden.bs.modal', '.modal', function () { 227 $('.modal:visible').length && $(document.body).addClass('modal-open'); 228 }); 229 $('#modal').on('hidden.bs.modal', function (event) { 230 dismiss() 231 }); 232 $("#capture_credentials_checkbox").change(function () { 233 $("#capture_passwords").toggle() 234 $("#redirect_url").toggle() 235 }) 236 CKEDITOR.on('dialogDefinition', function (ev) { 237 // Take the dialog name and its definition from the event data. 238 var dialogName = ev.data.name; 239 var dialogDefinition = ev.data.definition; 240 241 // Check if the definition is from the dialog window you are interested in (the "Link" dialog window). 242 if (dialogName == 'link') { 243 dialogDefinition.minWidth = 500 244 dialogDefinition.minHeight = 100 245 246 // Remove the linkType field 247 var infoTab = dialogDefinition.getContents('info'); 248 infoTab.get('linkType').hidden = true; 249 } 250 }); 251 252 load() 253 })