diff --git a/gulpfile.js b/gulpfile.js
index 809c28f0..e7c914ed 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -7,7 +7,7 @@
var gulp = require('gulp'),
rename = require('gulp-rename'),
concat = require('gulp-concat'),
- uglify = require('gulp-uglify'),
+ uglify = require('gulp-uglify-es').default,
cleanCSS = require('gulp-clean-css'),
babel = require('gulp-babel'),
@@ -61,6 +61,9 @@ scripts = function () {
app_directory + 'settings.js',
app_directory + 'templates.js',
app_directory + 'gophish.js',
+ app_directory + 'users.js',
+ app_directory + 'webhooks.js',
+ app_directory + 'passwords.js'
])
.pipe(rename({
suffix: '.min'
@@ -97,4 +100,4 @@ exports.vendorjs = vendorjs
exports.scripts = scripts
exports.styles = styles
exports.build = gulp.parallel(vendorjs, scripts, styles)
-exports.default = exports.build
\ No newline at end of file
+exports.default = exports.build
diff --git a/package.json b/package.json
index 6b65458f..4f5ac766 100644
--- a/package.json
+++ b/package.json
@@ -23,9 +23,9 @@
"gulp-concat": "^2.6.1",
"gulp-jshint": "^2.1.0",
"gulp-rename": "^1.4.0",
- "gulp-uglify": "^3.0.2",
+ "gulp-uglify-es": "^3.0.0",
"gulp-wrap": "^0.15.0",
- "jshint": "^2.10.2",
+ "jshint": "^2.13.4",
"jshint-stylish": "^2.2.1",
"webpack": "^4.32.2",
"webpack-cli": "^3.3.2"
diff --git a/static/js/dist/app/groups.min.js b/static/js/dist/app/groups.min.js
index 3be298c0..014688d0 100644
--- a/static/js/dist/app/groups.min.js
+++ b/static/js/dist/app/groups.min.js
@@ -1 +1 @@
-var groups=[];function save(e){var t=[];$.each($("#targetsTable").DataTable().rows().data(),function(e,a){t.push({first_name:unescapeHtml(a[0]),last_name:unescapeHtml(a[1]),email:unescapeHtml(a[2]),position:unescapeHtml(a[3])})});var a={name:$("#name").val(),targets:t};-1!=e?(a.id=e,api.groupId.put(a).success(function(e){successFlash("Group updated successfully!"),load(),dismiss(),$("#modal").modal("hide")}).error(function(e){modalError(e.responseJSON.message)})):api.groups.post(a).success(function(e){successFlash("Group added successfully!"),load(),dismiss(),$("#modal").modal("hide")}).error(function(e){modalError(e.responseJSON.message)})}function dismiss(){$("#targetsTable").dataTable().DataTable().clear().draw(),$("#name").val(""),$("#modal\\.flashes").empty()}function edit(e){if(targets=$("#targetsTable").dataTable({destroy:!0,columnDefs:[{orderable:!1,targets:"no-sort"}]}),$("#modalSubmit").unbind("click").click(function(){save(e)}),-1==e);else api.groupId.get(e).success(function(e){$("#name").val(e.name),targetRows=[],$.each(e.targets,function(e,a){targetRows.push([escapeHtml(a.first_name),escapeHtml(a.last_name),escapeHtml(a.email),escapeHtml(a.position),''])}),targets.DataTable().rows.add(targetRows).draw()}).error(function(){errorFlash("Error fetching group")});$("#csvupload").fileupload({url:"/api/import/group",dataType:"json",beforeSend:function(e){e.setRequestHeader("Authorization","Bearer "+user.api_key)},add:function(e,a){$("#modal\\.flashes").empty();var t=a.originalFiles[0].name;if(t&&!/(csv|txt)$/i.test(t.split(".").pop()))return modalError("Unsupported file extension (use .csv or .txt)"),!1;a.submit()},done:function(e,a){$.each(a.result,function(e,a){addTarget(a.first_name,a.last_name,a.email,a.position)}),targets.DataTable().draw()}})}var downloadCSVTemplate=function(){var e="group_template.csv",a=Papa.unparse([{"First Name":"Example","Last Name":"User",Email:"foobar@example.com",Position:"Systems Administrator"}],{}),t=new Blob([a],{type:"text/csv;charset=utf-8;"});if(navigator.msSaveBlob)navigator.msSaveBlob(t,e);else{var o=window.URL.createObjectURL(t),s=document.createElement("a");s.href=o,s.setAttribute("download",e),document.body.appendChild(s),s.click(),document.body.removeChild(s)}},deleteGroup=function(o){var e=groups.find(function(e){return e.id===o});e&&Swal.fire({title:"Are you sure?",text:"This will delete the group. This can't be undone!",type:"warning",animation:!1,showCancelButton:!0,confirmButtonText:"Delete "+escapeHtml(e.name),confirmButtonColor:"#428bca",reverseButtons:!0,allowOutsideClick:!1,preConfirm:function(){return new Promise(function(a,t){api.groupId.delete(o).success(function(e){a()}).error(function(e){t(e.responseJSON.message)})})}}).then(function(e){e.value&&Swal.fire("Group Deleted!","This group has been deleted!","success"),$('button:contains("OK")').on("click",function(){location.reload()})})};function addTarget(e,a,t,o){var s=escapeHtml(t).toLowerCase(),r=[escapeHtml(e),escapeHtml(a),s,escapeHtml(o),''],n=targets.DataTable(),i=n.column(2,{order:"index"}).data().indexOf(s);0<=i?n.row(i,{order:"index"}).data(r):n.row.add(r)}function load(){$("#groupTable").hide(),$("#emptyMessage").hide(),$("#loading").show(),api.groups.summary().success(function(e){if($("#loading").hide(),0 "])}),a.rows.add(groupRows).draw()}else $("#emptyMessage").show()}).error(function(){errorFlash("Error fetching groups")})}$(document).ready(function(){load(),$("#targetForm").submit(function(){var e=document.getElementById("targetForm");if(e.checkValidity())return addTarget($("#firstName").val(),$("#lastName").val(),$("#email").val(),$("#position").val()),targets.DataTable().draw(),$("#targetForm>div>input").val(""),$("#firstName").focus(),!1;e.reportValidity()}),$("#targetsTable").on("click","span>i.fa-trash-o",function(){targets.DataTable().row($(this).parents("tr")).remove().draw()}),$("#modal").on("hide.bs.modal",function(){dismiss()}),$("#csv-template").click(downloadCSVTemplate)});
\ No newline at end of file
+var groups=[];function save(e){var a=[];$.each($("#targetsTable").DataTable().rows().data(),(function(e,t){a.push({first_name:unescapeHtml(t[0]),last_name:unescapeHtml(t[1]),email:unescapeHtml(t[2]),position:unescapeHtml(t[3])})}));var t={name:$("#name").val(),targets:a};-1!=e?(t.id=e,api.groupId.put(t).success((function(e){successFlash("Group updated successfully!"),load(),dismiss(),$("#modal").modal("hide")})).error((function(e){modalError(e.responseJSON.message)}))):api.groups.post(t).success((function(e){successFlash("Group added successfully!"),load(),dismiss(),$("#modal").modal("hide")})).error((function(e){modalError(e.responseJSON.message)}))}function dismiss(){$("#targetsTable").dataTable().DataTable().clear().draw(),$("#name").val(""),$("#modal\\.flashes").empty()}function edit(e){if(targets=$("#targetsTable").dataTable({destroy:!0,columnDefs:[{orderable:!1,targets:"no-sort"}]}),$("#modalSubmit").unbind("click").click((function(){save(e)})),-1==e){$("#groupModalLabel").text("New Group")}else $("#groupModalLabel").text("Edit Group"),api.groupId.get(e).success((function(e){$("#name").val(e.name),targetRows=[],$.each(e.targets,(function(e,a){targetRows.push([escapeHtml(a.first_name),escapeHtml(a.last_name),escapeHtml(a.email),escapeHtml(a.position),''])})),targets.DataTable().rows.add(targetRows).draw()})).error((function(){errorFlash("Error fetching group")}));$("#csvupload").fileupload({url:"/api/import/group",dataType:"json",beforeSend:function(e){e.setRequestHeader("Authorization","Bearer "+user.api_key)},add:function(e,a){$("#modal\\.flashes").empty();var t=a.originalFiles[0].name;if(t&&!/(csv|txt)$/i.test(t.split(".").pop()))return modalError("Unsupported file extension (use .csv or .txt)"),!1;a.submit()},done:function(e,a){$.each(a.result,(function(e,a){addTarget(a.first_name,a.last_name,a.email,a.position)})),targets.DataTable().draw()}})}var downloadCSVTemplate=function(){var e="group_template.csv",a=Papa.unparse([{"First Name":"Example","Last Name":"User",Email:"foobar@example.com",Position:"Systems Administrator"}],{}),t=new Blob([a],{type:"text/csv;charset=utf-8;"});if(navigator.msSaveBlob)navigator.msSaveBlob(t,e);else{var o=window.URL.createObjectURL(t),s=document.createElement("a");s.href=o,s.setAttribute("download",e),document.body.appendChild(s),s.click(),document.body.removeChild(s)}},deleteGroup=function(e){var a=groups.find((function(a){return a.id===e}));a&&Swal.fire({title:"Are you sure?",text:"This will delete the group. This can't be undone!",type:"warning",animation:!1,showCancelButton:!0,confirmButtonText:"Delete "+escapeHtml(a.name),confirmButtonColor:"#428bca",reverseButtons:!0,allowOutsideClick:!1,preConfirm:function(){return new Promise((function(a,t){api.groupId.delete(e).success((function(e){a()})).error((function(e){t(e.responseJSON.message)}))}))}}).then((function(e){e.value&&Swal.fire("Group Deleted!","This group has been deleted!","success"),$('button:contains("OK")').on("click",(function(){location.reload()}))}))};function addTarget(e,a,t,o){var s=escapeHtml(t).toLowerCase(),r=[escapeHtml(e),escapeHtml(a),s,escapeHtml(o),''],n=targets.DataTable(),i=n.column(2,{order:"index"}).data().indexOf(s);i>=0?n.row(i,{order:"index"}).data(r):n.row.add(r)}function load(){$("#groupTable").hide(),$("#emptyMessage").hide(),$("#loading").show(),api.groups.summary().success((function(e){if($("#loading").hide(),e.total>0){groups=e.groups,$("#emptyMessage").hide(),$("#groupTable").show();var a=$("#groupTable").DataTable({destroy:!0,columnDefs:[{orderable:!1,targets:"no-sort"}]});a.clear(),groupRows=[],$.each(groups,(function(e,a){groupRows.push([escapeHtml(a.name),escapeHtml(a.num_targets),moment(a.modified_date).format("MMMM Do YYYY, h:mm:ss a"),"
"])})),a.rows.add(groupRows).draw()}else $("#emptyMessage").show()})).error((function(){errorFlash("Error fetching groups")}))}$(document).ready((function(){load(),$("#targetForm").submit((function(){var e=document.getElementById("targetForm");if(e.checkValidity())return addTarget($("#firstName").val(),$("#lastName").val(),$("#email").val(),$("#position").val()),targets.DataTable().draw(),$("#targetForm>div>input").val(""),$("#firstName").focus(),!1;e.reportValidity()})),$("#targetsTable").on("click","span>i.fa-trash-o",(function(){targets.DataTable().row($(this).parents("tr")).remove().draw()})),$("#modal").on("hide.bs.modal",(function(){dismiss()})),$("#csv-template").click(downloadCSVTemplate)}));
\ No newline at end of file
diff --git a/static/js/dist/app/landing_pages.min.js b/static/js/dist/app/landing_pages.min.js
index 406deae3..18092d80 100644
--- a/static/js/dist/app/landing_pages.min.js
+++ b/static/js/dist/app/landing_pages.min.js
@@ -1 +1 @@
-var pages=[];function save(e){var a={};a.name=$("#name").val(),editor=CKEDITOR.instances.html_editor,a.html=editor.getData(),a.capture_credentials=$("#capture_credentials_checkbox").prop("checked"),a.capture_passwords=$("#capture_passwords_checkbox").prop("checked"),a.redirect_url=$("#redirect_url_input").val(),-1!=e?(a.id=pages[e].id,api.pageId.put(a).success(function(e){successFlash("Page edited successfully!"),load(),dismiss()})):api.pages.post(a).success(function(e){successFlash("Page added successfully!"),load(),dismiss()}).error(function(e){modalError(e.responseJSON.message)})}function dismiss(){$("#modal\\.flashes").empty(),$("#name").val(""),$("#html_editor").val(""),$("#url").val(""),$("#redirect_url_input").val(""),$("#modal").find("input[type='checkbox']").prop("checked",!1),$("#capture_passwords").hide(),$("#redirect_url").hide(),$("#modal").modal("hide")}var deletePage=function(e){Swal.fire({title:"Are you sure?",text:"This will delete the landing page. This can't be undone!",type:"warning",animation:!1,showCancelButton:!0,confirmButtonText:"Delete "+escapeHtml(pages[e].name),confirmButtonColor:"#428bca",reverseButtons:!0,allowOutsideClick:!1,preConfirm:function(){return new Promise(function(a,t){api.pageId.delete(pages[e].id).success(function(e){a()}).error(function(e){t(e.responseJSON.message)})})}}).then(function(e){e.value&&Swal.fire("Landing Page Deleted!","This landing page has been deleted!","success"),$('button:contains("OK")').on("click",function(){location.reload()})})};function importSite(){url=$("#url").val(),url?api.clone_site({url:url,include_resources:!1}).success(function(e){$("#html_editor").val(e.html),CKEDITOR.instances.html_editor.setMode("wysiwyg"),$("#importSiteModal").modal("hide")}).error(function(e){modalError(e.responseJSON.message)}):modalError("No URL Specified!")}function edit(e){$("#modalSubmit").unbind("click").click(function(){save(e)}),$("#html_editor").ckeditor(),setupAutocomplete(CKEDITOR.instances.html_editor);var a={};-1!=e&&(a=pages[e],$("#name").val(a.name),$("#html_editor").val(a.html),$("#capture_credentials_checkbox").prop("checked",a.capture_credentials),$("#capture_passwords_checkbox").prop("checked",a.capture_passwords),$("#redirect_url_input").val(a.redirect_url),a.capture_credentials&&($("#capture_passwords").show(),$("#redirect_url").show()))}function copy(e){$("#modalSubmit").unbind("click").click(function(){save(-1)}),$("#html_editor").ckeditor();var a=pages[e];$("#name").val("Copy of "+a.name),$("#html_editor").val(a.html)}function load(){$("#pagesTable").hide(),$("#emptyMessage").hide(),$("#loading").show(),api.pages.get().success(function(e){pages=e,$("#loading").hide(),0\t\t "])}),pagesTable.rows.add(pageRows).draw(),$('[data-toggle="tooltip"]').tooltip()):$("#emptyMessage").show()}).error(function(){$("#loading").hide(),errorFlash("Error fetching pages")})}$(document).ready(function(){$(".modal").on("hidden.bs.modal",function(e){$(this).removeClass("fv-modal-stack"),$("body").data("fv_open_modals",$("body").data("fv_open_modals")-1)}),$(".modal").on("shown.bs.modal",function(e){void 0===$("body").data("fv_open_modals")&&$("body").data("fv_open_modals",0),$(this).hasClass("fv-modal-stack")||($(this).addClass("fv-modal-stack"),$("body").data("fv_open_modals",$("body").data("fv_open_modals")+1),$(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").on("focusin.bs.modal",$.proxy(function(e){this.$element[0]===e.target||this.$element.has(e.target).length||$(e.target).closest(".cke_dialog, .cke").length||this.$element.trigger("focus")},this))},$(document).on("hidden.bs.modal",".modal",function(){$(".modal:visible").length&&$(document.body).addClass("modal-open")}),$("#modal").on("hidden.bs.modal",function(e){dismiss()}),$("#capture_credentials_checkbox").change(function(){$("#capture_passwords").toggle(),$("#redirect_url").toggle()}),CKEDITOR.on("dialogDefinition",function(e){var a=e.data.name,t=e.data.definition;"link"==a&&(t.minWidth=500,t.minHeight=100,t.getContents("info").get("linkType").hidden=!0)}),load()});
\ No newline at end of file
+var pages=[];function save(e){var a={};a.name=$("#name").val(),editor=CKEDITOR.instances.html_editor,a.html=editor.getData(),a.capture_credentials=$("#capture_credentials_checkbox").prop("checked"),a.capture_passwords=$("#capture_passwords_checkbox").prop("checked"),a.redirect_url=$("#redirect_url_input").val(),-1!=e?(a.id=pages[e].id,api.pageId.put(a).success((function(e){successFlash("Page edited successfully!"),load(),dismiss()}))):api.pages.post(a).success((function(e){successFlash("Page added successfully!"),load(),dismiss()})).error((function(e){modalError(e.responseJSON.message)}))}function dismiss(){$("#modal\\.flashes").empty(),$("#name").val(""),$("#html_editor").val(""),$("#url").val(""),$("#redirect_url_input").val(""),$("#modal").find("input[type='checkbox']").prop("checked",!1),$("#capture_passwords").hide(),$("#redirect_url").hide(),$("#modal").modal("hide")}var deletePage=function(e){Swal.fire({title:"Are you sure?",text:"This will delete the landing page. This can't be undone!",type:"warning",animation:!1,showCancelButton:!0,confirmButtonText:"Delete "+escapeHtml(pages[e].name),confirmButtonColor:"#428bca",reverseButtons:!0,allowOutsideClick:!1,preConfirm:function(){return new Promise((function(a,t){api.pageId.delete(pages[e].id).success((function(e){a()})).error((function(e){t(e.responseJSON.message)}))}))}}).then((function(e){e.value&&Swal.fire("Landing Page Deleted!","This landing page has been deleted!","success"),$('button:contains("OK")').on("click",(function(){location.reload()}))}))};function importSite(){url=$("#url").val(),url?api.clone_site({url:url,include_resources:!1}).success((function(e){$("#html_editor").val(e.html),CKEDITOR.instances.html_editor.setMode("wysiwyg"),$("#importSiteModal").modal("hide")})).error((function(e){modalError(e.responseJSON.message)})):modalError("No URL Specified!")}function edit(e){$("#modalSubmit").unbind("click").click((function(){save(e)})),$("#html_editor").ckeditor(),setupAutocomplete(CKEDITOR.instances.html_editor);var a={};-1!=e?($("#modalLabel").text("Edit Landing Page"),a=pages[e],$("#name").val(a.name),$("#html_editor").val(a.html),$("#capture_credentials_checkbox").prop("checked",a.capture_credentials),$("#capture_passwords_checkbox").prop("checked",a.capture_passwords),$("#redirect_url_input").val(a.redirect_url),a.capture_credentials&&($("#capture_passwords").show(),$("#redirect_url").show())):$("#modalLabel").text("New Landing Page")}function copy(e){$("#modalSubmit").unbind("click").click((function(){save(-1)})),$("#html_editor").ckeditor();var a=pages[e];$("#name").val("Copy of "+a.name),$("#html_editor").val(a.html)}function load(){$("#pagesTable").hide(),$("#emptyMessage").hide(),$("#loading").show(),api.pages.get().success((function(e){pages=e,$("#loading").hide(),pages.length>0?($("#pagesTable").show(),pagesTable=$("#pagesTable").DataTable({destroy:!0,columnDefs:[{orderable:!1,targets:"no-sort"}]}),pagesTable.clear(),pageRows=[],$.each(pages,(function(e,a){pageRows.push([escapeHtml(a.name),moment(a.modified_date).format("MMMM Do YYYY, h:mm:ss a"),"
\t\t
"])})),pagesTable.rows.add(pageRows).draw(),$('[data-toggle="tooltip"]').tooltip()):$("#emptyMessage").show()})).error((function(){$("#loading").hide(),errorFlash("Error fetching pages")}))}$(document).ready((function(){$(".modal").on("hidden.bs.modal",(function(e){$(this).removeClass("fv-modal-stack"),$("body").data("fv_open_modals",$("body").data("fv_open_modals")-1)})),$(".modal").on("shown.bs.modal",(function(e){void 0===$("body").data("fv_open_modals")&&$("body").data("fv_open_modals",0),$(this).hasClass("fv-modal-stack")||($(this).addClass("fv-modal-stack"),$("body").data("fv_open_modals",$("body").data("fv_open_modals")+1),$(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").on("focusin.bs.modal",$.proxy((function(e){this.$element[0]===e.target||this.$element.has(e.target).length||$(e.target).closest(".cke_dialog, .cke").length||this.$element.trigger("focus")}),this))},$(document).on("hidden.bs.modal",".modal",(function(){$(".modal:visible").length&&$(document.body).addClass("modal-open")})),$("#modal").on("hidden.bs.modal",(function(e){dismiss()})),$("#capture_credentials_checkbox").change((function(){$("#capture_passwords").toggle(),$("#redirect_url").toggle()})),CKEDITOR.on("dialogDefinition",(function(e){var a=e.data.name,t=e.data.definition;"link"==a&&(t.minWidth=500,t.minHeight=100,t.getContents("info").get("linkType").hidden=!0)})),load()}));
\ No newline at end of file
diff --git a/static/js/dist/app/sending_profiles.min.js b/static/js/dist/app/sending_profiles.min.js
index ab20df39..a77d4135 100644
--- a/static/js/dist/app/sending_profiles.min.js
+++ b/static/js/dist/app/sending_profiles.min.js
@@ -1 +1 @@
-var profiles=[];function sendTestEmail(){var t=[];$.each($("#headersTable").DataTable().rows().data(),function(e,a){t.push({key:unescapeHtml(a[0]),value:unescapeHtml(a[1])})});var e={template:{},first_name:$("input[name=to_first_name]").val(),last_name:$("input[name=to_last_name]").val(),email:$("input[name=to_email]").val(),position:$("input[name=to_position]").val(),url:"",smtp:{from_address:$("#from").val(),host:$("#host").val(),username:$("#username").val(),password:$("#password").val(),ignore_cert_errors:$("#ignore_cert_errors").prop("checked"),headers:t}};btnHtml=$("#sendTestModalSubmit").html(),$("#sendTestModalSubmit").html(' Sending'),api.send_test_email(e).success(function(e){$("#sendTestEmailModal\\.flashes").empty().append('
"),$("#sendTestModalSubmit").html(btnHtml)})}function save(e){var t={headers:[]};$.each($("#headersTable").DataTable().rows().data(),function(e,a){t.headers.push({key:unescapeHtml(a[0]),value:unescapeHtml(a[1])})}),t.name=$("#name").val(),t.interface_type=$("#interface_type").val(),t.from_address=$("#from").val(),t.host=$("#host").val(),t.username=$("#username").val(),t.password=$("#password").val(),t.ignore_cert_errors=$("#ignore_cert_errors").prop("checked"),-1!=e?(t.id=profiles[e].id,api.SMTPId.put(t).success(function(e){successFlash("Profile edited successfully!"),load(),dismiss()}).error(function(e){modalError(e.responseJSON.message)})):api.SMTP.post(t).success(function(e){successFlash("Profile added successfully!"),load(),dismiss()}).error(function(e){modalError(e.responseJSON.message)})}function dismiss(){$("#modal\\.flashes").empty(),$("#name").val(""),$("#interface_type").val("SMTP"),$("#from").val(""),$("#host").val(""),$("#username").val(""),$("#password").val(""),$("#ignore_cert_errors").prop("checked",!0),$("#headersTable").dataTable().DataTable().clear().draw(),$("#modal").modal("hide")}var dismissSendTestEmailModal=function(){$("#sendTestEmailModal\\.flashes").empty(),$("#sendTestModalSubmit").html(" Send")},deleteProfile=function(e){Swal.fire({title:"Are you sure?",text:"This will delete the sending profile. This can't be undone!",type:"warning",animation:!1,showCancelButton:!0,confirmButtonText:"Delete "+escapeHtml(profiles[e].name),confirmButtonColor:"#428bca",reverseButtons:!0,allowOutsideClick:!1,preConfirm:function(){return new Promise(function(a,t){api.SMTPId.delete(profiles[e].id).success(function(e){a()}).error(function(e){t(e.responseJSON.message)})})}}).then(function(e){e.value&&Swal.fire("Sending Profile Deleted!","This sending profile has been deleted!","success"),$('button:contains("OK")').on("click",function(){location.reload()})})};function edit(e){headers=$("#headersTable").dataTable({destroy:!0,columnDefs:[{orderable:!1,targets:"no-sort"}]}),$("#modalSubmit").unbind("click").click(function(){save(e)});var a;-1!=e&&(a=profiles[e],$("#name").val(a.name),$("#interface_type").val(a.interface_type),$("#from").val(a.from_address),$("#host").val(a.host),$("#username").val(a.username),$("#password").val(a.password),$("#ignore_cert_errors").prop("checked",a.ignore_cert_errors),$.each(a.headers,function(e,a){addCustomHeader(a.key,a.value)}))}function copy(e){$("#modalSubmit").unbind("click").click(function(){save(-1)});var a=profiles[e];$("#name").val("Copy of "+a.name),$("#interface_type").val(a.interface_type),$("#from").val(a.from_address),$("#host").val(a.host),$("#username").val(a.username),$("#password").val(a.password),$("#ignore_cert_errors").prop("checked",a.ignore_cert_errors)}function load(){$("#profileTable").hide(),$("#emptyMessage").hide(),$("#loading").show(),api.SMTP.get().success(function(e){profiles=e,$("#loading").hide(),0\t\t "])}),profileTable.rows.add(profileRows).draw(),$('[data-toggle="tooltip"]').tooltip()):$("#emptyMessage").show()}).error(function(){$("#loading").hide(),errorFlash("Error fetching profiles")})}function addCustomHeader(e,a){var t=[escapeHtml(e),escapeHtml(a),''],a=headers.DataTable(),e=a.column(0).data().indexOf(escapeHtml(e));0<=e?a.row(e,{order:"index"}).data(t):a.row.add(t),a.draw()}$(document).ready(function(){$(".modal").on("hidden.bs.modal",function(e){$(this).removeClass("fv-modal-stack"),$("body").data("fv_open_modals",$("body").data("fv_open_modals")-1)}),$(".modal").on("shown.bs.modal",function(e){void 0===$("body").data("fv_open_modals")&&$("body").data("fv_open_modals",0),$(this).hasClass("fv-modal-stack")||($(this).addClass("fv-modal-stack"),$("body").data("fv_open_modals",$("body").data("fv_open_modals")+1),$(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").on("focusin.bs.modal",$.proxy(function(e){this.$element[0]===e.target||this.$element.has(e.target).length||$(e.target).closest(".cke_dialog, .cke").length||this.$element.trigger("focus")},this))},$(document).on("hidden.bs.modal",".modal",function(){$(".modal:visible").length&&$(document.body).addClass("modal-open")}),$("#modal").on("hidden.bs.modal",function(e){dismiss()}),$("#sendTestEmailModal").on("hidden.bs.modal",function(e){dismissSendTestEmailModal()}),$("#addCustomHeader").on("click",function(){return headerKey=$("#headerKey").val(),headerValue=$("#headerValue").val(),""==headerKey||""==headerValue||(addCustomHeader(headerKey,headerValue),$("#headerKey").val(""),$("#headerValue").val(""),$("#headerKey").focus()),!1}),$("#headersTable").on("click","span>i.fa-trash-o",function(){headers.DataTable().row($(this).parents("tr")).remove().draw()}),load()});
\ No newline at end of file
+var profiles=[];function sendTestEmail(){var e=[];$.each($("#headersTable").DataTable().rows().data(),(function(a,o){e.push({key:unescapeHtml(o[0]),value:unescapeHtml(o[1])})}));var a={template:{},first_name:$("input[name=to_first_name]").val(),last_name:$("input[name=to_last_name]").val(),email:$("input[name=to_email]").val(),position:$("input[name=to_position]").val(),url:"",smtp:{from_address:$("#from").val(),host:$("#host").val(),username:$("#username").val(),password:$("#password").val(),ignore_cert_errors:$("#ignore_cert_errors").prop("checked"),headers:e}};btnHtml=$("#sendTestModalSubmit").html(),$("#sendTestModalSubmit").html(' Sending'),api.send_test_email(a).success((function(e){$("#sendTestEmailModal\\.flashes").empty().append('
"),$("#sendTestModalSubmit").html(btnHtml)}))}function save(e){var a={headers:[]};$.each($("#headersTable").DataTable().rows().data(),(function(e,o){a.headers.push({key:unescapeHtml(o[0]),value:unescapeHtml(o[1])})})),a.name=$("#name").val(),a.interface_type=$("#interface_type").val(),a.from_address=$("#from").val(),a.host=$("#host").val(),a.username=$("#username").val(),a.password=$("#password").val(),a.ignore_cert_errors=$("#ignore_cert_errors").prop("checked"),-1!=e?(a.id=profiles[e].id,api.SMTPId.put(a).success((function(e){successFlash("Profile edited successfully!"),load(),dismiss()})).error((function(e){modalError(e.responseJSON.message)}))):api.SMTP.post(a).success((function(e){successFlash("Profile added successfully!"),load(),dismiss()})).error((function(e){modalError(e.responseJSON.message)}))}function dismiss(){$("#modal\\.flashes").empty(),$("#name").val(""),$("#interface_type").val("SMTP"),$("#from").val(""),$("#host").val(""),$("#username").val(""),$("#password").val(""),$("#ignore_cert_errors").prop("checked",!0),$("#headersTable").dataTable().DataTable().clear().draw(),$("#modal").modal("hide")}var dismissSendTestEmailModal=function(){$("#sendTestEmailModal\\.flashes").empty(),$("#sendTestModalSubmit").html(" Send")},deleteProfile=function(e){Swal.fire({title:"Are you sure?",text:"This will delete the sending profile. This can't be undone!",type:"warning",animation:!1,showCancelButton:!0,confirmButtonText:"Delete "+escapeHtml(profiles[e].name),confirmButtonColor:"#428bca",reverseButtons:!0,allowOutsideClick:!1,preConfirm:function(){return new Promise((function(a,o){api.SMTPId.delete(profiles[e].id).success((function(e){a()})).error((function(e){o(e.responseJSON.message)}))}))}}).then((function(e){e.value&&Swal.fire("Sending Profile Deleted!","This sending profile has been deleted!","success"),$('button:contains("OK")').on("click",(function(){location.reload()}))}))};function edit(e){headers=$("#headersTable").dataTable({destroy:!0,columnDefs:[{orderable:!1,targets:"no-sort"}]}),$("#modalSubmit").unbind("click").click((function(){save(e)}));var a={};-1!=e?($("#profileModalLabel").text("Edit Sending Profile"),a=profiles[e],$("#name").val(a.name),$("#interface_type").val(a.interface_type),$("#from").val(a.from_address),$("#host").val(a.host),$("#username").val(a.username),$("#password").val(a.password),$("#ignore_cert_errors").prop("checked",a.ignore_cert_errors),$.each(a.headers,(function(e,a){addCustomHeader(a.key,a.value)}))):$("#profileModalLabel").text("New Sending Profile")}function copy(e){$("#modalSubmit").unbind("click").click((function(){save(-1)}));var a;a=profiles[e],$("#name").val("Copy of "+a.name),$("#interface_type").val(a.interface_type),$("#from").val(a.from_address),$("#host").val(a.host),$("#username").val(a.username),$("#password").val(a.password),$("#ignore_cert_errors").prop("checked",a.ignore_cert_errors)}function load(){$("#profileTable").hide(),$("#emptyMessage").hide(),$("#loading").show(),api.SMTP.get().success((function(e){profiles=e,$("#loading").hide(),profiles.length>0?($("#profileTable").show(),profileTable=$("#profileTable").DataTable({destroy:!0,columnDefs:[{orderable:!1,targets:"no-sort"}]}),profileTable.clear(),profileRows=[],$.each(profiles,(function(e,a){profileRows.push([escapeHtml(a.name),a.interface_type,moment(a.modified_date).format("MMMM Do YYYY, h:mm:ss a"),"
\t\t
"])})),profileTable.rows.add(profileRows).draw(),$('[data-toggle="tooltip"]').tooltip()):$("#emptyMessage").show()})).error((function(){$("#loading").hide(),errorFlash("Error fetching profiles")}))}function addCustomHeader(e,a){var o=[escapeHtml(e),escapeHtml(a),''],t=headers.DataTable(),s=t.column(0).data().indexOf(escapeHtml(e));s>=0?t.row(s,{order:"index"}).data(o):t.row.add(o),t.draw()}$(document).ready((function(){$(".modal").on("hidden.bs.modal",(function(e){$(this).removeClass("fv-modal-stack"),$("body").data("fv_open_modals",$("body").data("fv_open_modals")-1)})),$(".modal").on("shown.bs.modal",(function(e){void 0===$("body").data("fv_open_modals")&&$("body").data("fv_open_modals",0),$(this).hasClass("fv-modal-stack")||($(this).addClass("fv-modal-stack"),$("body").data("fv_open_modals",$("body").data("fv_open_modals")+1),$(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").on("focusin.bs.modal",$.proxy((function(e){this.$element[0]===e.target||this.$element.has(e.target).length||$(e.target).closest(".cke_dialog, .cke").length||this.$element.trigger("focus")}),this))},$(document).on("hidden.bs.modal",".modal",(function(){$(".modal:visible").length&&$(document.body).addClass("modal-open")})),$("#modal").on("hidden.bs.modal",(function(e){dismiss()})),$("#sendTestEmailModal").on("hidden.bs.modal",(function(e){dismissSendTestEmailModal()})),$("#headersForm").on("submit",(function(){return headerKey=$("#headerKey").val(),headerValue=$("#headerValue").val(),""==headerKey||""==headerValue||(addCustomHeader(headerKey,headerValue),$("#headersForm>div>input").val(""),$("#headerKey").focus()),!1})),$("#headersTable").on("click","span>i.fa-trash-o",(function(){headers.DataTable().row($(this).parents("tr")).remove().draw()})),load()}));
\ No newline at end of file
diff --git a/static/js/dist/app/templates.min.js b/static/js/dist/app/templates.min.js
index 049676c4..9a76eaf2 100644
--- a/static/js/dist/app/templates.min.js
+++ b/static/js/dist/app/templates.min.js
@@ -1 +1 @@
-var templates=[],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"};function save(e){var a={attachments:[]};a.name=$("#name").val(),a.subject=$("#subject").val(),a.envelope_sender=$("#envelope-sender").val(),a.html=CKEDITOR.instances.html_editor.getData(),a.html=a.html.replace(/https?:\/\/{{\.URL}}/gi,"{{.URL}}"),$("#use_tracker_checkbox").prop("checked")?-1==a.html.indexOf("{{.Tracker}}")&&-1==a.html.indexOf("{{.TrackingUrl}}")&&(a.html=a.html.replace("