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