mirror of https://github.com/gophish/gophish
Updated dashboard to show full final statuses instead of just "Successful" vs "Unsuccessful".
parent
269568148e
commit
80c68194a6
File diff suppressed because one or more lines are too long
|
@ -1,12 +1,89 @@
|
|||
var campaigns = []
|
||||
// labels is a map of campaign statuses to
|
||||
// CSS classes
|
||||
var labels = {
|
||||
"In progress": "label-primary",
|
||||
"Queued": "label-info",
|
||||
"Completed": "label-success",
|
||||
"Emails Sent": "label-success",
|
||||
"Error": "label-danger"
|
||||
|
||||
// statuses is a helper map to point result statuses to ui classes
|
||||
var statuses = {
|
||||
"Email Sent": {
|
||||
slice: "ct-slice-donut-sent",
|
||||
legend: "ct-legend-sent",
|
||||
label: "label-success",
|
||||
icon: "fa-envelope",
|
||||
point: "ct-point-sent"
|
||||
},
|
||||
"Email Sent": {
|
||||
slice: "ct-slice-donut-sent",
|
||||
legend: "ct-legend-sent",
|
||||
label: "label-success",
|
||||
icon: "fa-envelope",
|
||||
point: "ct-point-sent"
|
||||
},
|
||||
"Email Opened": {
|
||||
slice: "ct-slice-donut-opened",
|
||||
legend: "ct-legend-opened",
|
||||
label: "label-warning",
|
||||
icon: "fa-envelope",
|
||||
point: "ct-point-opened"
|
||||
},
|
||||
"Clicked Link": {
|
||||
slice: "ct-slice-donut-clicked",
|
||||
legend: "ct-legend-clicked",
|
||||
label: "label-clicked",
|
||||
icon: "fa-mouse-pointer",
|
||||
point: "ct-point-clicked"
|
||||
},
|
||||
"Success": {
|
||||
slice: "ct-slice-donut-success",
|
||||
legend: "ct-legend-success",
|
||||
label: "label-danger",
|
||||
icon: "fa-exclamation",
|
||||
point: "ct-point-clicked"
|
||||
},
|
||||
"Error": {
|
||||
slice: "ct-slice-donut-error",
|
||||
legend: "ct-legend-error",
|
||||
label: "label-default",
|
||||
icon: "fa-times",
|
||||
point: "ct-point-error"
|
||||
},
|
||||
"Error Sending Email": {
|
||||
slice: "ct-slice-donut-error",
|
||||
legend: "ct-legend-error",
|
||||
label: "label-default",
|
||||
icon: "fa-times",
|
||||
point: "ct-point-error"
|
||||
},
|
||||
"Submitted Data": {
|
||||
slice: "ct-slice-donut-success",
|
||||
legend: "ct-legend-success",
|
||||
label: "label-danger",
|
||||
icon: "fa-exclamation",
|
||||
point: "ct-point-clicked"
|
||||
},
|
||||
"Unknown": {
|
||||
slice: "ct-slice-donut-error",
|
||||
legend: "ct-legend-error",
|
||||
label: "label-default",
|
||||
icon: "fa-question",
|
||||
point: "ct-point-error"
|
||||
},
|
||||
"Sending": {
|
||||
slice: "ct-slice-donut-sending",
|
||||
legend: "ct-legend-sending",
|
||||
label: "label-primary",
|
||||
icon: "fa-spinner",
|
||||
point: "ct-point-sending"
|
||||
},
|
||||
"Campaign Created": {
|
||||
label: "label-success",
|
||||
icon: "fa-rocket"
|
||||
}
|
||||
}
|
||||
|
||||
var statsMapping = {
|
||||
"sent": "Email Sent",
|
||||
"opened": "Email Opened",
|
||||
"clicked": "Clicked Link",
|
||||
"submitted_data": "Submitted Data",
|
||||
"error": "Error"
|
||||
}
|
||||
|
||||
function deleteCampaign(idx) {
|
||||
|
@ -19,6 +96,75 @@ function deleteCampaign(idx) {
|
|||
}
|
||||
}
|
||||
|
||||
function generateStatsPieChart(campaigns) {
|
||||
var stats_opts = {
|
||||
donut: true,
|
||||
donutWidth: 40,
|
||||
chartPadding: 0,
|
||||
showLabel: false
|
||||
}
|
||||
var stats_series_data = {}
|
||||
var stats_data = {
|
||||
series: []
|
||||
}
|
||||
var total = 0
|
||||
|
||||
$.each(campaigns, function(i, campaign) {
|
||||
$.each(campaign.stats, function(status, count) {
|
||||
if (status == "total") {
|
||||
total += count
|
||||
return true
|
||||
}
|
||||
if (!stats_series_data[status]) {
|
||||
stats_series_data[status] = count;
|
||||
} else {
|
||||
stats_series_data[status] += count;
|
||||
}
|
||||
})
|
||||
})
|
||||
$.each(stats_series_data, function(status, count) {
|
||||
// I don't like this, but I guess it'll have to work.
|
||||
// Turns submitted_data into Submitted Data
|
||||
status_label = statsMapping[status]
|
||||
stats_data.series.push({
|
||||
meta: status_label,
|
||||
value: Math.floor((count / total) * 100)
|
||||
})
|
||||
$("#stats_chart_legend").append('<li><span class="' + statuses[status_label].legend + '"></span>' + status_label + '</li>')
|
||||
})
|
||||
|
||||
var stats_chart = new Chartist.Pie("#stats_chart", stats_data, stats_opts)
|
||||
|
||||
$piechart = $("#stats_chart")
|
||||
var $pietoolTip = $piechart
|
||||
.append('<div class="chartist-tooltip"></div>')
|
||||
.find('.chartist-tooltip')
|
||||
.hide();
|
||||
|
||||
$piechart.get(0).__chartist__.on('draw', function(data) {
|
||||
data.element.addClass(statuses[data.meta].slice)
|
||||
})
|
||||
// Update with the latest data
|
||||
$piechart.get(0).__chartist__.update(stats_data)
|
||||
|
||||
$piechart.on('mouseenter', '.ct-slice-donut', function() {
|
||||
var $point = $(this)
|
||||
value = $point.attr('ct:value')
|
||||
label = $point.attr('ct:meta')
|
||||
$pietoolTip.html(label + ': ' + value.toString() + "%").show();
|
||||
});
|
||||
|
||||
$piechart.on('mouseleave', '.ct-slice-donut', function() {
|
||||
$pietoolTip.hide();
|
||||
});
|
||||
$piechart.on('mousemove', function(event) {
|
||||
$pietoolTip.css({
|
||||
left: (event.offsetX || event.originalEvent.layerX) - $pietoolTip.width() / 2 - 10,
|
||||
top: (event.offsetY + 40 || event.originalEvent.layerY) - $pietoolTip.height() - 80
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
api.campaigns.summary()
|
||||
.success(function(data) {
|
||||
|
@ -33,9 +179,6 @@ $(document).ready(function() {
|
|||
[]
|
||||
]
|
||||
}
|
||||
var average_data = {
|
||||
series: []
|
||||
}
|
||||
var overview_opts = {
|
||||
axisX: {
|
||||
showGrid: false
|
||||
|
@ -45,13 +188,6 @@ $(document).ready(function() {
|
|||
low: 0,
|
||||
high: 100
|
||||
}
|
||||
var average_opts = {
|
||||
donut: true,
|
||||
donutWidth: 40,
|
||||
chartPadding: 0,
|
||||
showLabel: false
|
||||
}
|
||||
var average = 0
|
||||
campaignTable = $("#campaignTable").DataTable({
|
||||
columnDefs: [{
|
||||
orderable: false,
|
||||
|
@ -62,19 +198,19 @@ $(document).ready(function() {
|
|||
]
|
||||
});
|
||||
$.each(campaigns, function(i, campaign) {
|
||||
var campaign_date = moment(campaign.created_date).format('MMMM Do YYYY, h:mm:ss a')
|
||||
var label = labels[campaign.status] || "label-default";
|
||||
//section for tooltips on the status of a campaign to show some quick stats
|
||||
var launchDate;
|
||||
if (moment(campaign.launch_date).isAfter(moment())) {
|
||||
launchDate = "Scheduled to start: " + moment(campaign.launch_date).format('MMMM Do YYYY, h:mm:ss a')
|
||||
var quickStats = launchDate + "<br><br>" + "Number of recipients: " + campaign.stats.total
|
||||
} else {
|
||||
launchDate = "Launch Date: " + moment(campaign.launch_date).format('MMMM Do YYYY, h:mm:ss a')
|
||||
var quickStats = launchDate + "<br><br>" + "Number of recipients: " + campaign.stats.total + "<br><br>" + "Emails opened: " + campaign.stats.opened + "<br><br>" + "Emails clicked: " + campaign.stats.clicked + "<br><br>" + "Submitted Credentials: " + campaign.stats.submitted_data + "<br><br>" + "Errors : " + campaign.stats.error
|
||||
}
|
||||
// Add it to the table
|
||||
campaignTable.row.add([
|
||||
var campaign_date = moment(campaign.created_date).format('MMMM Do YYYY, h:mm:ss a')
|
||||
var label = statuses[campaign.status] || "label-default";
|
||||
//section for tooltips on the status of a campaign to show some quick stats
|
||||
var launchDate;
|
||||
if (moment(campaign.launch_date).isAfter(moment())) {
|
||||
launchDate = "Scheduled to start: " + moment(campaign.launch_date).format('MMMM Do YYYY, h:mm:ss a')
|
||||
var quickStats = launchDate + "<br><br>" + "Number of recipients: " + campaign.stats.total
|
||||
} else {
|
||||
launchDate = "Launch Date: " + moment(campaign.launch_date).format('MMMM Do YYYY, h:mm:ss a')
|
||||
var quickStats = launchDate + "<br><br>" + "Number of recipients: " + campaign.stats.total + "<br><br>" + "Emails opened: " + campaign.stats.opened + "<br><br>" + "Emails clicked: " + campaign.stats.clicked + "<br><br>" + "Submitted Credentials: " + campaign.stats.submitted_data + "<br><br>" + "Errors : " + campaign.stats.error
|
||||
}
|
||||
// Add it to the table
|
||||
campaignTable.row.add([
|
||||
escapeHtml(campaign.name),
|
||||
campaign_date,
|
||||
"<span class=\"label " + label + "\" data-toggle=\"tooltip\" data-placement=\"right\" data-html=\"true\" title=\"" + quickStats + "\">" + campaign.status + "</span>",
|
||||
|
@ -85,54 +221,21 @@ $(document).ready(function() {
|
|||
<i class='fa fa-trash-o'></i>\
|
||||
</button></div>"
|
||||
]).draw()
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
// Add it to the chart data
|
||||
campaign.y = 0
|
||||
campaign.y += campaign.stats.clicked + campaign.stats.submitted_data
|
||||
campaign.y = Math.floor((campaign.y / campaign.stats.total) * 100)
|
||||
average += campaign.y
|
||||
// Add the data to the overview chart
|
||||
overview_data.labels.push(campaign_date)
|
||||
overview_data.series[0].push({
|
||||
meta: i,
|
||||
value: campaign.y
|
||||
})
|
||||
})
|
||||
average = Math.floor(average / data.total);
|
||||
average_data.series.push({
|
||||
meta: "Unsuccessful Phishes",
|
||||
value: 100 - average
|
||||
})
|
||||
average_data.series.push({
|
||||
meta: "Successful Phishes",
|
||||
value: average
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
// Add it to the chart data
|
||||
campaign.y = 0
|
||||
campaign.y += campaign.stats.clicked + campaign.stats.submitted_data
|
||||
campaign.y = Math.floor((campaign.y / campaign.stats.total) * 100)
|
||||
// Add the data to the overview chart
|
||||
overview_data.labels.push(campaign_date)
|
||||
overview_data.series[0].push({
|
||||
meta: i,
|
||||
value: campaign.y
|
||||
})
|
||||
})
|
||||
// Build the charts
|
||||
var average_chart = new Chartist.Pie("#average_chart", average_data, average_opts)
|
||||
generateStatsPieChart(campaigns)
|
||||
var overview_chart = new Chartist.Line('#overview_chart', overview_data, overview_opts)
|
||||
// Setup the average chart listeners
|
||||
$piechart = $("#average_chart")
|
||||
var $pietoolTip = $piechart
|
||||
.append('<div class="chartist-tooltip"></div>')
|
||||
.find('.chartist-tooltip')
|
||||
.hide();
|
||||
|
||||
$piechart.on('mouseenter', '.ct-slice-donut', function() {
|
||||
var $point = $(this)
|
||||
value = $point.attr('ct:value')
|
||||
label = $point.attr('ct:meta')
|
||||
$pietoolTip.html(label + ': ' + value.toString() + "%").show();
|
||||
});
|
||||
|
||||
$piechart.on('mouseleave', '.ct-slice-donut', function() {
|
||||
$pietoolTip.hide();
|
||||
});
|
||||
$piechart.on('mousemove', function(event) {
|
||||
$pietoolTip.css({
|
||||
left: (event.offsetX || event.originalEvent.layerX) - $pietoolTip.width() / 2 - 10,
|
||||
top: (event.offsetY + 40 || event.originalEvent.layerY) - $pietoolTip.height() - 80
|
||||
});
|
||||
});
|
||||
|
||||
// Setup the overview chart listeners
|
||||
$chart = $("#overview_chart")
|
||||
|
|
|
@ -45,15 +45,9 @@
|
|||
</div>
|
||||
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
|
||||
<p style="text-align:center;">Average Phishing Results</p>
|
||||
<div id="average_chart" class="col-lg-7 col-md-7"></div>
|
||||
<div id="average_chart_legend" class="col-lg-5 col-md-5">
|
||||
<ul class="chartist-legend">
|
||||
<li>
|
||||
<span style="background-color:#f05b4f;"></span> Successful Phishes
|
||||
</li>
|
||||
<li>
|
||||
<span style="background-color:#1abc9c;"></span> Unsuccessful Phishes
|
||||
</li>
|
||||
<div id="stats_chart" class="col-lg-7 col-md-7"></div>
|
||||
<div class="col-lg-5 col-md-5">
|
||||
<ul id="stats_chart_legend" class="chartist-legend">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue