github.com/jonathaningram/gophish@v0.3.1-0.20170829042651-ac3fe6aeae6c/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 dataType: "json", 91 add: function(e, data) { 92 $("#modal\\.flashes").empty() 93 var acceptFileTypes = /(csv|txt)$/i; 94 var filename = data.originalFiles[0]['name'] 95 if (filename && !acceptFileTypes.test(filename.split(".").pop())) { 96 modalError("Unsupported file extension (use .csv or .txt)") 97 return false; 98 } 99 data.submit(); 100 }, 101 done: function(e, data) { 102 $.each(data.result, function(i, record) { 103 addTarget( 104 record.first_name, 105 record.last_name, 106 record.email, 107 record.position); 108 }); 109 targets.DataTable().draw(); 110 } 111 }) 112 } 113 114 function deleteGroup(id) { 115 var group = groups.find(function(x){return x.id === id}) 116 if (!group) { 117 console.log('wat'); 118 return 119 } 120 if (confirm("Delete " + group.name + "?")) { 121 api.groupId.delete(id) 122 .success(function(data) { 123 successFlash(data.message) 124 load() 125 }) 126 } 127 } 128 129 function addTarget(firstNameInput, lastNameInput, emailInput, positionInput) { 130 // Create new data row. 131 var email = escapeHtml(emailInput).toLowerCase(); 132 var newRow = [ 133 escapeHtml(firstNameInput), 134 escapeHtml(lastNameInput), 135 email, 136 escapeHtml(positionInput), 137 '<span style="cursor:pointer;"><i class="fa fa-trash-o"></i></span>' 138 ]; 139 140 // Check table to see if email already exists. 141 var targetsTable = targets.DataTable(); 142 var existingRowIndex = targetsTable 143 .column(2, { 144 order: "index" 145 }) // Email column has index of 2 146 .data() 147 .indexOf(email); 148 // Update or add new row as necessary. 149 if (existingRowIndex >= 0) { 150 targetsTable 151 .row(existingRowIndex, { 152 order: "index" 153 }) 154 .data(newRow); 155 } else { 156 targetsTable.row.add(newRow); 157 } 158 } 159 160 function load() { 161 $("#groupTable").hide() 162 $("#emptyMessage").hide() 163 $("#loading").show() 164 api.groups.summary() 165 .success(function(response) { 166 $("#loading").hide() 167 if (response.total > 0) { 168 groups = response.groups 169 $("#emptyMessage").hide() 170 $("#groupTable").show() 171 var groupTable = $("#groupTable").DataTable({ 172 destroy: true, 173 columnDefs: [{ 174 orderable: false, 175 targets: "no-sort" 176 }] 177 }); 178 groupTable.clear(); 179 $.each(groups, function(i, group) { 180 groupTable.row.add([ 181 escapeHtml(group.name), 182 escapeHtml(group.num_targets), 183 moment(group.modified_date).format('MMMM Do YYYY, h:mm:ss a'), 184 "<div class='pull-right'><button class='btn btn-primary' data-toggle='modal' data-target='#modal' onclick='edit(" + group.id + ")'>\ 185 <i class='fa fa-pencil'></i>\ 186 </button>\ 187 <button class='btn btn-danger' onclick='deleteGroup(" + group.id + ")'>\ 188 <i class='fa fa-trash-o'></i>\ 189 </button></div>" 190 ]).draw() 191 }) 192 } else { 193 $("#emptyMessage").show() 194 } 195 }) 196 .error(function() { 197 errorFlash("Error fetching groups") 198 }) 199 } 200 201 $(document).ready(function() { 202 load() 203 // Setup the event listeners 204 // Handle manual additions 205 $("#targetForm").submit(function() { 206 addTarget( 207 $("#firstName").val(), 208 $("#lastName").val(), 209 $("#email").val(), 210 $("#position").val()); 211 targets.DataTable().draw(); 212 213 // Reset user input. 214 $("#targetForm>div>input").val(''); 215 $("#firstName").focus(); 216 return false; 217 }); 218 // Handle Deletion 219 $("#targetsTable").on("click", "span>i.fa-trash-o", function() { 220 targets.DataTable() 221 .row($(this).parents('tr')) 222 .remove() 223 .draw(); 224 }); 225 $("#modal").on("hide.bs.modal", function() { 226 dismiss(); 227 }); 228 });