github.com/Ne0nd0g/gophish@v0.7.1-0.20190220040016-11493024a07d/static/js/src/app/users.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?api_key=" + user.api_key, 91 dataType: "json", 92 add: function (e, data) { 93 $("#modal\\.flashes").empty() 94 var acceptFileTypes = /(csv|txt)$/i; 95 var filename = data.originalFiles[0]['name'] 96 if (filename && !acceptFileTypes.test(filename.split(".").pop())) { 97 modalError("Unsupported file extension (use .csv or .txt)") 98 return false; 99 } 100 data.submit(); 101 }, 102 done: function (e, data) { 103 $.each(data.result, function (i, record) { 104 addTarget( 105 record.first_name, 106 record.last_name, 107 record.email, 108 record.position); 109 }); 110 targets.DataTable().draw(); 111 } 112 }) 113 } 114 115 var downloadCSVTemplate = function () { 116 var csvScope = [{ 117 'First Name': 'Example', 118 'Last Name': 'User', 119 'Email': 'foobar@example.com', 120 'Position': 'Systems Administrator' 121 }] 122 var filename = 'group_template.csv' 123 var csvString = Papa.unparse(csvScope, {}) 124 var csvData = new Blob([csvString], { 125 type: 'text/csv;charset=utf-8;' 126 }); 127 if (navigator.msSaveBlob) { 128 navigator.msSaveBlob(csvData, filename); 129 } else { 130 var csvURL = window.URL.createObjectURL(csvData); 131 var dlLink = document.createElement('a'); 132 dlLink.href = csvURL; 133 dlLink.setAttribute('download', filename) 134 document.body.appendChild(dlLink) 135 dlLink.click(); 136 document.body.removeChild(dlLink) 137 } 138 } 139 140 141 var deleteGroup = function (id) { 142 var group = groups.find(function (x) { 143 return x.id === id 144 }) 145 if (!group) { 146 return 147 } 148 swal({ 149 title: "Are you sure?", 150 text: "This will delete the group. This can't be undone!", 151 type: "warning", 152 animation: false, 153 showCancelButton: true, 154 confirmButtonText: "Delete " + escapeHtml(group.name), 155 confirmButtonColor: "#428bca", 156 reverseButtons: true, 157 allowOutsideClick: false, 158 preConfirm: function () { 159 return new Promise(function (resolve, reject) { 160 api.groupId.delete(id) 161 .success(function (msg) { 162 resolve() 163 }) 164 .error(function (data) { 165 reject(data.responseJSON.message) 166 }) 167 }) 168 } 169 }).then(function () { 170 swal( 171 'Group Deleted!', 172 'This group has been deleted!', 173 'success' 174 ); 175 $('button:contains("OK")').on('click', function () { 176 location.reload() 177 }) 178 }) 179 } 180 181 function addTarget(firstNameInput, lastNameInput, emailInput, positionInput) { 182 // Create new data row. 183 var email = escapeHtml(emailInput).toLowerCase(); 184 var newRow = [ 185 escapeHtml(firstNameInput), 186 escapeHtml(lastNameInput), 187 email, 188 escapeHtml(positionInput), 189 '<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>' 190 ]; 191 192 // Check table to see if email already exists. 193 var targetsTable = targets.DataTable(); 194 var existingRowIndex = targetsTable 195 .column(2, { 196 order: "index" 197 }) // Email column has index of 2 198 .data() 199 .indexOf(email); 200 // Update or add new row as necessary. 201 if (existingRowIndex >= 0) { 202 targetsTable 203 .row(existingRowIndex, { 204 order: "index" 205 }) 206 .data(newRow); 207 } else { 208 targetsTable.row.add(newRow); 209 } 210 } 211 212 function load() { 213 $("#groupTable").hide() 214 $("#emptyMessage").hide() 215 $("#loading").show() 216 api.groups.summary() 217 .success(function (response) { 218 $("#loading").hide() 219 if (response.total > 0) { 220 groups = response.groups 221 $("#emptyMessage").hide() 222 $("#groupTable").show() 223 var groupTable = $("#groupTable").DataTable({ 224 destroy: true, 225 columnDefs: [{ 226 orderable: false, 227 targets: "no-sort" 228 }] 229 }); 230 groupTable.clear(); 231 $.each(groups, function (i, group) { 232 groupTable.row.add([ 233 escapeHtml(group.name), 234 escapeHtml(group.num_targets), 235 moment(group.modified_date).format('MMMM Do YYYY, h:mm:ss a'), 236 "<div class='pull-right'><button class='btn btn-primary' data-toggle='modal' data-backdrop='static' data-target='#modal' onclick='edit(" + group.id + ")'>\ 237 <i class='fa fa-pencil'></i>\ 238 </button>\ 239 <button class='btn btn-danger' onclick='deleteGroup(" + group.id + ")'>\ 240 <i class='fa fa-trash-o'></i>\ 241 </button></div>" 242 ]).draw() 243 }) 244 } else { 245 $("#emptyMessage").show() 246 } 247 }) 248 .error(function () { 249 errorFlash("Error fetching groups") 250 }) 251 } 252 253 $(document).ready(function () { 254 load() 255 // Setup the event listeners 256 // Handle manual additions 257 $("#targetForm").submit(function () { 258 addTarget( 259 $("#firstName").val(), 260 $("#lastName").val(), 261 $("#email").val(), 262 $("#position").val()); 263 targets.DataTable().draw(); 264 265 // Reset user input. 266 $("#targetForm>div>input").val(''); 267 $("#firstName").focus(); 268 return false; 269 }); 270 // Handle Deletion 271 $("#targetsTable").on("click", "span>i.fa-trash-o", function () { 272 targets.DataTable() 273 .row($(this).parents('tr')) 274 .remove() 275 .draw(); 276 }); 277 $("#modal").on("hide.bs.modal", function () { 278 dismiss(); 279 }); 280 $("#csv-template").click(downloadCSVTemplate) 281 });