mirror of https://github.com/gophish/gophish
Adding the ability to import emails - WIP
parent
abafb02586
commit
b45a72618d
|
@ -4,7 +4,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
@ -14,6 +13,7 @@ import (
|
||||||
ctx "github.com/gorilla/context"
|
ctx "github.com/gorilla/context"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
|
"github.com/jordan-wright/email"
|
||||||
"github.com/jordan-wright/gophish/auth"
|
"github.com/jordan-wright/gophish/auth"
|
||||||
"github.com/jordan-wright/gophish/models"
|
"github.com/jordan-wright/gophish/models"
|
||||||
"github.com/jordan-wright/gophish/util"
|
"github.com/jordan-wright/gophish/util"
|
||||||
|
@ -363,12 +363,17 @@ func API_Import_Email(w http.ResponseWriter, r *http.Request) {
|
||||||
JSONResponse(w, models.Response{Success: false, Message: "Method not allowed"}, http.StatusBadRequest)
|
JSONResponse(w, models.Response{Success: false, Message: "Method not allowed"}, http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
body, err := ioutil.ReadAll(r.Body)
|
defer r.Body.Close()
|
||||||
|
e, err := email.NewEmailFromReader(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Logger.Println(err)
|
Logger.Println(err)
|
||||||
}
|
}
|
||||||
w.Header().Set("Content-Type", "text/plain")
|
er := emailResponse{
|
||||||
fmt.Fprintf(w, "%s", body)
|
Subject: e.Subject,
|
||||||
|
Text: string(e.Text),
|
||||||
|
HTML: string(e.HTML),
|
||||||
|
}
|
||||||
|
JSONResponse(w, er, http.StatusOK)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,3 +448,9 @@ func (cr *cloneRequest) validate() error {
|
||||||
type cloneResponse struct {
|
type cloneResponse struct {
|
||||||
HTML string `json:"html"`
|
HTML string `json:"html"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type emailResponse struct {
|
||||||
|
Text string `json:"text"`
|
||||||
|
HTML string `json:"html"`
|
||||||
|
Subject string `json:"subject"`
|
||||||
|
}
|
||||||
|
|
|
@ -52,7 +52,6 @@ function save(idx){
|
||||||
|
|
||||||
function dismiss(){
|
function dismiss(){
|
||||||
$("#modal\\.flashes").empty()
|
$("#modal\\.flashes").empty()
|
||||||
$("#modal").modal('hide')
|
|
||||||
$("#attachmentsTable").dataTable().DataTable().clear().draw()
|
$("#attachmentsTable").dataTable().DataTable().clear().draw()
|
||||||
$("#name").val("")
|
$("#name").val("")
|
||||||
$("#text_editor").val("")
|
$("#text_editor").val("")
|
||||||
|
@ -113,6 +112,7 @@ function edit(idx){
|
||||||
if (idx != -1) {
|
if (idx != -1) {
|
||||||
template = templates[idx]
|
template = templates[idx]
|
||||||
$("#name").val(template.name)
|
$("#name").val(template.name)
|
||||||
|
$("#subject").val(template.subject)
|
||||||
$("#html_editor").val(template.html)
|
$("#html_editor").val(template.html)
|
||||||
$("#text_editor").val(template.text)
|
$("#text_editor").val(template.text)
|
||||||
$.each(template.attachments, function(i, file){
|
$.each(template.attachments, function(i, file){
|
||||||
|
@ -135,6 +135,30 @@ function edit(idx){
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function importEmail(){
|
||||||
|
raw = $("#email_content").val()
|
||||||
|
if (!raw){
|
||||||
|
modalError("No Content Specified!")
|
||||||
|
} else {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/api/import/email",
|
||||||
|
data: raw,
|
||||||
|
dataType: "json",
|
||||||
|
contentType: "text/plain"
|
||||||
|
})
|
||||||
|
.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(){
|
function load(){
|
||||||
$("#templateTable").hide()
|
$("#templateTable").hide()
|
||||||
$("#emptyMessage").hide()
|
$("#emptyMessage").hide()
|
||||||
|
@ -170,7 +194,32 @@ function load(){
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
$.fn.modal.Constructor.prototype.enforceFocus = 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 )
|
$( document )
|
||||||
.off( 'focusin.bs.modal' ) // guard against infinite focus loop
|
.off( 'focusin.bs.modal' ) // guard against infinite focus loop
|
||||||
.on( 'focusin.bs.modal', $.proxy( function( e ) {
|
.on( 'focusin.bs.modal', $.proxy( function( e ) {
|
||||||
|
|
|
@ -132,6 +132,10 @@ var api = {
|
||||||
return query("/pages/" + id, "DELETE", {})
|
return query("/pages/" + id, "DELETE", {})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// import handles all of the "import" functions in the api
|
||||||
|
import_email : function(raw) {
|
||||||
|
return query("/import/email", "POST", {})
|
||||||
|
},
|
||||||
clone_site : function(req){
|
clone_site : function(req){
|
||||||
return query("/import/site", "POST", req)
|
return query("/import/site", "POST", req)
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@
|
||||||
<input type="text" class="form-control" ng-model="template.name" placeholder="Template name" id="name" autofocus/>
|
<input type="text" class="form-control" ng-model="template.name" placeholder="Template name" id="name" autofocus/>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<button class="btn btn-danger btn-disabled" ng-click="importEmail()"><i class="fa fa-envelope"></i> Import Email (Coming Soon!)</button>
|
<button class="btn btn-danger" data-toggle="modal" data-target="#importEmailModal"><i class="fa fa-envelope"></i> Import Email (Coming Soon!)</button>
|
||||||
</div>
|
</div>
|
||||||
<label class="control-label" for="subject">Subject:</label>
|
<label class="control-label" for="subject">Subject:</label>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -111,10 +111,34 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-default" onclick="dismiss()">Cancel</button>
|
<button type="button" data-dismiss="modal" class="btn btn-default" onclick="dismiss()">Cancel</button>
|
||||||
<button type="button" class="btn btn-primary" id="modalSubmit">Save Template</button>
|
<button type="button" class="btn btn-primary" id="modalSubmit">Save Template</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Modal -->
|
||||||
|
<div class="modal fade" id="importEmailModal" tabindex="-1" role="dialog" aria-labelledby="modalLabel">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<!-- New Email Modal -->
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||||
|
<h4 class="modal-title" id="importEmailModalLabel">Import Email</h4>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="row" id="modal.flashes"></div>
|
||||||
|
<label class="control-label" for="email">Email Content:</label>
|
||||||
|
<div class="form-group">
|
||||||
|
<textarea rows="10" id="email_content" class="form-control" placeholder="Raw Email Source"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" data-dismiss="modal" class="btn btn-default" onclick="dismiss()">Cancel</button>
|
||||||
|
<button type="button" class="btn btn-primary" id="modalSubmit" onclick="importEmail()">Import</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{define "scripts"}}
|
{{define "scripts"}}
|
||||||
|
|
Loading…
Reference in New Issue