Making the results map an optional setting stored in localStorage. Fixes #747

Also does more formatting fixes for various files.
pull/843/merge
Jordan Wright 2017-09-16 23:30:04 -05:00
parent c49474fd10
commit 6f81f1f2e2
8 changed files with 585 additions and 492 deletions

File diff suppressed because one or more lines are too long

106
static/css/main.css vendored
View File

@ -1,49 +1,63 @@
.nav-tabs {
cursor: pointer;
}
.datatable_hidden {
display: none;
}
.navbar-logo {
margin: 4px 0px;
float: left;
}
#navbar-login {
padding-top: 8px;
padding-bottom: 0px;
}
#navbar-dropdown {
margin-top: 6px;
margin-right: 15px;
}
.sans {
font-family: 'Open Sans', sans-serif !important;
}
.label {
font-family: 'Roboto', sans-serif !important;
}
.form-signin {
max-width: 400px;
padding: 15px;
margin: 40px auto 0px auto;
}
ul .dropdown-menu .ng-isolate-scope {
visibility: visible;
display: block;
opacity: 1;
}
#login-button {
padding: 10px 15px;
}
.form-signin-heading {
text-align: center;
}
.form-signin .form-signin-heading, .form-signin .checkbox {
.form-signin .form-signin-heading,
.form-signin .checkbox {
margin-bottom: 10px;
}
.form-signin .checkbox {
font-weight: normal;
}
.form-signin .form-control {
font-family: 'Open Sans', sans-serif;
position: relative;
@ -54,14 +68,17 @@
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.form-signin .form-control:focus {
z-index: 2;
}
.form-signin .top-input {
margin-bottom: -1px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.form-signin .middle-input {
margin-bottom: -1px;
border-top-left-radius: 0;
@ -69,32 +86,40 @@
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.form-signin .bottom-input {
margin-bottom: 10px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
#logo {
display: block;
margin-left: auto;
margin-right: auto;
}
footer>p {
color: #444444;
font-family: 'Open Sans', sans-serif;
}
.header {
margin-top: 10px;
}
.sidebar {
padding-left: 0px;
}
.sidebar a {
color: #201e1c;
}
.sidebar a:hover {
color: #201e1c;
}
.api_heading {
font-family: 'Open Sans', sans-serif;
background-color: #201e1c;
@ -103,6 +128,7 @@
color: #E2E2E2;
width: 100%;
}
p {
font-size: 1.2em;
}
@ -148,6 +174,7 @@
position: relative;
overflow: hidden;
}
.btn-file input[type=file] {
position: absolute;
top: 0;
@ -162,18 +189,22 @@
cursor: inherit;
display: block;
}
.typeahead {
border-left-radius: 6px !important;
float: none !important;
}
.tt-query {
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.tt-hint {
color: #999
}
.tt-menu {
width: 422px;
margin-top: 4px;
@ -188,18 +219,21 @@
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
}
.tt-suggestion {
padding: 3px 20px;
line-height: 24px;
}
.tt-suggestion.tt-cursor {
color: #fff;
background-color: #0097cf;
}
.tt-suggestion p {
margin: 0;
}
.typeahead-button {
line-height: 1.39 !important;
}
@ -292,6 +326,7 @@
padding-left: 0px;
top: 0;
}
.chartist-legend li {
display: block;
position: relative;
@ -305,6 +340,7 @@
-o-transition: background-color 200ms ease-in-out;
transition: background-color 200ms ease-in-out;
}
.chartist-legend li span {
display: inline-block;
vertical-align: middle;
@ -374,10 +410,14 @@
font-family: 'Courier New', Monospace !important;
font-size: small !important;
}
#resultsMap {
margin-top: -30px;
}
/* Handle the navbar collapse at < 1300px */
@media (min-width: 768px) and (max-width: 1300px) {
.navbar-collapse.collapse {
display: none !important;
@ -385,23 +425,33 @@
.navbar-collapse.collapse.in {
display: block !important;
}
.navbar-header .collapse, .navbar-toggle {
.navbar-header .collapse,
.navbar-toggle {
display: block !important;
}
.navbar-header {
float: none !important;
}
}
/* Table Styling */
.modal-content .dataTable tbody td {
font-size: 16px;/* Smaller font on modal tables */
font-size: 16px;
/* Smaller font on modal tables */
}
.dataTables_info {
font-size: 15px;
}
/* Sort Icons */
table.dataTable thead .sorting:after, table.dataTable thead .sorting_asc:after, table.dataTable thead .sorting_desc:after {
table.dataTable thead .sorting:after,
table.dataTable thead .sorting_asc:after,
table.dataTable thead .sorting_desc:after {
font-family: 'FontAwesome' !important;
position: relative !important;
display: initial !important;
@ -410,42 +460,52 @@ table.dataTable thead .sorting:after, table.dataTable thead .sorting_asc:after,
left: 6px;
color: #1abc9c;
}
table.dataTable thead .sorting:after {
content: "\f0dc" !important;
color: initial;
}
table.dataTable thead .sorting_asc:after {
content: "\f0de" !important;
opacity: .8 !important;
}
table.dataTable thead .sorting_desc:after {
content: "\f0dd" !important;
opacity: .8 !important;
}
td.details-control {
cursor: pointer;
}
.timeline {
text-align: left;
background-color: #ffffff;
}
.timeline-graph {
margin-left: 30px;
}
.timeline>h6 {
margin-top: 0px;
margin-bottom: 5px;
}
.timeline>.subtitle {
color: #999999;
font-style: italic;
margin-bottom: 15px;
display: block;
}
.timeline-entry {
position: relative;
padding-bottom: 36px;
}
.timeline-bar {
display: block;
content: "";
@ -456,12 +516,15 @@ td.details-control{
left: -6px;
background: #aaaaaa;
}
.timeline-entry:last-child .timeline-bar {
display: none;
}
.timeline-entry:last-child {
padding-bottom: 0px;
}
.timeline-icon {
position: relative;
float: left;
@ -472,98 +535,129 @@ td.details-control{
text-align: center;
border-radius: 50%;
}
.timeline-icon>i {
margin-top: 10px;
color: #ffffff;
}
.timeline-message {
padding-left: 30px;
}
.timeline-date {
float: right;
color: #999999;
font-style: italic;
}
.timeline-event-details {
font-size: 16px;
margin-top: 5px;
cursor: pointer;
}
.timeline-replay-button {
margin-top: 10px;
}
.timeline-event-details>.table-responsive {
display: none;
}
.timeline-event-details {
margin-top: 10px;
margin-bottom: 10px;
}
.timeline-event-results {
font-size: 16px;
display: none;
}
.tooltip-inner {
width: 300px !important;
}
#refresh_message {
display: none;
}
#capture_passwords {
display: none;
}
#redirect_url {
display: none;
}
@media (max-width: 767px) {
.navbar-header {
margin-left: 10px !important;
}
}
table.dataTable {
width: 100% !important;
}
.btn-blue {
color: #fff;
background-color: #428bca;
border-color: #428bca;
}
.btn-blue:hover {
background-color: #64a1d6;
}
.select2-container--bootstrap .select2-selection--single .select2-selection__rendered {
font-size: 15px !important;
}
.select2-container--bootstrap .select2-selection--single {
height: 42px !important;
padding: 8px 12px !important;
}
.input-group-btn .btn {
line-height: 20px !important;
}
.highcharts-title {
font-family: "Source Sans Pro", Helvetica, Arial, sans-serif;
font-size: 16px !important;
}
.color-success {
font-weight: bold;
color: #f05b4f;
}
.color-sent {
font-weight: bold;
color: #1abc9c;
}
.color-opened {
font-weight: bold;
color: #f9bf3b;
}
.color-clicked {
font-weight: bold;
color: #f39c12;
}
.color-success {
color: #f05b4f;
}
.nav-sidebar>li.active>a:focus, .nav-sidebar>li.active>a:hover {
.nav-sidebar>li.active>a:focus,
.nav-sidebar>li.active>a:hover {
background-color: #37485a;
}
#resultsMapContainer {
display: none;
}

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
$(document).ready(function(){$("#apiResetForm").submit(function(s){return $.post("/api/reset",$(this).serialize()).done(function(s){api_key=s.data,successFlash(s.message),$("#api_key").val(api_key)}).fail(function(s){errorFlash(s.message)}),!1}),$("#settingsForm").submit(function(s){return $.post("/settings",$(this).serialize()).done(function(s){successFlash(s.message)}).fail(function(s){errorFlash(s.responseJSON.message)}),!1})});
$(document).ready(function(){$("#apiResetForm").submit(function(e){return $.post("/api/reset",$(this).serialize()).done(function(e){api_key=e.data,successFlash(e.message),$("#api_key").val(api_key)}).fail(function(e){errorFlash(e.message)}),!1}),$("#settingsForm").submit(function(e){return $.post("/settings",$(this).serialize()).done(function(e){successFlash(e.message)}).fail(function(e){errorFlash(e.responseJSON.message)}),!1});var e=localStorage.getItem("gophish.use_map");$("#use_map").prop("checked",JSON.parse(e)),$("#use_map").on("change",function(){localStorage.setItem("gophish.use_map",JSON.stringify(this.checked))})});

View File

@ -413,7 +413,9 @@ var renderPieChart = function (chartopts) {
}).add();
},
render: function () {
this.innerText.attr({ text: chartopts['data'][0].y })
this.innerText.attr({
text: chartopts['data'][0].y
})
}
}
},
@ -446,6 +448,41 @@ var renderPieChart = function (chartopts) {
})
}
/* Updates the bubbles on the map
@param {campaign.result[]} results - The campaign results to process
*/
var updateMap = function (results) {
if (!map) {
return
}
bubbles = []
$.each(campaign.results, function (i, result) {
// Check that it wasn't an internal IP
if (result.latitude == 0 && result.longitude == 0) {
return true;
}
newIP = true
$.each(bubbles, function (i, bubble) {
if (bubble.ip == result.ip) {
bubbles[i].radius += 1
newIP = false
return false
}
})
if (newIP) {
bubbles.push({
latitude: result.latitude,
longitude: result.longitude,
name: result.ip,
fillKey: "point",
radius: 2
})
}
})
map.bubbles(bubbles)
}
/* poll - Queries the API and updates the UI with the results
*
* Updates:
@ -536,31 +573,7 @@ function poll() {
})
})
/* Update the map information */
bubbles = []
$.each(campaign.results, function (i, result) {
// Check that it wasn't an internal IP
if (result.latitude == 0 && result.longitude == 0) {
return true;
}
newIP = true
$.each(bubbles, function (i, bubble) {
if (bubble.ip == result.ip) {
bubbles[i].radius += 1
newIP = false
return false
}
})
if (newIP) {
bubbles.push({
latitude: result.latitude,
longitude: result.longitude,
name: result.ip,
fillKey: "point",
radius: 2
})
}
})
map.bubbles(bubbles)
updateMap(campaign.results)
$("#refresh_message").hide()
$("#refresh_btn").show()
})
@ -568,6 +581,7 @@ function poll() {
function load() {
campaign.id = window.location.pathname.split('/').slice(-1)[0]
var use_map = JSON.parse(localStorage.getItem('gophish.use_map'))
api.campaignId.results(campaign.id)
.success(function (c) {
campaign = c
@ -696,7 +710,8 @@ function load() {
colors: [statuses[status].color, '#dddddd']
})
})
if (!map) {
if (use_map) {
$("#resultsMapContainer").show()
map = new Datamap({
element: document.getElementById("resultsMap"),
responsive: true,
@ -713,49 +728,8 @@ function load() {
}
});
}
$.each(campaign.results, function (i, result) {
// Check that it wasn't an internal IP
if (result.latitude == 0 && result.longitude == 0) {
return true;
updateMap(campaign.results)
}
newIP = true
$.each(bubbles, function (i, bubble) {
if (bubble.ip == result.ip) {
bubbles[i].radius += 1
newIP = false
return false
}
})
if (newIP) {
bubbles.push({
latitude: result.latitude,
longitude: result.longitude,
name: result.ip,
fillKey: "point",
radius: 2
})
}
})
map.bubbles(bubbles)
}
// Load up the map data (only once!)
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
if ($(e.target).attr('href') == "#overview") {
if (!map) {
map = new Datamap({
element: document.getElementById("resultsMap"),
responsive: true,
fills: {
defaultFill: "#ffffff"
},
geographyConfig: {
highlightFillColor: "#1abc9c",
borderColor: "#283F50"
}
});
}
}
})
})
.error(function () {
$("#loading").hide()
@ -764,6 +738,7 @@ function load() {
}
var setRefresh
function refresh() {
if (!doPoll) {
return;

View File

@ -21,4 +21,9 @@ $(document).ready(function() {
})
return false
})
var use_map = localStorage.getItem('gophish.use_map')
$("#use_map").prop('checked', JSON.parse(use_map))
$("#use_map").on('change', function () {
localStorage.setItem('gophish.use_map', JSON.stringify(this.checked))
})
})

