mirror of https://github.com/gophish/gophish
349 lines
12 KiB
JavaScript
349 lines
12 KiB
JavaScript
var templates = []
|
|
var icons = {
|
|
"application/vnd.ms-excel": "fa-file-excel-o",
|
|
"text/plain": "fa-file-text-o",
|
|
"image/gif": "fa-file-image-o",
|
|
"image/png": "fa-file-image-o",
|
|
"application/pdf": "fa-file-pdf-o",
|
|
"application/x-zip-compressed": "fa-file-archive-o",
|
|
"application/x-gzip": "fa-file-archive-o",
|
|
"application/vnd.openxmlformats-officedocument.presentationml.presentation": "fa-file-powerpoint-o",
|
|
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "fa-file-word-o",
|
|
"application/octet-stream": "fa-file-o",
|
|
"application/x-msdownload": "fa-file-o"
|
|
}
|
|
|
|
// Save attempts to POST to /templates/
|
|
function save(idx) {
|
|
var template = {
|
|
attachments: []
|
|
}
|
|
template.name = $("#name").val()
|
|
template.subject = $("#subject").val()
|
|
template.html = CKEDITOR.instances["html_editor"].getData();
|
|
// Fix the URL Scheme added by CKEditor (until we can remove it from the plugin)
|
|
template.html = template.html.replace(/https?:\/\/{{\.URL}}/gi, "{{.URL}}")
|
|
// If the "Add Tracker Image" checkbox is checked, add the tracker
|
|
if ($("#use_tracker_checkbox").prop("checked") &&
|
|
template.html.indexOf("{{.Tracker}}") == -1 &&
|
|
template.html.indexOf("{{.TrackingUrl}}") == -1) {
|
|
template.html = template.html.replace("</body>", "{{.Tracker}}</body>")
|
|
} else {
|
|
// Otherwise, remove the tracker
|
|
template.html = template.html.replace("{{.Tracker}}</body>", "</body>")
|
|
}
|
|
template.text = $("#text_editor").val()
|
|
// Add the attachments
|
|
$.each($("#attachmentsTable").DataTable().rows().data(), function(i, target) {
|
|
template.attachments.push({
|
|
name: unescapeHtml(target[1]),
|
|
content: target[3],
|
|
type: target[4],
|
|
})
|
|
})
|
|
if (idx != -1) {
|
|
template.id = templates[idx].id
|
|
api.templateId.put(template)
|
|
.success(function(data) {
|
|
successFlash("Template edited successfully!")
|
|
load()
|
|
dismiss()
|
|
})
|
|
.error(function(data) {
|
|
modalError(data.responseJSON.message)
|
|
})
|
|
} else {
|
|
// Submit the template
|
|
api.templates.post(template)
|
|
.success(function(data) {
|
|
successFlash("Template added successfully!")
|
|
load()
|
|
dismiss()
|
|
})
|
|
.error(function(data) {
|
|
modalError(data.responseJSON.message)
|
|
})
|
|
}
|
|
}
|
|
|
|
function dismiss() {
|
|
$("#modal\\.flashes").empty()
|
|
$("#attachmentsTable").dataTable().DataTable().clear().draw()
|
|
$("#name").val("")
|
|
$("#subject").val("")
|
|
$("#text_editor").val("")
|
|
$("#html_editor").val("")
|
|
$("#modal").modal('hide')
|
|
}
|
|
|
|
function deleteTemplate(idx) {
|
|
if (confirm("Delete " + templates[idx].name + "?")) {
|
|
api.templateId.delete(templates[idx].id)
|
|
.success(function(data) {
|
|
successFlash(data.message)
|
|
load()
|
|
})
|
|
}
|
|
}
|
|
|
|
function attach(files) {
|
|
attachmentsTable = $("#attachmentsTable").DataTable({
|
|
destroy: true,
|
|
"order": [
|
|
[1, "asc"]
|
|
],
|
|
columnDefs: [{
|
|
orderable: false,
|
|
targets: "no-sort"
|
|
}, {
|
|
sClass: "datatable_hidden",
|
|
targets: [3, 4]
|
|
}]
|
|
});
|
|
$.each(files, function(i, file) {
|
|
var reader = new FileReader();
|
|
/* Make this a datatable */
|
|
reader.onload = function(e) {
|
|
var icon = icons[file.type] || "fa-file-o"
|
|
// Add the record to the modal
|
|
attachmentsTable.row.add([
|
|
'<i class="fa ' + icon + '"></i>',
|
|
escapeHtml(file.name),
|
|
'<span class="remove-row"><i class="fa fa-trash-o"></i></span>',
|
|
reader.result.split(",")[1],
|
|
file.type || "application/octet-stream"
|
|
]).draw()
|
|
}
|
|
reader.onerror = function(e) {
|
|
console.log(e)
|
|
}
|
|
reader.readAsDataURL(file)
|
|
})
|
|
}
|
|
|
|
function edit(idx) {
|
|
$("#modalSubmit").unbind('click').click(function() {
|
|
save(idx)
|
|
})
|
|
$("#attachmentUpload").unbind('click').click(function() {
|
|
this.value = null
|
|
})
|
|
$("#html_editor").ckeditor()
|
|
$("#attachmentsTable").show()
|
|
attachmentsTable = $('#attachmentsTable').DataTable({
|
|
destroy: true,
|
|
"order": [
|
|
[1, "asc"]
|
|
],
|
|
columnDefs: [{
|
|
orderable: false,
|
|
targets: "no-sort"
|
|
}, {
|
|
sClass: "datatable_hidden",
|
|
targets: [3, 4]
|
|
}]
|
|
});
|
|
var template = {
|
|
attachments: []
|
|
}
|
|
if (idx != -1) {
|
|
template = templates[idx]
|
|
$("#name").val(template.name)
|
|
$("#subject").val(template.subject)
|
|
$("#html_editor").val(template.html)
|
|
$("#text_editor").val(template.text)
|
|
$.each(template.attachments, function(i, file) {
|
|
var icon = icons[file.type] || "fa-file-o"
|
|
// Add the record to the modal
|
|
attachmentsTable.row.add([
|
|
'<i class="fa ' + icon + '"></i>',
|
|
escapeHtml(file.name),
|
|
'<span class="remove-row"><i class="fa fa-trash-o"></i></span>',
|
|
file.content,
|
|
file.type || "application/octet-stream"
|
|
]).draw()
|
|
})
|
|
if (template.html.indexOf("{{.Tracker}}</body>") != -1) {
|
|
$("#use_tracker_checkbox").prop("checked", true)
|
|
} else {
|
|
$("#use_tracker_checkbox").prop("checked", false)
|
|
}
|
|
}
|
|
// Handle Deletion
|
|
$("#attachmentsTable").unbind('click').on("click", "span>i.fa-trash-o", function() {
|
|
attachmentsTable.row($(this).parents('tr'))
|
|
.remove()
|
|
.draw();
|
|
})
|
|
}
|
|
|
|
function copy(idx) {
|
|
$("#modalSubmit").unbind('click').click(function() {
|
|
save(-1)
|
|
})
|
|
$("#attachmentUpload").unbind('click').click(function() {
|
|
this.value = null
|
|
})
|
|
$("#html_editor").ckeditor()
|
|
$("#attachmentsTable").show()
|
|
attachmentsTable = $('#attachmentsTable').DataTable({
|
|
destroy: true,
|
|
"order": [
|
|
[1, "asc"]
|
|
],
|
|
columnDefs: [{
|
|
orderable: false,
|
|
targets: "no-sort"
|
|
}, {
|
|
sClass: "datatable_hidden",
|
|
targets: [3, 4]
|
|
}]
|
|
});
|
|
var template = {
|
|
attachments: []
|
|
}
|
|
template = templates[idx]
|
|
$("#name").val("Copy of " + template.name)
|
|
$("#subject").val(template.subject)
|
|
$("#html_editor").val(template.html)
|
|
$("#text_editor").val(template.text)
|
|
$.each(template.attachments, function(i, file) {
|
|
var icon = icons[file.type] || "fa-file-o"
|
|
// Add the record to the modal
|
|
attachmentsTable.row.add([
|
|
'<i class="fa ' + icon + '"></i>',
|
|
escapeHtml(file.name),
|
|
'<span class="remove-row"><i class="fa fa-trash-o"></i></span>',
|
|
file.content,
|
|
file.type || "application/octet-stream"
|
|
]).draw()
|
|
})
|
|
// Handle Deletion
|
|
$("#attachmentsTable").unbind('click').on("click", "span>i.fa-trash-o", function() {
|
|
attachmentsTable.row($(this).parents('tr'))
|
|
.remove()
|
|
.draw();
|
|
})
|
|
if (template.html.indexOf("{{.Tracker}}</body>") != -1) {
|
|
$("#use_tracker_checkbox").prop("checked", true)
|
|
} else {
|
|
$("#use_tracker_checkbox").prop("checked", false)
|
|
}
|
|
}
|
|
|
|
function importEmail() {
|
|
raw = $("#email_content").val()
|
|
convert_links = $("#convert_links_checkbox").prop("checked")
|
|
if (!raw) {
|
|
modalError("No Content Specified!")
|
|
} else {
|
|
$.ajax({
|
|
method: "POST",
|
|
url: "/api/import/email",
|
|
data: JSON.stringify({
|
|
content: raw,
|
|
convert_links: convert_links
|
|
}),
|
|
dataType: "json",
|
|
contentType: "application/json"
|
|
})
|
|
.success(function(data) {
|
|
$("#text_editor").val(data.text)
|
|
$("#html_editor").val(data.html)
|
|
$("#subject").val(data.subject)
|
|
$("#importEmailModal").modal("hide")
|
|
})
|
|
.error(function(data) {
|
|
modalError(data.responseJSON.message)
|
|
})
|
|
}
|
|
}
|
|
|
|
function load() {
|
|
$("#templateTable").hide()
|
|
$("#emptyMessage").hide()
|
|
$("#loading").show()
|
|
api.templates.get()
|
|
.success(function(ts) {
|
|
templates = ts
|
|
$("#loading").hide()
|
|
if (templates.length > 0) {
|
|
$("#templateTable").show()
|
|
templateTable = $("#templateTable").DataTable({
|
|
destroy: true,
|
|
columnDefs: [{
|
|
orderable: false,
|
|
targets: "no-sort"
|
|
}]
|
|
});
|
|
templateTable.clear()
|
|
$.each(templates, function(i, template) {
|
|
templateTable.row.add([
|
|
escapeHtml(template.name),
|
|
moment(template.modified_date).format('MMMM Do YYYY, h:mm:ss a'),
|
|
"<div class='pull-right'><span data-toggle='modal' data-target='#modal'><button class='btn btn-primary' data-toggle='tooltip' data-placement='left' title='Edit Template' onclick='edit(" + i + ")'>\
|
|
<i class='fa fa-pencil'></i>\
|
|
</button></span>\
|
|
<span data-toggle='modal' data-target='#modal'><button class='btn btn-primary' data-toggle='tooltip' data-placement='left' title='Copy Template' onclick='copy(" + i + ")'>\
|
|
<i class='fa fa-copy'></i>\
|
|
</button></span>\
|
|
<button class='btn btn-danger' data-toggle='tooltip' data-placement='left' title='Delete Template' onclick='deleteTemplate(" + i + ")'>\
|
|
<i class='fa fa-trash-o'></i>\
|
|
</button></div>"
|
|
]).draw()
|
|
})
|
|
$('[data-toggle="tooltip"]').tooltip()
|
|
} else {
|
|
$("#emptyMessage").show()
|
|
}
|
|
})
|
|
.error(function() {
|
|
$("#loading").hide()
|
|
errorFlash("Error fetching templates")
|
|
})
|
|
}
|
|
|
|
$(document).ready(function() {
|
|
// Setup multiple modals
|
|
// Code based on http://miles-by-motorcycle.com/static/bootstrap-modal/index.html
|
|
$('.modal').on('hidden.bs.modal', function(event) {
|
|
$(this).removeClass('fv-modal-stack');
|
|
$('body').data('fv_open_modals', $('body').data('fv_open_modals') - 1);
|
|
});
|
|
$('.modal').on('shown.bs.modal', function(event) {
|
|
// Keep track of the number of open modals
|
|
if (typeof($('body').data('fv_open_modals')) == 'undefined') {
|
|
$('body').data('fv_open_modals', 0);
|
|
}
|
|
// if the z-index of this modal has been set, ignore.
|
|
if ($(this).hasClass('fv-modal-stack')) {
|
|
return;
|
|
}
|
|
$(this).addClass('fv-modal-stack');
|
|
// Increment the number of open modals
|
|
$('body').data('fv_open_modals', $('body').data('fv_open_modals') + 1);
|
|
// Setup the appropriate z-index
|
|
$(this).css('z-index', 1040 + (10 * $('body').data('fv_open_modals')));
|
|
$('.modal-backdrop').not('.fv-modal-stack').css('z-index', 1039 + (10 * $('body').data('fv_open_modals')));
|
|
$('.modal-backdrop').not('fv-modal-stack').addClass('fv-modal-stack');
|
|
});
|
|
$.fn.modal.Constructor.prototype.enforceFocus = function() {
|
|
$(document)
|
|
.off('focusin.bs.modal') // guard against infinite focus loop
|
|
.on('focusin.bs.modal', $.proxy(function(e) {
|
|
if (
|
|
this.$element[0] !== e.target && !this.$element.has(e.target).length
|
|
// CKEditor compatibility fix start.
|
|
&& !$(e.target).closest('.cke_dialog, .cke').length
|
|
// CKEditor compatibility fix end.
|
|
) {
|
|
this.$element.trigger('focus');
|
|
}
|
|
}, this));
|
|
};
|
|
$('#modal').on('hidden.bs.modal', function(event) {
|
|
dismiss()
|
|
});
|
|
load()
|
|
})
|