github.com/merlinepedra/gophish1@v0.9.0/static/js/src/app/groups.js (about) 1 var groups = [] 2 3 // Save attempts to POST or PUT to /groups/ 4 function save(id) { 5 var targets = [] 6 $.each($("#targetsTable").DataTable().rows().data(), function (i, target) { 7 targets.push({ 8 first_name: unescapeHtml(target[0]), 9 last_name: unescapeHtml(target[1]), 10 email: unescapeHtml(target[2]), 11 position: unescapeHtml(target[3]) 12 }) 13 }) 14 var group = { 15 name: $("#name").val(), 16 targets: targets 17 } 18 // Submit the group 19 if (id != -1) { 20 // If we're just editing an existing group, 21 // we need to PUT /groups/:id 22 group.id = id 23 api.groupId.put(group) 24 .success(function (data) { 25 successFlash("Group updated successfully!") 26 load() 27 dismiss() 28 $("#modal").modal('hide') 29 }) 30 .error(function (data) { 31 modalError(data.responseJSON.message) 32 }) 33 } else { 34 // Else, if this is a new group, POST it 35 // to /groups 36 api.groups.post(group) 37 .success(function (data) { 38 successFlash("Group added successfully!") 39 load() 40 dismiss() 41 $("#modal").modal('hide') 42 }) 43 .error(function (data) { 44 modalError(data.responseJSON.message) 45 }) 46 } 47 } 48 49 function dismiss() { 50 $("#targetsTable").dataTable().DataTable().clear().draw() 51 $("#name").val("") 52 $("#modal\\.flashes").empty() 53 } 54 55 function edit(id) { 56 targets = $("#targetsTable").dataTable({ 57 destroy: true, // Destroy any other instantiated table - http://datatables.net/manual/tech-notes/3#destroy 58 columnDefs: [{ 59 orderable: false, 60 targets: "no-sort" 61 }] 62 }) 63 $("#modalSubmit").unbind('click').click(function () { 64 save(id) 65 }) 66 if (id == -1) { 67 var group = {} 68 } else { 69 api.groupId.get(id) 70 .success(function (group) { 71 $("#name").val(group.name) 72 $.each(group.targets, function (i, record) { 73 targets.DataTable() 74 .row.add([ 75 escapeHtml(record.first_name), 76 escapeHtml(record.last_name), 77 escapeHtml(record.email), 78 escapeHtml(record.position), 79 '<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>' 80 ]).draw() 81 }); 82 83 }) 84 .error(function () { 85 errorFlash("Error fetching group") 86 }) 87 } 88 // Handle file uploads 89 $("#csvupload").fileupload({ 90 url: "/api/import/group", 91 dataType: "json", 92 beforeSend: function (xhr) { 93 xhr.setRequestHeader('Authorization', 'Bearer ' + user.api_key); 94 }, 95 add: function (e, data) { 96 $("#modal\\.flashes").empty() 97 var acceptFileTypes = /(csv|txt)$/i; 98 var filename = data.originalFiles[0]['name'] 99 if (filename && !acceptFileTypes.test(filename.split(".").pop())) { 100 modalError("Unsupported file extension (use .csv or .txt)") 101 return false; 102 } 103 data.submit(); 104 }, 105 done: function (e, data) { 106 $.each(data.result, function (i, record) { 107 addTarget( 108 record.first_name, 109 record.last_name, 110 record.email, 111 record.position); 112 }); 113 targets.DataTable().draw(); 114 } 115 }) 116 } 117 118 var downloadCSVTemplate = function () { 119 var csvScope = [{ 120 'First Name': 'Example', 121 'Last Name': 'User', 122 'Email': 'foobar@example.com', 123 'Position': 'Systems Administrator' 124 }] 125 var filename = 'group_template.csv' 126 var csvString = Papa.unparse(csvScope, {}) 127 var csvData = new Blob([csvString], { 128 type: 'text/csv;charset=utf-8;' 129 }); 130 if (navigator.msSaveBlob) { 131 navigator.msSaveBlob(csvData, filename); 132 } else { 133 var csvURL = window.URL.createObjectURL(csvData); 134 var dlLink = document.createElement('a'); 135 dlLink.href = csvURL; 136 dlLink.setAttribute('download', filename) 137 document.body.appendChild(dlLink) 138 dlLink.click(); 139 document.body.removeChild(dlLink) 140 } 141 } 142 143 144 var deleteGroup = function (id) { 145 var group = groups.find(function (x) { 146 return x.id === id 147 }) 148 if (!group) { 149 return 150 } 151 Swal.fire({ 152 title: "Are you sure?", 153 text: "This will delete the group. This can't be undone!", 154 type: "warning", 155 animation: false, 156 showCancelButton: true, 157 confirmButtonText: "Delete " + escapeHtml(group.name), 158 confirmButtonColor: "#428bca", 159 reverseButtons: true, 160 allowOutsideClick: false, 161 preConfirm: function () { 162 return new Promise(function (resolve, reject) { 163 api.groupId.delete(id) 164 .success(function (msg) { 165 resolve() 166 }) 167 .error(function (data) { 168 reject(data.responseJSON.message) 169 }) 170 }) 171 } 172 }).then(function (result) { 173 if (result.value){ 174 Swal.fire( 175 'Group Deleted!', 176 'This group has been deleted!', 177 'success' 178 ); 179 } 180 $('button:contains("OK")').on('click', function () { 181 location.reload() 182 }) 183 }) 184 } 185 186 function addTarget(firstNameInput, lastNameInput, emailInput, positionInput) { 187 // Create new data row. 188 var email = escapeHtml(emailInput).toLowerCase(); 189 var newRow = [ 190 escapeHtml(firstNameInput), 191 escapeHtml(lastNameInput), 192 email, 193 escapeHtml(positionInput), 194 '<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>' 195 ]; 196 197 // Check table to see if email already exists. 198 var targetsTable = targets.DataTable(); 199 var existingRowIndex = targetsTable 200 .column(2, { 201 order: "index" 202 }) // Email column has index of 2 203 .data() 204 .indexOf(email); 205 // Update or add new row as necessary. 206 if (existingRowIndex >= 0) { 207 targetsTable 208 .row(existingRowIndex, { 209 order: "index" 210 }) 211 .data(newRow); 212 } else { 213 targetsTable.row.add(newRow); 214 } 215 } 216 217 function load() { 218 $("#groupTable").hide() 219 $("#emptyMessage").hide() 220 $("#loading").show() 221 api.groups.summary() 222 .success(function (response) { 223 $("#loading").hide() 224 if (response.total > 0) { 225 groups = response.groups 226 $("#emptyMessage").hide() 227 $("#groupTable").show() 228 var groupTable = $("#groupTable").DataTable({ 229 destroy: true, 230 columnDefs: [{ 231 orderable: false, 232 targets: "no-sort" 233 }] 234 }); 235 groupTable.clear(); 236 $.each(groups, function (i, group) { 237 groupTable.row.add([ 238 escapeHtml(group.name), 239 escapeHtml(group.num_targets), 240 moment(group.modified_date).format('MMMM Do YYYY, h:mm:ss a'), 241 "<div class='pull-right'><button class='btn btn-primary' data-toggle='modal' data-backdrop='static' data-target='#modal' onclick='edit(" + group.id + ")'>\ 242 <i class='fa fa-pencil'></i>\ 243 </button>\ 244 <button class='btn btn-danger' onclick='deleteGroup(" + group.id + ")'>\ 245 <i class='fa fa-trash-o'></i>\ 246 </button></div>" 247 ]).draw() 248 }) 249 } else { 250 $("#emptyMessage").show() 251 } 252 }) 253 .error(function () { 254 errorFlash("Error fetching groups") 255 }) 256 } 257 258 $(document).ready(function () { 259 load() 260 // Setup the event listeners 261 // Handle manual additions 262 $("#targetForm").submit(function () { 263 // Validate the form data 264 var targetForm = document.getElementById("targetForm") 265 if (!targetForm.checkValidity()) { 266 targetForm.reportValidity() 267 return 268 } 269 addTarget( 270 $("#firstName").val(), 271 $("#lastName").val(), 272 $("#email").val(), 273 $("#position").val()); 274 targets.DataTable().draw(); 275 276 // Reset user input. 277 $("#targetForm>div>input").val(''); 278 $("#firstName").focus(); 279 return false; 280 }); 281 // Handle Deletion 282 $("#targetsTable").on("click", "span>i.fa-trash-o", function () { 283 targets.DataTable() 284 .row($(this).parents('tr')) 285 .remove() 286 .draw(); 287 }); 288 $("#modal").on("hide.bs.modal", function () { 289 dismiss(); 290 }); 291 $("#csv-template").click(downloadCSVTemplate) 292 });