View File

@ -78,7 +78,7 @@
<div id="clicked_chart" style="height:200px;" class="col-lg-3 col-md-3"></div>
<div id="submitted_data_chart" style="height:200px;" class="col-lg-3 col-md-3"></div>
</div>
<div class="row">
<div class="row" id="resultsMapContainer">
<div class="col-md-6">
<p style="text-align:center;">Targets Map</p>
<div id="resultsMap"></div>

View File

@ -17,7 +17,9 @@
</li>
<li class="active"><a href="/settings">Settings</a>
</li>
<li><hr></li>
<li>
<hr>
</li>
<li><a href="https://gophish.gitbooks.io/user-guide/content/">User Guide</a>
</li>
<li><a href="/api/">API Documentation</a>
@ -31,6 +33,15 @@
<h1 class="page-header">Settings</h1>
</div>
<div id="flashes" class="row"></div>
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li class="active" role="mainSettings"><a href="#mainSettings" aria-controls="mainSettings" role="tab" data-toggle="tab">Account Settings</a></li>
<li role="uiSettings"><a href="#uiSettings" aria-controls="uiSettings" role="tab" data-toggle="tab">UI Settings</a></li>
</ul>
<!-- Tab Panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="mainSettings">
<br/>
<div class="row">
<label class="col-sm-2 control-label form-label">Gophish version</label>
<div class="col-md-6">
@ -90,7 +101,15 @@
</form>
<br/>
</div>
{{end}}
{{define "scripts"}}
<div role="tabpanel" class="tab-pane" id="uiSettings">
<br/>
<div class="checkbox checkbox-primary">
<input id="use_map" type="checkbox">
<label for="use_map">Show campaign results map</label>
</div>
</div>
</div>
</div>
{{end}} {{define "scripts"}}
<script src="/js/dist/app/settings.min.js"></script>
{{end}}